Commit 0d98604b authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] epoll: microoptimisations

From: Davide Libenzi <davidel@xmailserver.org>

- 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 <linux/types.h> inclusion due __u32 and __u64 usage

- Fix debug printf that would otherwise panic if enabled with the new
  epoll code
parent 1c630a8d
...@@ -443,28 +443,16 @@ void eventpoll_init_file(struct file *file) ...@@ -443,28 +443,16 @@ void eventpoll_init_file(struct file *file)
/* /*
* This is called from inside fs/file_table.c:__fput() to unlink files * This is called from eventpoll_release() to unlink files from the eventpoll
* from the eventpoll interface. We need to have this facility to cleanup * interface. We need to have this facility to cleanup correctly files that are
* correctly files that are closed without being removed from the eventpoll * closed without being removed from the eventpoll interface.
* interface.
*/ */
void eventpoll_release(struct file *file) void eventpoll_release_file(struct file *file)
{ {
struct list_head *lsthead = &file->f_ep_links; struct list_head *lsthead = &file->f_ep_links;
struct eventpoll *ep; struct eventpoll *ep;
struct epitem *epi; 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 * 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" * necessary. It is not necessary because we're in the "struct file"
...@@ -541,7 +529,7 @@ asmlinkage long sys_epoll_create(int size) ...@@ -541,7 +529,7 @@ asmlinkage long sys_epoll_create(int size)
/* /*
* The following function implement the controller interface for the eventpoll * The following function implement the controller interface for the eventpoll
* file that enable the insertion/removal/change of file descriptors inside * 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) 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, int op, int fd, struct epoll_event *even ...@@ -551,8 +539,8 @@ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *even
struct epitem *epi; struct epitem *epi;
struct epoll_event epds; struct epoll_event epds;
DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u)\n", DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p)\n",
current, epfd, op, fd, event->events)); current, epfd, op, fd, event));
error = -EFAULT; error = -EFAULT;
if (copy_from_user(&epds, event, sizeof(struct epoll_event))) if (copy_from_user(&epds, event, sizeof(struct epoll_event)))
...@@ -633,8 +621,8 @@ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *even ...@@ -633,8 +621,8 @@ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *even
eexit_2: eexit_2:
fput(file); fput(file);
eexit_1: eexit_1:
DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %u) = %d\n", DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p) = %d\n",
current, epfd, op, fd, event->events, error)); current, epfd, op, fd, event, error));
return error; return error;
} }
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#ifndef _LINUX_EVENTPOLL_H #ifndef _LINUX_EVENTPOLL_H
#define _LINUX_EVENTPOLL_H #define _LINUX_EVENTPOLL_H
#include <linux/types.h>
/* Valid opcodes to issue to sys_epoll_ctl() */ /* Valid opcodes to issue to sys_epoll_ctl() */
#define EPOLL_CTL_ADD 1 #define EPOLL_CTL_ADD 1
...@@ -55,8 +57,37 @@ asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxeven ...@@ -55,8 +57,37 @@ asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxeven
/* Used to initialize the epoll bits inside the "struct file" */ /* Used to initialize the epoll bits inside the "struct file" */
void eventpoll_init_file(struct file *file); void eventpoll_init_file(struct file *file);
/* Used in fs/file_table.c:__fput() to unlink files from the eventpoll interface */ /* Used to release the epoll bits inside the "struct file" */
void eventpoll_release(struct file *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 #else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment