[bug report] aoe: convert aoeblk to blk-mq

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Jens Axboe,

The patch 3582dd291788: "aoe: convert aoeblk to blk-mq" from Oct 12,
2018, leads to the following static checker warning:

	block/blk-mq.c:151 blk_mq_freeze_queue_wait()
	warn: sleeping in atomic context

The problem is that aoedev_downdev() can sleep now.

There are two callers of aoedev_downdev() and originally they were both
called under spinlock.  One was fixed in commit 430380b4637a
("block: aoe: Fix kernel crash due to atomic sleep when exiting") but
the other is still buggy.

drivers/block/aoe/aoecmd.c
   726  static void
   727  rexmit_timer(struct timer_list *timer)
   728  {
   729          struct aoedev *d;
   730          struct aoetgt *t;
   731          struct aoeif *ifp;
   732          struct frame *f;
   733          struct list_head *head, *pos, *nx;
   734          LIST_HEAD(flist);
   735          register long timeout;
   736          ulong flags, n;
   737          int i;
   738          int utgts;      /* number of aoetgt descriptors (not slots) */
   739          int since;
   740  
   741          d = from_timer(d, timer, timer);
   742  
   743          spin_lock_irqsave(&d->lock, flags);
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
spin lock held.

   744  
   745          /* timeout based on observed timings and variations */
   746          timeout = rto(d);
   747  
   748          utgts = count_targets(d, NULL);
   749  
   750          if (d->flags & DEVFL_TKILL) {
   751                  spin_unlock_irqrestore(&d->lock, flags);
   752                  return;
   753          }
   754  
   755          /* collect all frames to rexmit into flist */
   756          for (i = 0; i < NFACTIVE; i++) {
   757                  head = &d->factive[i];
   758                  list_for_each_safe(pos, nx, head) {
   759                          f = list_entry(pos, struct frame, head);
   760                          if (tsince_hr(f) < timeout)
   761                                  break;  /* end of expired frames */
   762                          /* move to flist for later processing */
   763                          list_move_tail(pos, &flist);
   764                  }
   765          }
   766  
   767          /* process expired frames */
   768          while (!list_empty(&flist)) {
   769                  pos = flist.next;
   770                  f = list_entry(pos, struct frame, head);
   771                  since = tsince_hr(f);
   772                  n = f->waited_total + since;
   773                  n /= USEC_PER_SEC;
   774                  if (aoe_deadsecs
   775                  && n > aoe_deadsecs
   776                  && !(f->flags & FFL_PROBE)) {
   777                          /* Waited too long.  Device failure.
   778                           * Hang all frames on first hash bucket for downdev
   779                           * to clean up.
   780                           */
   781                          list_splice(&flist, &d->factive[0]);
   782                          aoedev_downdev(d);
                                ^^^^^^^^^^^^^^^^^
Sleeps in atomic if we call blk_mq_freeze_queue().

   783                          goto out;
   784                  }
   785  
   786                  t = f->t;
   787                  n = f->waited + since;
   788                  n /= USEC_PER_SEC;
   789                  if (aoe_deadsecs && utgts > 0
   790                  && (n > aoe_deadsecs / utgts || n > HARD_SCORN_SECS))
   791                          scorn(t); /* avoid this target */
   792

regards,
dan carpenter



[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux