]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/geom/sched/g_sched.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / geom / sched / g_sched.h
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_ */