Skip to content

Commit

Permalink
stallion: prune lock_kernel calls
Browse files Browse the repository at this point in the history
Remove unneeded tty layer lock kernel bits. Relock the needed bits using the
port mutex. The istallion still has brd state races but those are not new
or introduced by the removal of the lock_kernel logic.

Signed-off-by: Alan Cox <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
Alan Cox authored and gregkh committed Aug 10, 2010
1 parent 8fd4bd2 commit b4eda9c
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 17 deletions.
22 changes: 13 additions & 9 deletions drivers/char/istallion.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* FIXME: brdp->state needs proper locking.
*/

/*****************************************************************************/
Expand Down Expand Up @@ -4011,6 +4012,7 @@ static int stli_getbrdstats(combrd_t __user *bp)
return -ENODEV;

memset(&stli_brdstats, 0, sizeof(combrd_t));

stli_brdstats.brd = brdp->brdnr;
stli_brdstats.type = brdp->brdtype;
stli_brdstats.hwid = 0;
Expand Down Expand Up @@ -4076,10 +4078,13 @@ static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp)
if (brdp == NULL)
return -ENODEV;

mutex_lock(&portp->port.mutex);
if (brdp->state & BST_STARTED) {
if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS,
&stli_cdkstats, sizeof(asystats_t), 1)) < 0)
&stli_cdkstats, sizeof(asystats_t), 1)) < 0) {
mutex_unlock(&portp->port.mutex);
return rc;
}
} else {
memset(&stli_cdkstats, 0, sizeof(asystats_t));
}
Expand Down Expand Up @@ -4124,6 +4129,7 @@ static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp)
stli_comstats.modem = stli_cdkstats.dcdcnt;
stli_comstats.hwid = stli_cdkstats.hwid;
stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals);
mutex_unlock(&portp->port.mutex);

return 0;
}
Expand Down Expand Up @@ -4186,15 +4192,20 @@ static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp)
if (!brdp)
return -ENODEV;

mutex_lock(&portp->port.mutex);

if (brdp->state & BST_STARTED) {
if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, NULL, 0, 0)) < 0)
if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, NULL, 0, 0)) < 0) {
mutex_unlock(&portp->port.mutex);
return rc;
}
}

memset(&stli_comstats, 0, sizeof(comstats_t));
stli_comstats.brd = portp->brdnr;
stli_comstats.panel = portp->panelnr;
stli_comstats.port = portp->portnr;
mutex_unlock(&portp->port.mutex);

if (copy_to_user(cp, &stli_comstats, sizeof(comstats_t)))
return -EFAULT;
Expand Down Expand Up @@ -4266,8 +4277,6 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
done = 0;
rc = 0;

lock_kernel();

switch (cmd) {
case COM_GETPORTSTATS:
rc = stli_getportstats(NULL, NULL, argp);
Expand All @@ -4290,8 +4299,6 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
done++;
break;
}
unlock_kernel();

if (done)
return rc;

Expand All @@ -4308,8 +4315,6 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
if (brdp->state == 0)
return -ENODEV;

lock_kernel();

switch (cmd) {
case STL_BINTR:
EBRDINTR(brdp);
Expand All @@ -4332,7 +4337,6 @@ static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
rc = -ENOIOCTLCMD;
break;
}
unlock_kernel();
return rc;
}

Expand Down
20 changes: 12 additions & 8 deletions drivers/char/stallion.c
Original file line number Diff line number Diff line change
Expand Up @@ -807,15 +807,13 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout)
timeout = HZ;
tend = jiffies + timeout;

lock_kernel();
while (stl_datastate(portp)) {
if (signal_pending(current))
break;
msleep_interruptible(20);
if (time_after_eq(jiffies, tend))
break;
}
unlock_kernel();
}

/*****************************************************************************/
Expand Down Expand Up @@ -1029,6 +1027,8 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp)
pr_debug("stl_getserial(portp=%p,sp=%p)\n", portp, sp);

memset(&sio, 0, sizeof(struct serial_struct));

mutex_lock(&portp->port.mutex);
sio.line = portp->portnr;
sio.port = portp->ioaddr;
sio.flags = portp->port.flags;
Expand All @@ -1048,6 +1048,7 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp)
brdp = stl_brds[portp->brdnr];
if (brdp != NULL)
sio.irq = brdp->irq;
mutex_unlock(&portp->port.mutex);

return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0;
}
Expand All @@ -1069,12 +1070,15 @@ static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp

if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
return -EFAULT;
mutex_lock(&portp->port.mutex);
if (!capable(CAP_SYS_ADMIN)) {
if ((sio.baud_base != portp->baud_base) ||
(sio.close_delay != portp->close_delay) ||
((sio.flags & ~ASYNC_USR_MASK) !=
(portp->port.flags & ~ASYNC_USR_MASK)))
(portp->port.flags & ~ASYNC_USR_MASK))) {
mutex_unlock(&portp->port.mutex);
return -EPERM;
}
}

portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
Expand All @@ -1083,6 +1087,7 @@ static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp
portp->close_delay = sio.close_delay;
portp->closing_wait = sio.closing_wait;
portp->custom_divisor = sio.custom_divisor;
mutex_unlock(&portp->port.mutex);
stl_setport(portp, tty->termios);
return 0;
}
Expand Down Expand Up @@ -1147,8 +1152,6 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd

rc = 0;

lock_kernel();

switch (cmd) {
case TIOCGSERIAL:
rc = stl_getserial(portp, argp);
Expand All @@ -1173,7 +1176,6 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd
rc = -ENOIOCTLCMD;
break;
}
unlock_kernel();
return rc;
}

Expand Down Expand Up @@ -2327,6 +2329,7 @@ static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comst
return -ENODEV;
}

mutex_lock(&portp->port.mutex);
portp->stats.state = portp->istate;
portp->stats.flags = portp->port.flags;
portp->stats.hwid = portp->hwid;
Expand Down Expand Up @@ -2358,6 +2361,7 @@ static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comst
(STL_TXBUFSIZE - (tail - head));

portp->stats.signals = (unsigned long) stl_getsignals(portp);
mutex_unlock(&portp->port.mutex);

return copy_to_user(cp, &portp->stats,
sizeof(comstats_t)) ? -EFAULT : 0;
Expand All @@ -2382,10 +2386,12 @@ static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp)
return -ENODEV;
}

mutex_lock(&portp->port.mutex);
memset(&portp->stats, 0, sizeof(comstats_t));
portp->stats.brd = portp->brdnr;
portp->stats.panel = portp->panelnr;
portp->stats.port = portp->portnr;
mutex_unlock(&portp->port.mutex);
return copy_to_user(cp, &portp->stats,
sizeof(comstats_t)) ? -EFAULT : 0;
}
Expand Down Expand Up @@ -2451,7 +2457,6 @@ static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
return -ENODEV;
rc = 0;

lock_kernel();
switch (cmd) {
case COM_GETPORTSTATS:
rc = stl_getportstats(NULL, NULL, argp);
Expand All @@ -2472,7 +2477,6 @@ static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg)
rc = -ENOIOCTLCMD;
break;
}
unlock_kernel();
return rc;
}

Expand Down

0 comments on commit b4eda9c

Please sign in to comment.