Author: hselasky
Date: Tue May 24 07:06:04 2016
New Revision: 300575
URL: https://svnweb.freebsd.org/changeset/base/300575

Log:
  Use make_dev_s() instead of make_dev() to avoid race setting
  "si_drv1". Convert panic() into regular error while at it.
  
  Suggested by: jhb @
  MFC after:    1 week
  Sponsored by: Mellanox Technologies

Modified:
  head/sys/compat/linuxkpi/common/include/linux/cdev.h

Modified: head/sys/compat/linuxkpi/common/include/linux/cdev.h
==============================================================================
--- head/sys/compat/linuxkpi/common/include/linux/cdev.h        Tue May 24 
06:42:14 2016        (r300574)
+++ head/sys/compat/linuxkpi/common/include/linux/cdev.h        Tue May 24 
07:06:04 2016        (r300575)
@@ -2,7 +2,7 @@
  * Copyright (c) 2010 Isilon Systems, Inc.
  * Copyright (c) 2010 iX Systems, Inc.
  * Copyright (c) 2010 Panasas, Inc.
- * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd.
+ * Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -80,12 +80,27 @@ cdev_put(struct linux_cdev *p)
 static inline int
 cdev_add(struct linux_cdev *cdev, dev_t dev, unsigned count)
 {
+       struct make_dev_args args;
+       int error;
+
        if (count != 1)
-               panic("cdev_add: Unsupported count: %d", count);
-       cdev->cdev = make_dev(&linuxcdevsw, MINOR(dev), 0, 0, 0700, 
-           "%s", kobject_name(&cdev->kobj));
+               return (-EINVAL);
+
        cdev->dev = dev;
-       cdev->cdev->si_drv1 = cdev;
+
+       /* Setup arguments for make_dev_s() */
+       make_dev_args_init(&args);
+       args.mda_devsw = &linuxcdevsw;
+       args.mda_uid = 0;
+       args.mda_gid = 0;
+       args.mda_mode = 0700;
+       args.mda_si_drv1 = cdev;
+       args.mda_unit = MINOR(dev);
+
+       error = make_dev_s(&args, &cdev->cdev, "%s",
+           kobject_name(&cdev->kobj));
+       if (error)
+               return (-error);
 
        kobject_get(cdev->kobj.parent);
        return (0);
@@ -94,10 +109,24 @@ cdev_add(struct linux_cdev *cdev, dev_t 
 static inline int
 cdev_add_ext(struct linux_cdev *cdev, dev_t dev, uid_t uid, gid_t gid, int 
mode)
 {
-       cdev->cdev = make_dev(&linuxcdevsw, MINOR(dev), uid, gid, mode, 
-           "%s/%d", kobject_name(&cdev->kobj), MINOR(dev));
+       struct make_dev_args args;
+       int error;
+
        cdev->dev = dev;
-       cdev->cdev->si_drv1 = cdev;
+       
+       /* Setup arguments for make_dev_s() */
+       make_dev_args_init(&args);
+       args.mda_devsw = &linuxcdevsw;
+       args.mda_uid = uid;
+       args.mda_gid = gid;
+       args.mda_mode = mode;
+       args.mda_si_drv1 = cdev;
+       args.mda_unit = MINOR(dev);
+
+       error = make_dev_s(&args, &cdev->cdev, "%s/%d",
+           kobject_name(&cdev->kobj), MINOR(dev));
+       if (error)
+               return (-error);
 
        kobject_get(cdev->kobj.parent);
        return (0);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to