aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2013-03-08 22:16:32 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-23 08:58:49 -0400
commitbdecbe43e345d1e5a0fa82625d7beb7c3371763e (patch)
tree1873a84591bd4e2ed928495625155f0fa4955d06
parent028c70ff42783509d3a7c7fa0faf900446a2657a (diff)
[media] dvb_usb_v2: replace Kernel userspace lock with wait queue
There was sync mutex which was held over userspace. That is very wrong and could cause deadlock if different userspace process is used to "unlock". Wait queue seems to be correct solution for that kind of synchronizing issue so use it instead. lock debug gives following bug report: ================================================ [ BUG: lock held when returning to user space! ] 3.9.0-rc1+ #38 Tainted: G O ------------------------------------------------ tzap/4614 is leaving the kernel with locks still held! 1 lock held by tzap/4614: Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb.h5
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_core.c53
2 files changed, 41 insertions, 17 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
index 42801f8ecaa8..658c6d47fdff 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
@@ -329,13 +329,16 @@ struct dvb_usb_adapter {
329 u8 feed_count; 329 u8 feed_count;
330 u8 max_feed_count; 330 u8 max_feed_count;
331 s8 active_fe; 331 s8 active_fe;
332#define ADAP_INIT 0
333#define ADAP_SLEEP 1
334#define ADAP_STREAMING 2
335 unsigned long state_bits;
332 336
333 /* dvb */ 337 /* dvb */
334 struct dvb_adapter dvb_adap; 338 struct dvb_adapter dvb_adap;
335 struct dmxdev dmxdev; 339 struct dmxdev dmxdev;
336 struct dvb_demux demux; 340 struct dvb_demux demux;
337 struct dvb_net dvb_net; 341 struct dvb_net dvb_net;
338 struct mutex sync_mutex;
339 342
340 struct dvb_frontend *fe[MAX_NO_OF_FE_PER_ADAP]; 343 struct dvb_frontend *fe[MAX_NO_OF_FE_PER_ADAP];
341 int (*fe_init[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *); 344 int (*fe_init[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
index 086792055912..c91da3c4d332 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
@@ -253,6 +253,13 @@ static int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
253 return usb_urb_exitv2(&adap->stream); 253 return usb_urb_exitv2(&adap->stream);
254} 254}
255 255
256static int wait_schedule(void *ptr)
257{
258 schedule();
259
260 return 0;
261}
262
256static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, 263static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
257 int count) 264 int count)
258{ 265{
@@ -266,6 +273,9 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
266 dvbdmxfeed->pid, dvbdmxfeed->index, 273 dvbdmxfeed->pid, dvbdmxfeed->index,
267 (count == 1) ? "on" : "off"); 274 (count == 1) ? "on" : "off");
268 275
276 wait_on_bit(&adap->state_bits, ADAP_INIT, wait_schedule,
277 TASK_UNINTERRUPTIBLE);
278
269 if (adap->active_fe == -1) 279 if (adap->active_fe == -1)
270 return -EINVAL; 280 return -EINVAL;
271 281
@@ -283,11 +293,14 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
283 "failed=%d\n", KBUILD_MODNAME, 293 "failed=%d\n", KBUILD_MODNAME,
284 ret); 294 ret);
285 usb_urb_killv2(&adap->stream); 295 usb_urb_killv2(&adap->stream);
286 goto err_mutex_unlock; 296 goto err_clear_wait;
287 } 297 }
288 } 298 }
289 usb_urb_killv2(&adap->stream); 299 usb_urb_killv2(&adap->stream);
290 mutex_unlock(&adap->sync_mutex); 300
301 clear_bit(ADAP_STREAMING, &adap->state_bits);
302 smp_mb__after_clear_bit();
303 wake_up_bit(&adap->state_bits, ADAP_STREAMING);
291 } 304 }
292 305
293 /* activate the pid on the device pid filter */ 306 /* activate the pid on the device pid filter */
@@ -303,7 +316,7 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
303 /* start feeding if it is first pid */ 316 /* start feeding if it is first pid */
304 if (adap->feed_count == 1 && count == 1) { 317 if (adap->feed_count == 1 && count == 1) {
305 struct usb_data_stream_properties stream_props; 318 struct usb_data_stream_properties stream_props;
306 mutex_lock(&adap->sync_mutex); 319 set_bit(ADAP_STREAMING, &adap->state_bits);
307 dev_dbg(&d->udev->dev, "%s: start feeding\n", __func__); 320 dev_dbg(&d->udev->dev, "%s: start feeding\n", __func__);
308 321
309 /* resolve input and output streaming paramters */ 322 /* resolve input and output streaming paramters */
@@ -314,7 +327,7 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
314 adap->fe[adap->active_fe], 327 adap->fe[adap->active_fe],
315 &adap->ts_type, &stream_props); 328 &adap->ts_type, &stream_props);
316 if (ret < 0) 329 if (ret < 0)
317 goto err_mutex_unlock; 330 goto err_clear_wait;
318 } else { 331 } else {
319 stream_props = adap->props->stream; 332 stream_props = adap->props->stream;
320 } 333 }
@@ -344,7 +357,7 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
344 dev_err(&d->udev->dev, "%s: " \ 357 dev_err(&d->udev->dev, "%s: " \
345 "pid_filter_ctrl() failed=%d\n", 358 "pid_filter_ctrl() failed=%d\n",
346 KBUILD_MODNAME, ret); 359 KBUILD_MODNAME, ret);
347 goto err_mutex_unlock; 360 goto err_clear_wait;
348 } 361 }
349 } 362 }
350 363
@@ -355,14 +368,16 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
355 dev_err(&d->udev->dev, "%s: streaming_ctrl() " \ 368 dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
356 "failed=%d\n", KBUILD_MODNAME, 369 "failed=%d\n", KBUILD_MODNAME,
357 ret); 370 ret);
358 goto err_mutex_unlock; 371 goto err_clear_wait;
359 } 372 }
360 } 373 }
361 } 374 }
362 375
363 return 0; 376 return 0;
364err_mutex_unlock: 377err_clear_wait:
365 mutex_unlock(&adap->sync_mutex); 378 clear_bit(ADAP_STREAMING, &adap->state_bits);
379 smp_mb__after_clear_bit();
380 wake_up_bit(&adap->state_bits, ADAP_STREAMING);
366 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); 381 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
367 return ret; 382 return ret;
368} 383}
@@ -435,8 +450,6 @@ static int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
435 goto err_dvb_net_init; 450 goto err_dvb_net_init;
436 } 451 }
437 452
438 mutex_init(&adap->sync_mutex);
439
440 return 0; 453 return 0;
441err_dvb_net_init: 454err_dvb_net_init:
442 dvb_dmxdev_release(&adap->dmxdev); 455 dvb_dmxdev_release(&adap->dmxdev);
@@ -500,7 +513,7 @@ static int dvb_usb_fe_init(struct dvb_frontend *fe)
500 513
501 if (!adap->suspend_resume_active) { 514 if (!adap->suspend_resume_active) {
502 adap->active_fe = fe->id; 515 adap->active_fe = fe->id;
503 mutex_lock(&adap->sync_mutex); 516 set_bit(ADAP_INIT, &adap->state_bits);
504 } 517 }
505 518
506 ret = dvb_usbv2_device_power_ctrl(d, 1); 519 ret = dvb_usbv2_device_power_ctrl(d, 1);
@@ -519,8 +532,11 @@ static int dvb_usb_fe_init(struct dvb_frontend *fe)
519 goto err; 532 goto err;
520 } 533 }
521err: 534err:
522 if (!adap->suspend_resume_active) 535 if (!adap->suspend_resume_active) {
523 mutex_unlock(&adap->sync_mutex); 536 clear_bit(ADAP_INIT, &adap->state_bits);
537 smp_mb__after_clear_bit();
538 wake_up_bit(&adap->state_bits, ADAP_INIT);
539 }
524 540
525 dev_dbg(&d->udev->dev, "%s: ret=%d\n", __func__, ret); 541 dev_dbg(&d->udev->dev, "%s: ret=%d\n", __func__, ret);
526 return ret; 542 return ret;
@@ -534,8 +550,11 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
534 dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id, 550 dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
535 fe->id); 551 fe->id);
536 552
537 if (!adap->suspend_resume_active) 553 if (!adap->suspend_resume_active) {
538 mutex_lock(&adap->sync_mutex); 554 set_bit(ADAP_SLEEP, &adap->state_bits);
555 wait_on_bit(&adap->state_bits, ADAP_STREAMING, wait_schedule,
556 TASK_UNINTERRUPTIBLE);
557 }
539 558
540 if (adap->fe_sleep[fe->id]) { 559 if (adap->fe_sleep[fe->id]) {
541 ret = adap->fe_sleep[fe->id](fe); 560 ret = adap->fe_sleep[fe->id](fe);
@@ -555,7 +574,9 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
555err: 574err:
556 if (!adap->suspend_resume_active) { 575 if (!adap->suspend_resume_active) {
557 adap->active_fe = -1; 576 adap->active_fe = -1;
558 mutex_unlock(&adap->sync_mutex); 577 clear_bit(ADAP_SLEEP, &adap->state_bits);
578 smp_mb__after_clear_bit();
579 wake_up_bit(&adap->state_bits, ADAP_SLEEP);
559 } 580 }
560 581
561 dev_dbg(&d->udev->dev, "%s: ret=%d\n", __func__, ret); 582 dev_dbg(&d->udev->dev, "%s: ret=%d\n", __func__, ret);