modesetting: Add retry logic to drmSetMaster to fix race condition

When Xorg starts immediately after the kernel driver loads, drmSetMaster
can fail with EACCES or EBUSY because the DRM device is not yet fully
initialized. This causes Xorg to crash on boot.

Add retry logic with a short delay (10ms) between attempts to allow
the kernel driver to complete initialization. Retry up to 5 times
before giving up.

This fixes the crash seen in xorg-boot.log where Xorg crashes on boot
but succeeds on the second attempt by lightdm.
This commit is contained in:
lichenggang 2026-03-15 11:39:50 +08:00
parent 7e7d1f027f
commit 4042f34bfa

View file

@ -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