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
=== modified file 'src/server/graphics/gbm/gbm_display_helpers.cpp'
--- src/server/graphics/gbm/gbm_display_helpers.cpp 2013-09-02 11:32:59 +0000
+++ src/server/graphics/gbm/gbm_display_helpers.cpp 2013-09-10 13:47:55 +0000
@@ -32,6 +32,9 @@
32namespace mgg = mir::graphics::gbm;32namespace mgg = mir::graphics::gbm;
33namespace mggh = mir::graphics::gbm::helpers;33namespace mggh = mir::graphics::gbm::helpers;
3434
35static void drm_set_master(int fd);
36static void drm_drop_master(int fd);
37
35/**************38/**************
36 * UdevHelper *39 * UdevHelper *
37 **************/40 **************/
@@ -210,6 +213,7 @@
210213
211int mggh::DRMHelper::open_drm_device(UdevHelper const& udev)214int mggh::DRMHelper::open_drm_device(UdevHelper const& udev)
212{ 215{
216 std::string excstr;
213 int tmp_fd = -1;217 int tmp_fd = -1;
214 int error;218 int error;
215219
@@ -237,6 +241,7 @@
237241
238 if ((error = is_appropriate_device(udev, dev)))242 if ((error = is_appropriate_device(udev, dev)))
239 {243 {
244 excstr = "Udev is not appropriate";
240 udev_device_unref(dev);245 udev_device_unref(dev);
241 continue;246 continue;
242 }247 }
@@ -247,6 +252,7 @@
247 tmp_fd = open(dev_path, O_RDWR, O_CLOEXEC);252 tmp_fd = open(dev_path, O_RDWR, O_CLOEXEC);
248 if (tmp_fd < 0)253 if (tmp_fd < 0)
249 {254 {
255 excstr = "Direct opening of drm device failed";
250 error = errno;256 error = errno;
251 udev_device_unref(dev);257 udev_device_unref(dev);
252 continue;258 continue;
@@ -254,6 +260,7 @@
254260
255 udev_device_unref(dev);261 udev_device_unref(dev);
256262
263 drm_set_master(tmp_fd);
257 // Check that the drm device is usable by setting the interface version we use (1.4)264 // Check that the drm device is usable by setting the interface version we use (1.4)
258 drmSetVersion sv;265 drmSetVersion sv;
259 sv.drm_di_major = 1;266 sv.drm_di_major = 1;
@@ -263,10 +270,13 @@
263270
264 if ((error = drmSetInterfaceVersion(tmp_fd, &sv)))271 if ((error = drmSetInterfaceVersion(tmp_fd, &sv)))
265 {272 {
273 excstr = "Invalid interface version";
274 drm_drop_master(tmp_fd);
266 close(tmp_fd);275 close(tmp_fd);
267 tmp_fd = -1;276 tmp_fd = -1;
268 continue;277 continue;
269 }278 }
279 drm_drop_master(tmp_fd);
270280
271 // Stop if this device has connections to display on281 // Stop if this device has connections to display on
272 if (count_connections(tmp_fd) > 0)282 if (count_connections(tmp_fd) > 0)
@@ -281,16 +291,19 @@
281 {291 {
282 BOOST_THROW_EXCEPTION(292 BOOST_THROW_EXCEPTION(
283 boost::enable_error_info(293 boost::enable_error_info(
284 std::runtime_error("Error opening DRM device")) << boost::errinfo_errno(-error));294 std::runtime_error("Error opening DRM device. Reason: " + excstr)) << boost::errinfo_errno(-error));
285 }295 }
286296
297 drm_set_master(tmp_fd);
287 return tmp_fd;298 return tmp_fd;
288}299}
289300
290mggh::DRMHelper::~DRMHelper()301mggh::DRMHelper::~DRMHelper()
291{302{
292 if (fd >= 0)303 if (fd >= 0)
304 {
293 mgg::drm_close_threadsafe(fd);305 mgg::drm_close_threadsafe(fd);
306 }
294}307}
295308
296/*************309/*************
@@ -470,3 +483,38 @@
470{483{
471 f(egl_display, egl_config);484 f(egl_display, egl_config);
472}485}
486
487void drm_set_master(int fd)
488{
489 if (fd < 0)
490 {
491 BOOST_THROW_EXCEPTION(
492 std::runtime_error("Tried to set DRM master without a DRM device"));
493 }
494
495 int ret = drmSetMaster(fd);
496 if (ret < 0)
497 {
498 BOOST_THROW_EXCEPTION(
499 boost::enable_error_info(
500 std::runtime_error("Failed to set DRM master"))
501 << boost::errinfo_errno(-ret));
502 }
503}
504
505void drm_drop_master(int fd)
506{
507 if (fd < 0)
508 {
509 BOOST_THROW_EXCEPTION(
510 std::runtime_error("Tried to drop DRM master without a DRM device"));
511 }
512 int ret = drmDropMaster(fd);
513 if (ret < 0)
514 {
515 BOOST_THROW_EXCEPTION(
516 boost::enable_error_info(
517 std::runtime_error("Failed to drop DRM master"))
518 << boost::errinfo_errno(-ret));
519 }
520}
473521
=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_display.cpp'
--- tests/unit-tests/graphics/gbm/test_gbm_display.cpp 2013-08-28 03:41:48 +0000
+++ tests/unit-tests/graphics/gbm/test_gbm_display.cpp 2013-09-10 13:47:55 +0000
@@ -647,7 +647,7 @@
647 using namespace testing;647 using namespace testing;
648648
649 EXPECT_CALL(mock_drm, drmDropMaster(mock_drm.fake_drm.fd()))649 EXPECT_CALL(mock_drm, drmDropMaster(mock_drm.fake_drm.fd()))
650 .Times(1);650 .Times(2);
651651
652 auto display = create_display(create_platform());652 auto display = create_display(create_platform());
653653
@@ -659,7 +659,7 @@
659 using namespace testing;659 using namespace testing;
660660
661 EXPECT_CALL(mock_drm, drmSetMaster(mock_drm.fake_drm.fd()))661 EXPECT_CALL(mock_drm, drmSetMaster(mock_drm.fake_drm.fd()))
662 .Times(1);662 .Times(3);
663663
664 auto display = create_display(create_platform());664 auto display = create_display(create_platform());
665665
@@ -670,10 +670,17 @@
670{670{
671 using namespace testing;671 using namespace testing;
672672
673 // drmDropMaster, drmSetMaster will be successful one time because they
674 // are called with a valid file descriptor in gbm_display_helpers.cpp
675 // open_drm_device()
676
673 EXPECT_CALL(mock_drm, drmDropMaster(_))677 EXPECT_CALL(mock_drm, drmDropMaster(_))
678 .WillOnce(Return(0))
674 .WillOnce(SetErrnoAndReturn(EACCES, -EACCES));679 .WillOnce(SetErrnoAndReturn(EACCES, -EACCES));
675680
676 EXPECT_CALL(mock_drm, drmSetMaster(_))681 EXPECT_CALL(mock_drm, drmSetMaster(_))
682 .WillOnce(Return(0))
683 .WillOnce(Return(0))
677 .WillOnce(SetErrnoAndReturn(EPERM, -EPERM));684 .WillOnce(SetErrnoAndReturn(EPERM, -EPERM));
678685
679 EXPECT_CALL(*mock_report, report_drm_master_failure(EACCES));686 EXPECT_CALL(*mock_report, report_drm_master_failure(EACCES));

Subscribers

People subscribed via source and target branches