From: Davide Libenzi - Inline eventpoll_release() so that __fput() does not need to call in epoll code if the file itself is not registered inside an epoll fd - Add inclusion due __u32 and __u64 usage - Fix debug printf that would otherwise panic if enabled with the new epoll code fs/eventpoll.c | 30 +++++++++--------------------- include/linux/eventpoll.h | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 23 deletions(-) diff -puN fs/eventpoll.c~epoll-optimisations fs/eventpoll.c --- 25/fs/eventpoll.c~epoll-optimisations 2003-07-02 21:14:21.000000000 -0700 +++ 25-akpm/fs/eventpoll.c 2003-07-02 21:14:21.000000000 -0700 @@ -443,29 +443,17 @@ void eventpoll_init_file(struct file *fi /* - * This is called from inside fs/file_table.c:__fput() to unlink files - * from the eventpoll interface. We need to have this facility to cleanup - * correctly files that are closed without being removed from the eventpoll - * interface. + * This is called from eventpoll_release() to unlink files from the eventpoll + * interface. We need to have this facility to cleanup correctly files that are + * closed without being removed from the eventpoll interface. */ -void eventpoll_release(struct file *file) +void eventpoll_release_file(struct file *file) { struct list_head *lsthead = &file->f_ep_links; struct eventpoll *ep; struct epitem *epi; /* - * Fast check to avoid the get/release of the semaphore. Since - * we're doing this outside the semaphore lock, it might return - * false negatives, but we don't care. It'll help in 99.99% of cases - * to avoid the semaphore lock. False positives simply cannot happen - * because the file in on the way to be removed and nobody ( but - * eventpoll ) has still a reference to this file. - */ - if (list_empty(lsthead)) - return; - - /* * We don't want to get "file->f_ep_lock" because it is not * necessary. It is not necessary because we're in the "struct file" * cleanup path, and this means that noone is using this file anymore. @@ -541,7 +529,7 @@ eexit_1: /* * The following function implement the controller interface for the eventpoll * file that enable the insertion/removal/change of file descriptors inside - * the interest set. It rapresents the kernel part of the user spcae epoll_ctl(2). + * the interest set. It rapresents the kernel part of the user space epoll_ctl(2). */ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) { @@ -551,8 +539,8 @@ asmlinkage long sys_epoll_ctl(int epfd, struct epitem *epi; struct epoll_event epds; - DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u)\n", - current, epfd, op, fd, event->events)); + DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p)\n", + current, epfd, op, fd, event)); error = -EFAULT; if (copy_from_user(&epds, event, sizeof(struct epoll_event))) @@ -633,8 +621,8 @@ eexit_3: eexit_2: fput(file); eexit_1: - DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u) = %d\n", - current, epfd, op, fd, event->events, error)); + DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p) = %d\n", + current, epfd, op, fd, event, error)); return error; } diff -puN include/linux/eventpoll.h~epoll-optimisations include/linux/eventpoll.h --- 25/include/linux/eventpoll.h~epoll-optimisations 2003-07-02 21:14:21.000000000 -0700 +++ 25-akpm/include/linux/eventpoll.h 2003-07-02 21:14:21.000000000 -0700 @@ -14,6 +14,8 @@ #ifndef _LINUX_EVENTPOLL_H #define _LINUX_EVENTPOLL_H +#include + /* Valid opcodes to issue to sys_epoll_ctl() */ #define EPOLL_CTL_ADD 1 @@ -55,8 +57,37 @@ asmlinkage long sys_epoll_wait(int epfd, /* Used to initialize the epoll bits inside the "struct file" */ void eventpoll_init_file(struct file *file); -/* Used in fs/file_table.c:__fput() to unlink files from the eventpoll interface */ -void eventpoll_release(struct file *file); +/* Used to release the epoll bits inside the "struct file" */ +void eventpoll_release_file(struct file *file); + +/* + * This is called from inside fs/file_table.c:__fput() to unlink files + * from the eventpoll interface. We need to have this facility to cleanup + * correctly files that are closed without being removed from the eventpoll + * interface. + */ +static inline void eventpoll_release(struct file *file) +{ + + /* + * Fast check to avoid the get/release of the semaphore. Since + * we're doing this outside the semaphore lock, it might return + * false negatives, but we don't care. It'll help in 99.99% of cases + * to avoid the semaphore lock. False positives simply cannot happen + * because the file in on the way to be removed and nobody ( but + * eventpoll ) has still a reference to this file. + */ + if (likely(list_empty(&file->f_ep_links))) + return; + + /* + * The file is being closed while it is still linked to an epoll + * descriptor. We need to handle this by correctly unlinking it + * from its containers. + */ + eventpoll_release_file(file); +} + #else _