Subject: Re: and now: COMPAT_IBCS2 vs. MP
To: J Chapman Flack <flack@cs.purdue.edu>
From: Jaromir Dolecek <jdolecek@NetBSD.org>
List: tech-kern
Date: 03/05/2005 18:15:49
--ikeVEW9yuYc//A+q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Sat, Mar 05, 2005 at 11:07:26AM -0500, J Chapman Flack wrote:
> Martin Husemann asked:
>
> > Can you try running it on a kernel with options LOCKDEBUG?
>
> simple_lock: locking against myself
> lock: 0xcb752264, currently at: ../../../../kern/kern_descrip.c:597
> on CPU 1
> last locked: ../../../../kern/kern_descrip.c:212
> last unlocked: ../../../../kern/vfs_syscalls.c:1176
>
Please try to apply attached patch. That should fix the locking
error in ibcs2_sys_ioctl().
Jaromir
--
Jaromir Dolecek <jdolecek@NetBSD.org> http://www.NetBSD.cz/
-=- We can walk our road together if our goals are all the same; -=-
-=- We can run alone and free if we pursue a different aim. -=-
--ikeVEW9yuYc//A+q
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ibcs2ioctl.diff"
Index: ibcs2_ioctl.c
===================================================================
RCS file: /cvsroot/src/sys/compat/ibcs2/ibcs2_ioctl.c,v
retrieving revision 1.31
diff -u -p -r1.31 ibcs2_ioctl.c
--- ibcs2_ioctl.c 5 Nov 2003 04:03:43 -0000 1.31
+++ ibcs2_ioctl.c 5 Mar 2005 17:12:00 -0000
@@ -118,6 +118,7 @@ static void stios2btios __P((struct ibcs
static void btios2stios __P((struct termios *, struct ibcs2_termios *));
static void stios2stio __P((struct ibcs2_termios *, struct ibcs2_termio *));
static void stio2stios __P((struct ibcs2_termio *, struct ibcs2_termios *));
+static int ibcs2_ioctlcmd __P((int));
static void
stios2btios(st, bt)
@@ -331,6 +332,31 @@ stio2stios(t, ts)
memcpy(ts->c_cc, t->c_cc, IBCS2_NCC);
}
+static int
+ibcs2_ioctlcmd(cmd)
+ int cmd;
+{
+ switch (cmd) {
+ case IBCS2_TIOCGWINSZ:
+ cmd = TIOCGWINSZ;
+ break;
+
+ case IBCS2_TIOCSWINSZ:
+ cmd = TIOCSWINSZ;
+ break;
+
+ case IBCS2_I_NREAD: /* STREAMS */
+ cmd = FIONREAD;
+ break;
+
+ default:
+ panic("ibcs2_ioctlcmd: unknown cmd '%d'", cmd);
+ /* NOTREACHED */
+ }
+
+ return cmd;
+}
+
int
ibcs2_sys_ioctl(l, v, retval)
struct lwp *l;
@@ -346,7 +372,7 @@ ibcs2_sys_ioctl(l, v, retval)
struct filedesc *fdp = p->p_fd;
struct file *fp;
int (*ctl)(struct file *, u_long, void *, struct proc *);
- int error;
+ int error, locked = 1;
if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL) {
DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p->p_pid,
@@ -354,8 +380,11 @@ ibcs2_sys_ioctl(l, v, retval)
return EBADF;
}
+ FILE_USE(fp);
+
if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
DPRINTF(("ibcs2_ioctl(%d): bad fp flag ", p->p_pid));
+ FILE_UNUSE(fp, p);
return EBADF;
}
@@ -371,7 +400,7 @@ ibcs2_sys_ioctl(l, v, retval)
struct ibcs2_termio st;
if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
- return error;
+ break;
btios2stios (&bts, &sts);
if (SCARG(uap, cmd) == IBCS2_TCGETA) {
@@ -381,11 +410,11 @@ ibcs2_sys_ioctl(l, v, retval)
if (error)
DPRINTF(("ibcs2_ioctl(%d): copyout failed ",
p->p_pid));
- return error;
- } else
- return copyout((caddr_t)&sts, SCARG(uap, data),
+ } else {
+ error = copyout((caddr_t)&sts, SCARG(uap, data),
sizeof (sts));
- /*NOTREACHED*/
+ }
+ break;
}
case IBCS2_TCSETA:
@@ -400,14 +429,14 @@ ibcs2_sys_ioctl(l, v, retval)
sizeof(st))) != 0) {
DPRINTF(("ibcs2_ioctl(%d): TCSET copyin failed ",
p->p_pid));
- return error;
+ break;
}
/* get full BSD termios so we don't lose information */
if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0) {
DPRINTF(("ibcs2_ioctl(%d): TCSET ctl failed fd %d ",
p->p_pid, SCARG(uap, fd)));
- return error;
+ break;
}
/*
@@ -418,8 +447,9 @@ ibcs2_sys_ioctl(l, v, retval)
stio2stios(&st, &sts);
stios2btios(&sts, &bts);
- return (*ctl)(fp, SCARG(uap, cmd) - IBCS2_TCSETA + TIOCSETA,
+ error = (*ctl)(fp, SCARG(uap, cmd) - IBCS2_TCSETA + TIOCSETA,
(caddr_t)&bts, p);
+ break;
}
case IBCS2_XCSETA:
@@ -431,11 +461,12 @@ ibcs2_sys_ioctl(l, v, retval)
if ((error = copyin(SCARG(uap, data), (caddr_t)&sts,
sizeof (sts))) != 0) {
- return error;
+ break;
}
stios2btios (&sts, &bts);
- return (*ctl)(fp, SCARG(uap, cmd) - IBCS2_XCSETA + TIOCSETA,
+ error = (*ctl)(fp, SCARG(uap, cmd) - IBCS2_XCSETA + TIOCSETA,
(caddr_t)&bts, p);
+ break;
}
case IBCS2_OXCSETA:
@@ -447,11 +478,12 @@ ibcs2_sys_ioctl(l, v, retval)
if ((error = copyin(SCARG(uap, data), (caddr_t)&sts,
sizeof (sts))) != 0) {
- return error;
+ break;
}
stios2btios (&sts, &bts);
- return (*ctl)(fp, SCARG(uap, cmd) - IBCS2_OXCSETA + TIOCSETA,
+ error = (*ctl)(fp, SCARG(uap, cmd) - IBCS2_OXCSETA + TIOCSETA,
(caddr_t)&bts, p);
+ break;
}
case IBCS2_TCSBRK:
@@ -461,13 +493,14 @@ ibcs2_sys_ioctl(l, v, retval)
t = (t ? t : 1) * hz * 4;
t /= 10;
if ((error = (*ctl)(fp, TIOCSBRK, (caddr_t)0, p)))
- return error;
+ break;
error = tsleep((caddr_t)&t, PZERO | PCATCH, "ibcs2_tcsbrk", t);
if (error == EINTR || error == ERESTART) {
(*ctl)(fp, TIOCCBRK, (caddr_t)0, p);
- return EINTR;
+ error = EINTR;
} else
- return (*ctl)(fp, TIOCCBRK, (caddr_t)0, p);
+ error = (*ctl)(fp, TIOCCBRK, (caddr_t)0, p);
+ break;
}
case IBCS2_TCXONC:
@@ -476,14 +509,20 @@ ibcs2_sys_ioctl(l, v, retval)
case 0:
case 1:
DPRINTF(("ibcs2_ioctl(%d): TCXONC ", p->p_pid));
- return ENOSYS;
+ error = ENOSYS;
+ break;
case 2:
- return (*ctl)(fp, TIOCSTOP, (caddr_t)0, p);
+ error = (*ctl)(fp, TIOCSTOP, (caddr_t)0, p);
+ break;
case 3:
- return (*ctl)(fp, TIOCSTART, (caddr_t)1, p);
+ error = (*ctl)(fp, TIOCSTART, (caddr_t)1, p);
+ break;
default:
- return EINVAL;
+ error = EINVAL;
+ break;
}
+
+ break;
}
case IBCS2_TCFLSH:
@@ -501,22 +540,17 @@ ibcs2_sys_ioctl(l, v, retval)
arg = FREAD | FWRITE;
break;
default:
- return EINVAL;
+ error = EINVAL;
+ goto out;
}
- return (*ctl)(fp, TIOCFLUSH, (caddr_t)&arg, p);
+ error = (*ctl)(fp, TIOCFLUSH, (caddr_t)&arg, p);
+ break;
}
- case IBCS2_TIOCGWINSZ:
- SCARG(uap, cmd) = TIOCGWINSZ;
- return sys_ioctl(l, uap, retval);
-
- case IBCS2_TIOCSWINSZ:
- SCARG(uap, cmd) = TIOCSWINSZ;
- return sys_ioctl(l, uap, retval);
-
case IBCS2_TIOCGPGRP:
- return copyout((caddr_t)&p->p_pgrp->pg_id, SCARG(uap, data),
+ error = copyout((caddr_t)&p->p_pgrp->pg_id, SCARG(uap, data),
sizeof(p->p_pgrp->pg_id));
+ break;
case IBCS2_TIOCSPGRP: /* XXX - is uap->data a pointer to pgid? */
{
@@ -524,19 +558,18 @@ ibcs2_sys_ioctl(l, v, retval)
SCARG(&sa, pid) = 0;
SCARG(&sa, pgid) = (int)SCARG(uap, data);
- if ((error = sys_setpgid(l, &sa, retval)) != 0)
- return error;
- return 0;
+ error = sys_setpgid(l, &sa, retval);
+ break;
}
case IBCS2_TCGETSC: /* SCO console - get scancode flags */
- return ENOSYS;
-
case IBCS2_TCSETSC: /* SCO console - set scancode flags */
- return ENOSYS;
+ error = ENOSYS;
+ break;
case IBCS2_SIOCSOCKSYS:
- return ibcs2_socksys(l, uap, retval);
+ error = ibcs2_socksys(l, uap, retval);
+ break;
case IBCS2_FIONBIO:
{
@@ -544,20 +577,38 @@ ibcs2_sys_ioctl(l, v, retval)
if ((error = copyin(SCARG(uap, data), &arg,
sizeof(arg))) != 0)
- return error;
+ break;
- return (*ctl)(fp, FIONBIO, (caddr_t)&arg, p);
+ error = (*ctl)(fp, FIONBIO, (caddr_t)&arg, p);
+ break;
}
+ case IBCS2_TIOCGWINSZ:
+ case IBCS2_TIOCSWINSZ:
case IBCS2_I_NREAD: /* STREAMS */
- SCARG(uap, cmd) = FIONREAD;
- return sys_ioctl(l, uap, retval);
+ SCARG(uap, cmd) = ibcs2_ioctlcmd(SCARG(uap, cmd));
+
+ /*
+ * Need to unlock file descriptor before calling sys_ioctl(),
+ * since that expects the descriptor unlocked and attemps
+ * to lock it.
+ */
+ FILE_UNUSE(fp, p);
+ locked = 0;
+ error = sys_ioctl(l, uap, retval);
+ break;
default:
DPRINTF(("ibcs2_ioctl(%d): unknown cmd 0x%x ",
p->p_pid, SCARG(uap, cmd)));
- return ENOSYS;
+ error = ENOSYS;
+ break;
}
+
+ out:
+ if (__predict_true(locked))
+ FILE_UNUSE(fp, p);
+ return error;
}
int
--ikeVEW9yuYc//A+q--