By directly using find_first_bit() and find_next_bit from the "bitops.h" API to iterate over the bitmap, we can remove the bitmap[] variable-length array copy on the stack and the complex manual bit testing/clearing logic.
Suggested-by: Stefan Hajnoczi <stefa...@redhat.com> Suggested-by: Richard Henderson <richard.hender...@linaro.org> Reviewed-by: Richard Henderson <richard.hender...@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <phi...@redhat.com> --- hw/block/dataplane/virtio-blk.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index e9050c8987e..a31fa94ca33 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -60,24 +60,14 @@ static void notify_guest_bh(void *opaque) { VirtIOBlockDataPlane *s = opaque; unsigned nvqs = s->conf->num_queues; - unsigned long bitmap[BITS_TO_LONGS(nvqs)]; - unsigned j; - memcpy(bitmap, s->batch_notify_vqs, sizeof(bitmap)); - memset(s->batch_notify_vqs, 0, sizeof(bitmap)); + for (unsigned long i = find_first_bit(s->batch_notify_vqs, nvqs); + i < nvqs; i = find_next_bit(s->batch_notify_vqs, nvqs, i)) { + VirtQueue *vq = virtio_get_queue(s->vdev, i); - for (j = 0; j < nvqs; j += BITS_PER_LONG) { - unsigned long bits = bitmap[j / BITS_PER_LONG]; - - while (bits != 0) { - unsigned i = j + ctzl(bits); - VirtQueue *vq = virtio_get_queue(s->vdev, i); - - virtio_notify_irqfd(s->vdev, vq); - - bits &= bits - 1; /* clear right-most bit */ - } + virtio_notify_irqfd(s->vdev, vq); } + bitmap_clear(s->batch_notify_vqs, 0, nvqs); } /* Context: QEMU global mutex held */ -- 2.26.3