[PATCH 11/22] staging: comedi: add a kref to comedi device

Ian Abbott abbotti at mev.co.uk
Fri Nov 8 15:03:32 UTC 2013


Add a `struct kref refcount` member to `struct comedi_device` to allow
safe destruction of the comedi device.  Only free the comedi device via
the 'release' callback `kref_put()`.  Currently, nothing calls
`kref_put()`, so the safe destruction is ineffective, but this will be
addressed by later patches.

Signed-off-by: Ian Abbott <abbotti at mev.co.uk>
---
 drivers/staging/comedi/comedi_fops.c | 22 +++++++++++++++++++---
 drivers/staging/comedi/comedidev.h   |  2 ++
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index fa8da20..403324c 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -89,12 +89,29 @@ static struct cdev comedi_cdev;
 
 static void comedi_device_init(struct comedi_device *dev)
 {
+	kref_init(&dev->refcount);
 	spin_lock_init(&dev->spinlock);
 	mutex_init(&dev->mutex);
 	init_rwsem(&dev->attach_lock);
 	dev->minor = -1;
 }
 
+static void comedi_dev_kref_release(struct kref *kref)
+{
+	struct comedi_device *dev =
+		container_of(kref, struct comedi_device, refcount);
+
+	mutex_destroy(&dev->mutex);
+	kfree(dev);
+}
+
+int comedi_dev_put(struct comedi_device *dev)
+{
+	if (dev)
+		return kref_put(&dev->refcount, comedi_dev_kref_release);
+	return 1;
+}
+
 static void comedi_device_cleanup(struct comedi_device *dev)
 {
 	struct module *driver_module = NULL;
@@ -112,7 +129,6 @@ static void comedi_device_cleanup(struct comedi_device *dev)
 		dev->use_count--;
 	}
 	mutex_unlock(&dev->mutex);
-	mutex_destroy(&dev->mutex);
 }
 
 static bool comedi_clear_board_dev(struct comedi_device *dev)
@@ -148,7 +164,7 @@ static void comedi_free_board_dev(struct comedi_device *dev)
 				       MKDEV(COMEDI_MAJOR, dev->minor));
 		}
 		comedi_device_cleanup(dev);
-		kfree(dev);
+		comedi_dev_put(dev);
 	}
 }
 
@@ -2494,7 +2510,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device)
 	if (i == COMEDI_NUM_BOARD_MINORS) {
 		mutex_unlock(&dev->mutex);
 		comedi_device_cleanup(dev);
-		kfree(dev);
+		comedi_dev_put(dev);
 		pr_err("comedi: error: ran out of minor numbers for board device files.\n");
 		return ERR_PTR(-EBUSY);
 	}
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
index 05cc8db..08652df 100644
--- a/drivers/staging/comedi/comedidev.h
+++ b/drivers/staging/comedi/comedidev.h
@@ -23,6 +23,7 @@
 #include <linux/mutex.h>
 #include <linux/spinlock_types.h>
 #include <linux/rwsem.h>
+#include <linux/kref.h>
 
 #include "comedi.h"
 
@@ -187,6 +188,7 @@ struct comedi_device {
 	spinlock_t spinlock;
 	struct mutex mutex;
 	struct rw_semaphore attach_lock;
+	struct kref refcount;
 
 	int n_subdevices;
 	struct comedi_subdevice *subdevices;
-- 
1.8.4.2



More information about the devel mailing list