Hello Kent Overstreet,

The patch 2d69588454f4: "bcachefs: Erasure coding" from Nov 1, 2018
(linux-next), leads to the following Smatch static checker warning:

        fs/bcachefs/alloc_foreground.c:1056 should_drop_bucket()
        warn: sleeping in atomic context

The call tree is:

    bch2_open_buckets_stop() <- disables preempt
    -> should_drop_bucket()

fs/bcachefs/alloc_foreground.c
  1114          spin_lock(&c->freelist_lock);

Preempt disabled

  1115          i = 0;
  1116          while (i < c->open_buckets_partial_nr) {
  1117                  struct open_bucket *ob =
  1118                          c->open_buckets + c->open_buckets_partial[i];
  1119  
  1120                  if (should_drop_bucket(ob, c, ca, ec)) {

Called

  1121                          --c->open_buckets_partial_nr;
  1122                          swap(c->open_buckets_partial[i],
  1123                               
c->open_buckets_partial[c->open_buckets_partial_nr]);
  1124                          ob->on_partial_list = false;
  1125                          spin_unlock(&c->freelist_lock);
  1126                          bch2_open_bucket_put(c, ob);
  1127                          spin_lock(&c->freelist_lock);
  1128                  } else {
  1129                          i++;
  1130                  }
  1131          }
  1132          spin_unlock(&c->freelist_lock);

fs/bcachefs/alloc_foreground.c
    1043 static bool should_drop_bucket(struct open_bucket *ob, struct bch_fs 
*c,
    1044                                struct bch_dev *ca, bool ec)
    1045 {
    1046         if (ec) {
    1047                 return ob->ec != NULL;
    1048         } else if (ca) {
    1049                 bool drop = ob->dev == ca->dev_idx;
    1050                 struct open_bucket *ob2;
    1051                 unsigned i;
    1052 
    1053                 if (!drop && ob->ec) {
    1054                         unsigned nr_blocks;
    1055 
--> 1056                         mutex_lock(&ob->ec->lock);

Sleeps.  Do you have CONFIG_DEBUG_ATOMIC_SLEEP enabled in your .config?

    1057                         nr_blocks = 
bkey_i_to_stripe(&ob->ec->new_stripe.key)->v.nr_blocks;
    1058 
    1059                         for (i = 0; i < nr_blocks; i++) {
    1060                                 if (!ob->ec->blocks[i])
    1061                                         continue;
    1062 
    1063                                 ob2 = c->open_buckets + 
ob->ec->blocks[i];
    1064                                 drop |= ob2->dev == ca->dev_idx;
    1065                         }
    1066                         mutex_unlock(&ob->ec->lock);
    1067                 }
    1068 
    1069                 return drop;
    1070         } else {
    1071                 return true;
    1072         }
    1073 }

regards,
dan carpenter

Reply via email to