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>
39 /* maximum number of class types */
40 #define CKRM_MAX_CLASSTYPES 32
41 /* maximum classtype name length */
42 #define CKRM_MAX_CLASSTYPE_NAME 32
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
50 struct ckrm_core_class;
51 struct ckrm_classtype;
53 /********************************************************************************
54 * Share specifications
55 *******************************************************************************/
57 typedef struct ckrm_shares {
62 int unused_guarantee; // not used as parameters
63 int cur_max_limit; // not used as parameters
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
72 /********************************************************************************
73 * RESOURCE CONTROLLERS
74 *******************************************************************************/
76 /* resource controller callback structure */
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
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 *);
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);
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);
98 void (*change_resclass)(void *, void *, void *);
102 /***************************************************************************************
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
108 ***************************************************************************************/
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 */
115 #define CKRM_MAX_TYPENAME_LEN 32
118 typedef struct ckrm_classtype {
119 /* Hubertus: Rearrange slots so that they are more cache friendly during access */
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];
130 /* state about my classes */
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
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
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
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 */
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 */
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 *);
163 int (*reset_stats) (struct ckrm_core_class *, const char *resname,
165 int (*set_config) (struct ckrm_core_class *, const char *resname,
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 *);
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
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; /* linked list of siblings */
191 struct list_head children; /* anchor for children */
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
202 struct ckrm_hnode hnode; // hierarchy
203 rwlock_t hnode_rwlock; // rw_clock protecting the hnode above.
206 int delayed; // core deletion delayed because of race conditions
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)
219 /******************************************************************************************
221 ******************************************************************************************/
223 #define ckrm_get_res_class(rescls,resid,type) ((type*)((rescls)->res_class[resid]))
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 *);
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);
236 // Hubertus ... need to straighten out all these I don't think we will even call thsie ore are we
238 /* interface to the RCFS filesystem */
239 extern struct ckrm_core_class *ckrm_alloc_core_class(struct ckrm_core_class *, const char *, int);
241 // Reclassify the given pid to the given core class by force
242 extern void ckrm_forced_reclassify_pid(int, struct ckrm_core_class *);
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 *);
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 *);
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 *);
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);
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);
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 *);
278 static inline void ckrm_core_grab(struct ckrm_core_class *core)
280 if (core) atomic_inc(&core->refcnt);
283 static inline void ckrm_core_drop(struct ckrm_core_class *core)
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);
291 static inline unsigned int
292 ckrm_is_core_valid(ckrm_core_class_t *core)
294 return (core && (core->magic == CKRM_CORE_MAGIC));
297 // iterate through all associate resource controllers:
298 // requires following arguments (ckrm_core_class *cls,
299 // ckrm_res_ctrl *ctlr,
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]))); }) ; \
308 extern struct ckrm_classtype* ckrm_classtypes[]; /* should provide a different interface */
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 *-----------------------------------------------------------------------------*/
319 struct ckrm_event_spec {
321 struct ckrm_hook_cb cb;
323 #define CKRM_EVENT_SPEC(EV,FCT) { CKRM_EVENT_##EV, { (ckrm_event_cb)FCT, NULL } }
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);
330 /******************************************************************************************
331 * CE Invocation interface
332 ******************************************************************************************/
334 #define ce_protect(ctype) (atomic_inc(&((ctype)->ce_nr_users)))
335 #define ce_release(ctype) (atomic_dec(&((ctype)->ce_nr_users)))
337 // CE Classification callbacks with
339 #define CE_CLASSIFY_NORET(ctype, event, objs_to_classify...) \
341 if ((ctype)->ce_cb_active && (test_bit(event,&(ctype)->ce_callbacks.c_interest))) \
342 (*(ctype)->ce_callbacks.classify)(event, objs_to_classify); \
345 #define CE_CLASSIFY_RET(ret, ctype, event, objs_to_classify...) \
347 if ((ctype)->ce_cb_active && (test_bit(event,&(ctype)->ce_callbacks.c_interest))) \
348 ret = (*(ctype)->ce_callbacks.classify)(event, objs_to_classify); \
351 #define CE_NOTIFY(ctype, event, cls, objs_to_classify) \
353 if ((ctype)->ce_cb_active && (test_bit(event,&(ctype)->ce_callbacks.n_interest))) \
354 (*(ctype)->ce_callbacks.notify)(event,cls,objs_to_classify); \
358 #endif // CONFIG_CKRM
362 #endif // _LINUX_CKRM_RC_H