From 4042f34bfa72f9a968377e4adc4e65f369bedb6e Mon Sep 17 00:00:00 2001 From: lichenggang Date: Sun, 15 Mar 2026 11:39:50 +0800 Subject: [PATCH] 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. --- hw/xfree86/drivers/modesetting/driver.c | 27 +++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) 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