drm - Fix kldload issue
[dragonfly.git] / sys / kern / dsched / bfq / bfq.h
CommitLineData
aabeb187
BP
1/*
2 * Copyright (c) 2011 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Brills Peng <brillsp@gmail.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
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
16 * distribution.
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.
20 *
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
32 * SUCH DAMAGE.
33 */
34
35
36#ifndef _DSCHED_BFQ_H_
37#define _DSCHED_BFQ_H_
38
39#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
40
41#ifndef _SYS_QUEUE_H_
42#include <sys/queue.h>
43#endif
44
45#ifndef _SYS_BIO_H_
46#include <sys/bio.h>
47#endif
48
49#ifndef _SYS_BIOTRACK_H_
50#include <sys/biotrack.h>
51#endif
52
53#ifndef _SYS_SPINLOCK_H_
54#include <sys/spinlock.h>
55#endif
56
57#ifndef _SYS_TREE_H_
58#include <sys/tree.h>
59#endif
60
61#ifndef _SYS_DSCHED_H_
62#include <sys/dsched.h>
63#endif
64
65#ifndef _DSCHED_BFQ_WF2Q_H_
66#include <kern/dsched/bfq/wf2q.h>
67#endif
68
69struct wf2q_t;
70
71struct bfq_thread_io {
72 struct dsched_thread_io head;
73 RB_ENTRY(bfq_thread_io) entry;
74 int budget; /* The budget of a thread */
75 int vd; /* Virtual deadline (finish time) */
76 int ve; /* Virtual eligible time (start time) */
77 int min_vd; /* Minimum vd among the sub trees, used for augmented rb-tree */
78 int weight; /* Weight of the thread, the higher, the more
79 chance to be dispatched the thread will have */
80
81 volatile int maybe_timeout; /* a flag indicating that the tdio may
82 expire, only when active_tdio = this is it valid */
83 int tdio_as_switch;
84
85 /* Statistic data */
86 off_t last_seek_end; /* the end point of seeking of the last bio
87 pushed down */
88 uint32_t seek_samples; /* averange seek length samples */
89 off_t seek_avg; /* averange seek length, fixed point */
90 off_t seek_total;
91
92 uint32_t ttime_samples; /* averange think time samples */
93 uint64_t ttime_avg; /* averange think time, usec */
94 uint64_t ttime_total;
95
96 struct timeval service_start_time; /* the time when the first request
97 of the current service period is dispatched */
98 struct timeval last_request_done_time; /* the time when the last
99 request is done */
100 struct timeval as_start_time; /* the start time of AS waiting */
101 struct timeval last_bio_pushed_time;
102
103 uint32_t service_received; /* the amount of read/write during
104 the time slice */
105 uint32_t bio_dispatched; /* number of bios dispatched during
106 the current period */
107 uint32_t bio_completed; /* number of bios completed during
108 the current period */
109};
110
111struct bfq_disk_ctx {
112 struct dsched_disk_ctx head;
113
114 struct lock bfq_lock;
115
116 struct callout bfq_callout; /* the blocking-timer callout */
117 struct wf2q_t bfq_wf2q; /* the wf2q scheduler */
118
119 struct bfq_thread_io *bfq_blockon; /* waiting on any */
120 struct bfq_thread_io *bfq_active_tdio; /* currently active tdio */
121
122 int pending_dequeue; /* number of dequeue() calls pending
123 on BFQ_LOCK */
124
125 int bfq_max_budget;
126 int bfq_remaining_budget; /* remaining budget of the current tdio */
127
128 uint32_t bfq_flag; /* SEE BFQ_FLAG_* define for all flags */
129
130 /* Statistic data */
131 uint32_t bfq_peak_rate_samples; /* peak rate samples */
132 uint64_t bfq_peak_rate; /* peak rate, fixed point */
133
134 int bfq_as_miss;
135 int bfq_as_hit;
136
137 uint32_t bfq_as_avg_wait_miss; /* average AS waiting time for
138 only AS miss, ms */
139 uint32_t bfq_as_avg_wait_all; /* average AS waiting time for all, ms */
140 uint32_t bfq_as_max_wait; /* maximum AS waiting time, ms */
141 uint32_t bfq_as_max_wait2; /* maximum AS waiting time(from callout), ms */
142
143 int bfq_as_high_wait_count; /* the number of times when AS waiting time
144 is longer than 5 * BFQ_T_WAIT_MIN (50ms now) */
145 int bfq_as_high_wait_count2; /* the number of times when AS waiting
146 time is longer than 5 * BFQ_T_WAIT_MIN (50ms now) */
147
148 uint32_t bfq_avg_time_slice; /* average time slice length, ms */
149 uint32_t bfq_max_time_slice; /* maximum time slice length, ms */
150 int bfq_high_time_slice_count; /* the number of times when a time slice
151 is longer than 5 * BFQ_SLICE_TIMEOUT */
152
153 struct sysctl_ctx_list bfq_sysctl_ctx; /* bfq statistics interface
154 with sysctl */
155 /* helper thread and its lwkt message cache and port*/
156 struct thread *helper_thread;
157 struct objcache *helper_msg_cache;
158 struct lwkt_port helper_msg_port;
159};
160
161enum bfq_expire_reason {
162 BFQ_REASON_TIMEOUT = 0,
163 BFQ_REASON_TOO_IDLE,
164 BFQ_REASON_OUT_OF_BUDGET,
165 BFQ_REASON_NO_MORE_REQ
166};
167
168#define BFQ_FLAG_AS 0x01
169#define BFQ_FLAG_AUTO_MAX_BUDGET 0x02
170
171#define BFQ_TDIO_SEEKY(x) (((x)->seek_avg) > (1024 * SECT_SIZE))
172
173#define BFQ_LOCKINIT(x) \
174 lockinit(&(x)->bfq_lock, "bfqwf2q", 0, LK_CANRECURSE);
175
176#define BFQ_LOCK(x) do { \
177 dsched_disk_ctx_ref(&(x)->head); \
178 lockmgr(&(x)->bfq_lock, LK_EXCLUSIVE); \
179 } while(0)
180
181#define BFQ_UNLOCK(x) do { \
182 lockmgr(&(x)->bfq_lock, LK_RELEASE); \
183 dsched_disk_ctx_unref(&(x)->head); \
184 } while(0)
185
186#define SECT_SIZE 512 /* XXX: DEV_BSIZE? */
187#define BFQ_DEBUG_CRITICAL 1
188#define BFQ_DEBUG_NORMAL 2
189#define BFQ_DEBUG_VERBOSE 3
190#define BFQ_DEFAULT_MAX_BUDGET (1024*512) /* 1024 sectors / 0.2sec */
191#define BFQ_DEFAULT_MIN_BUDGET (32*512) /* 32 sectors / 0.2sec */
192#define BFQ_BUDG_INC_STEP (1*128*512) /* The linear increasing step of budget */
193
194/* If the budget is larger than this threshold,
195 * it will get linear increment, else,
196 * it will get exponential increment.*/
197#define BFQ_BUDGET_MULTIPLE_THRESHOLD (256*512)
198
199#define BFQ_DEFAULT_WEIGHT 1
200
201/* Get the size of a bio */
202#define BIO_SIZE(x) ((x)->bio_buf->b_bcount)
203
204/* Anticipatory waiting time (ticks) ~ 20ms, min ~ 10ms */
205#define BFQ_T_WAIT ((hz/50) > 5 ? (hz/50) : 5)
206
207#define BFQ_T_WAIT_MIN ((hz/100 > 0) ? (hz/100) : 1)
208
209/* Time slice for each service period ~200ms (ticks) */
210#define BFQ_SLICE_TIMEOUT (hz/5)
211
212#define BFQ_FIXPOINT_SHIFT 10 /* fixed point arithmetic shift */
213
214#define BFQ_VALID_MIN_SAMPLES 80 /* minimum number of samples */
215
216#define ABS(x) (((x) < 0) ? (-(x)) : (x))
217
218/* as statistics define */
219#define BFQ_AS_STAT_ALL 0x1
220#define BFQ_AS_STAT_ONLY_MISS 0x2
221
222/* functions helper thread calls */
223void bfq_timeout(void *);
224void bfq_dequeue(struct dsched_disk_ctx *);
225void bfq_helper_destroy_tdio(struct dsched_thread_io *, struct bfq_disk_ctx *);
226
227/* sysctl handlers, registered in the helper thread */
228int bfq_sysctl_as_switch_handler(SYSCTL_HANDLER_ARGS);
229int bfq_sysctl_auto_max_budget_handler(SYSCTL_HANDLER_ARGS);
230
231#endif /* _KERNEL || _KERNEL_STRUCTURES */
232struct dsched_bfq_stats {
233 int32_t as_missed;
234 int32_t as_hit;
235 int32_t as_fake;
236 int32_t unused;
237};
238#endif /*_DSCHED_BFQ_H_ */