diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2014-05-28 10:07:02 -0400 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2014-06-09 09:21:06 -0400 |
commit | 98f9ca0a3faa99b7388578d55eccecf272be4038 (patch) | |
tree | 991e7bc48ed0cb9da73aefe8cf454a54fcf96435 /drivers/vhost | |
parent | 23cc5a991c7a9fb7e6d6550e65cee4f4173111c5 (diff) |
vhost: replace rcu with mutex
All memory accesses are done under some VQ mutex.
So lock/unlock all VQs is a faster equivalent of synchronize_rcu()
for memory access changes.
Some guests cause a lot of these changes, so it's helpful
to make them faster.
Reported-by: "Gonglei (Arei)" <arei.gonglei@huawei.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/vhost')
-rw-r--r-- | drivers/vhost/vhost.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 78987e481bc6..1c05e6030d42 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -593,6 +593,7 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) | |||
593 | { | 593 | { |
594 | struct vhost_memory mem, *newmem, *oldmem; | 594 | struct vhost_memory mem, *newmem, *oldmem; |
595 | unsigned long size = offsetof(struct vhost_memory, regions); | 595 | unsigned long size = offsetof(struct vhost_memory, regions); |
596 | int i; | ||
596 | 597 | ||
597 | if (copy_from_user(&mem, m, size)) | 598 | if (copy_from_user(&mem, m, size)) |
598 | return -EFAULT; | 599 | return -EFAULT; |
@@ -619,7 +620,14 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) | |||
619 | oldmem = rcu_dereference_protected(d->memory, | 620 | oldmem = rcu_dereference_protected(d->memory, |
620 | lockdep_is_held(&d->mutex)); | 621 | lockdep_is_held(&d->mutex)); |
621 | rcu_assign_pointer(d->memory, newmem); | 622 | rcu_assign_pointer(d->memory, newmem); |
622 | synchronize_rcu(); | 623 | |
624 | /* All memory accesses are done under some VQ mutex. | ||
625 | * So below is a faster equivalent of synchronize_rcu() | ||
626 | */ | ||
627 | for (i = 0; i < d->nvqs; ++i) { | ||
628 | mutex_lock(&d->vqs[i]->mutex); | ||
629 | mutex_unlock(&d->vqs[i]->mutex); | ||
630 | } | ||
623 | kfree(oldmem); | 631 | kfree(oldmem); |
624 | return 0; | 632 | return 0; |
625 | } | 633 | } |