Skip to content

Commit

Permalink
isdn: fix multiple sleep_on races
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Arnd Bergmann authored and David S. Miller committed Feb 26, 2014
1 parent c11da83 commit 94fcf69
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions drivers/isdn/i4l/isdn_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,8 @@ isdn_readbchan(int di, int channel, u_char *buf, u_char *fp, int len, wait_queue
return 0;
if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) {
if (sleep)
interruptible_sleep_on(sleep);
wait_event_interruptible(*sleep,
!skb_queue_empty(&dev->drv[di]->rpqueue[channel]));
else
return 0;
}
Expand Down Expand Up @@ -1072,7 +1073,8 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t *off)
retval = -EAGAIN;
goto out;
}
interruptible_sleep_on(&(dev->info_waitq));
wait_event_interruptible(dev->info_waitq,
file->private_data);
}
p = isdn_statstr();
file->private_data = NULL;
Expand Down Expand Up @@ -1128,7 +1130,8 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t *off)
retval = -EAGAIN;
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 (count > dev->drv[drvidx]->stavail)
Expand Down Expand Up @@ -1188,8 +1191,8 @@ isdn_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
goto out;
}
chidx = isdn_minor2chan(minor);
while ((retval = isdn_writebuf_stub(drvidx, chidx, buf, count)) == 0)
interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]);
wait_event_interruptible(dev->drv[drvidx]->snd_waitq[chidx],
(retval = isdn_writebuf_stub(drvidx, chidx, buf, count)));
goto out;
}
if (minor <= ISDN_MINOR_CTRLMAX) {
Expand Down

0 comments on commit 94fcf69

Please sign in to comment.