[Mesa-dev] [PATCH 1/2] loader: add loader_open_name(..)

Eric Engestrom eric.engestrom at intel.com
Thu Aug 2 11:09:27 UTC 2018


On Wednesday, 2018-08-01 23:07:02 +0200, Christian Gmeiner wrote:
> Add an improved drmOpenWithType(..) clone which fixes some serious
> flaws. Some highlights:
>  - using busid works only with PCI devices
>  - open() w/o O_CLOEXEC
>  - when build w/o udev - it creates a node: mkdir, chown(root), chmod, mknod
>  - calls back into Xserver/DDX module
>  - last but no least - borderline hacks with massive documentation [1]
>    to keep this running.
> 
> Signed-off-by: Christian Gmeiner <christian.gmeiner at gmail.com>

The idea sounds good, but I have a few remarks below.

> ---
>  src/loader/loader.c | 79 +++++++++++++++++++++++++++++++++++++++++++++
>  src/loader/loader.h |  3 ++
>  2 files changed, 82 insertions(+)
> 
> diff --git a/src/loader/loader.c b/src/loader/loader.c
> index 43275484cc..c2d2122bb8 100644
> --- a/src/loader/loader.c
> +++ b/src/loader/loader.c
> @@ -82,6 +82,85 @@ loader_open_device(const char *device_name)
>     return fd;
>  }
>  
> +static int
> +open_minor(int minor, int type)
> +{
> +   const char *dev_name;
> +   char buf[64];
> +
> +   switch (type) {
> +   case DRM_NODE_PRIMARY:
> +      dev_name = DRM_DEV_NAME;
> +      break;
> +   case DRM_NODE_CONTROL:
> +      dev_name = DRM_CONTROL_DEV_NAME;
> +      break;
> +   case DRM_NODE_RENDER:
> +      dev_name = DRM_RENDER_DEV_NAME;
> +      break;
> +   default:
> +      return -EINVAL;

This function is returning an fd, so this should be -1.
That said, giving an invalid type here is a serious misuse of the api,
so I think you should replace the default return here and below ([1])
with an `unreachable("invalid DRM node type");`

> +   };

Nit: no need for `;` after a switch

> +
> +   sprintf(buf, dev_name, DRM_DIR_NAME, minor);

unlikely, but you should probably use snprintf(buf, sizeof(buf), ...)

You should also use the `util_*` versions from u_string.h for
compatibility with toolchains that don't support them natively.

> +
> +   return loader_open_device(buf);
> +}
> +
> +static int minor_base(int type)
> +{
> +    switch (type) {
> +    case DRM_NODE_PRIMARY:
> +        return 0;
> +    case DRM_NODE_CONTROL:
> +        return 64;
> +    case DRM_NODE_RENDER:
> +        return 128;
> +    default:
> +        return -1;

[1] ^ to replace with unreachable()

> +    };

(`;` again)

> +}
> +
> +int
> +loader_open_name(const char *name, int type)
> +{
> +   int base = minor_base(type);
> +   drmVersionPtr version;
> +   int i, fd;
> +   char *id;
> +
> +   if (base < 0)
> +      return -1;

with unreachable() above, this can go

> +
> +   /*
> +   * Open the first minor number that matches the driver name and isn't
> +   * already in use.  If it's in use it will have a busid assigned already.
> +   */
> +   for (i = base; i < base + DRM_MAX_MINOR; i++) {
> +      if ((fd = open_minor(i, type)) >= 0) {
> +         if ((version = drmGetVersion(fd))) {
> +            if (!strcmp(version->name, name)) {

I would suggest inverting these `if`s to avoid nesting so deep.

> +               drmFreeVersion(version);
> +               id = drmGetBusid(fd);
> +               drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL");
> +               if (!id || !*id) {
> +                  if (id)
> +                     drmFreeBusid(id);
> +                  return fd;

This condition looks wrong; surely you want to keep the one that has
a bus id, not the one that doesn't?

The `if(!id) if(id)` also looks weird; I suggest rewriting this bit of
your code. Flattening your logic should also make it more readable.

> +               } else {
> +                  drmFreeBusid(id);
> +               }
> +            } else {
> +               drmFreeVersion(version);
> +            }
> +         }
> +         close(fd);
> +      }
> +   }
> +
> +   return -1;
> +}
> +
>  #if defined(HAVE_LIBDRM)
>  #ifdef USE_DRICONF
>  static const char __driConfigOptionsLoader[] =
> diff --git a/src/loader/loader.h b/src/loader/loader.h
> index 3859b45dc4..7e1612301a 100644
> --- a/src/loader/loader.h
> +++ b/src/loader/loader.h
> @@ -38,6 +38,9 @@ extern "C" {
>  int
>  loader_open_device(const char *);
>  
> +int
> +loader_open_name(const char *name, int type);
> +
>  int
>  loader_get_pci_id_for_fd(int fd, int *vendor_id, int *chip_id);
>  
> -- 
> 2.17.1
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list