Hi Davide I found in my tests that there is no need to have a f_ep_lock spinlock attached to each struct file, using 8 bytes on 64bits platforms. The lock is hold for a very short time period and can be global, with almost no change in performance for applications using epoll, and a gain for all others.
Thank you Eric Dumazet [PATCH] eventpoll : Suppress a short lived lock from struct file Signed-off-by: Eric Dumazet <[EMAIL PROTECTED]>
--- linux-2.6.12/fs/eventpoll.c 2005-06-17 21:48:29.000000000 +0200 +++ linux-2.6.12-ed/fs/eventpoll.c 2005-07-11 08:56:07.000000000 +0200 @@ -179,6 +179,8 @@ spinlock_t lock; }; +static DEFINE_SPINLOCK(f_ep_lock); + /* * This structure is stored inside the "private_data" member of the file * structure and rapresent the main data sructure for the eventpoll @@ -426,7 +428,6 @@ { INIT_LIST_HEAD(&file->f_ep_links); - spin_lock_init(&file->f_ep_lock); } @@ -967,9 +968,9 @@ goto eexit_2; /* Add the current item to the list of active epoll hook for this file */ - spin_lock(&tfile->f_ep_lock); + spin_lock(&f_ep_lock); list_add_tail(&epi->fllink, &tfile->f_ep_links); - spin_unlock(&tfile->f_ep_lock); + spin_unlock(&f_ep_lock); /* We have to drop the new item inside our item list to keep track of it */ write_lock_irqsave(&ep->lock, flags); @@ -1160,7 +1161,6 @@ { int error; unsigned long flags; - struct file *file = epi->ffd.file; /* * Removes poll wait queue hooks. We _have_ to do this without holding @@ -1173,10 +1173,10 @@ ep_unregister_pollwait(ep, epi); /* Remove the current item from the list of epoll hooks */ - spin_lock(&file->f_ep_lock); + spin_lock(&f_ep_lock); if (EP_IS_LINKED(&epi->fllink)) EP_LIST_DEL(&epi->fllink); - spin_unlock(&file->f_ep_lock); + spin_unlock(&f_ep_lock); /* We need to acquire the write IRQ lock before calling ep_unlink() */ write_lock_irqsave(&ep->lock, flags); --- linux-2.6.12/include/linux/fs.h 2005-06-17 21:48:29.000000000 +0200 +++ linux-2.6.12-ed/include/linux/fs.h 2005-07-11 08:58:02.000000000 +0200 @@ -597,7 +597,6 @@ #ifdef CONFIG_EPOLL /* Used by fs/eventpoll.c to link all the hooks to this file */ struct list_head f_ep_links; - spinlock_t f_ep_lock; #endif /* #ifdef CONFIG_EPOLL */ struct address_space *f_mapping; };