This commit was manufactured by cvs2svn to create branch 'ckrm'.
[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
39 /* maximum number of class types */
40 #define CKRM_MAX_CLASSTYPES         32       
41 /* maximum classtype name length */
42 #define CKRM_MAX_CLASSTYPE_NAME     32       
43
44 /* maximum resource controllers per classtype */
45 #define CKRM_MAX_RES_CTLRS           8     
46 /* maximum resource controller name length */
47 #define CKRM_MAX_RES_NAME          128       
48
49
50 struct ckrm_core_class;
51 struct ckrm_classtype;
52
53 /********************************************************************************
54  * Share specifications
55  *******************************************************************************/
56
57 typedef struct ckrm_shares {
58         int my_guarantee;
59         int my_limit;
60         int total_guarantee;
61         int max_limit;
62         int unused_guarantee;  // not used as parameters
63         int cur_max_limit;     // not used as parameters
64 } ckrm_shares_t;
65
66 #define CKRM_SHARE_UNCHANGED     (-1)  // value to indicate no change
67 #define CKRM_SHARE_DONTCARE      (-2)  // value to indicate don't care.
68 #define CKRM_SHARE_DFLT_TOTAL_GUARANTEE (100) // Start off with these values
69 #define CKRM_SHARE_DFLT_MAX_LIMIT     (100) // to simplify set_res_shares logic
70
71
72 /********************************************************************************
73  * RESOURCE CONTROLLERS
74  *******************************************************************************/
75
76 /* resource controller callback structure */
77
78 typedef struct ckrm_res_ctlr {
79         char res_name[CKRM_MAX_RES_NAME];
80         int  res_hdepth;                  // maximum hierarchy
81         int  resid;                       // (for now) same as the enum resid
82         struct ckrm_classtype *classtype; // classtype owning this resource controller
83
84         /* allocate/free new resource class object for resource controller */
85         void *(*res_alloc)  (struct ckrm_core_class *this, struct ckrm_core_class *parent);
86         void  (*res_free)   (void *);
87
88         /* set/get limits/guarantees for a resource controller class */
89         int  (*set_share_values) (void* , struct ckrm_shares *shares);
90         int  (*get_share_values) (void* , struct ckrm_shares *shares);
91
92         /* statistics and configuration access */
93         int  (*get_stats)    (void* , struct seq_file *);
94         int  (*reset_stats)  (void *);
95         int  (*show_config)  (void* , struct seq_file *);
96         int  (*set_config)   (void* , const char *cfgstr);
97
98         void (*change_resclass)(void *, void *, void *);
99
100 } ckrm_res_ctlr_t;
101
102 /***************************************************************************************
103  * CKRM_CLASSTYPE
104  *
105  *   A <struct ckrm_classtype> object describes a dimension for CKRM to classify 
106  *   along. I needs to provide methods to create and manipulate class objects in
107  *   this dimension
108  ***************************************************************************************/
109
110 /* list of predefined class types, we always recognize */
111 #define CKRM_CLASSTYPE_TASK_CLASS    0
112 #define CKRM_CLASSTYPE_SOCKET_CLASS 1
113 #define CKRM_RESV_CLASSTYPES         2  /* always +1 of last known type */
114
115 #define CKRM_MAX_TYPENAME_LEN       32
116
117
118 typedef struct ckrm_classtype {
119         /* Hubertus:   Rearrange slots so that they are more cache friendly during access */
120
121         /* resource controllers */
122         spinlock_t        res_ctlrs_lock;        /* protect data below (other than atomics) */
123         int               max_res_ctlrs;         /* maximum number of resource controller allowed */
124         int               max_resid;             /* maximum resid used                      */
125         int               resid_reserved;        /* maximum number of reserved controllers  */
126         long              bit_res_ctlrs;         /* bitmap of resource ID used              */
127         atomic_t          nr_resusers[CKRM_MAX_RES_CTLRS];
128         ckrm_res_ctlr_t*  res_ctlrs[CKRM_MAX_RES_CTLRS];
129
130         /* state about my classes */
131
132         struct ckrm_core_class   *default_class; // pointer to default class
133         struct list_head          classes;       // listhead to link up all classes of this classtype
134         int                       num_classes;    // how many classes do exist
135
136         /* state about my ce interaction */
137         int                       ce_regd;       // Has a CE been registered for this classtype
138         int                       ce_cb_active;  // are callbacks active
139         atomic_t                  ce_nr_users;   // how many transient calls active
140         struct ckrm_eng_callback  ce_callbacks;  // callback engine
141
142         // Begin classtype-rcfs private data. No rcfs/fs specific types used. 
143         int               mfidx;             // Index into genmfdesc array used to initialize
144                                              // mfdesc and mfcount 
145         void              *mfdesc;           // Array of descriptors of root and magic files
146         int               mfcount;           // length of above array 
147         void              *rootde;           // root dentry created by rcfs
148         // End rcfs private data 
149
150         char name[CKRM_MAX_TYPENAME_LEN];    // currently same as mfdesc[0]->name but could be different
151         int  typeID;                           /* unique TypeID                         */
152         int  maxdepth;                         /* maximum depth supported               */
153
154         /* functions to be called on any class type by external API's */
155         struct ckrm_core_class*  (*alloc)(struct ckrm_core_class *parent, const char *name);   /* alloc class instance */
156         int                      (*free) (struct ckrm_core_class *cls);                        /* free  class instance */
157         
158         int                      (*show_members)(struct ckrm_core_class *, struct seq_file *);
159         int                      (*show_stats)  (struct ckrm_core_class *, struct seq_file *);
160         int                      (*show_config) (struct ckrm_core_class *, struct seq_file *);
161         int                      (*show_shares) (struct ckrm_core_class *, struct seq_file *);
162
163         int                      (*reset_stats) (struct ckrm_core_class *, const char *resname, 
164                                                  const char *);
165         int                      (*set_config)  (struct ckrm_core_class *, const char *resname,
166                                                  const char *cfgstr);
167         int                      (*set_shares)  (struct ckrm_core_class *, const char *resname,
168                                                  struct ckrm_shares *shares);
169         int                      (*forced_reclassify)(struct ckrm_core_class *, const char *);
170
171   
172         /* functions to be called on a class type by ckrm internals */
173         void                     (*add_resctrl)(struct ckrm_core_class *, int resid);     // class initialization for new RC
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; /* linked list of siblings */
191         struct list_head   children; /* anchor for children     */
192 } ckrm_hnode_t;
193
194 typedef struct ckrm_core_class {
195         struct ckrm_classtype *classtype; // what type does this core class belong to
196         void* res_class[CKRM_MAX_RES_CTLRS];                 // pointer to array of resource classes
197         spinlock_t class_lock;             // to protect the list and the array above
198         struct list_head objlist;         // generic list for any object list to be maintained by class
199         struct list_head clslist;         // to link up all classes in a single list type wrt to type
200         struct dentry  *dentry;           // dentry of inode in the RCFS
201         int magic;
202         struct ckrm_hnode  hnode;    // hierarchy
203         rwlock_t hnode_rwlock; // rw_clock protecting the hnode above.
204         atomic_t refcnt;
205         const char *name;
206         int delayed;                      // core deletion delayed because of race conditions
207 } ckrm_core_class_t;
208
209 /* type coerce between derived class types and ckrm core class type */
210 #define class_type(type,coreptr)   container_of(coreptr,type,core)
211 #define class_core(clsptr)         (&(clsptr)->core)
212 /* locking classes */
213 #define class_lock(coreptr)        spin_lock(&(coreptr)->class_lock)
214 #define class_unlock(coreptr)      spin_unlock(&(coreptr)->class_lock)
215 /* what type is a class of ISA */
216 #define class_isa(clsptr)          (class_core(clsptr)->classtype)
217
218
219 /******************************************************************************************
220  * OTHER
221  ******************************************************************************************/
222
223 #define ckrm_get_res_class(rescls,resid,type)   ((type*)((rescls)->res_class[resid]))
224
225 extern int ckrm_register_res_ctlr   (struct ckrm_classtype *, ckrm_res_ctlr_t *);
226 extern int ckrm_unregister_res_ctlr (ckrm_res_ctlr_t *);
227
228 extern int ckrm_validate_and_grab_core(struct ckrm_core_class *core);
229 extern int ckrm_init_core_class(struct ckrm_classtype  *clstype,struct ckrm_core_class *dcore,
230                                 struct ckrm_core_class *parent, const char *name);
231 extern int ckrm_release_core_class(struct ckrm_core_class *);   // Hubertus .. can disappear after cls del debugging
232 extern struct ckrm_res_ctlr *ckrm_resctlr_lookup(struct ckrm_classtype *type, const char *resname);
233
234 #if 0
235
236 // Hubertus ... need to straighten out all these I don't think we will even call thsie ore are we 
237
238 /* interface to the RCFS filesystem */
239 extern struct ckrm_core_class *ckrm_alloc_core_class(struct ckrm_core_class *, const char *, int);
240
241 // Reclassify the given pid to the given core class by force
242 extern void ckrm_forced_reclassify_pid(int, struct ckrm_core_class *);
243
244 // Reclassify the given net_struct  to the given core class by force
245 extern void ckrm_forced_reclassify_laq(struct ckrm_net_struct *, 
246                 struct ckrm_core_class *);
247
248 #endif
249
250 extern void ckrm_lock_hier(struct ckrm_core_class *);
251 extern void ckrm_unlock_hier(struct ckrm_core_class *);
252 extern struct ckrm_core_class * ckrm_get_next_child(struct ckrm_core_class *,
253                             struct ckrm_core_class *);
254
255 extern void child_guarantee_changed(struct ckrm_shares *, int, int);
256 extern void child_maxlimit_changed(struct ckrm_shares *, int);
257 extern int  set_shares(struct ckrm_shares *, struct ckrm_shares *, struct ckrm_shares *);
258
259 /* classtype registration and lookup */
260 extern int ckrm_register_classtype  (struct ckrm_classtype *clstype);
261 extern int ckrm_unregister_classtype(struct ckrm_classtype *clstype);
262 extern struct ckrm_classtype* ckrm_find_classtype_by_name(const char *name);
263
264 /* default functions that can be used in classtypes's function table */
265 extern int ckrm_class_show_shares(struct ckrm_core_class *core, struct seq_file *seq);
266 extern int ckrm_class_show_stats(struct ckrm_core_class *core, struct seq_file *seq);
267 extern int ckrm_class_show_config(struct ckrm_core_class *core, struct seq_file *seq);
268 extern int ckrm_class_set_config(struct ckrm_core_class *core, const char *resname, const char *cfgstr);
269 extern int ckrm_class_set_shares(struct ckrm_core_class *core, const char *resname, struct ckrm_shares *shares);
270 extern int ckrm_class_reset_stats(struct ckrm_core_class *core, const char *resname, const char *unused);
271
272 #if 0
273 extern void ckrm_ns_hold(struct ckrm_net_struct *);
274 extern void ckrm_ns_put(struct ckrm_net_struct *);
275 extern void *ckrm_set_rootcore_byname(char *, void *);
276 #endif
277
278 static inline void ckrm_core_grab(struct ckrm_core_class *core)  
279
280         if (core) atomic_inc(&core->refcnt);
281 }
282
283 static inline void ckrm_core_drop(struct ckrm_core_class *core) 
284
285         // only make definition available in this context
286         extern void ckrm_free_core_class(struct ckrm_core_class *core);   
287         if (core && (atomic_dec_and_test(&core->refcnt)))
288             ckrm_free_core_class(core);
289 }
290
291 static inline unsigned int
292 ckrm_is_core_valid(ckrm_core_class_t *core)
293 {
294         return (core && (core->magic == CKRM_CORE_MAGIC));
295 }
296
297 // iterate through all associate resource controllers:
298 // requires following arguments (ckrm_core_class *cls, 
299 //                               ckrm_res_ctrl   *ctlr,
300 //                               void            *robj,
301 //                               int              bmap)
302 #define forall_class_resobjs(cls,rcbs,robj,bmap)                                                                        \
303        for ( bmap=((cls->classtype)->bit_res_ctlrs) ;                                                                   \
304              ({ int rid; ((rid=ffs(bmap)-1) >= 0) &&                                                                    \
305                          (bmap&=~(1<<rid),((rcbs=cls->classtype->res_ctlrs[rid]) && (robj=cls->res_class[rid]))); }) ;  \
306            )
307
308 extern struct ckrm_classtype* ckrm_classtypes[]; /* should provide a different interface */
309
310
311 /*-----------------------------------------------------------------------------
312  * CKRM event callback specification for the classtypes or resource controllers 
313  *   typically an array is specified using CKRM_EVENT_SPEC terminated with 
314  *   CKRM_EVENT_SPEC_LAST and then that array is registered using
315  *   ckrm_register_event_set.
316  *   Individual registration of event_cb is also possible
317  *-----------------------------------------------------------------------------*/
318
319 struct ckrm_event_spec {
320         enum ckrm_event     ev;
321         struct ckrm_hook_cb cb;
322 };
323 #define CKRM_EVENT_SPEC(EV,FCT) { CKRM_EVENT_##EV, { (ckrm_event_cb)FCT, NULL } }
324
325 int ckrm_register_event_set(struct ckrm_event_spec especs[]);
326 int ckrm_unregister_event_set(struct ckrm_event_spec especs[]);
327 int ckrm_register_event_cb(enum ckrm_event ev, struct ckrm_hook_cb *cb);
328 int ckrm_unregister_event_cb(enum ckrm_event ev, struct ckrm_hook_cb *cb);
329
330 /******************************************************************************************
331  * CE Invocation interface
332  ******************************************************************************************/
333
334 #define ce_protect(ctype)      (atomic_inc(&((ctype)->ce_nr_users)))
335 #define ce_release(ctype)      (atomic_dec(&((ctype)->ce_nr_users)))
336
337 // CE Classification callbacks with 
338
339 #define CE_CLASSIFY_NORET(ctype, event, objs_to_classify...)                                    \
340 do {                                                                                            \
341         if ((ctype)->ce_cb_active && (test_bit(event,&(ctype)->ce_callbacks.c_interest)))       \
342                 (*(ctype)->ce_callbacks.classify)(event, objs_to_classify);                     \
343 } while (0)
344
345 #define CE_CLASSIFY_RET(ret, ctype, event, objs_to_classify...)                                 \
346 do {                                                                                            \
347         if ((ctype)->ce_cb_active && (test_bit(event,&(ctype)->ce_callbacks.c_interest)))       \
348                 ret = (*(ctype)->ce_callbacks.classify)(event, objs_to_classify);               \
349 } while (0)
350
351 #define CE_NOTIFY(ctype, event, cls, objs_to_classify)                                          \
352 do {                                                                                            \
353         if ((ctype)->ce_cb_active && (test_bit(event,&(ctype)->ce_callbacks.n_interest)))       \
354                 (*(ctype)->ce_callbacks.notify)(event,cls,objs_to_classify);                    \
355 } while (0)
356
357
358 #endif // CONFIG_CKRM
359
360 #endif // __KERNEL__
361
362 #endif // _LINUX_CKRM_RC_H
363
364
365
366
367