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