Author: delphij Date: Wed May 8 17:45:22 2013 New Revision: 250374 URL: http://svnweb.freebsd.org/changeset/base/250374
Log: According to the documentation, on Linux, cancel_delayed_work() does not do drain (flush_workqueue() in Linux terms) but instead returns true if the work was removed before it is run, or false otherwise. Simulate this by removing the taskqueue_drain() and return the value derived from taskqueue_cancel()'s return value. This would solve a witness warning caused by calling taskqueue_drain() with a non-sleepable lock held, like: taskqueue_drain with the following non-sleepable locks held: exclusive rw lle (lle) r = 0 (0xfffffe001450b410) locked @ /usr/src/sys/netinet/in.c:1484 KDB: stack backtrace: db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xffffff848d4f7690 kdb_backtrace() at kdb_backtrace+0x39/frame 0xffffff848d4f7740 witness_warn() at witness_warn+0x4a8/frame 0xffffff848d4f7800 taskqueue_drain() at taskqueue_drain+0x3a/frame 0xffffff848d4f7840 set_timeout() at set_timeout+0x4a/frame 0xffffff848d4f7860 netevent_callback() at netevent_callback+0x16/frame 0xffffff848d4f7870 arpintr() at arpintr+0x9b5/frame 0xffffff848d4f7930 This do not affect kernel without OFED compiled in. Reported by: Garrett Cooper <yaneurabeya gmail com> (who also tested an earlier version of this patch, but bugs are mine) MFC after: 2 weeks Modified: head/sys/ofed/include/linux/workqueue.h Modified: head/sys/ofed/include/linux/workqueue.h ============================================================================== --- head/sys/ofed/include/linux/workqueue.h Wed May 8 16:43:52 2013 (r250373) +++ head/sys/ofed/include/linux/workqueue.h Wed May 8 17:45:22 2013 (r250374) @@ -184,9 +184,9 @@ cancel_delayed_work(struct delayed_work { callout_stop(&work->timer); - if (work->work.taskqueue && - taskqueue_cancel(work->work.taskqueue, &work->work.work_task, NULL)) - taskqueue_drain(work->work.taskqueue, &work->work.work_task); + if (work->work.taskqueue) + return (taskqueue_cancel(work->work.taskqueue, + &work->work.work_task, NULL) == 0); return 0; } _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"