Commit 94fcf696 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by David S. Miller

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: default avatarArnd Bergmann <arnd@arndb.de>
Cc: Karsten Keil <isdn@linux-pingi.de>
Cc: netdev@vger.kernel.org
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c11da83b
...@@ -777,7 +777,8 @@ isdn_readbchan(int di, int channel, u_char *buf, u_char *fp, int len, wait_queue ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment