aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/fs.h
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-04-14 05:55:35 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-21 19:19:29 -0400
commit989a2979205dd34269382b357e6d4b4b6956b889 (patch)
tree2f504e9f4d8d418dd8fb2d042b076c1318232360 /include/linux/fs.h
parente5700aff144fbbba46be40049f0c55fb57283777 (diff)
fasync: RCU and fine grained locking
kill_fasync() uses a central rwlock, candidate for RCU conversion, to avoid cache line ping pongs on SMP. fasync_remove_entry() and fasync_add_entry() can disable IRQS on a short section instead during whole list scan. Use a spinlock per fasync_struct to synchronize kill_fasync_rcu() and fasync_{remove|add}_entry(). This spinlock is IRQ safe, so sock_fasync() doesnt need its own implementation and can use fasync_helper(), to reduce code size and complexity. We can remove __kill_fasync() direct use in net/socket.c, and rename it to kill_fasync_rcu(). Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Lai Jiangshan <laijs@cn.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/fs.h')
-rw-r--r--include/linux/fs.h12
1 files changed, 6 insertions, 6 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 39d57bc6cc71..018d382f6f92 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1280,10 +1280,12 @@ static inline int lock_may_write(struct inode *inode, loff_t start,
1280 1280
1281 1281
1282struct fasync_struct { 1282struct fasync_struct {
1283 int magic; 1283 spinlock_t fa_lock;
1284 int fa_fd; 1284 int magic;
1285 struct fasync_struct *fa_next; /* singly linked list */ 1285 int fa_fd;
1286 struct file *fa_file; 1286 struct fasync_struct *fa_next; /* singly linked list */
1287 struct file *fa_file;
1288 struct rcu_head fa_rcu;
1287}; 1289};
1288 1290
1289#define FASYNC_MAGIC 0x4601 1291#define FASYNC_MAGIC 0x4601
@@ -1292,8 +1294,6 @@ struct fasync_struct {
1292extern int fasync_helper(int, struct file *, int, struct fasync_struct **); 1294extern int fasync_helper(int, struct file *, int, struct fasync_struct **);
1293/* can be called from interrupts */ 1295/* can be called from interrupts */
1294extern void kill_fasync(struct fasync_struct **, int, int); 1296extern void kill_fasync(struct fasync_struct **, int, int);
1295/* only for net: no internal synchronization */
1296extern void __kill_fasync(struct fasync_struct *, int, int);
1297 1297
1298extern int __f_setown(struct file *filp, struct pid *, enum pid_type, int force); 1298extern int __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
1299extern int f_setown(struct file *filp, unsigned long arg, int force); 1299extern int f_setown(struct file *filp, unsigned long arg, int force);