diff options
author | alc <alc@FreeBSD.org> | 2004-01-02 19:38:25 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2004-01-02 19:38:25 +0000 |
commit | fca40d687b8eef583db0b854cd6840658ee9ec54 (patch) | |
tree | 802cc5476ffb0434458d84e62b61cdb61eb3b397 /sys/vm/vm_meter.c | |
parent | 7d2f8d32ae1d9bf5def622d91d179ad176d0f683 (diff) | |
download | FreeBSD-src-fca40d687b8eef583db0b854cd6840658ee9ec54.zip FreeBSD-src-fca40d687b8eef583db0b854cd6840658ee9ec54.tar.gz |
Avoid lock-order reversal between the vm object list mutex and the vm
object mutex.
Diffstat (limited to 'sys/vm/vm_meter.c')
-rw-r--r-- | sys/vm/vm_meter.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/sys/vm/vm_meter.c b/sys/vm/vm_meter.c index 1638f3d..9d92eb9 100644 --- a/sys/vm/vm_meter.c +++ b/sys/vm/vm_meter.c @@ -100,7 +100,14 @@ vmtotal(SYSCTL_HANDLER_ARGS) GIANT_REQUIRED; mtx_lock(&vm_object_list_mtx); TAILQ_FOREACH(object, &vm_object_list, object_list) { - VM_OBJECT_LOCK(object); + if (!VM_OBJECT_TRYLOCK(object)) { + /* + * Avoid a lock-order reversal. Consequently, + * the reported number of active pages may be + * greater than the actual number. + */ + continue; + } vm_object_clear_flag(object, OBJ_ACTIVE); VM_OBJECT_UNLOCK(object); } @@ -176,12 +183,16 @@ vmtotal(SYSCTL_HANDLER_ARGS) */ mtx_lock(&vm_object_list_mtx); TAILQ_FOREACH(object, &vm_object_list, object_list) { - VM_OBJECT_LOCK(object); /* - * devices, like /dev/mem, will badly skew our totals + * Perform unsynchronized reads on the object to avoid + * a lock-order reversal. In this case, the lack of + * synchronization should not impair the accuracy of + * the reported statistics. */ if (object->type == OBJT_DEVICE) { - VM_OBJECT_UNLOCK(object); + /* + * Devices, like /dev/mem, will badly skew our totals. + */ continue; } totalp->t_vm += object->size; @@ -199,7 +210,6 @@ vmtotal(SYSCTL_HANDLER_ARGS) totalp->t_armshr += object->resident_page_count; } } - VM_OBJECT_UNLOCK(object); } mtx_unlock(&vm_object_list_mtx); totalp->t_free = cnt.v_free_count + cnt.v_cache_count; |