1 /* ckrm_rc.h - Header file to be used by Resource controllers of CKRM
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
8 * Provides data structures, macros and kernel API of CKRM for
9 * resource controllers.
11 * Latest version, more details at http://ckrm.sf.net
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.
26 #ifndef _LINUX_CKRM_RC_H
27 #define _LINUX_CKRM_RC_H
33 #include <linux/list.h>
34 #include <linux/ckrm.h>
35 #include <linux/ckrm_ce.h>
36 #include <linux/seq_file.h>
38 /* maximum number of class types */
39 #define CKRM_MAX_CLASSTYPES 32
40 /* maximum classtype name length */
41 #define CKRM_MAX_CLASSTYPE_NAME 32
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
48 struct ckrm_core_class;
49 struct ckrm_classtype;
51 /*****************************************************************************
52 * Share specifications
53 *****************************************************************************/
55 typedef struct ckrm_shares {
60 int unused_guarantee; // not used as parameters
61 int cur_max_limit; // not used as parameters
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)
69 /******************************************************************************
70 * RESOURCE CONTROLLERS
71 *****************************************************************************/
73 /* resource controller callback structure */
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
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 *);
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);
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);
96 void (*change_resclass) (void *, void *, void *);
100 /******************************************************************************
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
106 *****************************************************************************/
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 */
113 #define CKRM_MAX_TYPENAME_LEN 32
115 typedef struct ckrm_classtype {
116 /* Hubertus: Rearrange slots later for cache friendliness */
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];
128 /* state about my classes */
130 struct ckrm_core_class *default_class;
131 struct list_head classes; // link all classes of this classtype
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
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
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
152 /* functions to be called on any class type by external API's */
154 struct ckrm_core_class *(*alloc) (struct ckrm_core_class * parent,
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 *);
162 int (*reset_stats) (struct ckrm_core_class *, const char *resname,
164 int (*set_config) (struct ckrm_core_class *, const char *resname,
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 *);
170 /* functions to be called on a class type by ckrm internals */
172 /* class initialization for new RC */
173 void (*add_resctrl) (struct ckrm_core_class *, int resid);
177 /******************************************************************************
179 * common part to any class structure (i.e. instance of a classtype)
180 ******************************************************************************/
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
186 #define CKRM_CORE_MAGIC 0xBADCAFFE
188 typedef struct ckrm_hnode {
189 struct ckrm_core_class *parent;
190 struct list_head siblings;
191 struct list_head children;
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
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
205 struct ckrm_hnode hnode; // hierarchy
206 rwlock_t hnode_rwlock; // protects hnode above.
209 int delayed; // core deletion delayed
210 // because of race conditions
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)
222 /******************************************************************************
224 ******************************************************************************/
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))
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 *);
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,
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);
247 // Hubertus ... need to straighten out all these I don't think we will even
248 // call this or are we
250 /* interface to the RCFS filesystem */
251 extern struct ckrm_core_class *ckrm_alloc_core_class(struct ckrm_core_class *,
254 // Reclassify the given pid to the given core class by force
255 extern void ckrm_forced_reclassify_pid(int, struct ckrm_core_class *);
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 *);
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 *);
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 *);
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);
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,
289 struct ckrm_shares *shares);
290 extern int ckrm_class_reset_stats(struct ckrm_core_class *core,
291 const char *resname, const char *unused);
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 *);
299 static inline void ckrm_core_grab(struct ckrm_core_class *core)
302 atomic_inc(&core->refcnt);
305 static inline void ckrm_core_drop(struct ckrm_core_class *core)
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);
313 static inline unsigned int ckrm_is_core_valid(ckrm_core_class_t * core)
315 return (core && (core->magic == CKRM_CORE_MAGIC));
318 // iterate through all associate resource controllers:
319 // requires following arguments (ckrm_core_class *cls,
320 // ckrm_res_ctrl *ctlr,
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]))); }); \
331 extern struct ckrm_classtype *ckrm_classtypes[];
332 /* should provide a different interface */
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 *-----------------------------------------------------------------------------*/
342 struct ckrm_event_spec {
344 struct ckrm_hook_cb cb;
346 #define CKRM_EVENT_SPEC(EV,FCT) { CKRM_EVENT_##EV, \
347 { (ckrm_event_cb)FCT, NULL } }
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);
354 /******************************************************************************
355 * CE Invocation interface
356 ******************************************************************************/
358 #define ce_protect(ctype) (atomic_inc(&((ctype)->ce_nr_users)))
359 #define ce_release(ctype) (atomic_dec(&((ctype)->ce_nr_users)))
361 // CE Classification callbacks with
363 #define CE_CLASSIFY_NORET(ctype, event, objs_to_classify...) \
365 if ((ctype)->ce_cb_active \
366 && (test_bit(event,&(ctype)->ce_callbacks.c_interest))) \
367 (*(ctype)->ce_callbacks.classify)(event, \
371 #define CE_CLASSIFY_RET(ret, ctype, event, objs_to_classify...) \
373 if ((ctype)->ce_cb_active \
374 && (test_bit(event,&(ctype)->ce_callbacks.c_interest))) \
375 ret = (*(ctype)->ce_callbacks.classify)(event, \
379 #define CE_NOTIFY(ctype, event, cls, objs_to_classify) \
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); \
391 /* vars needed by other modules/core */
393 extern int rcfs_mounted;
394 extern int rcfs_engine_regd;
396 #endif // CONFIG_CKRM
400 #endif // _LINUX_CKRM_RC_H