From dd80ddaf144efc9592b66a7da8fe3682c44b8f4c Mon Sep 17 00:00:00 2001 From: yamt Date: Sat, 29 Oct 2005 12:31:07 +0000 Subject: [PATCH] just use ltsleep rather than lockmgr + PCATCH with horrible timeout dance. --- sys/kern/sys_pipe.c | 58 +++++++++++++++++++-------------------------- sys/sys/pipe.h | 7 ++++-- 2 files changed, 29 insertions(+), 36 deletions(-) diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index bea0c9fb0e2b..b744c55570db 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -1,4 +1,4 @@ -/* $NetBSD: sys_pipe.c,v 1.66 2005/09/11 17:55:26 christos Exp $ */ +/* $NetBSD: sys_pipe.c,v 1.67 2005/10/29 12:31:07 yamt Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -83,7 +83,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.66 2005/09/11 17:55:26 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.67 2005/10/29 12:31:07 yamt Exp $"); #include #include @@ -324,7 +324,6 @@ pipe_create(pipep, allockva) pipe->pipe_atime = pipe->pipe_ctime; pipe->pipe_mtime = pipe->pipe_ctime; simple_lock_init(&pipe->pipe_slock); - lockinit(&pipe->pipe_lock, PSOCK | PCATCH, "pipelk", 0, 0); if (allockva && (error = pipespace(pipe, PIPE_SIZE))) return (error); @@ -343,40 +342,24 @@ pipelock(pipe, catch) struct pipe *pipe; int catch; { - int error; LOCK_ASSERT(simple_lock_held(&pipe->pipe_slock)); - while (1) { - error = lockmgr(&pipe->pipe_lock, LK_EXCLUSIVE | LK_INTERLOCK, - &pipe->pipe_slock); - if (error == 0) - break; + while (pipe->pipe_state & PIPE_LOCKFL) { + int error; + const int pcatch = catch ? PCATCH : 0; - simple_lock(&pipe->pipe_slock); - if (catch || (error != EINTR && error != ERESTART)) - break; - /* - * XXX XXX XXX - * The pipe lock is initialised with PCATCH on and we cannot - * override this in a lockmgr() call. Thus a pending signal - * will cause lockmgr() to return with EINTR or ERESTART. - * We cannot simply re-enter lockmgr() at this point since - * the pending signals have not yet been posted and would - * cause an immediate EINTR/ERESTART return again. - * As a workaround we pause for a while here, giving the lock - * a chance to drain, before trying again. - * XXX XXX XXX - * - * NOTE: Consider dropping PCATCH from this lock; in practice - * it is never held for long enough periods for having it - * interruptable at the start of pipe_read/pipe_write to be - * beneficial. - */ - (void) ltsleep(&lbolt, PSOCK, "rstrtpipelock", hz, + pipe->pipe_state |= PIPE_LWANT; + error = ltsleep(pipe, PSOCK | pcatch, "pipelk", 0, &pipe->pipe_slock); + if (error != 0) + return error; } - return (error); + + pipe->pipe_state |= PIPE_LOCKFL; + simple_unlock(&pipe->pipe_slock); + + return 0; } /* @@ -387,7 +370,13 @@ pipeunlock(pipe) struct pipe *pipe; { - lockmgr(&pipe->pipe_lock, LK_RELEASE, NULL); + KASSERT(pipe->pipe_state & PIPE_LOCKFL); + + pipe->pipe_state &= ~PIPE_LOCKFL; + if (pipe->pipe_state & PIPE_LWANT) { + pipe->pipe_state &= ~PIPE_LWANT; + wakeup(pipe); + } } /* @@ -1352,8 +1341,9 @@ retry: PIPE_UNLOCK(ppipe); } - (void)lockmgr(&pipe->pipe_lock, LK_DRAIN | LK_INTERLOCK, - &pipe->pipe_slock); + KASSERT((pipe->pipe_state & PIPE_LOCKFL) == 0); + + PIPE_UNLOCK(pipe); /* * free resources diff --git a/sys/sys/pipe.h b/sys/sys/pipe.h index 5be732aa7650..ff96e66a341c 100644 --- a/sys/sys/pipe.h +++ b/sys/sys/pipe.h @@ -1,4 +1,4 @@ -/* $NetBSD: pipe.h,v 1.16 2005/03/17 20:39:17 kleink Exp $ */ +/* $NetBSD: pipe.h,v 1.17 2005/10/29 12:31:07 yamt Exp $ */ /* * Copyright (c) 1996 John S. Dyson @@ -94,6 +94,10 @@ struct pipemapping { #define PIPE_SIGNALR 0x020 /* Do selwakeup() on read(2) */ #define PIPE_DIRECTW 0x040 /* Pipe in direct write mode setup */ #define PIPE_DIRECTR 0x080 /* Pipe direct read request (setup complete) */ +#define PIPE_LOCKFL 0x100 /* Process has exclusive access to + pointers/data. */ +#define PIPE_LWANT 0x200 /* Process wants exclusive access to + pointers/data. */ /* * Per-pipe data structure. @@ -101,7 +105,6 @@ struct pipemapping { */ struct pipe { struct simplelock pipe_slock; /* pipe mutex */ - struct lock pipe_lock; /* long-term pipe lock */ struct pipebuf pipe_buffer; /* data storage */ struct pipemapping pipe_map; /* pipe mapping for direct I/O */ struct selinfo pipe_sel; /* for compat with select */