isdn: fix multiple sleep_on races

The isdn core code uses a couple of wait queues with
interruptible_sleep_on, which is racy and about to get
removed from the kernel. Fortunately, we know for each case
what we are waiting for, so they can all be converted to
the better wait_event_interruptible interface.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Karsten Keil <isdn@linux-pingi.de>
Cc: netdev@vger.kernel.org
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Arnd Bergmann 2014-02-26 12:01:55 +01:00 committed by David S. Miller
parent c11da83bda
commit 94fcf6964c

View File

@ -777,7 +777,8 @@ isdn_readbchan(int di, int channel, u_char *buf, u_char *fp, int len, wait_queue
return 0; return 0;
if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) { if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) {
if (sleep) if (sleep)
interruptible_sleep_on(sleep); wait_event_interruptible(*sleep,
!skb_queue_empty(&dev->drv[di]->rpqueue[channel]));
else else
return 0; return 0;
} }
@ -1072,7 +1073,8 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t *off)
retval = -EAGAIN; retval = -EAGAIN;
goto out; goto out;
} }
interruptible_sleep_on(&(dev->info_waitq)); wait_event_interruptible(dev->info_waitq,
file->private_data);
} }
p = isdn_statstr(); p = isdn_statstr();
file->private_data = NULL; file->private_data = NULL;
@ -1128,7 +1130,8 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t *off)
retval = -EAGAIN; retval = -EAGAIN;
goto out; goto out;
} }
interruptible_sleep_on(&(dev->drv[drvidx]->st_waitq)); wait_event_interruptible(dev->drv[drvidx]->st_waitq,
dev->drv[drvidx]->stavail);
} }
if (dev->drv[drvidx]->interface->readstat) { if (dev->drv[drvidx]->interface->readstat) {
if (count > dev->drv[drvidx]->stavail) if (count > dev->drv[drvidx]->stavail)
@ -1188,8 +1191,8 @@ isdn_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
goto out; goto out;
} }
chidx = isdn_minor2chan(minor); chidx = isdn_minor2chan(minor);
while ((retval = isdn_writebuf_stub(drvidx, chidx, buf, count)) == 0) wait_event_interruptible(dev->drv[drvidx]->snd_waitq[chidx],
interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]); (retval = isdn_writebuf_stub(drvidx, chidx, buf, count)));
goto out; goto out;
} }
if (minor <= ISDN_MINOR_CTRLMAX) { if (minor <= ISDN_MINOR_CTRLMAX) {