summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2007-12-23 01:59:59 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2007-12-23 01:59:59 +0000
commitb138fdba471acf705e1bea127c1da17179e67dd5 (patch)
treef141eb33d15eefe36bb2684c7f216113ae1eb4a6 /sys
parent8602dbb5d540b780ded7baca4f0f52226105a1b2 (diff)
protect the disk statistics with a mutex.
ok tedu@ kettenis@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_sysctl.c6
-rw-r--r--sys/kern/subr_disk.c12
-rw-r--r--sys/sys/disk.h4
3 files changed, 17 insertions, 5 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index c9b12d50fab..a855b835c6a 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.158 2007/10/10 15:53:53 art Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.159 2007/12/23 01:59:58 dlg Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -1587,6 +1587,7 @@ sysctl_diskinit(int update, struct proc *p)
sdk = diskstats + i;
strlcpy(sdk->ds_name, dk->dk_name,
sizeof(sdk->ds_name));
+ mtx_enter(&dk->dk_mtx);
sdk->ds_busy = dk->dk_busy;
sdk->ds_rxfer = dk->dk_rxfer;
sdk->ds_wxfer = dk->dk_wxfer;
@@ -1596,6 +1597,7 @@ sysctl_diskinit(int update, struct proc *p)
sdk->ds_attachtime = dk->dk_attachtime;
sdk->ds_timestamp = dk->dk_timestamp;
sdk->ds_time = dk->dk_time;
+ mtx_leave(&dk->dk_mtx);
}
/* Eliminate trailing comma */
@@ -1609,6 +1611,7 @@ sysctl_diskinit(int update, struct proc *p)
sdk = diskstats + i;
strlcpy(sdk->ds_name, dk->dk_name,
sizeof(sdk->ds_name));
+ mtx_enter(&dk->dk_mtx);
sdk->ds_busy = dk->dk_busy;
sdk->ds_rxfer = dk->dk_rxfer;
sdk->ds_wxfer = dk->dk_wxfer;
@@ -1618,6 +1621,7 @@ sysctl_diskinit(int update, struct proc *p)
sdk->ds_attachtime = dk->dk_attachtime;
sdk->ds_timestamp = dk->dk_timestamp;
sdk->ds_time = dk->dk_time;
+ mtx_leave(&dk->dk_mtx);
}
}
rw_exit_write(&sysctl_disklock);
diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c
index 2bf6f11b7e0..a07904647e4 100644
--- a/sys/kern/subr_disk.c
+++ b/sys/kern/subr_disk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_disk.c,v 1.67 2007/12/16 20:57:17 otto Exp $ */
+/* $OpenBSD: subr_disk.c,v 1.68 2007/12/23 01:59:58 dlg Exp $ */
/* $NetBSD: subr_disk.c,v 1.17 1996/03/16 23:17:08 christos Exp $ */
/*
@@ -712,6 +712,7 @@ int
disk_construct(struct disk *diskp, char *lockname)
{
rw_init(&diskp->dk_lock, lockname);
+ mtx_init(&diskp->dk_mtx, IPL_BIO);
diskp->dk_flags |= DKF_CONSTRUCTED;
@@ -784,9 +785,10 @@ disk_busy(struct disk *diskp)
* XXX We'd like to use something as accurate as microtime(),
* but that doesn't depend on the system TOD clock.
*/
- if (diskp->dk_busy++ == 0) {
+ mtx_enter(&diskp->dk_mtx);
+ if (diskp->dk_busy++ == 0)
microuptime(&diskp->dk_timestamp);
- }
+ mtx_leave(&diskp->dk_mtx);
}
/*
@@ -798,6 +800,8 @@ disk_unbusy(struct disk *diskp, long bcount, int read)
{
struct timeval dv_time, diff_time;
+ mtx_enter(&diskp->dk_mtx);
+
if (diskp->dk_busy-- == 0)
printf("disk_unbusy: %s: dk_busy < 0\n", diskp->dk_name);
@@ -818,6 +822,8 @@ disk_unbusy(struct disk *diskp, long bcount, int read)
} else
diskp->dk_seek++;
+ mtx_leave(&diskp->dk_mtx);
+
add_disk_randomness(bcount ^ diff_time.tv_usec);
}
diff --git a/sys/sys/disk.h b/sys/sys/disk.h
index ccab35d1010..e045bb08f5f 100644
--- a/sys/sys/disk.h
+++ b/sys/sys/disk.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: disk.h,v 1.17 2007/06/20 18:15:47 deraadt Exp $ */
+/* $OpenBSD: disk.h,v 1.18 2007/12/23 01:59:58 dlg Exp $ */
/* $NetBSD: disk.h,v 1.11 1996/04/28 20:22:50 thorpej Exp $ */
/*
@@ -51,6 +51,7 @@
#include <sys/time.h>
#include <sys/queue.h>
#include <sys/rwlock.h>
+#include <sys/mutex.h>
struct buf;
struct disklabel;
@@ -73,6 +74,7 @@ struct diskstats {
struct disk {
TAILQ_ENTRY(disk) dk_link; /* link in global disklist */
struct rwlock dk_lock; /* disk lock */
+ struct mutex dk_mtx; /* busy/unbusy mtx */
char *dk_name; /* disk name */
int dk_flags; /* disk flags */
#define DKF_CONSTRUCTED 0x0001