diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 06147fb96..4dfb79861 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -1959,7 +1959,7 @@ static Bool SetMaster(ScrnInfoPtr pScrn) { modesettingPtr ms = modesettingPTR(pScrn); - int ret; + int ret, retries = 5; #ifdef XF86_PDEV_SERVER_FD if (ms->pEnt->location.type == BUS_PLATFORM && @@ -1970,12 +1970,27 @@ SetMaster(ScrnInfoPtr pScrn) if (ms->fd_passed) return TRUE; - ret = drmSetMaster(ms->fd); - if (ret) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmSetMaster failed: %s\n", - strerror(errno)); + /* Retry drmSetMaster a few times to handle race conditions + * where the DRM device is not yet fully initialized. + * This can happen when Xorg starts immediately after the + * kernel driver loads. */ + do { + ret = drmSetMaster(ms->fd); + if (ret == 0) + return TRUE; - return ret == 0; + if (retries > 0 && (errno == EACCES || errno == EBUSY)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "drmSetMaster failed: %s, retrying...\n", + strerror(errno)); + usleep(10000); /* 10ms */ + } + } while (ret && retries-- > 0); + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmSetMaster failed: %s\n", + strerror(errno)); + + return FALSE; } /* When the root window is created, initialize the screen contents from