2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
39 #include <sys/rtprio.h>
40 #include <sys/queue.h>
41 #include <machine/cpu.h>
42 #include <sys/spinlock.h>
43 #include <sys/iosched.h>
44 #include <sys/sysctl.h>
46 #include <sys/limits.h>
48 #include <sys/spinlock2.h>
51 #include <vm/vm_param.h>
52 #include <vm/vm_kern.h>
53 #include <vm/vm_extern.h>
55 SYSCTL_NODE(, OID_AUTO
, iosched
, CTLFLAG_RW
, 0, "I/O Scheduler");
57 static int iosched_debug
= 0;
58 SYSCTL_INT(_iosched
, OID_AUTO
, debug
, CTLFLAG_RW
, &iosched_debug
, 0, "");
60 static struct iosched_data ioscpu
[SMP_MAXCPU
];
66 badjiosched(thread_t td
, size_t bytes
)
68 globaldata_t gd
= mycpu
;
75 for (i
= 0; i
< ncpus
; ++i
)
76 iostotal
+= ioscpu
[i
].iowbytes
;
77 if (SIZE_T_MAX
/ SMP_MAXCPU
- td
->td_iosdata
.iowbytes
< bytes
)
78 bytes
= SIZE_T_MAX
/ SMP_MAXCPU
- td
->td_iosdata
.iowbytes
;
79 td
->td_iosdata
.iowbytes
+= bytes
;
80 ioscpu
[gd
->gd_cpuid
].iowbytes
+= bytes
;
82 delta
= ticks
- td
->td_iosdata
.lastticks
;
84 td
->td_iosdata
.lastticks
= ticks
;
85 if (delta
< 0 || delta
> hz
* 10)
87 /* be careful of interger overflows */
88 bytes
= (int64_t)td
->td_iosdata
.iowbytes
* delta
/ (hz
* 10);
89 td
->td_iosdata
.iowbytes
-= bytes
;
90 ioscpu
[gd
->gd_cpuid
].iowbytes
-= bytes
;
94 /* be careful of interger overflows */
96 factor
= (int64_t)td
->td_iosdata
.iowbytes
* 100 / iostotal
;
100 if (delta
&& (iosched_debug
& 1)) {
101 kprintf("proc %12s (%-5d) factor %3d (%zd/%zd)\n",
103 (td
->td_lwp
? (int)td
->td_lwp
->lwp_proc
->p_pid
: -1),
104 factor
, td
->td_iosdata
.iowbytes
, iostotal
);
110 biosched_done(thread_t td
)
112 globaldata_t gd
= mycpu
;
115 if ((bytes
= td
->td_iosdata
.iowbytes
) != 0) {
116 td
->td_iosdata
.iowbytes
= 0;
117 ioscpu
[gd
->gd_cpuid
].iowbytes
-= bytes
;
122 * Caller intends to write (bytes)
127 bwillwrite(int bytes
)
134 /* be careful of interger overflows */
135 factor
= badjiosched(curthread
, (size_t)bytes
);
136 count
= hidirtybufspace
/ 100 * factor
;
142 * Caller intends to read (bytes)
152 * Call intends to do an inode-modifying operation of some sort.
164 factor
= badjiosched(curthread
, PAGE_SIZE
);
165 count
= count
* factor
/ 100;