[patch] better SMP performance for pipes [2.3.*]

From: Martin Schenk (schenkm@ping.at)
Date: Sun Feb 27 2000 - 11:12:22 EST


On a SMP system, contention of PIPE_SEM leads to unnecessary scheduling.
Using "adaptive semaphores" (from my previous post to this list), this
problem is easily solved.

I originally tried to do this replacing PIPE_SEM with a spinlock, but
this
is a cleaner way and it should not deadlock when copy_from_user
pagefaults
(Thanks to Manfred Spraul for pointing out this problem).

Hope this patch is useful,

Martin

PS: a good example to show the performance problem of stock SMP 2.3.*
kernels is the "pipedis" benchmark program in the IX_SSBA benchmark
suite
(basically it's just one process writing into a pipe and another reading
from it).

Under 2.2.14. "pipedis 500000 1" takes about 2 seconds, under 2.3.47
almost 6 seconds - using this patch the time is back to a bit more than
2 seconds. [under 2.2.14 the access to pipe_read/pipe_write was
protected
by the kernel lock instead of the semaphore]

--- /home/martin/linuxelf-2.3.orig/fs/pipe.c Fri Feb 11 20:02:05 2000
+++ pipe.c Sun Feb 27 16:34:33 2000
@@ -62,9 +62,9 @@
 
         /* Get the pipe semaphore */
         ret = -ERESTARTSYS;
- if (down_interruptible(PIPE_SEM(*inode)))
- goto out_nolock;
 
+ /* try to spin first, interruptible is not necessary */
+ down_adapt(PIPE_SEM(*inode));
         if (PIPE_EMPTY(*inode)) {
 do_more_read:
                 ret = 0;
@@ -82,8 +82,7 @@
                         ret = -ERESTARTSYS;
                         if (signal_pending(current))
                                 goto out_nolock;
- if (down_interruptible(PIPE_SEM(*inode)))
- goto out_nolock;
+ down_adapt(PIPE_SEM(*inode));
                         ret = 0;
                         if (!PIPE_EMPTY(*inode))
                                 break;
@@ -159,9 +158,7 @@
                 goto out_nolock;
 
         ret = -ERESTARTSYS;
- if (down_interruptible(PIPE_SEM(*inode)))
- goto out_nolock;
-
+ down_adapt(PIPE_SEM(*inode));
 do_more_write:
         /* No readers yields SIGPIPE. */
         if (!PIPE_READERS(*inode))
@@ -183,9 +180,7 @@
                         ret = -ERESTARTSYS;
                         if (signal_pending(current))
                                 goto out_nolock;
- if (down_interruptible(PIPE_SEM(*inode)))
- goto out_nolock;
-
+ down_adapt(PIPE_SEM(*inode));
                         if (!PIPE_READERS(*inode))
                                 goto sigpipe;
                 }
@@ -231,8 +226,7 @@
                         PIPE_WAITING_WRITERS(*inode)--;
                         if (signal_pending(current))
                                 goto out_nolock;
- if (down_interruptible(PIPE_SEM(*inode)))
- goto out_nolock;
+ down_adapt(PIPE_SEM(*inode));
                         if (!PIPE_READERS(*inode))
                                 goto sigpipe;
                 } while (!PIPE_FREE(*inode));

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



This archive was generated by hypermail 2b29 : Tue Feb 29 2000 - 21:00:17 EST