• Jens Axboe's avatar
    lib/percpu_counter.c: fix bad percpu counter state during suspend · e39435ce
    Jens Axboe authored
    I got a bug report yesterday from Laszlo Ersek in which he states that
    his kvm instance fails to suspend.  Laszlo bisected it down to this
    commit 1cf7e9c6 ("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.
    Signed-off-by: default avatarJens Axboe <axboe@fb.com>
    Reported-by: default avatarLaszlo Ersek <lersek@redhat.com>
    Tested-by: default avatarLaszlo Ersek <lersek@redhat.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    e39435ce
percpu_counter.c 5.3 KB