lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 24 Jan 2008 23:09:33 -0800
From:	Greg Kroah-Hartman <gregkh@...e.de>
To:	linux-kernel@...r.kernel.org
Cc:	Greg Kroah-Hartman <gregkh@...e.de>,
	Anton Blanchard <anton@...ibm.com>,
	Paul Mackerras <paulus@...ibm.com>,
	Benjamin Herrenschmidt <benh@...nel.crashing.org>,
	"Ryan S. Arnold" <rsa@...ibm.com>,
	Kay Sievers <kay.sievers@...y.org>
Subject: [PATCH 035/196] kobject: convert hvcs to use kref, not kobject

hvcs is using a kobject only for reference counting, nothing else.  So
switch it to use a kref instead, which is all that is needed, and is
much smaller.

Cc: Anton Blanchard <anton@...ibm.com>
Cc: Paul Mackerras <paulus@...ibm.com>
Cc: Benjamin Herrenschmidt <benh@...nel.crashing.org>
Cc: Ryan S. Arnold <rsa@...ibm.com>
Cc: Kay Sievers <kay.sievers@...y.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@...e.de>
---
 drivers/char/hvcs.c |   78 ++++++++++++++++----------------------------------
 1 files changed, 25 insertions(+), 53 deletions(-)

diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index 69d8866..fd75590 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -57,11 +57,7 @@
  * rescanning partner information upon a user's request.
  *
  * Each vty-server, prior to being exposed to this driver is reference counted
- * using the 2.6 Linux kernel kobject construct.  This kobject is also used by
- * the vio bus to provide a vio device sysfs entry that this driver attaches
- * device specific attributes to, including partner information.  The vio bus
- * framework also provides a sysfs entry for each vio driver.  The hvcs driver
- * provides driver attributes in this entry.
+ * using the 2.6 Linux kernel kref construct.
  *
  * For direction on installation and usage of this driver please reference
  * Documentation/powerpc/hvcs.txt.
@@ -71,7 +67,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
-#include <linux/kobject.h>
+#include <linux/kref.h>
 #include <linux/kthread.h>
 #include <linux/list.h>
 #include <linux/major.h>
@@ -293,12 +289,12 @@ struct hvcs_struct {
 	int chars_in_buffer;
 
 	/*
-	 * Any variable below the kobject is valid before a tty is connected and
+	 * Any variable below the kref is valid before a tty is connected and
 	 * stays valid after the tty is disconnected.  These shouldn't be
 	 * whacked until the koject refcount reaches zero though some entries
 	 * may be changed via sysfs initiatives.
 	 */
-	struct kobject kobj; /* ref count & hvcs_struct lifetime */
+	struct kref kref; /* ref count & hvcs_struct lifetime */
 	int connected; /* is the vty-server currently connected to a vty? */
 	uint32_t p_unit_address; /* partner unit address */
 	uint32_t p_partition_ID; /* partner partition ID */
@@ -307,8 +303,8 @@ struct hvcs_struct {
 	struct vio_dev *vdev;
 };
 
-/* Required to back map a kobject to its containing object */
-#define from_kobj(kobj) container_of(kobj, struct hvcs_struct, kobj)
+/* Required to back map a kref to its containing object */
+#define from_kref(k) container_of(k, struct hvcs_struct, kref)
 
 static struct list_head hvcs_structs = LIST_HEAD_INIT(hvcs_structs);
 static DEFINE_SPINLOCK(hvcs_structs_lock);
@@ -334,7 +330,6 @@ static void hvcs_partner_free(struct hvcs_struct *hvcsd);
 static int hvcs_enable_device(struct hvcs_struct *hvcsd,
 		uint32_t unit_address, unsigned int irq, struct vio_dev *dev);
 
-static void destroy_hvcs_struct(struct kobject *kobj);
 static int hvcs_open(struct tty_struct *tty, struct file *filp);
 static void hvcs_close(struct tty_struct *tty, struct file *filp);
 static void hvcs_hangup(struct tty_struct * tty);
@@ -703,10 +698,10 @@ static void hvcs_return_index(int index)
 		hvcs_index_list[index] = -1;
 }
 
-/* callback when the kboject ref count reaches zero */
-static void destroy_hvcs_struct(struct kobject *kobj)
+/* callback when the kref ref count reaches zero */
+static void destroy_hvcs_struct(struct kref *kref)
 {
-	struct hvcs_struct *hvcsd = from_kobj(kobj);
+	struct hvcs_struct *hvcsd = from_kref(kref);
 	struct vio_dev *vdev;
 	unsigned long flags;
 
@@ -743,10 +738,6 @@ static void destroy_hvcs_struct(struct kobject *kobj)
 	kfree(hvcsd);
 }
 
-static struct kobj_type hvcs_kobj_type = {
-	.release = destroy_hvcs_struct,
-};
-
 static int hvcs_get_index(void)
 {
 	int i;
@@ -791,9 +782,7 @@ static int __devinit hvcs_probe(
 
 	spin_lock_init(&hvcsd->lock);
 	/* Automatically incs the refcount the first time */
-	kobject_init(&hvcsd->kobj);
-	/* Set up the callback for terminating the hvcs_struct's life */
-	hvcsd->kobj.ktype = &hvcs_kobj_type;
+	kref_init(&hvcsd->kref);
 
 	hvcsd->vdev = dev;
 	dev->dev.driver_data = hvcsd;
@@ -844,7 +833,6 @@ static int __devexit hvcs_remove(struct vio_dev *dev)
 {
 	struct hvcs_struct *hvcsd = dev->dev.driver_data;
 	unsigned long flags;
-	struct kobject *kobjp;
 	struct tty_struct *tty;
 
 	if (!hvcsd)
@@ -856,15 +844,13 @@ static int __devexit hvcs_remove(struct vio_dev *dev)
 
 	tty = hvcsd->tty;
 
-	kobjp = &hvcsd->kobj;
-
 	spin_unlock_irqrestore(&hvcsd->lock, flags);
 
 	/*
 	 * Let the last holder of this object cause it to be removed, which
 	 * would probably be tty_hangup below.
 	 */
-	kobject_put (kobjp);
+	kref_put(&hvcsd->kref, destroy_hvcs_struct);
 
 	/*
 	 * The hangup is a scheduled function which will auto chain call
@@ -1086,7 +1072,7 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address,
 }
 
 /*
- * This always increments the kobject ref count if the call is successful.
+ * This always increments the kref ref count if the call is successful.
  * Please remember to dec when you are done with the instance.
  *
  * NOTICE: Do NOT hold either the hvcs_struct.lock or hvcs_structs_lock when
@@ -1103,7 +1089,7 @@ static struct hvcs_struct *hvcs_get_by_index(int index)
 		list_for_each_entry(hvcsd, &hvcs_structs, next) {
 			spin_lock_irqsave(&hvcsd->lock, flags);
 			if (hvcsd->index == index) {
-				kobject_get(&hvcsd->kobj);
+				kref_get(&hvcsd->kref);
 				spin_unlock_irqrestore(&hvcsd->lock, flags);
 				spin_unlock(&hvcs_structs_lock);
 				return hvcsd;
@@ -1129,14 +1115,13 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp)
 	unsigned int irq;
 	struct vio_dev *vdev;
 	unsigned long unit_address;
-	struct kobject *kobjp;
 
 	if (tty->driver_data)
 		goto fast_open;
 
 	/*
 	 * Is there a vty-server that shares the same index?
-	 * This function increments the kobject index.
+	 * This function increments the kref index.
 	 */
 	if (!(hvcsd = hvcs_get_by_index(tty->index))) {
 		printk(KERN_WARNING "HVCS: open failed, no device associated"
@@ -1181,7 +1166,7 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp)
 	 * and will grab the spinlock and free the connection if it fails.
 	 */
 	if (((rc = hvcs_enable_device(hvcsd, unit_address, irq, vdev)))) {
-		kobject_put(&hvcsd->kobj);
+		kref_put(&hvcsd->kref, destroy_hvcs_struct);
 		printk(KERN_WARNING "HVCS: enable device failed.\n");
 		return rc;
 	}
@@ -1192,17 +1177,11 @@ fast_open:
 	hvcsd = tty->driver_data;
 
 	spin_lock_irqsave(&hvcsd->lock, flags);
-	if (!kobject_get(&hvcsd->kobj)) {
-		spin_unlock_irqrestore(&hvcsd->lock, flags);
-		printk(KERN_ERR "HVCS: Kobject of open"
-			" hvcs doesn't exist.\n");
-		return -EFAULT; /* Is this the right return value? */
-	}
-
+	kref_get(&hvcsd->kref);
 	hvcsd->open_count++;
-
 	hvcsd->todo_mask |= HVCS_SCHED_READ;
 	spin_unlock_irqrestore(&hvcsd->lock, flags);
+
 open_success:
 	hvcs_kick();
 
@@ -1212,9 +1191,8 @@ open_success:
 	return 0;
 
 error_release:
-	kobjp = &hvcsd->kobj;
 	spin_unlock_irqrestore(&hvcsd->lock, flags);
-	kobject_put(&hvcsd->kobj);
+	kref_put(&hvcsd->kref, destroy_hvcs_struct);
 
 	printk(KERN_WARNING "HVCS: partner connect failed.\n");
 	return retval;
@@ -1224,7 +1202,6 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
 {
 	struct hvcs_struct *hvcsd;
 	unsigned long flags;
-	struct kobject *kobjp;
 	int irq = NO_IRQ;
 
 	/*
@@ -1245,7 +1222,6 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
 	hvcsd = tty->driver_data;
 
 	spin_lock_irqsave(&hvcsd->lock, flags);
-	kobjp = &hvcsd->kobj;
 	if (--hvcsd->open_count == 0) {
 
 		vio_disable_interrupts(hvcsd->vdev);
@@ -1270,7 +1246,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
 		tty->driver_data = NULL;
 
 		free_irq(irq, hvcsd);
-		kobject_put(kobjp);
+		kref_put(&hvcsd->kref, destroy_hvcs_struct);
 		return;
 	} else if (hvcsd->open_count < 0) {
 		printk(KERN_ERR "HVCS: vty-server@%X open_count: %d"
@@ -1279,7 +1255,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
 	}
 
 	spin_unlock_irqrestore(&hvcsd->lock, flags);
-	kobject_put(kobjp);
+	kref_put(&hvcsd->kref, destroy_hvcs_struct);
 }
 
 static void hvcs_hangup(struct tty_struct * tty)
@@ -1287,21 +1263,17 @@ static void hvcs_hangup(struct tty_struct * tty)
 	struct hvcs_struct *hvcsd = tty->driver_data;
 	unsigned long flags;
 	int temp_open_count;
-	struct kobject *kobjp;
 	int irq = NO_IRQ;
 
 	spin_lock_irqsave(&hvcsd->lock, flags);
-	/* Preserve this so that we know how many kobject refs to put */
+	/* Preserve this so that we know how many kref refs to put */
 	temp_open_count = hvcsd->open_count;
 
 	/*
-	 * Don't kobject put inside the spinlock because the destruction
+	 * Don't kref put inside the spinlock because the destruction
 	 * callback may use the spinlock and it may get called before the
-	 * spinlock has been released.  Get a pointer to the kobject and
-	 * kobject_put on that after releasing the spinlock.
+	 * spinlock has been released.
 	 */
-	kobjp = &hvcsd->kobj;
-
 	vio_disable_interrupts(hvcsd->vdev);
 
 	hvcsd->todo_mask = 0;
@@ -1324,7 +1296,7 @@ static void hvcs_hangup(struct tty_struct * tty)
 	free_irq(irq, hvcsd);
 
 	/*
-	 * We need to kobject_put() for every open_count we have since the
+	 * We need to kref_put() for every open_count we have since the
 	 * tty_hangup() function doesn't invoke a close per open connection on a
 	 * non-console device.
 	 */
@@ -1335,7 +1307,7 @@ static void hvcs_hangup(struct tty_struct * tty)
 		 * NOTE:  If this hangup was signaled from user space then the
 		 * final put will never happen.
 		 */
-		kobject_put(kobjp);
+		kref_put(&hvcsd->kref, destroy_hvcs_struct);
 	}
 }
 
-- 
1.5.3.8

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ