xref: /trueos/sys/geom/sched/g_sched.h (revision 8fe640108653f13042f1b15213769e338aa524f6)
1 /*-
2  * Copyright (c) 2009-2010 Fabio Checconi
3  * Copyright (c) 2009-2010 Luigi Rizzo, Universita` di Pisa
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #ifndef	_G_SCHED_H_
29 #define	_G_SCHED_H_
30 
31 /*
32  * $Id$
33  * $FreeBSD$
34  *
35  * Header for the geom_sched class (userland library and kernel part).
36  * See g_sched.c for documentation.
37  * The userland code only needs the three G_SCHED_* values below.
38  */
39 
40 #define	G_SCHED_CLASS_NAME	"SCHED"
41 #define	G_SCHED_VERSION		0
42 #define	G_SCHED_SUFFIX		".sched."
43 
44 #ifdef _KERNEL
45 #define	G_SCHED_DEBUG(lvl, ...)	do {				\
46 	if (me.gs_debug >= (lvl)) {				\
47 		printf("GEOM_SCHED");				\
48 		if (me.gs_debug > 0)				\
49 			printf("[%u]", lvl);			\
50 		printf(": ");					\
51 		printf(__VA_ARGS__);				\
52 		printf("\n");					\
53 	}							\
54 } while (0)
55 
56 #define	G_SCHED_LOGREQ(bp, ...)	do {				\
57 	if (me.gs_debug >= 2) {					\
58 		printf("GEOM_SCHED[2]: ");			\
59 		printf(__VA_ARGS__);				\
60 		printf(" ");					\
61 		g_print_bio(bp);				\
62 		printf("\n");					\
63 	}							\
64 } while (0)
65 
66 LIST_HEAD(g_hash, g_sched_class);
67 
68 /*
69  * Descriptor of a scheduler.
70  * In addition to the obvious fields, sc_flushing and sc_pending
71  * support dynamic switching of scheduling algorithm.
72  * Normally, sc_flushing is 0, and requests that are scheduled are
73  * also added to the sc_pending queue, and removed when we receive
74  * the 'done' event.
75  *
76  * When we are transparently inserted on an existing provider,
77  * sc_proxying is set. The detach procedure is slightly different.
78  *
79  * When switching schedulers, sc_flushing is set so requests bypass us,
80  * and at the same time we update the pointer in the pending bios
81  * to ignore us when they return up.
82  * XXX it would be more efficient to implement sc_pending with
83  * a generation number: the softc generation is increased when
84  * we change scheduling algorithm, we store the current generation
85  * number in the pending bios, and when they come back we ignore
86  * the done() call if the generation number do not match.
87  */
88 struct g_sched_softc {
89 	/*
90 	 * Generic fields used by any scheduling algorithm:
91 	 * a mutex, the class descriptor, flags, list of pending
92 	 * requests (used when flushing the module) and support
93 	 * for hash tables where we store per-flow queues.
94 	 */
95 	struct mtx	sc_mtx;
96 	struct g_gsched	*sc_gsched;	/* Scheduler descriptor. */
97 	int		sc_pending;	/* Pending requests. */
98 	int		sc_flags;	/* Various flags. */
99 
100 	/*
101 	 * Hash tables to store per-flow queues are generally useful
102 	 * so we handle them in the common code.
103 	 * sc_hash and sc_mask are parameters of the hash table,
104 	 * the last two fields are used to periodically remove
105 	 * expired items from the hash table.
106 	 */
107 	struct g_hash	*sc_hash;
108 	u_long		sc_mask;
109 	int		sc_flush_ticks;	/* Next tick for a flush. */
110 	int		sc_flush_bucket; /* Next bucket to flush. */
111 
112 	/*
113 	 * Pointer to the algorithm's private data, which is the value
114 	 * returned by sc_gsched->gs_init() . A NULL here means failure.
115 	 * XXX intptr_t might be more appropriate.
116 	 */
117 	void		*sc_data;
118 };
119 
120 #define	G_SCHED_PROXYING	1
121 #define	G_SCHED_FLUSHING	2
122 
123 /*
124  * Temporary- our own version of the disksort, because the
125  * version in 7.x and 8.x before march 2009 is buggy.
126  */
127 void gs_bioq_init(struct bio_queue_head *);
128 void gs_bioq_remove(struct bio_queue_head *, struct bio *);
129 void gs_bioq_flush(struct bio_queue_head *, struct devstat *, int);
130 void gs_bioq_insert_head(struct bio_queue_head *, struct bio *);
131 void gs_bioq_insert_tail(struct bio_queue_head *, struct bio *);
132 struct bio *gs_bioq_first(struct bio_queue_head *);
133 struct bio *gs_bioq_takefirst(struct bio_queue_head *);
134 void gs_bioq_disksort(struct bio_queue_head *, struct bio *);
135 
136 #endif	/* _KERNEL */
137 
138 #endif	/* _G_SCHED_H_ */
139