Mir

Merge lp:~hikiko/mir/mir.bug-1206633 into lp:~mir-team/mir/trunk

Proposed by Eleni Maria Stea
Status: Work in progress
Proposed branch: lp:~hikiko/mir/mir.bug-1206633
Merge into: lp:~mir-team/mir/trunk
Diff against target: 159 lines (+58/-3)
2 files modified
src/server/graphics/gbm/gbm_display_helpers.cpp (+49/-1)
tests/unit-tests/graphics/gbm/test_gbm_display.cpp (+9/-2)
To merge this branch: bzr merge lp:~hikiko/mir/mir.bug-1206633
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Mir development team Pending
Review via email: mp+184520@code.launchpad.net

Commit message

This branch seems to fix the bug #1206633.
Changes:
- added significant messages to all errors in open_drm_device (not only those with errno)
- added drmSetMaster drmDropMaster around the drmSetInterfaceVersion (only drm master can run this command)
- added a call to drmSetMaster right before returning the selected and opened drm device to avoid the crash (some operations that need mir to be the master take place before we call drmSetMaster otherwise)

Question:
I think that the drmSetInterfaceVersion is not 100% necessary (we can just assume that the device is "usable" based on the other checks we have), also this call doesn't exist in older libdrm versions. Do you think I should remove it?

Description of the change

This branch seems to fix the bug #1206633.
Changes:
- added significant messages to all errors in open_drm_device (not only those with errno)
- added drmSetMaster drmDropMaster around the drmSetInterfaceVersion (only drm master can run this command)
- added a call to drmSetMaster right before returning the selected and opened drm device to avoid the crash (some operations that need mir to be the master take place before we call drmSetMaster otherwise)

Question:
I think that the drmSetInterfaceVersion is not 100% necessary (we can just assume that the device is "usable" based on the other checks we have), also this call doesn't exist in older libdrm versions. Do you think I should remove it?

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/server/graphics/gbm/gbm_display_helpers.cpp'
2--- src/server/graphics/gbm/gbm_display_helpers.cpp 2013-09-02 11:32:59 +0000
3+++ src/server/graphics/gbm/gbm_display_helpers.cpp 2013-09-10 13:47:55 +0000
4@@ -32,6 +32,9 @@
5 namespace mgg = mir::graphics::gbm;
6 namespace mggh = mir::graphics::gbm::helpers;
7
8+static void drm_set_master(int fd);
9+static void drm_drop_master(int fd);
10+
11 /**************
12 * UdevHelper *
13 **************/
14@@ -210,6 +213,7 @@
15
16 int mggh::DRMHelper::open_drm_device(UdevHelper const& udev)
17 {
18+ std::string excstr;
19 int tmp_fd = -1;
20 int error;
21
22@@ -237,6 +241,7 @@
23
24 if ((error = is_appropriate_device(udev, dev)))
25 {
26+ excstr = "Udev is not appropriate";
27 udev_device_unref(dev);
28 continue;
29 }
30@@ -247,6 +252,7 @@
31 tmp_fd = open(dev_path, O_RDWR, O_CLOEXEC);
32 if (tmp_fd < 0)
33 {
34+ excstr = "Direct opening of drm device failed";
35 error = errno;
36 udev_device_unref(dev);
37 continue;
38@@ -254,6 +260,7 @@
39
40 udev_device_unref(dev);
41
42+ drm_set_master(tmp_fd);
43 // Check that the drm device is usable by setting the interface version we use (1.4)
44 drmSetVersion sv;
45 sv.drm_di_major = 1;
46@@ -263,10 +270,13 @@
47
48 if ((error = drmSetInterfaceVersion(tmp_fd, &sv)))
49 {
50+ excstr = "Invalid interface version";
51+ drm_drop_master(tmp_fd);
52 close(tmp_fd);
53 tmp_fd = -1;
54 continue;
55 }
56+ drm_drop_master(tmp_fd);
57
58 // Stop if this device has connections to display on
59 if (count_connections(tmp_fd) > 0)
60@@ -281,16 +291,19 @@
61 {
62 BOOST_THROW_EXCEPTION(
63 boost::enable_error_info(
64- std::runtime_error("Error opening DRM device")) << boost::errinfo_errno(-error));
65+ std::runtime_error("Error opening DRM device. Reason: " + excstr)) << boost::errinfo_errno(-error));
66 }
67
68+ drm_set_master(tmp_fd);
69 return tmp_fd;
70 }
71
72 mggh::DRMHelper::~DRMHelper()
73 {
74 if (fd >= 0)
75+ {
76 mgg::drm_close_threadsafe(fd);
77+ }
78 }
79
80 /*************
81@@ -470,3 +483,38 @@
82 {
83 f(egl_display, egl_config);
84 }
85+
86+void drm_set_master(int fd)
87+{
88+ if (fd < 0)
89+ {
90+ BOOST_THROW_EXCEPTION(
91+ std::runtime_error("Tried to set DRM master without a DRM device"));
92+ }
93+
94+ int ret = drmSetMaster(fd);
95+ if (ret < 0)
96+ {
97+ BOOST_THROW_EXCEPTION(
98+ boost::enable_error_info(
99+ std::runtime_error("Failed to set DRM master"))
100+ << boost::errinfo_errno(-ret));
101+ }
102+}
103+
104+void drm_drop_master(int fd)
105+{
106+ if (fd < 0)
107+ {
108+ BOOST_THROW_EXCEPTION(
109+ std::runtime_error("Tried to drop DRM master without a DRM device"));
110+ }
111+ int ret = drmDropMaster(fd);
112+ if (ret < 0)
113+ {
114+ BOOST_THROW_EXCEPTION(
115+ boost::enable_error_info(
116+ std::runtime_error("Failed to drop DRM master"))
117+ << boost::errinfo_errno(-ret));
118+ }
119+}
120
121=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_display.cpp'
122--- tests/unit-tests/graphics/gbm/test_gbm_display.cpp 2013-08-28 03:41:48 +0000
123+++ tests/unit-tests/graphics/gbm/test_gbm_display.cpp 2013-09-10 13:47:55 +0000
124@@ -647,7 +647,7 @@
125 using namespace testing;
126
127 EXPECT_CALL(mock_drm, drmDropMaster(mock_drm.fake_drm.fd()))
128- .Times(1);
129+ .Times(2);
130
131 auto display = create_display(create_platform());
132
133@@ -659,7 +659,7 @@
134 using namespace testing;
135
136 EXPECT_CALL(mock_drm, drmSetMaster(mock_drm.fake_drm.fd()))
137- .Times(1);
138+ .Times(3);
139
140 auto display = create_display(create_platform());
141
142@@ -670,10 +670,17 @@
143 {
144 using namespace testing;
145
146+ // drmDropMaster, drmSetMaster will be successful one time because they
147+ // are called with a valid file descriptor in gbm_display_helpers.cpp
148+ // open_drm_device()
149+
150 EXPECT_CALL(mock_drm, drmDropMaster(_))
151+ .WillOnce(Return(0))
152 .WillOnce(SetErrnoAndReturn(EACCES, -EACCES));
153
154 EXPECT_CALL(mock_drm, drmSetMaster(_))
155+ .WillOnce(Return(0))
156+ .WillOnce(Return(0))
157 .WillOnce(SetErrnoAndReturn(EPERM, -EPERM));
158
159 EXPECT_CALL(*mock_report, report_drm_master_failure(EACCES));

Subscribers

People subscribed via source and target branches