aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vhost/vhost.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-21 15:54:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-21 15:54:12 -0400
commit888a6f77e0418b049f83d37547c209b904d30af4 (patch)
tree42cdb9f781d2177e6b380e69a66a27ec7705f51f /drivers/vhost/vhost.c
parent31b7eab27a314b153d8fa07ba9e9ec00a98141e1 (diff)
parent6506cf6ce68d78a5470a8360c965dafe8e4b78e3 (diff)
Merge branch 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'core-rcu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (52 commits) sched: fix RCU lockdep splat from task_group() rcu: using ACCESS_ONCE() to observe the jiffies_stall/rnp->qsmask value sched: suppress RCU lockdep splat in task_fork_fair net: suppress RCU lockdep false positive in sock_update_classid rcu: move check from rcu_dereference_bh to rcu_read_lock_bh_held rcu: Add advice to PROVE_RCU_REPEATEDLY kernel config parameter rcu: Add tracing data to support queueing models rcu: fix sparse errors in rcutorture.c rcu: only one evaluation of arg in rcu_dereference_check() unless sparse kernel: Remove undead ifdef CONFIG_DEBUG_LOCK_ALLOC rcu: fix _oddness handling of verbose stall warnings rcu: performance fixes to TINY_PREEMPT_RCU callback checking rcu: upgrade stallwarn.txt documentation for CPU-bound RT processes vhost: add __rcu annotations rcu: add comment stating that list_empty() applies to RCU-protected lists rcu: apply TINY_PREEMPT_RCU read-side speedup to TREE_PREEMPT_RCU rcu: combine duplicate code, courtesy of CONFIG_PREEMPT_RCU rcu: Upgrade srcu_read_lock() docbook about SRCU grace periods rcu: document ways of stalling updates in low-memory situations rcu: repair code-duplication FIXMEs ...
Diffstat (limited to 'drivers/vhost/vhost.c')
-rw-r--r--drivers/vhost/vhost.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index dd3d6f7406f8..8b5a1b33d0fe 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -320,7 +320,7 @@ long vhost_dev_reset_owner(struct vhost_dev *dev)
320 vhost_dev_cleanup(dev); 320 vhost_dev_cleanup(dev);
321 321
322 memory->nregions = 0; 322 memory->nregions = 0;
323 dev->memory = memory; 323 RCU_INIT_POINTER(dev->memory, memory);
324 return 0; 324 return 0;
325} 325}
326 326
@@ -352,8 +352,9 @@ void vhost_dev_cleanup(struct vhost_dev *dev)
352 fput(dev->log_file); 352 fput(dev->log_file);
353 dev->log_file = NULL; 353 dev->log_file = NULL;
354 /* No one will access memory at this point */ 354 /* No one will access memory at this point */
355 kfree(dev->memory); 355 kfree(rcu_dereference_protected(dev->memory,
356 dev->memory = NULL; 356 lockdep_is_held(&dev->mutex)));
357 RCU_INIT_POINTER(dev->memory, NULL);
357 if (dev->mm) 358 if (dev->mm)
358 mmput(dev->mm); 359 mmput(dev->mm);
359 dev->mm = NULL; 360 dev->mm = NULL;
@@ -440,14 +441,22 @@ static int vq_access_ok(unsigned int num,
440/* Caller should have device mutex but not vq mutex */ 441/* Caller should have device mutex but not vq mutex */
441int vhost_log_access_ok(struct vhost_dev *dev) 442int vhost_log_access_ok(struct vhost_dev *dev)
442{ 443{
443 return memory_access_ok(dev, dev->memory, 1); 444 struct vhost_memory *mp;
445
446 mp = rcu_dereference_protected(dev->memory,
447 lockdep_is_held(&dev->mutex));
448 return memory_access_ok(dev, mp, 1);
444} 449}
445 450
446/* Verify access for write logging. */ 451/* Verify access for write logging. */
447/* Caller should have vq mutex and device mutex */ 452/* Caller should have vq mutex and device mutex */
448static int vq_log_access_ok(struct vhost_virtqueue *vq, void __user *log_base) 453static int vq_log_access_ok(struct vhost_virtqueue *vq, void __user *log_base)
449{ 454{
450 return vq_memory_access_ok(log_base, vq->dev->memory, 455 struct vhost_memory *mp;
456
457 mp = rcu_dereference_protected(vq->dev->memory,
458 lockdep_is_held(&vq->mutex));
459 return vq_memory_access_ok(log_base, mp,
451 vhost_has_feature(vq->dev, VHOST_F_LOG_ALL)) && 460 vhost_has_feature(vq->dev, VHOST_F_LOG_ALL)) &&
452 (!vq->log_used || log_access_ok(log_base, vq->log_addr, 461 (!vq->log_used || log_access_ok(log_base, vq->log_addr,
453 sizeof *vq->used + 462 sizeof *vq->used +
@@ -487,7 +496,8 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
487 kfree(newmem); 496 kfree(newmem);
488 return -EFAULT; 497 return -EFAULT;
489 } 498 }
490 oldmem = d->memory; 499 oldmem = rcu_dereference_protected(d->memory,
500 lockdep_is_held(&d->mutex));
491 rcu_assign_pointer(d->memory, newmem); 501 rcu_assign_pointer(d->memory, newmem);
492 synchronize_rcu(); 502 synchronize_rcu();
493 kfree(oldmem); 503 kfree(oldmem);