[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