[PATCH 1/2] xserver: add xorg.conf support for gpu devices.

Aaron Plattner aplattner at nvidia.com
Tue Mar 31 12:32:29 PDT 2015


On 03/31/2015 12:12 AM, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This allows gpu devices to be specified in xorg.conf Screen sections.
>
> Section "Device"
>          Driver "intel"
>          Identifier "intel0"
>          Option "AccelMethod" "uxa"
> EndSection
>
> Section "Device"
>          Driver "modesetting"
>          Identifier "usb0"
> EndSection
>
> Section "Screen"
>          Identifier "screen"
>          Device "intel0"
>          GPUDevice "usb0"
> EndSection
>
> This should allow for easier tweaking of driver options which
> currently mess up the GPU device discovery process.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>   hw/xfree86/common/xf86Config.c | 39 +++++++++++++++++++++++++++++----------
>   hw/xfree86/common/xf86Helper.c | 13 ++++++++++++-
>   hw/xfree86/common/xf86str.h    |  3 +++
>   hw/xfree86/man/xorg.conf.man   | 13 +++++++++++++
>   hw/xfree86/parser/Screen.c     | 20 ++++++++++++++++++--
>   hw/xfree86/parser/xf86Parser.h |  5 +++++
>   hw/xfree86/parser/xf86tokens.h |  1 +
>   7 files changed, 81 insertions(+), 13 deletions(-)
>
> diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
> index d42572f..8992208 100644
> --- a/hw/xfree86/common/xf86Config.c
> +++ b/hw/xfree86/common/xf86Config.c
> @@ -126,7 +126,7 @@ static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
>                            int scrnum, MessageType from);
>   static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
>   static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
> -                         Bool active);
> +                         Bool active, Bool gpu);
>   static Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input,
>                           MessageType from);
>   static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
> @@ -390,7 +390,7 @@ const char **
>   xf86DriverlistFromConfig(void)
>   {
>       int count = 0;
> -    int j;
> +    int j, k;
>       const char **modulearray;
>       screenLayoutPtr slp;
>
> @@ -411,8 +411,10 @@ xf86DriverlistFromConfig(void)
>        */
>       if (xf86ConfigLayout.screens) {
>           slp = xf86ConfigLayout.screens;
> -        while ((slp++)->screen) {
> +        while ((slp)->screen) {
>               count++;
> +            count += (slp)->screen->num_gpu_devices;
> +            slp++;
>           }
>       }
>
> @@ -435,6 +437,10 @@ xf86DriverlistFromConfig(void)
>       while (slp->screen) {
>           modulearray[count] = slp->screen->device->driver;
>           count++;
> +        for (k = 0; k < slp->screen->num_gpu_devices; k++) {
> +            modulearray[count] = slp->screen->gpu_devices[k]->driver;
> +            count++;
> +        }
>           slp++;
>       }
>
> @@ -1631,7 +1637,7 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
>       idp = conf_layout->lay_inactive_lst;
>       count = 0;
>       while (idp) {
> -        if (!configDevice(&gdp[count], idp->inactive_device, FALSE))
> +        if (!configDevice(&gdp[count], idp->inactive_device, FALSE, FALSE))
>               goto bail;
>           count++;
>           idp = (XF86ConfInactivePtr) idp->list.next;
> @@ -1769,6 +1775,7 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
>       XF86ConfAdaptorLinkPtr conf_adaptor;
>       Bool defaultMonitor = FALSE;
>       XF86ConfScreenRec local_conf_screen;
> +    int i;
>
>       if (!conf_screen) {
>           memset(&local_conf_screen, 0, sizeof(local_conf_screen));
> @@ -1811,12 +1818,20 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
>           xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
>                   "\tUsing the first device section listed.\n", screenp->id);
>       }
> -    if (configDevice(screenp->device, conf_screen->scrn_device, TRUE)) {
> +    if (configDevice(screenp->device, conf_screen->scrn_device, TRUE, FALSE)) {
>           screenp->device->myScreenSection = screenp;
>       }
>       else {
>           screenp->device = NULL;
>       }
> +
> +    for (i = 0; i < conf_screen->num_gpu_devices; i++) {
> +        screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
> +        if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
> +            screenp->gpu_devices[i]->myScreenSection = screenp;
> +        }
> +    }
> +    screenp->num_gpu_devices = conf_screen->num_gpu_devices;
>       screenp->options = conf_screen->scrn_option_lst;
>
>       /*
> @@ -2110,7 +2125,7 @@ configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
>   }
>
>   static Bool
> -configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
> +configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active, Bool gpu)
>   {
>       int i;
>
> @@ -2118,10 +2133,14 @@ configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
>           return FALSE;
>       }
>
> -    if (active)
> -        xf86Msg(X_CONFIG, "|   |-->Device \"%s\"\n",
> -                conf_device->dev_identifier);
> -    else
> +    if (active) {
> +        if (gpu)
> +            xf86Msg(X_CONFIG, "|   |-->GPUDevice \"%s\"\n",
> +                    conf_device->dev_identifier);
> +        else
> +            xf86Msg(X_CONFIG, "|   |-->Device \"%s\"\n",
> +                    conf_device->dev_identifier);
> +    } else
>           xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
>                   conf_device->dev_identifier);
>
> diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
> index e2b32a0..745c85f 100644
> --- a/hw/xfree86/common/xf86Helper.c
> +++ b/hw/xfree86/common/xf86Helper.c
> @@ -1367,7 +1367,7 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
>   {
>       GDevPtr gdp, *pgdp = NULL;
>       confScreenPtr screensecptr;
> -    int i, j;
> +    int i, j, k;
>
>       if (sectlist)
>           *sectlist = NULL;
> @@ -1411,6 +1411,17 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
>               pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
>               pgdp[i++] = screensecptr->device;
>           }
> +        for (k = 0; k < screensecptr->num_gpu_devices; k++) {
> +            if ((screensecptr->gpu_devices[k]->driver != NULL)
> +            && (xf86NameCmp(screensecptr->gpu_devices[k]->driver, drivername) == 0)

Indentation got a little funky here.

> +                && (!screensecptr->gpu_devices[k]->claimed)) {
> +            /*
> +             * we have a matching driver that wasn't claimed, yet
> +             */
> +                pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
> +                pgdp[i++] = screensecptr->gpu_devices[k];
> +            }
> +        }
>       }
>
>       /* Then handle the inactive devices */
> diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
> index 643a65d..9893f98 100644
> --- a/hw/xfree86/common/xf86str.h
> +++ b/hw/xfree86/common/xf86str.h
> @@ -453,6 +453,9 @@ typedef struct _confscreenrec {
>       int numxvadaptors;
>       confXvAdaptorPtr xvadaptors;
>       void *options;
> +
> +    int num_gpu_devices;
> +    GDevPtr gpu_devices[4];
>   } confScreenRec, *confScreenPtr;
>
>   typedef enum {
> diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
> index d26c3cc..928fdf7 100644
> --- a/hw/xfree86/man/xorg.conf.man
> +++ b/hw/xfree86/man/xorg.conf.man
> @@ -1906,6 +1906,7 @@ sections have the following format:
>   .B  "Section \*qScreen\*q"
>   .BI "    Identifier \*q" name \*q
>   .BI "    Device     \*q" devid \*q
> +.BI "    GPUDevice     \*q" devid \*q

More weird indentation, unless it's Exchange that screwed it up again...

>   .BI "    Monitor    \*q" monid \*q
>   .I  "    entries"
>   .I  "    ..."
> @@ -1949,6 +1950,18 @@ of a
>   .B Device
>   section in the config file.
>   .TP 7
> +.BI "GPUDevice  \*q" device\-id \*q
> +This entry specifies the
> +.B Device
> +section to be used as a secondary GPU devices for this screen.  When multiple graphics cards are

"a secondary GPU devices" should probably be "a secondary GPU device"

If I'm reading the change correctly, you can specify GPUDevice multiple 
times to get multiple GPU screens.  It's probably worth mentioning that 
here.

> +present, this is what ties a specific secondary card to a screen.  The
> +.I device\-id
> +must match the
> +.B Identifier
> +of a
> +.B Device
> +section in the config file.
> +.TP 7
>   .BI "Monitor  \*q" monitor\-id \*q
>   specifies which monitor description is to be used for this screen.
>   If a
> diff --git a/hw/xfree86/parser/Screen.c b/hw/xfree86/parser/Screen.c
> index 9d8eda2..85c5bec 100644
> --- a/hw/xfree86/parser/Screen.c
> +++ b/hw/xfree86/parser/Screen.c
> @@ -211,6 +211,7 @@ static xf86ConfigSymTabRec ScreenTab[] = {
>       {DEFAULTFBBPP, "defaultfbbpp"},
>       {VIRTUAL, "virtual"},
>       {OPTION, "option"},
> +    {GDEVICE, "gpudevice"},
>       {-1, ""},
>   };
>
> @@ -270,6 +271,11 @@ xf86parseScreenSection(void)
>                   Error(QUOTE_MSG, "Device");
>               ptr->scrn_device_str = xf86_lex_val.str;
>               break;
> +        case GDEVICE:
> +            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
> +                Error(QUOTE_MSG, "GPUDevice");
> +            ptr->scrn_gpu_device_str[ptr->num_gpu_devices++] = xf86_lex_val.str;

Like Emil said, this seems like it would be easy to overrun the fixed 
size of scrn_gpu_device_str[4] here.

-- Aaron

> +            break;
>           case MONITOR:
>               if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
>                   Error(QUOTE_MSG, "Monitor");
> @@ -342,7 +348,7 @@ xf86printScreenSection(FILE * cf, XF86ConfScreenPtr ptr)
>       XF86ConfAdaptorLinkPtr aptr;
>       XF86ConfDisplayPtr dptr;
>       XF86ModePtr mptr;
> -
> +    int i;
>       while (ptr) {
>           fprintf(cf, "Section \"Screen\"\n");
>           if (ptr->scrn_comment)
> @@ -353,6 +359,9 @@ xf86printScreenSection(FILE * cf, XF86ConfScreenPtr ptr)
>               fprintf(cf, "\tDriver     \"%s\"\n", ptr->scrn_obso_driver);
>           if (ptr->scrn_device_str)
>               fprintf(cf, "\tDevice     \"%s\"\n", ptr->scrn_device_str);
> +        for (i = 0; i < ptr->num_gpu_devices; i++)
> +            if (ptr->scrn_gpu_device_str[i])
> +                fprintf(cf, "\tGPUDevice     \"%s\"\n", ptr->scrn_gpu_device_str[i]);
>           if (ptr->scrn_monitor_str)
>               fprintf(cf, "\tMonitor    \"%s\"\n", ptr->scrn_monitor_str);
>           if (ptr->scrn_defaultdepth)
> @@ -426,11 +435,13 @@ void
>   xf86freeScreenList(XF86ConfScreenPtr ptr)
>   {
>       XF86ConfScreenPtr prev;
> -
> +    int i;
>       while (ptr) {
>           TestFree(ptr->scrn_identifier);
>           TestFree(ptr->scrn_monitor_str);
>           TestFree(ptr->scrn_device_str);
> +        for (i = 0; i < ptr->num_gpu_devices; i++)
> +            TestFree(ptr->scrn_gpu_device_str[i]);
>           TestFree(ptr->scrn_comment);
>           xf86optionListFree(ptr->scrn_option_lst);
>           xf86freeAdaptorLinkList(ptr->scrn_adaptor_lst);
> @@ -487,6 +498,7 @@ xf86validateScreen(XF86ConfigPtr p)
>       XF86ConfScreenPtr screen = p->conf_screen_lst;
>       XF86ConfMonitorPtr monitor;
>       XF86ConfAdaptorLinkPtr adaptor;
> +    int i;
>
>       while (screen) {
>           if (screen->scrn_obso_driver && !screen->scrn_identifier)
> @@ -505,6 +517,10 @@ xf86validateScreen(XF86ConfigPtr p)
>           screen->scrn_device =
>               xf86findDevice(screen->scrn_device_str, p->conf_device_lst);
>
> +        for (i = 0; i < screen->num_gpu_devices; i++) {
> +            screen->scrn_gpu_devices[i] =
> +                xf86findDevice(screen->scrn_gpu_device_str[i], p->conf_device_lst);
> +        }
>           adaptor = screen->scrn_adaptor_lst;
>           while (adaptor) {
>               adaptor->al_adaptor =
> diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
> index 43e1755..0cd58c9 100644
> --- a/hw/xfree86/parser/xf86Parser.h
> +++ b/hw/xfree86/parser/xf86Parser.h
> @@ -259,6 +259,7 @@ typedef struct {
>       XF86ConfVideoAdaptorPtr al_adaptor;
>   } XF86ConfAdaptorLinkRec, *XF86ConfAdaptorLinkPtr;
>
> +#define CONFMAXGPUDEVICES 4
>   typedef struct {
>       GenericListRec list;
>       const char *scrn_identifier;
> @@ -276,6 +277,10 @@ typedef struct {
>       char *scrn_comment;
>       int scrn_virtualX, scrn_virtualY;
>       char *match_seat;
> +
> +    int num_gpu_devices;
> +    const char *scrn_gpu_device_str[CONFMAXGPUDEVICES];
> +    XF86ConfDevicePtr scrn_gpu_devices[CONFMAXGPUDEVICES];
>   } XF86ConfScreenRec, *XF86ConfScreenPtr;
>
>   typedef struct {
> diff --git a/hw/xfree86/parser/xf86tokens.h b/hw/xfree86/parser/xf86tokens.h
> index 9c44970..bbd6b90 100644
> --- a/hw/xfree86/parser/xf86tokens.h
> +++ b/hw/xfree86/parser/xf86tokens.h
> @@ -143,6 +143,7 @@ typedef enum {
>       /* Screen tokens */
>       OBSDRIVER,
>       MDEVICE,
> +    GDEVICE,
>       MONITOR,
>       SCREENNO,
>       DEFAULTDEPTH,
>



More information about the xorg-devel mailing list