Message ID | 20160805174131.22043-1-roman.penyaev@profitbricks.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi Roman, [auto build test ERROR on block/for-next] [also build test ERROR on v4.7 next-20160805] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Roman-Pen/blk-mq-fix-hang-caused-by-freeze-unfreeze-sequence/20160806-014441 base: https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-next config: x86_64-randconfig-x015-201631 (attached as .config) compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All error/warnings (new ones prefixed by >>): In file included from include/linux/mmzone.h:9:0, from include/linux/gfp.h:5, from include/linux/kmod.h:22, from include/linux/module.h:13, from block/blk-core.c:15: block/blk-core.c: In function 'blk_queue_enter': >> block/blk-core.c:661:18: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types] !atomic_read(&q->mq_freeze_depth) || ^ include/linux/wait.h:473:8: note: in definition of macro 'wait_event_interruptible' if (!(condition)) \ ^~~~~~~~~ In file included from arch/x86/include/asm/msr.h:66:0, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:54, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/stat.h:18, from include/linux/module.h:10, from block/blk-core.c:15: arch/x86/include/asm/atomic.h:24:28: note: expected 'const atomic_t * {aka const struct <anonymous> *}' but argument is of type 'int *' static __always_inline int atomic_read(const atomic_t *v) ^~~~~~~~~~~ In file included from include/linux/mmzone.h:9:0, from include/linux/gfp.h:5, from include/linux/kmod.h:22, from include/linux/module.h:13, from block/blk-core.c:15: >> block/blk-core.c:661:18: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types] !atomic_read(&q->mq_freeze_depth) || ^ include/linux/wait.h:278:7: note: in definition of macro '___wait_event' if (condition) \ ^~~~~~~~~ include/linux/wait.h:474:11: note: in expansion of macro '__wait_event_interruptible' __ret = __wait_event_interruptible(wq, condition); \ ^~~~~~~~~~~~~~~~~~~~~~~~~~ >> block/blk-core.c:660:9: note: in expansion of macro 'wait_event_interruptible' ret = wait_event_interruptible(q->mq_freeze_wq, ^~~~~~~~~~~~~~~~~~~~~~~~ In file included from arch/x86/include/asm/msr.h:66:0, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:54, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/stat.h:18, from include/linux/module.h:10, from block/blk-core.c:15: arch/x86/include/asm/atomic.h:24:28: note: expected 'const atomic_t * {aka const struct <anonymous> *}' but argument is of type 'int *' static __always_inline int atomic_read(const atomic_t *v) ^~~~~~~~~~~ cc1: some warnings being treated as errors vim +/atomic_read +661 block/blk-core.c 3ef28e83 Dan Williams 2015-10-21 654 if (percpu_ref_tryget_live(&q->q_usage_counter)) 3ef28e83 Dan Williams 2015-10-21 655 return 0; 3ef28e83 Dan Williams 2015-10-21 656 6f3b0e8b Christoph Hellwig 2015-11-26 657 if (nowait) 3ef28e83 Dan Williams 2015-10-21 658 return -EBUSY; 3ef28e83 Dan Williams 2015-10-21 659 3ef28e83 Dan Williams 2015-10-21 @660 ret = wait_event_interruptible(q->mq_freeze_wq, 3ef28e83 Dan Williams 2015-10-21 @661 !atomic_read(&q->mq_freeze_depth) || 3ef28e83 Dan Williams 2015-10-21 662 blk_queue_dying(q)); 3ef28e83 Dan Williams 2015-10-21 663 if (blk_queue_dying(q)) 3ef28e83 Dan Williams 2015-10-21 664 return -ENODEV; :::::: The code at line 661 was first introduced by commit :::::: 3ef28e83ab15799742e55fd13243a5f678b04242 block: generic request_queue reference counting :::::: TO: Dan Williams <dan.j.williams@intel.com> :::::: CC: Jens Axboe <axboe@fb.com> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Roman, [auto build test WARNING on block/for-next] [also build test WARNING on v4.7 next-20160805] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Roman-Pen/blk-mq-fix-hang-caused-by-freeze-unfreeze-sequence/20160806-014441 base: https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-next config: x86_64-randconfig-x012-201631 (attached as .config) compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): In file included from include/linux/linkage.h:4:0, from include/linux/kernel.h:6, from block/blk-core.c:14: block/blk-core.c: In function 'blk_queue_enter': block/blk-core.c:661:18: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types] !atomic_read(&q->mq_freeze_depth) || ^ include/linux/compiler.h:151:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> include/linux/wait.h:473:2: note: in expansion of macro 'if' if (!(condition)) \ ^~ block/blk-core.c:660:9: note: in expansion of macro 'wait_event_interruptible' ret = wait_event_interruptible(q->mq_freeze_wq, ^~~~~~~~~~~~~~~~~~~~~~~~ In file included from arch/x86/include/asm/msr.h:66:0, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:54, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/stat.h:18, from include/linux/module.h:10, from block/blk-core.c:15: arch/x86/include/asm/atomic.h:24:28: note: expected 'const atomic_t * {aka const struct <anonymous> *}' but argument is of type 'int *' static __always_inline int atomic_read(const atomic_t *v) ^~~~~~~~~~~ In file included from include/linux/linkage.h:4:0, from include/linux/kernel.h:6, from block/blk-core.c:14: block/blk-core.c:661:18: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types] !atomic_read(&q->mq_freeze_depth) || ^ include/linux/compiler.h:151:42: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> include/linux/wait.h:473:2: note: in expansion of macro 'if' if (!(condition)) \ ^~ block/blk-core.c:660:9: note: in expansion of macro 'wait_event_interruptible' ret = wait_event_interruptible(q->mq_freeze_wq, ^~~~~~~~~~~~~~~~~~~~~~~~ In file included from arch/x86/include/asm/msr.h:66:0, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:54, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/stat.h:18, from include/linux/module.h:10, from block/blk-core.c:15: arch/x86/include/asm/atomic.h:24:28: note: expected 'const atomic_t * {aka const struct <anonymous> *}' but argument is of type 'int *' static __always_inline int atomic_read(const atomic_t *v) ^~~~~~~~~~~ In file included from include/linux/linkage.h:4:0, from include/linux/kernel.h:6, from block/blk-core.c:14: block/blk-core.c:661:18: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types] !atomic_read(&q->mq_freeze_depth) || ^ include/linux/compiler.h:162:16: note: in definition of macro '__trace_if' ______r = !!(cond); \ ^~~~ >> include/linux/wait.h:473:2: note: in expansion of macro 'if' if (!(condition)) \ ^~ block/blk-core.c:660:9: note: in expansion of macro 'wait_event_interruptible' ret = wait_event_interruptible(q->mq_freeze_wq, ^~~~~~~~~~~~~~~~~~~~~~~~ In file included from arch/x86/include/asm/msr.h:66:0, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:54, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/stat.h:18, from include/linux/module.h:10, from block/blk-core.c:15: arch/x86/include/asm/atomic.h:24:28: note: expected 'const atomic_t * {aka const struct <anonymous> *}' but argument is of type 'int *' static __always_inline int atomic_read(const atomic_t *v) ^~~~~~~~~~~ In file included from include/linux/linkage.h:4:0, from include/linux/kernel.h:6, from block/blk-core.c:14: block/blk-core.c:661:18: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types] !atomic_read(&q->mq_freeze_depth) || ^ include/linux/compiler.h:151:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ include/linux/wait.h:278:3: note: in expansion of macro 'if' if (condition) \ ^~ >> include/linux/wait.h:451:2: note: in expansion of macro '___wait_event' ___wait_event(wq, condition, TASK_INTERRUPTIBLE, 0, 0, \ ^~~~~~~~~~~~~ include/linux/wait.h:474:11: note: in expansion of macro '__wait_event_interruptible' __ret = __wait_event_interruptible(wq, condition); \ ^~~~~~~~~~~~~~~~~~~~~~~~~~ block/blk-core.c:660:9: note: in expansion of macro 'wait_event_interruptible' ret = wait_event_interruptible(q->mq_freeze_wq, ^~~~~~~~~~~~~~~~~~~~~~~~ In file included from arch/x86/include/asm/msr.h:66:0, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:54, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/stat.h:18, from include/linux/module.h:10, from block/blk-core.c:15: arch/x86/include/asm/atomic.h:24:28: note: expected 'const atomic_t * {aka const struct <anonymous> *}' but argument is of type 'int *' static __always_inline int atomic_read(const atomic_t *v) ^~~~~~~~~~~ In file included from include/linux/linkage.h:4:0, from include/linux/kernel.h:6, from block/blk-core.c:14: block/blk-core.c:661:18: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types] !atomic_read(&q->mq_freeze_depth) || ^ include/linux/compiler.h:151:42: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ include/linux/wait.h:278:3: note: in expansion of macro 'if' if (condition) \ ^~ >> include/linux/wait.h:451:2: note: in expansion of macro '___wait_event' ___wait_event(wq, condition, TASK_INTERRUPTIBLE, 0, 0, \ ^~~~~~~~~~~~~ include/linux/wait.h:474:11: note: in expansion of macro '__wait_event_interruptible' __ret = __wait_event_interruptible(wq, condition); \ ^~~~~~~~~~~~~~~~~~~~~~~~~~ block/blk-core.c:660:9: note: in expansion of macro 'wait_event_interruptible' ret = wait_event_interruptible(q->mq_freeze_wq, ^~~~~~~~~~~~~~~~~~~~~~~~ In file included from arch/x86/include/asm/msr.h:66:0, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:54, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/stat.h:18, from include/linux/module.h:10, from block/blk-core.c:15: arch/x86/include/asm/atomic.h:24:28: note: expected 'const atomic_t * {aka const struct <anonymous> *}' but argument is of type 'int *' static __always_inline int atomic_read(const atomic_t *v) ^~~~~~~~~~~ In file included from include/linux/linkage.h:4:0, from include/linux/kernel.h:6, from block/blk-core.c:14: block/blk-core.c:661:18: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types] !atomic_read(&q->mq_freeze_depth) || ^ include/linux/compiler.h:162:16: note: in definition of macro '__trace_if' ______r = !!(cond); \ ^~~~ include/linux/wait.h:278:3: note: in expansion of macro 'if' if (condition) \ ^~ >> include/linux/wait.h:451:2: note: in expansion of macro '___wait_event' ___wait_event(wq, condition, TASK_INTERRUPTIBLE, 0, 0, \ ^~~~~~~~~~~~~ include/linux/wait.h:474:11: note: in expansion of macro '__wait_event_interruptible' __ret = __wait_event_interruptible(wq, condition); \ ^~~~~~~~~~~~~~~~~~~~~~~~~~ block/blk-core.c:660:9: note: in expansion of macro 'wait_event_interruptible' ret = wait_event_interruptible(q->mq_freeze_wq, ^~~~~~~~~~~~~~~~~~~~~~~~ In file included from arch/x86/include/asm/msr.h:66:0, from arch/x86/include/asm/processor.h:20, from arch/x86/include/asm/cpufeature.h:4, from arch/x86/include/asm/thread_info.h:52, from include/linux/thread_info.h:54, from arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/seqlock.h:35, from include/linux/time.h:5, from include/linux/stat.h:18, from include/linux/module.h:10, from block/blk-core.c:15: arch/x86/include/asm/atomic.h:24:28: note: expected 'const atomic_t * {aka const struct <anonymous> *}' but argument is of type 'int *' static __always_inline int atomic_read(const atomic_t *v) ^~~~~~~~~~~ cc1: some warnings being treated as errors vim +/if +473 include/linux/wait.h 41a1431b1 Peter Zijlstra 2013-10-02 272 else \ c2d816443 Oleg Nesterov 2013-10-07 273 __wait.flags = 0; \ c2d816443 Oleg Nesterov 2013-10-07 274 \ c2d816443 Oleg Nesterov 2013-10-07 275 for (;;) { \ c2d816443 Oleg Nesterov 2013-10-07 276 long __int = prepare_to_wait_event(&wq, &__wait, state);\ 41a1431b1 Peter Zijlstra 2013-10-02 277 \ 41a1431b1 Peter Zijlstra 2013-10-02 @278 if (condition) \ 41a1431b1 Peter Zijlstra 2013-10-02 279 break; \ 41a1431b1 Peter Zijlstra 2013-10-02 280 \ c2d816443 Oleg Nesterov 2013-10-07 281 if (___wait_is_interruptible(state) && __int) { \ c2d816443 Oleg Nesterov 2013-10-07 282 __ret = __int; \ 41a1431b1 Peter Zijlstra 2013-10-02 283 if (exclusive) { \ 41a1431b1 Peter Zijlstra 2013-10-02 284 abort_exclusive_wait(&wq, &__wait, \ 41a1431b1 Peter Zijlstra 2013-10-02 285 state, NULL); \ 41a1431b1 Peter Zijlstra 2013-10-02 286 goto __out; \ 41a1431b1 Peter Zijlstra 2013-10-02 287 } \ 41a1431b1 Peter Zijlstra 2013-10-02 288 break; \ 41a1431b1 Peter Zijlstra 2013-10-02 289 } \ 41a1431b1 Peter Zijlstra 2013-10-02 290 \ 41a1431b1 Peter Zijlstra 2013-10-02 291 cmd; \ 41a1431b1 Peter Zijlstra 2013-10-02 292 } \ 41a1431b1 Peter Zijlstra 2013-10-02 293 finish_wait(&wq, &__wait); \ 35a2af94c Peter Zijlstra 2013-10-02 294 __out: __ret; \ 35a2af94c Peter Zijlstra 2013-10-02 295 }) 41a1431b1 Peter Zijlstra 2013-10-02 296 ^1da177e4 Linus Torvalds 2005-04-16 297 #define __wait_event(wq, condition) \ 35a2af94c Peter Zijlstra 2013-10-02 298 (void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, 0, \ 35a2af94c Peter Zijlstra 2013-10-02 299 schedule()) ^1da177e4 Linus Torvalds 2005-04-16 300 ^1da177e4 Linus Torvalds 2005-04-16 301 /** ^1da177e4 Linus Torvalds 2005-04-16 302 * wait_event - sleep until a condition gets true ^1da177e4 Linus Torvalds 2005-04-16 303 * @wq: the waitqueue to wait on ^1da177e4 Linus Torvalds 2005-04-16 304 * @condition: a C expression for the event to wait for ^1da177e4 Linus Torvalds 2005-04-16 305 * ^1da177e4 Linus Torvalds 2005-04-16 306 * The process is put to sleep (TASK_UNINTERRUPTIBLE) until the ^1da177e4 Linus Torvalds 2005-04-16 307 * @condition evaluates to true. The @condition is checked each time ^1da177e4 Linus Torvalds 2005-04-16 308 * the waitqueue @wq is woken up. ^1da177e4 Linus Torvalds 2005-04-16 309 * ^1da177e4 Linus Torvalds 2005-04-16 310 * wake_up() has to be called after changing any variable that could ^1da177e4 Linus Torvalds 2005-04-16 311 * change the result of the wait condition. ^1da177e4 Linus Torvalds 2005-04-16 312 */ ^1da177e4 Linus Torvalds 2005-04-16 313 #define wait_event(wq, condition) \ ^1da177e4 Linus Torvalds 2005-04-16 314 do { \ e22b886a8 Peter Zijlstra 2014-09-24 315 might_sleep(); \ ^1da177e4 Linus Torvalds 2005-04-16 316 if (condition) \ ^1da177e4 Linus Torvalds 2005-04-16 317 break; \ ^1da177e4 Linus Torvalds 2005-04-16 318 __wait_event(wq, condition); \ ^1da177e4 Linus Torvalds 2005-04-16 319 } while (0) ^1da177e4 Linus Torvalds 2005-04-16 320 2c5612465 Peter Zijlstra 2015-02-03 321 #define __io_wait_event(wq, condition) \ 2c5612465 Peter Zijlstra 2015-02-03 322 (void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, 0, \ 2c5612465 Peter Zijlstra 2015-02-03 323 io_schedule()) 2c5612465 Peter Zijlstra 2015-02-03 324 2c5612465 Peter Zijlstra 2015-02-03 325 /* 2c5612465 Peter Zijlstra 2015-02-03 326 * io_wait_event() -- like wait_event() but with io_schedule() 2c5612465 Peter Zijlstra 2015-02-03 327 */ 2c5612465 Peter Zijlstra 2015-02-03 328 #define io_wait_event(wq, condition) \ 2c5612465 Peter Zijlstra 2015-02-03 329 do { \ 2c5612465 Peter Zijlstra 2015-02-03 330 might_sleep(); \ 2c5612465 Peter Zijlstra 2015-02-03 331 if (condition) \ 2c5612465 Peter Zijlstra 2015-02-03 332 break; \ 2c5612465 Peter Zijlstra 2015-02-03 333 __io_wait_event(wq, condition); \ 2c5612465 Peter Zijlstra 2015-02-03 334 } while (0) 2c5612465 Peter Zijlstra 2015-02-03 335 36df04bc5 Peter Zijlstra 2014-10-29 336 #define __wait_event_freezable(wq, condition) \ 36df04bc5 Peter Zijlstra 2014-10-29 337 ___wait_event(wq, condition, TASK_INTERRUPTIBLE, 0, 0, \ 36df04bc5 Peter Zijlstra 2014-10-29 338 schedule(); try_to_freeze()) 36df04bc5 Peter Zijlstra 2014-10-29 339 36df04bc5 Peter Zijlstra 2014-10-29 340 /** f4bcfa1da Stafford Horne 2016-02-23 341 * wait_event_freezable - sleep (or freeze) until a condition gets true 36df04bc5 Peter Zijlstra 2014-10-29 342 * @wq: the waitqueue to wait on 36df04bc5 Peter Zijlstra 2014-10-29 343 * @condition: a C expression for the event to wait for 36df04bc5 Peter Zijlstra 2014-10-29 344 * 36df04bc5 Peter Zijlstra 2014-10-29 345 * The process is put to sleep (TASK_INTERRUPTIBLE -- so as not to contribute 36df04bc5 Peter Zijlstra 2014-10-29 346 * to system load) until the @condition evaluates to true. The 36df04bc5 Peter Zijlstra 2014-10-29 347 * @condition is checked each time the waitqueue @wq is woken up. 36df04bc5 Peter Zijlstra 2014-10-29 348 * 36df04bc5 Peter Zijlstra 2014-10-29 349 * wake_up() has to be called after changing any variable that could 36df04bc5 Peter Zijlstra 2014-10-29 350 * change the result of the wait condition. 36df04bc5 Peter Zijlstra 2014-10-29 351 */ 36df04bc5 Peter Zijlstra 2014-10-29 352 #define wait_event_freezable(wq, condition) \ 36df04bc5 Peter Zijlstra 2014-10-29 353 ({ \ 36df04bc5 Peter Zijlstra 2014-10-29 354 int __ret = 0; \ 36df04bc5 Peter Zijlstra 2014-10-29 355 might_sleep(); \ 36df04bc5 Peter Zijlstra 2014-10-29 356 if (!(condition)) \ 36df04bc5 Peter Zijlstra 2014-10-29 357 __ret = __wait_event_freezable(wq, condition); \ 36df04bc5 Peter Zijlstra 2014-10-29 358 __ret; \ 36df04bc5 Peter Zijlstra 2014-10-29 359 }) 36df04bc5 Peter Zijlstra 2014-10-29 360 35a2af94c Peter Zijlstra 2013-10-02 361 #define __wait_event_timeout(wq, condition, timeout) \ 35a2af94c Peter Zijlstra 2013-10-02 362 ___wait_event(wq, ___wait_cond_timeout(condition), \ 35a2af94c Peter Zijlstra 2013-10-02 363 TASK_UNINTERRUPTIBLE, 0, timeout, \ 35a2af94c Peter Zijlstra 2013-10-02 364 __ret = schedule_timeout(__ret)) ^1da177e4 Linus Torvalds 2005-04-16 365 ^1da177e4 Linus Torvalds 2005-04-16 366 /** ^1da177e4 Linus Torvalds 2005-04-16 367 * wait_event_timeout - sleep until a condition gets true or a timeout elapses ^1da177e4 Linus Torvalds 2005-04-16 368 * @wq: the waitqueue to wait on ^1da177e4 Linus Torvalds 2005-04-16 369 * @condition: a C expression for the event to wait for ^1da177e4 Linus Torvalds 2005-04-16 370 * @timeout: timeout, in jiffies ^1da177e4 Linus Torvalds 2005-04-16 371 * ^1da177e4 Linus Torvalds 2005-04-16 372 * The process is put to sleep (TASK_UNINTERRUPTIBLE) until the ^1da177e4 Linus Torvalds 2005-04-16 373 * @condition evaluates to true. The @condition is checked each time ^1da177e4 Linus Torvalds 2005-04-16 374 * the waitqueue @wq is woken up. ^1da177e4 Linus Torvalds 2005-04-16 375 * ^1da177e4 Linus Torvalds 2005-04-16 376 * wake_up() has to be called after changing any variable that could ^1da177e4 Linus Torvalds 2005-04-16 377 * change the result of the wait condition. ^1da177e4 Linus Torvalds 2005-04-16 378 * 6b44f5190 Scot Doyle 2014-08-24 379 * Returns: 6b44f5190 Scot Doyle 2014-08-24 380 * 0 if the @condition evaluated to %false after the @timeout elapsed, 6b44f5190 Scot Doyle 2014-08-24 381 * 1 if the @condition evaluated to %true after the @timeout elapsed, 6b44f5190 Scot Doyle 2014-08-24 382 * or the remaining jiffies (at least 1) if the @condition evaluated 6b44f5190 Scot Doyle 2014-08-24 383 * to %true before the @timeout elapsed. ^1da177e4 Linus Torvalds 2005-04-16 384 */ ^1da177e4 Linus Torvalds 2005-04-16 385 #define wait_event_timeout(wq, condition, timeout) \ ^1da177e4 Linus Torvalds 2005-04-16 386 ({ \ ^1da177e4 Linus Torvalds 2005-04-16 387 long __ret = timeout; \ e22b886a8 Peter Zijlstra 2014-09-24 388 might_sleep(); \ 8922915b3 Oleg Nesterov 2013-10-07 389 if (!___wait_cond_timeout(condition)) \ 35a2af94c Peter Zijlstra 2013-10-02 390 __ret = __wait_event_timeout(wq, condition, timeout); \ ^1da177e4 Linus Torvalds 2005-04-16 391 __ret; \ ^1da177e4 Linus Torvalds 2005-04-16 392 }) ^1da177e4 Linus Torvalds 2005-04-16 393 36df04bc5 Peter Zijlstra 2014-10-29 394 #define __wait_event_freezable_timeout(wq, condition, timeout) \ 36df04bc5 Peter Zijlstra 2014-10-29 395 ___wait_event(wq, ___wait_cond_timeout(condition), \ 36df04bc5 Peter Zijlstra 2014-10-29 396 TASK_INTERRUPTIBLE, 0, timeout, \ 36df04bc5 Peter Zijlstra 2014-10-29 397 __ret = schedule_timeout(__ret); try_to_freeze()) 36df04bc5 Peter Zijlstra 2014-10-29 398 36df04bc5 Peter Zijlstra 2014-10-29 399 /* 36df04bc5 Peter Zijlstra 2014-10-29 400 * like wait_event_timeout() -- except it uses TASK_INTERRUPTIBLE to avoid 36df04bc5 Peter Zijlstra 2014-10-29 401 * increasing load and is freezable. 36df04bc5 Peter Zijlstra 2014-10-29 402 */ 36df04bc5 Peter Zijlstra 2014-10-29 403 #define wait_event_freezable_timeout(wq, condition, timeout) \ 36df04bc5 Peter Zijlstra 2014-10-29 404 ({ \ 36df04bc5 Peter Zijlstra 2014-10-29 405 long __ret = timeout; \ 36df04bc5 Peter Zijlstra 2014-10-29 406 might_sleep(); \ 36df04bc5 Peter Zijlstra 2014-10-29 407 if (!___wait_cond_timeout(condition)) \ 36df04bc5 Peter Zijlstra 2014-10-29 408 __ret = __wait_event_freezable_timeout(wq, condition, timeout); \ 36df04bc5 Peter Zijlstra 2014-10-29 409 __ret; \ 36df04bc5 Peter Zijlstra 2014-10-29 410 }) 36df04bc5 Peter Zijlstra 2014-10-29 411 9f3520c31 Yuanhan Liu 2015-05-08 412 #define __wait_event_exclusive_cmd(wq, condition, cmd1, cmd2) \ 9f3520c31 Yuanhan Liu 2015-05-08 413 (void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 1, 0, \ 9f3520c31 Yuanhan Liu 2015-05-08 414 cmd1; schedule(); cmd2) 9f3520c31 Yuanhan Liu 2015-05-08 415 /* 9f3520c31 Yuanhan Liu 2015-05-08 416 * Just like wait_event_cmd(), except it sets exclusive flag 9f3520c31 Yuanhan Liu 2015-05-08 417 */ 9f3520c31 Yuanhan Liu 2015-05-08 418 #define wait_event_exclusive_cmd(wq, condition, cmd1, cmd2) \ 9f3520c31 Yuanhan Liu 2015-05-08 419 do { \ 9f3520c31 Yuanhan Liu 2015-05-08 420 if (condition) \ 9f3520c31 Yuanhan Liu 2015-05-08 421 break; \ 9f3520c31 Yuanhan Liu 2015-05-08 422 __wait_event_exclusive_cmd(wq, condition, cmd1, cmd2); \ 9f3520c31 Yuanhan Liu 2015-05-08 423 } while (0) 9f3520c31 Yuanhan Liu 2015-05-08 424 82e06c811 Shaohua Li 2013-11-14 425 #define __wait_event_cmd(wq, condition, cmd1, cmd2) \ 82e06c811 Shaohua Li 2013-11-14 426 (void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, 0, \ 82e06c811 Shaohua Li 2013-11-14 427 cmd1; schedule(); cmd2) 82e06c811 Shaohua Li 2013-11-14 428 82e06c811 Shaohua Li 2013-11-14 429 /** 82e06c811 Shaohua Li 2013-11-14 430 * wait_event_cmd - sleep until a condition gets true 82e06c811 Shaohua Li 2013-11-14 431 * @wq: the waitqueue to wait on 82e06c811 Shaohua Li 2013-11-14 432 * @condition: a C expression for the event to wait for f434f7afa Masanari Iida 2014-01-22 433 * @cmd1: the command will be executed before sleep f434f7afa Masanari Iida 2014-01-22 434 * @cmd2: the command will be executed after sleep 82e06c811 Shaohua Li 2013-11-14 435 * 82e06c811 Shaohua Li 2013-11-14 436 * The process is put to sleep (TASK_UNINTERRUPTIBLE) until the 82e06c811 Shaohua Li 2013-11-14 437 * @condition evaluates to true. The @condition is checked each time 82e06c811 Shaohua Li 2013-11-14 438 * the waitqueue @wq is woken up. 82e06c811 Shaohua Li 2013-11-14 439 * 82e06c811 Shaohua Li 2013-11-14 440 * wake_up() has to be called after changing any variable that could 82e06c811 Shaohua Li 2013-11-14 441 * change the result of the wait condition. 82e06c811 Shaohua Li 2013-11-14 442 */ 82e06c811 Shaohua Li 2013-11-14 443 #define wait_event_cmd(wq, condition, cmd1, cmd2) \ 82e06c811 Shaohua Li 2013-11-14 444 do { \ 82e06c811 Shaohua Li 2013-11-14 445 if (condition) \ 82e06c811 Shaohua Li 2013-11-14 446 break; \ 82e06c811 Shaohua Li 2013-11-14 447 __wait_event_cmd(wq, condition, cmd1, cmd2); \ 82e06c811 Shaohua Li 2013-11-14 448 } while (0) 82e06c811 Shaohua Li 2013-11-14 449 35a2af94c Peter Zijlstra 2013-10-02 450 #define __wait_event_interruptible(wq, condition) \ 35a2af94c Peter Zijlstra 2013-10-02 @451 ___wait_event(wq, condition, TASK_INTERRUPTIBLE, 0, 0, \ f13f4c41c Peter Zijlstra 2013-10-02 452 schedule()) ^1da177e4 Linus Torvalds 2005-04-16 453 ^1da177e4 Linus Torvalds 2005-04-16 454 /** ^1da177e4 Linus Torvalds 2005-04-16 455 * wait_event_interruptible - sleep until a condition gets true ^1da177e4 Linus Torvalds 2005-04-16 456 * @wq: the waitqueue to wait on ^1da177e4 Linus Torvalds 2005-04-16 457 * @condition: a C expression for the event to wait for ^1da177e4 Linus Torvalds 2005-04-16 458 * ^1da177e4 Linus Torvalds 2005-04-16 459 * The process is put to sleep (TASK_INTERRUPTIBLE) until the ^1da177e4 Linus Torvalds 2005-04-16 460 * @condition evaluates to true or a signal is received. ^1da177e4 Linus Torvalds 2005-04-16 461 * The @condition is checked each time the waitqueue @wq is woken up. ^1da177e4 Linus Torvalds 2005-04-16 462 * ^1da177e4 Linus Torvalds 2005-04-16 463 * wake_up() has to be called after changing any variable that could ^1da177e4 Linus Torvalds 2005-04-16 464 * change the result of the wait condition. ^1da177e4 Linus Torvalds 2005-04-16 465 * ^1da177e4 Linus Torvalds 2005-04-16 466 * The function will return -ERESTARTSYS if it was interrupted by a ^1da177e4 Linus Torvalds 2005-04-16 467 * signal and 0 if @condition evaluated to true. ^1da177e4 Linus Torvalds 2005-04-16 468 */ ^1da177e4 Linus Torvalds 2005-04-16 469 #define wait_event_interruptible(wq, condition) \ ^1da177e4 Linus Torvalds 2005-04-16 470 ({ \ ^1da177e4 Linus Torvalds 2005-04-16 471 int __ret = 0; \ e22b886a8 Peter Zijlstra 2014-09-24 472 might_sleep(); \ ^1da177e4 Linus Torvalds 2005-04-16 @473 if (!(condition)) \ 35a2af94c Peter Zijlstra 2013-10-02 474 __ret = __wait_event_interruptible(wq, condition); \ ^1da177e4 Linus Torvalds 2005-04-16 475 __ret; \ ^1da177e4 Linus Torvalds 2005-04-16 476 }) :::::: The code at line 473 was first introduced by commit :::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2 :::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org> :::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Roman, [auto build test WARNING on block/for-next] [also build test WARNING on v4.7 next-20160805] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Roman-Pen/blk-mq-fix-hang-caused-by-freeze-unfreeze-sequence/20160806-014441 base: https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-next config: tile-allyesconfig (attached as .config) compiler: tilegx-linux-gcc (GCC) 4.6.2 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=tile All warnings (new ones prefixed by >>): block/blk-core.c: In function 'blk_queue_enter': >> block/blk-core.c:660:3: warning: passing argument 1 of 'atomic_read' from incompatible pointer type [enabled by default] arch/tile/include/asm/atomic.h:35:19: note: expected 'const struct atomic_t *' but argument is of type 'int *' >> block/blk-core.c:660:3: warning: passing argument 1 of 'atomic_read' from incompatible pointer type [enabled by default] arch/tile/include/asm/atomic.h:35:19: note: expected 'const struct atomic_t *' but argument is of type 'int *' vim +/atomic_read +660 block/blk-core.c ^1da177e drivers/block/ll_rw_blk.c Linus Torvalds 2005-04-16 644 { c304a51b block/blk-core.c Ezequiel Garcia 2012-11-10 645 return blk_alloc_queue_node(gfp_mask, NUMA_NO_NODE); 1946089a drivers/block/ll_rw_blk.c Christoph Lameter 2005-06-23 646 } 1946089a drivers/block/ll_rw_blk.c Christoph Lameter 2005-06-23 647 EXPORT_SYMBOL(blk_alloc_queue); ^1da177e drivers/block/ll_rw_blk.c Linus Torvalds 2005-04-16 648 6f3b0e8b block/blk-core.c Christoph Hellwig 2015-11-26 649 int blk_queue_enter(struct request_queue *q, bool nowait) 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 650 { 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 651 while (true) { 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 652 int ret; 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 653 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 654 if (percpu_ref_tryget_live(&q->q_usage_counter)) 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 655 return 0; 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 656 6f3b0e8b block/blk-core.c Christoph Hellwig 2015-11-26 657 if (nowait) 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 658 return -EBUSY; 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 659 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 @660 ret = wait_event_interruptible(q->mq_freeze_wq, 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 661 !atomic_read(&q->mq_freeze_depth) || 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 662 blk_queue_dying(q)); 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 663 if (blk_queue_dying(q)) 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 664 return -ENODEV; 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 665 if (ret) 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 666 return ret; 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 667 } 3ef28e83 block/blk-core.c Dan Williams 2015-10-21 668 } :::::: The code at line 660 was first introduced by commit :::::: 3ef28e83ab15799742e55fd13243a5f678b04242 block: generic request_queue reference counting :::::: TO: Dan Williams <dan.j.williams@intel.com> :::::: CC: Jens Axboe <axboe@fb.com> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/block/blk-core.c b/block/blk-core.c index ef78848..01dcb02 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -740,6 +740,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) __set_bit(QUEUE_FLAG_BYPASS, &q->queue_flags); init_waitqueue_head(&q->mq_freeze_wq); + mutex_init(&q->mq_freeze_lock); /* * Init percpu_ref in atomic mode so that it's faster to shutdown. diff --git a/block/blk-mq.c b/block/blk-mq.c index 6d6f8fe..1f3e81b 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -80,13 +80,13 @@ static void blk_mq_hctx_clear_pending(struct blk_mq_hw_ctx *hctx, void blk_mq_freeze_queue_start(struct request_queue *q) { - int freeze_depth; - - freeze_depth = atomic_inc_return(&q->mq_freeze_depth); - if (freeze_depth == 1) { + mutex_lock(&q->mq_freeze_lock); + if (++q->mq_freeze_depth == 1) { percpu_ref_kill(&q->q_usage_counter); + mutex_unlock(&q->mq_freeze_lock); blk_mq_run_hw_queues(q, false); - } + } else + mutex_unlock(&q->mq_freeze_lock); } EXPORT_SYMBOL_GPL(blk_mq_freeze_queue_start); @@ -124,14 +124,14 @@ EXPORT_SYMBOL_GPL(blk_mq_freeze_queue); void blk_mq_unfreeze_queue(struct request_queue *q) { - int freeze_depth; - - freeze_depth = atomic_dec_return(&q->mq_freeze_depth); - WARN_ON_ONCE(freeze_depth < 0); - if (!freeze_depth) { + mutex_lock(&q->mq_freeze_lock); + q->mq_freeze_depth--; + WARN_ON_ONCE(q->mq_freeze_depth < 0); + if (!q->mq_freeze_depth) { percpu_ref_reinit(&q->q_usage_counter); wake_up_all(&q->mq_freeze_wq); } + mutex_unlock(&q->mq_freeze_lock); } EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue); @@ -2105,7 +2105,7 @@ void blk_mq_free_queue(struct request_queue *q) static void blk_mq_queue_reinit(struct request_queue *q, const struct cpumask *online_mask) { - WARN_ON_ONCE(!atomic_read(&q->mq_freeze_depth)); + WARN_ON_ONCE(!q->mq_freeze_depth); blk_mq_sysfs_unregister(q); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index f6ff9d1..d692c16 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -445,7 +445,7 @@ struct request_queue { struct mutex sysfs_lock; int bypass_depth; - atomic_t mq_freeze_depth; + int mq_freeze_depth; #if defined(CONFIG_BLK_DEV_BSG) bsg_job_fn *bsg_job_fn; @@ -459,6 +459,11 @@ struct request_queue { #endif struct rcu_head rcu_head; wait_queue_head_t mq_freeze_wq; + /* + * Protect concurrent access to q_usage_counter by + * percpu_ref_kill() and percpu_ref_reinit(). + */ + struct mutex mq_freeze_lock; struct percpu_ref q_usage_counter; struct list_head all_q_node;
Long time ago there was a similar fix proposed by Akinobu Mita[1], but it seems that time everyone decided to fix this subtle race in percpu-refcount and Tejun Heo[2] did an attempt (as I can see that patchset was not applied). The following is a description of a queue hang - same fix but a bug from another angle. The hang happens on queue freeze because of a simultaneous calls of blk_mq_freeze_queue() and blk_mq_unfreeze_queue() from different threads, and because of a reference race percpu_ref_reinit() and percpu_ref_kill() swap. CPU#0 CPU#1 ---------------- ----------------- percpu_ref_kill() percpu_ref_kill() << atomic reference does not percpu_ref_reinit() << guarantee the order blk_mq_freeze_queue_wait() << HANG HERE percpu_ref_reinit() Firstly this wrong sequence raises two kernel warnings: 1st. WARNING at lib/percpu-recount.c:309 percpu_ref_kill_and_confirm called more than once 2nd. WARNING at lib/percpu-refcount.c:331 But the most unpleasant effect is a hang of a blk_mq_freeze_queue_wait(), which waits for a zero of a q_usage_counter, which never happens because percpu-ref was not reinited and stays in PERCPU state forever. The simplified sequence above is reproduced on shared tags, when one queue is going to die meanwhile another one is initing: CPU#0 CPU#1 ------------------------------- ------------------------------------ q1 = blk_mq_init_queue(shared_tags) q2 = blk_mq_init_queue(shared_tags): blk_mq_add_queue_tag_set(shared_tags): blk_mq_update_tag_set_depth(shared_tags): blk_mq_freeze_queue(q1) blk_cleanup_queue(q1) ... blk_mq_freeze_queue(q1) <<<->>> blk_mq_unfreeze_queue(q1) [1] Message id: 1443287365-4244-7-git-send-email-akinobu.mita@gmail.com [2] Message id: 1443563240-29306-6-git-send-email-tj@kernel.org Signed-off-by: Roman Pen <roman.penyaev@profitbricks.com> Cc: Akinobu Mita <akinobu.mita@gmail.com> Cc: Tejun Heo <tj@kernel.org> Cc: Jens Axboe <axboe@kernel.dk> Cc: Christoph Hellwig <hch@lst.de> Cc: linux-block@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- block/blk-core.c | 1 + block/blk-mq.c | 22 +++++++++++----------- include/linux/blkdev.h | 7 ++++++- 3 files changed, 18 insertions(+), 12 deletions(-)