]> git.hungrycats.org Git - linux/commitdiff
[PATCH] kill_fasync speedup
authorAndrew Morton <akpm@osdl.org>
Mon, 19 Jan 2004 02:29:54 +0000 (18:29 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Mon, 19 Jan 2004 02:29:54 +0000 (18:29 -0800)
From: Manfred Spraul <manfred@colorfullife.com>

fasync_helper and kill_fasync are helpers for managing F_SETFL fcntl
calls that change FASYNC and sending the necessary signals. The locking
uses one global rwlock that's acquired for read in all kill_fasync
calls, and that causes cache line trashing. This is not necessary: if
the fasync list is empty, then there is no need to acquire the rwlock.
Tests with reaim on a 4-way pIII on STP showed an 80% reduction of the
time within kill_fasync.

fs/fcntl.c

index d4d43638b15398e03b8810fb88e438239e13a5dd..7e824087e71f92ad5fa2e4bc961a4497df43a68a 100644 (file)
@@ -609,9 +609,15 @@ EXPORT_SYMBOL(__kill_fasync);
 
 void kill_fasync(struct fasync_struct **fp, int sig, int band)
 {
-       read_lock(&fasync_lock);
-       __kill_fasync(*fp, sig, band);
-       read_unlock(&fasync_lock);
+       /* First a quick test without locking: usually
+        * the list is empty.
+        */
+       if (*fp) {
+               read_lock(&fasync_lock);
+               /* reread *fp after obtaining the lock */
+               __kill_fasync(*fp, sig, band);
+               read_unlock(&fasync_lock);
+       }
 }
 
 EXPORT_SYMBOL(kill_fasync);