xfree86: Fix autoconfig secondary GPU devices
The code path added by commit 69e4b8e6 (xfree86: attempt to autoconfig
gpu slave devices (v3)) assumes that it will only be run if the primary
device on the screen is the first device in xf86configptr->conf_device_lst.
While this is true most of the time, there are two specific cases where
this assumption fails.
First, if the first device in conf_device_lst is assigned to a different
seat than the running X server, it will be skipped by the previous
FIND_SUITABLE macro usage. Second, if the primary device was explicitly
assigned to the screen but auto_gpu_device is still set and no secondary
devices were explicitly listed, that device may not be the first device
in conf_device_lst.
When the first device in conf_device_lst is not the primary device
assigned to the screen, two problems emerge. First, the first device in
conf_device_lst will never be assigned to the screen as a secondary
device. Second, the primary device is additionally assigned to the
screen as a secondary device. The combination of these problems causes
certain otherwise valid configurations to be invalid. For example, if a
primary device is assigned to a screen and a secondary device is listed
in the config but not explicitly assigned to the screen, then one order
of the device sections results in a usable PRIME or Reverse PRIME setup
and the other order does not.
This commit removes the assumption that the primary device is the first
device in conf_device_lst by starting the loop from the start of
conf_device_lst and skipping the primary device when it is encountered.
Signed-off-by: Jacob Cherry <jcherry@nvidia.com>
			
			
This commit is contained in:
		
							parent
							
								
									97ed0048e4
								
							
						
					
					
						commit
						a5367face1
					
				| 
						 | 
					@ -1738,15 +1738,34 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (auto_gpu_device && conf_screen->num_gpu_devices == 0 &&
 | 
					    if (auto_gpu_device && conf_screen->num_gpu_devices == 0 &&
 | 
				
			||||||
        xf86configptr->conf_device_lst) {
 | 
					        xf86configptr->conf_device_lst) {
 | 
				
			||||||
        XF86ConfDevicePtr sdevice = xf86configptr->conf_device_lst->list.next;
 | 
					        /* Loop through the entire device list and skip the primary device
 | 
				
			||||||
 | 
					         * assigned to the screen. This is important because there are two
 | 
				
			||||||
 | 
					         * cases where the assigned primary device is not the first device in
 | 
				
			||||||
 | 
					         * the device list. Firstly, if the first device in the list is assigned
 | 
				
			||||||
 | 
					         * to a different seat than this X server, it will not have been picked
 | 
				
			||||||
 | 
					         * by the previous FIND_SUITABLE. Secondly, if the device was explicitly
 | 
				
			||||||
 | 
					         * assigned in the config but there is still only one screen, this code
 | 
				
			||||||
 | 
					         * path is executed but the explicitly assigned device may not be the
 | 
				
			||||||
 | 
					         * first device in the list. */
 | 
				
			||||||
 | 
					        XF86ConfDevicePtr ptmp, sdevice = xf86configptr->conf_device_lst;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (i = 0; i < MAX_GPUDEVICES; i++) {
 | 
					        for (i = 0; i < MAX_GPUDEVICES; i++) {
 | 
				
			||||||
            if (!sdevice)
 | 
					            if (!sdevice)
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            FIND_SUITABLE (XF86ConfDevicePtr, sdevice, conf_screen->scrn_gpu_devices[i]);
 | 
					            FIND_SUITABLE (XF86ConfDevicePtr, sdevice, ptmp);
 | 
				
			||||||
            if (!conf_screen->scrn_gpu_devices[i])
 | 
					            if (!ptmp)
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* skip the primary device on the screen */
 | 
				
			||||||
 | 
					            if (ptmp != conf_screen->scrn_device) {
 | 
				
			||||||
 | 
					                conf_screen->scrn_gpu_devices[i] = ptmp;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                sdevice = ptmp->list.next;
 | 
				
			||||||
 | 
					                i--; /* run the next iteration with the same index */
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
 | 
					            screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
 | 
				
			||||||
            if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
 | 
					            if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
 | 
				
			||||||
                screenp->gpu_devices[i]->myScreenSection = screenp;
 | 
					                screenp->gpu_devices[i]->myScreenSection = screenp;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue