lkml.org 
[lkml]   [2000]   [Feb]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch] better SMP performance for pipes [2.3.*]
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));
\
 
 \ /
  Last update: 2005-03-22 13:56    [W:0.040 / U:0.768 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site