Skip to content
  • Jens Axboe's avatar
    percpu_counter: fix bad counter state during suspend · 60b0ea12
    Jens Axboe authored
    I got a bug report yesterday from Laszlo Ersek <lersek@xxxxxxxxxx>, in
    which he states that his kvm instance fails to suspend. He Laszlo
    bisected it down to this commit:
    
    commit 1cf7e9c6
    
    
    Author: Jens Axboe <axboe@xxxxxxxxx>
    Date: Fri Nov 1 10:52:52 2013 -0600
    
    virtio_blk: blk-mq support
    
    where virtio-blk is converted to use the blk-mq infrastructure. After
    digging a bit, it became clear that the issue was with the queue drain.
    blk-mq tracks queue usage in a percpu counter, which is incremented on
    request alloc and decremented when the request is freed. The initial
    hunt was for an inconsistency in blk-mq, but everything seemed fine. In
    fact, the counter only returned crazy values when suspend was in
    progress. When a CPU is unplugged, the percpu counters merges that CPU
    state with the general state. blk-mq takes care to register a hotcpu
    notifier with the appropriate priority, so we know it runs after the
    percpu counter notifier. However, the percpu counter notifier only
    merges the state when the CPU is fully gone. This leaves a state
    transition where the CPU going away is no longer in the online mask, yet
    it still holds private values. This means that in this state,
    percpu_counter_sum() returns invalid results, and the suspend then hangs
    waiting for abs(dead-cpu-value) requests to complete which of course
    will never happen.
    
    Fix this by clearing the state earlier, so we never have a case where
    the CPU isn't in online mask but still holds private state. This bug has
    been there since forever, I guess we don't have a lot of users where
    percpu counters needs to be reliable during the suspend cycle.
    
    Reported-by: default avatar <lersek@redhat.com>
    Tested-by: default avatarLaszlo Ersek <lersek@redhat.com>
    Signed-off-by: default avatarJens Axboe <axboe@fb.com>
    60b0ea12