From 4d497602680edbb3c60d6ab45e886f485a98c9f2 Mon Sep 17 00:00:00 2001 From: jdolecek Date: Sun, 22 Feb 2004 17:51:25 +0000 Subject: [PATCH] use the new NOTE_SUBMIT to flag if the locking is necessary for EVFILT_READ/EVFILT_WRITE knotes fixes PR kern/23915 by Martin Husemann (pipes), and similar locking problem in tty code --- sys/kern/sys_pipe.c | 24 +++++++++++++++--------- sys/kern/tty.c | 20 ++++++++++++-------- sys/kern/tty_pty.c | 16 ++++++++-------- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index bffdb3293666..03c48f3480bb 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -1,4 +1,4 @@ -/* $NetBSD: sys_pipe.c,v 1.47 2003/12/04 19:38:24 atatat Exp $ */ +/* $NetBSD: sys_pipe.c,v 1.48 2004/02/22 17:51:25 jdolecek Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -83,7 +83,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.47 2003/12/04 19:38:24 atatat Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.48 2004/02/22 17:51:25 jdolecek Exp $"); #include #include @@ -405,7 +405,7 @@ pipeselwakeup(selp, sigp, data, code) /*###406 [cc] warning: `band' might be used uninitialized in this function%%%*/ int band; - selnotify(&selp->pipe_sel, 0); + selnotify(&selp->pipe_sel, NOTE_SUBMIT); if (sigp == NULL || (sigp->pipe_state & PIPE_ASYNC) == 0) return; @@ -1372,7 +1372,8 @@ filt_piperead(struct knote *kn, long hint) struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data; struct pipe *wpipe = rpipe->pipe_peer; - PIPE_LOCK(rpipe); + if ((hint & NOTE_SUBMIT) == 0) + PIPE_LOCK(rpipe); kn->kn_data = rpipe->pipe_buffer.cnt; if ((kn->kn_data == 0) && (rpipe->pipe_state & PIPE_DIRECTW)) kn->kn_data = rpipe->pipe_map.cnt; @@ -1381,10 +1382,12 @@ filt_piperead(struct knote *kn, long hint) if ((rpipe->pipe_state & PIPE_EOF) || (wpipe == NULL) || (wpipe->pipe_state & PIPE_EOF)) { kn->kn_flags |= EV_EOF; - PIPE_UNLOCK(rpipe); + if ((hint & NOTE_SUBMIT) == 0) + PIPE_UNLOCK(rpipe); return (1); } - PIPE_UNLOCK(rpipe); + if ((hint & NOTE_SUBMIT) == 0) + PIPE_UNLOCK(rpipe); return (kn->kn_data > 0); } @@ -1395,19 +1398,22 @@ filt_pipewrite(struct knote *kn, long hint) struct pipe *rpipe = (struct pipe *)kn->kn_fp->f_data; struct pipe *wpipe = rpipe->pipe_peer; - PIPE_LOCK(rpipe); + if ((hint & NOTE_SUBMIT) == 0) + PIPE_LOCK(rpipe); /* XXXSMP: race for peer */ if ((wpipe == NULL) || (wpipe->pipe_state & PIPE_EOF)) { kn->kn_data = 0; kn->kn_flags |= EV_EOF; - PIPE_UNLOCK(rpipe); + if ((hint & NOTE_SUBMIT) == 0) + PIPE_UNLOCK(rpipe); return (1); } kn->kn_data = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt; if (wpipe->pipe_state & PIPE_DIRECTW) kn->kn_data = 0; - PIPE_UNLOCK(rpipe); + if ((hint & NOTE_SUBMIT) == 0) + PIPE_UNLOCK(rpipe); return (kn->kn_data >= PIPE_BUF); } diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 2bd4fcfed637..84eb2b8236be 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.161 2004/02/13 11:36:23 wiz Exp $ */ +/* $NetBSD: tty.c,v 1.162 2004/02/22 17:51:25 jdolecek Exp $ */ /*- * Copyright (c) 1982, 1986, 1990, 1991, 1993 @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.161 2004/02/13 11:36:23 wiz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tty.c,v 1.162 2004/02/22 17:51:25 jdolecek Exp $"); #include #include @@ -1239,9 +1239,11 @@ filt_ttyread(struct knote *kn, long hint) tp = kn->kn_hook; s = spltty(); - TTY_LOCK(tp); + if ((hint & NOTE_SUBMIT) == 0) + TTY_LOCK(tp); kn->kn_data = ttnread(tp); - TTY_UNLOCK(tp); + if ((hint & NOTE_SUBMIT) == 0) + TTY_UNLOCK(tp); splx(s); return (kn->kn_data > 0); } @@ -1268,10 +1270,12 @@ filt_ttywrite(struct knote *kn, long hint) tp = kn->kn_hook; s = spltty(); - TTY_LOCK(tp); + if ((hint & NOTE_SUBMIT) == 0) + TTY_LOCK(tp); kn->kn_data = tp->t_outq.c_cn - tp->t_outq.c_cc; canwrite = (tp->t_outq.c_cc <= tp->t_lowat) && CONNECTED(tp); - TTY_UNLOCK(tp); + if ((hint & NOTE_SUBMIT) == 0) + TTY_UNLOCK(tp); splx(s); return (canwrite); } @@ -1405,7 +1409,7 @@ ttyflush(struct tty *tp, int rw) (*cdev->d_stop)(tp, rw); FLUSHQ(&tp->t_outq); wakeup((caddr_t)&tp->t_outq); - selnotify(&tp->t_wsel, 0); + selnotify(&tp->t_wsel, NOTE_SUBMIT); } } @@ -2224,7 +2228,7 @@ void ttwakeup(struct tty *tp) { - selnotify(&tp->t_rsel, 0); + selnotify(&tp->t_rsel, NOTE_SUBMIT); if (ISSET(tp->t_state, TS_ASYNC)) pgsignal(tp->t_pgrp, SIGIO, 1); wakeup((caddr_t)&tp->t_rawq); diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c index d68c2073fe6c..2d7288fd413f 100644 --- a/sys/kern/tty_pty.c +++ b/sys/kern/tty_pty.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty_pty.c,v 1.72 2003/08/07 16:31:56 agc Exp $ */ +/* $NetBSD: tty_pty.c,v 1.73 2004/02/22 17:51:26 jdolecek Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tty_pty.c,v 1.72 2003/08/07 16:31:56 agc Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tty_pty.c,v 1.73 2004/02/22 17:51:26 jdolecek Exp $"); #include "opt_compat_sunos.h" @@ -468,7 +468,7 @@ ptsstart(tp) pti->pt_send = TIOCPKT_START; } - selnotify(&pti->pt_selr, 0); + selnotify(&pti->pt_selr, NOTE_SUBMIT); wakeup((caddr_t)&tp->t_outq.c_cf); } @@ -493,11 +493,11 @@ ptsstop(tp, flush) /* change of perspective */ if (flush & FREAD) { - selnotify(&pti->pt_selw, 0); + selnotify(&pti->pt_selw, NOTE_SUBMIT); wakeup((caddr_t)&tp->t_rawq.c_cf); } if (flush & FWRITE) { - selnotify(&pti->pt_selr, 0); + selnotify(&pti->pt_selr, NOTE_SUBMIT); wakeup((caddr_t)&tp->t_outq.c_cf); } } @@ -511,11 +511,11 @@ ptcwakeup(tp, flag) TTY_LOCK(tp); if (flag & FREAD) { - selnotify(&pti->pt_selr, 0); + selnotify(&pti->pt_selr, NOTE_SUBMIT); wakeup((caddr_t)&tp->t_outq.c_cf); } if (flag & FWRITE) { - selnotify(&pti->pt_selw, 0); + selnotify(&pti->pt_selw, NOTE_SUBMIT); wakeup((caddr_t)&tp->t_rawq.c_cf); } TTY_UNLOCK(tp); @@ -660,7 +660,7 @@ ptcread(dev, uio, flag) CLR(tp->t_state, TS_ASLEEP); wakeup((caddr_t)&tp->t_outq); } - selnotify(&tp->t_wsel, 0); + selnotify(&tp->t_wsel, NOTE_SUBMIT); } out: TTY_UNLOCK(tp);