Skip to content

Commit

Permalink
[media] smsusb: don't sleep while atomic
Browse files Browse the repository at this point in the history
smscore_getbuffer() calls internally wait_event(), with can sleep.
As smsusb_onresponse() is called on interrupt context, this causes
the following warning:

	BUG: sleeping function called from invalid context at drivers/media/common/siano/smscoreapi.c:1653
	in_atomic(): 1, irqs_disabled(): 1, pid: 11084, name: systemd-udevd
	INFO: lockdep is turned off.
	irq event stamp: 0
	hardirqs last  enabled at (0): [<          (null)>]           (null)
	hardirqs last disabled at (0): [<ffffffff811480f7>] copy_process.part.7+0x10e7/0x56d0
	softirqs last  enabled at (0): [<ffffffff81148193>] copy_process.part.7+0x1183/0x56d0
	softirqs last disabled at (0): [<          (null)>]           (null)
	CPU: 2 PID: 11084 Comm: systemd-udevd Tainted: G    B   W       4.5.0-rc3+ #47
	Hardware name:                  /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722 08/12/2015
	 0000000000000000 ffff8803c6907a80 ffffffff81933901 ffff8802bd916000
	 ffff8802bd9165c8 ffff8803c6907aa8 ffffffff811c6af5 ffff8802bd916000
	 ffffffffa0ce9b60 0000000000000675 ffff8803c6907ae8 ffffffff811c6ce5
	Call Trace:
	 <IRQ>  [<ffffffff81933901>] dump_stack+0x85/0xc4
	 [<ffffffff811c6af5>] ___might_sleep+0x245/0x3a0
	 [<ffffffff811c6ce5>] __might_sleep+0x95/0x1a0
	 [<ffffffffa0ce020a>] ? list_add_locked+0xca/0x140 [smsmdtv]
	 [<ffffffffa0ce3b8d>] smscore_getbuffer+0x7d/0x120 [smsmdtv]
	 [<ffffffff8123819d>] ? trace_hardirqs_off+0xd/0x10
	 [<ffffffffa0ce3b10>] ? smscore_sendrequest_and_wait.isra.5+0x120/0x120 [smsmdtv]
	 [<ffffffffa0ce020a>] ? list_add_locked+0xca/0x140 [smsmdtv]
	 [<ffffffffa0ce13ca>] ? smscore_putbuffer+0x3a/0x40 [smsmdtv]
	 [<ffffffffa0d107bc>] smsusb_submit_urb+0x2ec/0x4f0 [smsusb]
	 [<ffffffffa0d10e36>] smsusb_onresponse+0x476/0x720 [smsusb]

Let's add a work queue to handle the bottom half, preventing this
problem.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  • Loading branch information
mchehab committed Feb 16, 2016
1 parent 21cf734 commit dd47fbd
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion drivers/media/usb/siano/smsusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ struct smsusb_urb_t {
struct smsusb_device_t *dev;

struct urb urb;

/* For the bottom half */
struct work_struct wq;
};

struct smsusb_device_t {
Expand All @@ -70,6 +73,18 @@ struct smsusb_device_t {
static int smsusb_submit_urb(struct smsusb_device_t *dev,
struct smsusb_urb_t *surb);

/**
* Completing URB's callback handler - bottom half (proccess context)
* submits the URB prepared on smsusb_onresponse()
*/
static void do_submit_urb(struct work_struct *work)
{
struct smsusb_urb_t *surb = container_of(work, struct smsusb_urb_t, wq);
struct smsusb_device_t *dev = surb->dev;

smsusb_submit_urb(dev, surb);
}

/**
* Completing URB's callback handler - top half (interrupt context)
* adds completing sms urb to the global surbs list and activtes the worker
Expand Down Expand Up @@ -138,13 +153,15 @@ static void smsusb_onresponse(struct urb *urb)


exit_and_resubmit:
smsusb_submit_urb(dev, surb);
INIT_WORK(&surb->wq, do_submit_urb);
schedule_work(&surb->wq);
}

static int smsusb_submit_urb(struct smsusb_device_t *dev,
struct smsusb_urb_t *surb)
{
if (!surb->cb) {
/* This function can sleep */
surb->cb = smscore_getbuffer(dev->coredev);
if (!surb->cb) {
pr_err("smscore_getbuffer(...) returned NULL\n");
Expand Down

0 comments on commit dd47fbd

Please sign in to comment.