lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon,  2 Feb 2009 11:20:09 -0700
From:	Jonathan Corbet <corbet@....net>
To:	linux-kernel@...r.kernel.org
Cc:	Andi Kleen <andi@...stfloor.org>, Oleg Nesterov <oleg@...hat.com>,
	Andrew Morton <akpm@...ux-foundation.org>,
	Al Viro <viro@...IV.linux.org.uk>,
	Davide Libenzi <davidel@...ilserver.org>,
	David Miller <davem@...emloft.net>,
	Christoph Hellwig <hch@....de>, linux-api@...r.kernel.org,
	Matt Mackall <mpm@...enic.com>,
	Alan Cox <alan@...rguk.ukuu.org.uk>,
	Jonathan Corbet <corbet@....net>
Subject: [PATCH 2/4] Convert epoll to a bitlock

Matt Mackall suggested converting epoll's ep_lock to a bitlock as a way of
saving space in struct file.  This patch makes that change.

Signed-off-by: Jonathan Corbet <corbet@....net>
---
 fs/eventpoll.c              |   13 ++++++++-----
 fs/fcntl.c                  |    2 +-
 include/asm-generic/fcntl.h |    4 ++++
 include/linux/eventpoll.h   |    2 +-
 include/linux/fs.h          |    1 -
 5 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index ba2f9ec..95fae01 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -25,6 +25,7 @@
 #include <linux/list.h>
 #include <linux/hash.h>
 #include <linux/spinlock.h>
+#include <linux/bit_spinlock.h>
 #include <linux/syscalls.h>
 #include <linux/rbtree.h>
 #include <linux/wait.h>
@@ -427,10 +428,10 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi)
 	ep_unregister_pollwait(ep, epi);
 
 	/* Remove the current item from the list of epoll hooks */
-	spin_lock(&file->f_ep_lock);
+	bit_spin_lock(NR_EPOLL_FILE_LOCK, &file->f_flags);
 	if (ep_is_linked(&epi->fllink))
 		list_del_init(&epi->fllink);
-	spin_unlock(&file->f_ep_lock);
+	bit_spin_unlock(NR_EPOLL_FILE_LOCK, &file->f_flags);
 
 	rb_erase(&epi->rbn, &ep->rbr);
 
@@ -549,7 +550,7 @@ void eventpoll_release_file(struct file *file)
 	struct epitem *epi;
 
 	/*
-	 * We don't want to get "file->f_ep_lock" because it is not
+	 * We don't want to get EPOLL_FILE_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.
 	 * So, for example, epoll_ctl() cannot hit here sicne if we reach this
@@ -558,6 +559,8 @@ void eventpoll_release_file(struct file *file)
 	 * will correctly serialize the operation. We do need to acquire
 	 * "ep->mtx" after "epmutex" because ep_remove() requires it when called
 	 * from anywhere but ep_free().
+	 *
+	 * Besides, ep_remove() takes the lock.
 	 */
 	mutex_lock(&epmutex);
 
@@ -800,9 +803,9 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
 		goto error_unregister;
 
 	/* Add the current item to the list of active epoll hook for this file */
-	spin_lock(&tfile->f_ep_lock);
+	bit_spin_lock(NR_EPOLL_FILE_LOCK, &tfile->f_flags);
 	list_add_tail(&epi->fllink, &tfile->f_ep_links);
-	spin_unlock(&tfile->f_ep_lock);
+	bit_spin_unlock(NR_EPOLL_FILE_LOCK, &tfile->f_flags);
 
 	/*
 	 * Add the current item to the RB tree. All RB tree operations are
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 3affd3e..756119e 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -299,7 +299,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
 		set_close_on_exec(fd, arg & FD_CLOEXEC);
 		break;
 	case F_GETFL:
-		err = filp->f_flags;
+		err = filp->f_flags & ~EPOLL_FILE_LOCK;
 		break;
 	case F_SETFL:
 		err = setfl(fd, filp, arg);
diff --git a/include/asm-generic/fcntl.h b/include/asm-generic/fcntl.h
index 41e9f88..d56a513 100644
--- a/include/asm-generic/fcntl.h
+++ b/include/asm-generic/fcntl.h
@@ -62,6 +62,10 @@
 #define NR_O_NDELAY	NR_O_NONBLOCK
 #endif
 
+/* Use bit 31 for epoll locking */
+#define NR_EPOLL_FILE_LOCK 31
+#define EPOLL_FILE_LOCK (1 << NR_EPOLL_FILE_LOCK)
+
 #define F_DUPFD		0	/* dup */
 #define F_GETFD		1	/* get close_on_exec */
 #define F_SETFD		2	/* set/clear close_on_exec */
diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h
index f1e1d3c..7b5c58a 100644
--- a/include/linux/eventpoll.h
+++ b/include/linux/eventpoll.h
@@ -61,7 +61,7 @@ struct file;
 static inline void eventpoll_init_file(struct file *file)
 {
 	INIT_LIST_HEAD(&file->f_ep_links);
-	spin_lock_init(&file->f_ep_lock);
+	clear_bit(NR_EPOLL_FILE_LOCK, &file->f_flags);
 }
 
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 9d7cb0e..ecd9a5b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -865,7 +865,6 @@ struct file {
 #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;
 #ifdef CONFIG_DEBUG_WRITECOUNT
-- 
1.6.1.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ