[svn-commits] sruffell: linux/trunk r9386 - /linux/trunk/drivers/dahdi/dahdi-base.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Sep 20 15:34:48 CDT 2010


Author: sruffell
Date: Mon Sep 20 15:34:44 2010
New Revision: 9386

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9386
Log:
dahdi: Channels can have their own file_operations structure.

If we know that an open file is associated with a channel (pseudo or
real) we can just update the file->f_ops pointer so that we can short
circuit some of the checks in read/write/poll. Trades sizeof(file_operations)
bytes for less function call overhead in the "hot" path.

On a 2.4 GHz Xeon, saves around 150 ns on each read / write.

Review: https://reviewboard.asterisk.org/r/905/

Signed-off-by: Shaun Ruffell <sruffell at digium.com>

Modified:
    linux/trunk/drivers/dahdi/dahdi-base.c

Modified: linux/trunk/drivers/dahdi/dahdi-base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=9386&r1=9385&r2=9386
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Mon Sep 20 15:34:44 2010
@@ -233,7 +233,6 @@
 static sumtype *conf_sums_prev;
 
 static struct dahdi_span *master;
-static struct file_operations dahdi_fops;
 struct file_operations *dahdi_transcode_fops = NULL;
 
 static struct {
@@ -2122,7 +2121,7 @@
 }
 
 static ssize_t dahdi_chan_read(struct file *file, char __user *usrbuf,
-			       size_t count)
+			       size_t count, loff_t *ppos)
 {
 	struct dahdi_chan *chan = file->private_data;
 	int amnt;
@@ -2241,7 +2240,7 @@
 }
 
 static ssize_t dahdi_chan_write(struct file *file, const char __user *usrbuf,
-				size_t count)
+				size_t count, loff_t *ppos)
 {
 	unsigned long flags;
 	struct dahdi_chan *chan = file->private_data;
@@ -2805,6 +2804,8 @@
 	return 0;
 }
 
+static const struct file_operations dahdi_chan_fops;
+
 static int dahdi_specchan_open(struct file *file)
 {
 	int res = 0;
@@ -2838,6 +2839,10 @@
 			if (!res) {
 				chan->file = file;
 				file->private_data = chan;
+				/* Since we know we're a channel now, we can
+				 * update the f_op pointer and bypass a few of
+				 * the checks on the minor number. */
+				file->f_op = &dahdi_chan_fops;
 				spin_unlock_irqrestore(&chan->lock, flags);
 			} else {
 				spin_unlock_irqrestore(&chan->lock, flags);
@@ -3002,69 +3007,6 @@
 	return res;
 }
 #endif
-
-static ssize_t dahdi_read(struct file *file, char __user *usrbuf, size_t count, loff_t *ppos)
-{
-	int unit = UNIT(file);
-	struct dahdi_chan *chan;
-
-	/* Can't read from control */
-	if (!unit) {
-		return -EINVAL;
-	}
-
-	if (unit == 253)
-		return -EINVAL;
-
-	if (unit == 254) {
-		chan = file->private_data;
-		if (!chan)
-			return -EINVAL;
-		return dahdi_chan_read(file, usrbuf, count);
-	}
-
-	if (unit == 255) {
-		chan = file->private_data;
-		if (!chan) {
-			module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
-			return -EINVAL;
-		}
-		return dahdi_chan_read(file, usrbuf, count);
-	}
-	if (count < 0)
-		return -EINVAL;
-
-	return dahdi_chan_read(file, usrbuf, count);
-}
-
-static ssize_t dahdi_write(struct file *file, const char __user *usrbuf, size_t count, loff_t *ppos)
-{
-	int unit = UNIT(file);
-	struct dahdi_chan *chan;
-	/* Can't read from control */
-	if (!unit)
-		return -EINVAL;
-	if (count < 0)
-		return -EINVAL;
-	if (unit == 253)
-		return -EINVAL;
-	if (unit == 254) {
-		chan = file->private_data;
-		if (!chan)
-			return -EINVAL;
-		return dahdi_chan_write(file, usrbuf, count);
-	}
-	if (unit == 255) {
-		chan = file->private_data;
-		if (!chan) {
-			module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
-			return -EINVAL;
-		}
-		return dahdi_chan_write(file, usrbuf, count);
-	}
-	return dahdi_chan_write(file, usrbuf, count);
-
-}
 
 static int dahdi_set_default_zone(int defzone)
 {
@@ -8325,30 +8267,14 @@
 
 static unsigned int dahdi_poll(struct file *file, struct poll_table_struct *wait_table)
 {
-	int unit = UNIT(file);
-
-	if (!unit)
-		return -EINVAL;
-
-	if (unit == 250)
-		return dahdi_transcode_fops->poll(file, wait_table);
-
-	if (unit == 253)
+	const int unit = UNIT(file);
+
+	if (likely(unit == 253))
 		return dahdi_timer_poll(file, wait_table);
 
-	if (unit == 254) {
-		if (!file->private_data)
-			return -EINVAL;
-		return dahdi_chan_poll(file, wait_table);
-	}
-	if (unit == 255) {
-		if (!file->private_data) {
-			module_printk(KERN_NOTICE, "No pseudo channel structure to read?\n");
-			return -EINVAL;
-		}
-		return dahdi_chan_poll(file, wait_table);
-	}
-	return dahdi_chan_poll(file, wait_table);
+	/* transcoders and channels should have updated their file_operations
+	 * before poll is ever called. */
+	return -EINVAL;
 }
 
 static void __dahdi_transmit_chunk(struct dahdi_chan *chan, unsigned char *buf)
@@ -8868,7 +8794,7 @@
 module_param(debug, int, 0644);
 module_param(deftaps, int, 0644);
 
-static struct file_operations dahdi_fops = {
+static const struct file_operations dahdi_fops = {
 	.owner   = THIS_MODULE,
 	.open    = dahdi_open,
 	.release = dahdi_release,
@@ -8880,9 +8806,24 @@
 #else
 	.ioctl   = dahdi_ioctl,
 #endif
-	.read    = dahdi_read,
-	.write   = dahdi_write,
 	.poll    = dahdi_poll,
+};
+
+static const struct file_operations dahdi_chan_fops = {
+	.owner   = THIS_MODULE,
+	.open    = dahdi_open,
+	.release = dahdi_release,
+#ifdef HAVE_UNLOCKED_IOCTL
+	.unlocked_ioctl  = dahdi_ioctl,
+#ifdef HAVE_COMPAT_IOCTL
+	.compat_ioctl = dahdi_ioctl_compat,
+#endif
+#else
+	.ioctl   = dahdi_ioctl,
+#endif
+	.read    = dahdi_chan_read,
+	.write   = dahdi_chan_write,
+	.poll    = dahdi_chan_poll,
 };
 
 #ifdef CONFIG_DAHDI_WATCHDOG




More information about the svn-commits mailing list