drivers/md/dm-mpath.c:432 choose_pgpath() error: double unlocked 'm->lock' (orig line 402)

From: kernel test robot
Date: Sat Aug 08 2020 - 06:21:31 EST


tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 449dc8c97089a6e09fb2dac4d92b1b7ac0eb7c1e
commit: 69cea0d45a618ad4ae74f36386ef1af5128b2b19 dm mpath: changes from initial m->flags locking audit
date: 4 weeks ago
config: arm-randconfig-m031-20200808 (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@xxxxxxxxx>

New smatch warnings:
drivers/md/dm-mpath.c:432 choose_pgpath() error: double unlocked 'm->lock' (orig line 402)

Old smatch warnings:
drivers/md/dm-mpath.c:443 choose_pgpath() error: double unlocked 'm->lock' (orig line 389)
drivers/md/dm-mpath.c:593 __map_bio() error: double unlocked 'm->lock' (orig line 589)
drivers/md/dm-mpath.c:1574 pg_init_done() error: double unlocked 'm->lock' (orig line 1527)

vim +432 drivers/md/dm-mpath.c

378
379 static struct pgpath *choose_pgpath(struct multipath *m, size_t nr_bytes)
380 {
381 unsigned long flags;
382 struct priority_group *pg;
383 struct pgpath *pgpath;
384 unsigned bypassed = 1;
385
386 if (!atomic_read(&m->nr_valid_paths)) {
387 spin_lock_irqsave(&m->lock, flags);
388 clear_bit(MPATHF_QUEUE_IO, &m->flags);
389 spin_unlock_irqrestore(&m->lock, flags);
390 goto failed;
391 }
392
393 /* Were we instructed to switch PG? */
394 if (READ_ONCE(m->next_pg)) {
395 spin_lock_irqsave(&m->lock, flags);
396 pg = m->next_pg;
397 if (!pg) {
398 spin_unlock_irqrestore(&m->lock, flags);
399 goto check_current_pg;
400 }
401 m->next_pg = NULL;
> 402 spin_unlock_irqrestore(&m->lock, flags);
403 pgpath = choose_path_in_pg(m, pg, nr_bytes);
404 if (!IS_ERR_OR_NULL(pgpath))
405 return pgpath;
406 }
407
408 /* Don't change PG until it has no remaining paths */
409 check_current_pg:
410 pg = READ_ONCE(m->current_pg);
411 if (pg) {
412 pgpath = choose_path_in_pg(m, pg, nr_bytes);
413 if (!IS_ERR_OR_NULL(pgpath))
414 return pgpath;
415 }
416
417 /*
418 * Loop through priority groups until we find a valid path.
419 * First time we skip PGs marked 'bypassed'.
420 * Second time we only try the ones we skipped, but set
421 * pg_init_delay_retry so we do not hammer controllers.
422 */
423 do {
424 list_for_each_entry(pg, &m->priority_groups, list) {
425 if (pg->bypassed == !!bypassed)
426 continue;
427 pgpath = choose_path_in_pg(m, pg, nr_bytes);
428 if (!IS_ERR_OR_NULL(pgpath)) {
429 if (!bypassed) {
430 spin_lock_irqsave(&m->lock, flags);
431 set_bit(MPATHF_PG_INIT_DELAY_RETRY, &m->flags);
> 432 spin_unlock_irqrestore(&m->lock, flags);
433 }
434 return pgpath;
435 }
436 }
437 } while (bypassed--);
438
439 failed:
440 spin_lock_irqsave(&m->lock, flags);
441 m->current_pgpath = NULL;
442 m->current_pg = NULL;
443 spin_unlock_irqrestore(&m->lock, flags);
444
445 return NULL;
446 }
447

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip