This commit was generated by cvs2svn to compensate for changes in r632,
[linux-2.6.git] / include / linux / ckrm_rc.h
1 /*
2  *  ckrm_rc.h - Header file to be used by Resource controllers of CKRM
3  *
4  * Copyright (C) Hubertus Franke, IBM Corp. 2003
5  *           (C) Shailabh Nagar,  IBM Corp. 2003
6  *           (C) Chandra Seetharaman, IBM Corp. 2003
7  *           (C) Vivek Kashyap , IBM Corp. 2004
8  * 
9  * Provides data structures, macros and kernel API of CKRM for 
10  * resource controllers.
11  *
12  * More details at http://ckrm.sf.net
13  * 
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  */
20
21 /*
22  * Changes
23  *
24  * 12 Nov 2003
25  *        Created.
26  */
27
28 #ifndef _LINUX_CKRM_RC_H
29 #define _LINUX_CKRM_RC_H
30
31 #ifdef __KERNEL__
32
33 #ifdef CONFIG_CKRM
34
35 #include <linux/list.h>
36 #include <linux/ckrm_events.h>
37 #include <linux/ckrm_ce.h>
38 #include <linux/seq_file.h>
39
40 #define CKRM_MAX_CLASSTYPES         32  /* maximum number of class types */
41 #define CKRM_MAX_CLASSTYPE_NAME     32  /* maximum classtype name length */
42
43 #define CKRM_MAX_RES_CTLRS           8  /* maximum resource controllers per classtype */
44 #define CKRM_MAX_RES_NAME          128  /* maximum resource controller name length */
45
46 struct ckrm_core_class;
47 struct ckrm_classtype;
48
49 /*
50  * Share specifications
51  */
52
53 typedef struct ckrm_shares {
54         int my_guarantee;
55         int my_limit;
56         int total_guarantee;
57         int max_limit;
58         int unused_guarantee;   /* not used as parameters */
59         int cur_max_limit;      /* not used as parameters */
60 } ckrm_shares_t;
61
62 #define CKRM_SHARE_UNCHANGED     (-1)   
63 #define CKRM_SHARE_DONTCARE      (-2)   
64 #define CKRM_SHARE_DFLT_TOTAL_GUARANTEE (100) 
65 #define CKRM_SHARE_DFLT_MAX_LIMIT     (100)  
66
67 /*
68  * RESOURCE CONTROLLERS
69  */
70
71 /* resource controller callback structure */
72
73 typedef struct ckrm_res_ctlr {
74         char res_name[CKRM_MAX_RES_NAME];
75         int res_hdepth;         /* maximum hierarchy */
76         int resid;              /* (for now) same as the enum resid */
77         struct ckrm_classtype *classtype;    /* classtype owning this res ctlr */
78
79         /* allocate/free new resource class object for resource controller */
80         void *(*res_alloc) (struct ckrm_core_class * this,
81                             struct ckrm_core_class * parent);
82         void (*res_free) (void *);
83
84         /* set/get limits/guarantees for a resource controller class */
85         int (*set_share_values) (void *, struct ckrm_shares * shares);
86         int (*get_share_values) (void *, struct ckrm_shares * shares);
87
88         /* statistics and configuration access */
89         int (*get_stats) (void *, struct seq_file *);
90         int (*reset_stats) (void *);
91         int (*show_config) (void *, struct seq_file *);
92         int (*set_config) (void *, const char *cfgstr);
93
94         void (*change_resclass) (void *, void *, void *);
95 } ckrm_res_ctlr_t;
96
97 /*
98  * CKRM_CLASSTYPE
99  *
100  * A <struct ckrm_classtype> object describes a dimension for CKRM to classify 
101  * along. Need to provide methods to create and manipulate class objects in
102  * this dimension
103  */
104
105 /* list of predefined class types, we always recognize */
106 #define CKRM_CLASSTYPE_TASK_CLASS    0
107 #define CKRM_CLASSTYPE_SOCKET_CLASS  1
108 #define CKRM_RESV_CLASSTYPES         2  /* always +1 of last known type */
109
110 #define CKRM_MAX_TYPENAME_LEN       32
111
112 typedef struct ckrm_classtype {
113         /* TODO: Review for cache alignment */
114
115         /* resource controllers */
116
117         spinlock_t res_ctlrs_lock;  /* protect res ctlr related data */
118         int max_res_ctlrs;          /* max number of res ctlrs allowed */
119         int max_resid;              /* max resid used */
120         int resid_reserved;         /* max number of reserved controllers */
121         long bit_res_ctlrs;         /* bitmap of resource ID used */
122         atomic_t nr_resusers[CKRM_MAX_RES_CTLRS];
123         ckrm_res_ctlr_t *res_ctlrs[CKRM_MAX_RES_CTLRS];
124
125         /* state about my classes */
126
127         struct ckrm_core_class *default_class;  
128         struct list_head classes;  /* link all classes of this classtype */
129         int num_classes;         
130
131         /* state about my ce interaction */
132         atomic_t ce_regd;               /* if CE registered */
133         int ce_cb_active;               /* if Callbacks active */
134         atomic_t ce_nr_users;           /* number of active transient calls */
135         struct ckrm_eng_callback ce_callbacks;  /* callback engine */
136
137         /* Begin classtype-rcfs private data. No rcfs/fs specific types used.  */
138
139         int mfidx;              /* Index into genmfdesc array used to initialize */
140         void *mfdesc;           /* Array of descriptors of root and magic files */
141         int mfcount;            /* length of above array */
142         void *rootde;           /* root dentry created by rcfs */
143         /* End rcfs private data */
144
145         char name[CKRM_MAX_TYPENAME_LEN]; /* currently same as mfdesc[0]->name  */
146                                           /* but could be different */
147         int typeID;                       /* unique TypeID */
148         int maxdepth;                     /* maximum depth supported */
149
150         /* functions to be called on any class type by external API's */
151
152         struct ckrm_core_class *(*alloc) (struct ckrm_core_class * parent, 
153                                           const char *name);    
154         int (*free) (struct ckrm_core_class * cls);     
155         int (*show_members) (struct ckrm_core_class *, struct seq_file *);
156         int (*show_stats) (struct ckrm_core_class *, struct seq_file *);
157         int (*show_config) (struct ckrm_core_class *, struct seq_file *);
158         int (*show_shares) (struct ckrm_core_class *, struct seq_file *);
159
160         int (*reset_stats) (struct ckrm_core_class *, const char *resname,
161                             const char *);
162         int (*set_config) (struct ckrm_core_class *, const char *resname,
163                            const char *cfgstr);
164         int (*set_shares) (struct ckrm_core_class *, const char *resname,
165                            struct ckrm_shares * shares);
166         int (*forced_reclassify) (struct ckrm_core_class *, const char *);
167
168         /* functions to be called on a class type by ckrm internals */
169
170         /* class initialization for new RC */
171         void (*add_resctrl) (struct ckrm_core_class *, int resid);      
172 } ckrm_classtype_t;
173
174 /*
175  * CKRM CORE CLASS
176  *      common part to any class structure (i.e. instance of a classtype)
177  */
178
179 /*
180  * basic definition of a hierarchy that is to be used by the the CORE classes
181  * and can be used by the resource class objects
182  */
183
184 #define CKRM_CORE_MAGIC         0xBADCAFFE
185
186 typedef struct ckrm_hnode {
187         struct ckrm_core_class *parent;
188         struct list_head siblings;      
189         struct list_head children;      
190 } ckrm_hnode_t;
191
192 typedef struct ckrm_core_class {
193         struct ckrm_classtype *classtype;       
194         void *res_class[CKRM_MAX_RES_CTLRS];    /* resource classes */
195         spinlock_t class_lock;                  /* protects list,array above */
196
197         struct list_head objlist;               /* generic object list */
198         struct list_head clslist;               /* peer classtype classes */
199         struct dentry *dentry;                  /* dentry of inode in the RCFS */
200         int magic;
201
202         struct ckrm_hnode hnode;                /* hierarchy */
203         rwlock_t hnode_rwlock;                  /* protects hnode above. */
204         atomic_t refcnt;
205         const char *name;
206         int delayed;                            /* core deletion delayed  */
207                                                 /* because of race conditions */
208 } ckrm_core_class_t;
209
210 /* type coerce between derived class types and ckrm core class type */
211 #define class_type(type,coreptr)   container_of(coreptr,type,core)
212 #define class_core(clsptr)         (&(clsptr)->core)
213 /* locking classes */
214 #define class_lock(coreptr)        spin_lock(&(coreptr)->class_lock)
215 #define class_unlock(coreptr)      spin_unlock(&(coreptr)->class_lock)
216 /* what type is a class of ISA */
217 #define class_isa(clsptr)          (class_core(clsptr)->classtype)
218
219 /*
220  * OTHER
221  */
222
223 #define ckrm_get_res_class(rescls, resid, type) \
224         ((type*) (((resid != -1) && ((rescls) != NULL) \
225                            && ((rescls) != (void *)-1)) ? \
226          ((struct ckrm_core_class *)(rescls))->res_class[resid] : NULL))
227
228
229 extern int ckrm_register_res_ctlr(struct ckrm_classtype *, ckrm_res_ctlr_t *);
230 extern int ckrm_unregister_res_ctlr(ckrm_res_ctlr_t *);
231
232 extern int ckrm_validate_and_grab_core(struct ckrm_core_class *core);
233 extern int ckrm_init_core_class(struct ckrm_classtype *clstype,
234                                 struct ckrm_core_class *dcore,
235                                 struct ckrm_core_class *parent,
236                                 const char *name);
237 extern int ckrm_release_core_class(struct ckrm_core_class *);   
238
239 /* TODO: can disappear after cls del debugging */
240
241 extern struct ckrm_res_ctlr *ckrm_resctlr_lookup(struct ckrm_classtype *type,
242                                                  const char *resname);
243
244 extern void ckrm_lock_hier(struct ckrm_core_class *);
245 extern void ckrm_unlock_hier(struct ckrm_core_class *);
246 extern struct ckrm_core_class *ckrm_get_next_child(struct ckrm_core_class *,
247                                                    struct ckrm_core_class *);
248
249 extern void child_guarantee_changed(struct ckrm_shares *, int, int);
250 extern void child_maxlimit_changed(struct ckrm_shares *, int);
251 extern int set_shares(struct ckrm_shares *, struct ckrm_shares *,
252                       struct ckrm_shares *);
253
254 /* classtype registration and lookup */
255 extern int ckrm_register_classtype(struct ckrm_classtype *clstype);
256 extern int ckrm_unregister_classtype(struct ckrm_classtype *clstype);
257 extern struct ckrm_classtype *ckrm_find_classtype_by_name(const char *name);
258
259 /* default functions that can be used in classtypes's function table */
260 extern int ckrm_class_show_shares(struct ckrm_core_class *core,
261                                   struct seq_file *seq);
262 extern int ckrm_class_show_stats(struct ckrm_core_class *core,
263                                  struct seq_file *seq);
264 extern int ckrm_class_show_config(struct ckrm_core_class *core,
265                                   struct seq_file *seq);
266 extern int ckrm_class_set_config(struct ckrm_core_class *core,
267                                  const char *resname, const char *cfgstr);
268 extern int ckrm_class_set_shares(struct ckrm_core_class *core,
269                                  const char *resname,
270                                  struct ckrm_shares *shares);
271 extern int ckrm_class_reset_stats(struct ckrm_core_class *core,
272                                   const char *resname, const char *unused);
273
274 static inline void ckrm_core_grab(struct ckrm_core_class *core)
275 {
276         if (core)
277                 atomic_inc(&core->refcnt);
278 }
279
280 static inline void ckrm_core_drop(struct ckrm_core_class *core)
281 {
282         /* only make definition available in this context */
283         extern void ckrm_free_core_class(struct ckrm_core_class *core);
284         if (core && (atomic_dec_and_test(&core->refcnt)))
285                 ckrm_free_core_class(core);
286 }
287
288 static inline unsigned int ckrm_is_core_valid(ckrm_core_class_t * core)
289 {
290         return (core && (core->magic == CKRM_CORE_MAGIC));
291 }
292
293 /*
294  * iterate through all associate resource controllers:
295  * requires following arguments (ckrm_core_class *cls, 
296  *                               ckrm_res_ctrl   *ctlr,
297  *                               void            *robj,
298  *                               int              bmap)
299  */
300
301 #define forall_class_resobjs(cls,rcbs,robj,bmap)                        \
302        for ( bmap=((cls->classtype)->bit_res_ctlrs) ;                   \
303              ({ int rid; ((rid=ffs(bmap)-1) >= 0) &&                    \
304                          (bmap &= ~(1<<rid),                            \
305                                 ((rcbs=cls->classtype->res_ctlrs[rid])  \
306                                  && (robj=cls->res_class[rid]))); });   \
307            )
308
309 extern struct ckrm_classtype *ckrm_classtypes[];        
310
311 /*
312  * CE Invocation interface
313  */
314
315 #define ce_protect(ctype)      (atomic_inc(&((ctype)->ce_nr_users)))
316 #define ce_release(ctype)      (atomic_dec(&((ctype)->ce_nr_users)))
317
318 /* CE Classification callbacks with */
319
320 #define CE_CLASSIFY_NORET(ctype, event, objs_to_classify...)            \
321 do {                                                                    \
322         if ((ctype)->ce_cb_active                                       \
323             && (test_bit(event,&(ctype)->ce_callbacks.c_interest)))     \
324                 (*(ctype)->ce_callbacks.classify)(event,                \
325                                                   objs_to_classify);    \
326 } while (0)
327
328 #define CE_CLASSIFY_RET(ret, ctype, event, objs_to_classify...)         \
329 do {                                                                    \
330         if ((ctype)->ce_cb_active                                       \
331             && (test_bit(event,&(ctype)->ce_callbacks.c_interest)))     \
332                 ret = (*(ctype)->ce_callbacks.classify)(event,          \
333                                                         objs_to_classify);\
334 } while (0)
335
336 #define CE_NOTIFY(ctype, event, cls, objs_to_classify)                  \
337 do {                                                                    \
338         if ((ctype)->ce_cb_active                                       \
339             && (test_bit(event,&(ctype)->ce_callbacks.n_interest)))     \
340                 (*(ctype)->ce_callbacks.notify)(event,                  \
341                                                 cls,objs_to_classify);  \
342 } while (0)
343
344 /*
345  * RCFS related 
346  */
347
348 /* vars needed by other modules/core */
349
350 extern int rcfs_mounted;
351 extern int rcfs_engine_regd;
352
353 #endif /* CONFIG_CKRM */
354 #endif /* __KERNEL__ */
355 #endif /* _LINUX_CKRM_RC_H */