1 /* ckrm.c - Class-based Kernel Resource Management (CKRM)
3 * Copyright (C) Hubertus Franke, IBM Corp. 2003, 2004
4 * (C) Shailabh Nagar, IBM Corp. 2003, 2004
5 * (C) Chandra Seetharaman, IBM Corp. 2003
6 * (C) Vivek Kashyap, IBM Corp. 2004
9 * Provides kernel API of CKRM for in-kernel,per-resource controllers
10 * (one each for cpu, memory, io, network) and callbacks for
11 * classification modules.
13 * Latest version, more details at http://ckrm.sf.net
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
27 * Made modifications to suit the new RBCE module.
29 * Fixed a bug in fork and exit callbacks. Added callbacks_active and
30 * surrounding logic. Added task paramter for all CE callbacks.
32 * moved to referenced counted class objects and correct locking
34 * Integrated ckrm hooks, classtypes, ...
38 #include <linux/config.h>
39 #include <linux/init.h>
40 #include <linux/linkage.h>
41 #include <linux/kernel.h>
42 #include <linux/errno.h>
43 #include <asm/uaccess.h>
45 #include <asm/errno.h>
46 #include <linux/string.h>
47 #include <linux/list.h>
48 #include <linux/spinlock.h>
49 #include <linux/module.h>
50 #include <linux/ckrm_rc.h>
51 #include <linux/rcfs.h>
56 rwlock_t ckrm_class_lock = RW_LOCK_UNLOCKED; // protect classlists
58 struct rcfs_functions rcfs_fn ;
59 EXPORT_SYMBOL(rcfs_fn);
62 /**************************************************************************
64 **************************************************************************/
67 * Return TRUE if the given core class pointer is valid.
71 * Return TRUE if the given resource is registered.
74 is_res_regd(struct ckrm_classtype *clstype, int resid)
76 return ( (resid>=0) && (resid < clstype->max_resid) &&
77 test_bit(resid, &clstype->bit_res_ctlrs)
82 ckrm_resctlr_lookup(struct ckrm_classtype *clstype, const char *resname)
86 for (resid=0; resid < clstype->max_resid; resid++) {
87 if (test_bit(resid, &clstype->bit_res_ctlrs)) {
88 struct ckrm_res_ctlr *rctrl = clstype->res_ctlrs[resid];
89 if (!strncmp(resname, rctrl->res_name,CKRM_MAX_RES_NAME))
95 EXPORT_SYMBOL(ckrm_resctlr_lookup);
97 /* given a classname return the class handle and its classtype*/
99 ckrm_classobj(char *classname, int *classTypeID)
104 if (!classname || !*classname) {
108 read_lock(&ckrm_class_lock);
109 for ( i=0 ; i<CKRM_MAX_CLASSTYPES; i++) {
110 struct ckrm_classtype *ctype = ckrm_classtypes[i];
111 struct ckrm_core_class *core;
115 list_for_each_entry(core, &ctype->classes, clslist) {
116 if (core->name && !strcmp(core->name, classname)) {
117 // FIXME: should grep reference..
118 read_unlock(&ckrm_class_lock);
119 *classTypeID = ctype->typeID;
124 read_unlock(&ckrm_class_lock);
128 EXPORT_SYMBOL(is_res_regd);
129 EXPORT_SYMBOL(ckrm_classobj);
131 /**************************************************************************
132 * Internal Functions/macros *
133 **************************************************************************/
136 set_callbacks_active(struct ckrm_classtype *ctype)
138 ctype->ce_cb_active = ((atomic_read(&ctype->ce_nr_users) > 0) &&
139 (ctype->ce_callbacks.always_callback || (ctype->num_classes > 1)));
143 ckrm_validate_and_grab_core(struct ckrm_core_class *core)
146 read_lock(&ckrm_class_lock);
147 if (likely(ckrm_is_core_valid(core))) {
148 ckrm_core_grab(core);
151 read_unlock(&ckrm_class_lock);
155 /****************************************************************************
156 * Interfaces for classification engine *
157 ****************************************************************************/
160 * Registering a callback structure by the classification engine.
162 * Returns typeId of class on success -errno for failure.
165 ckrm_register_engine(const char *typename, ckrm_eng_callback_t *ecbs)
167 struct ckrm_classtype *ctype;
169 ctype = ckrm_find_classtype_by_name(typename);
174 if (atomic_read(&ctype->ce_nr_users) != 1) {
175 // Some engine is acive, deregister it first.
180 /* we require that either classify and class_delete are set (due to object reference)
181 * or that notify is set (in case no real classification is supported only notification
182 * also require that the function pointer be set the momement the mask is non-null
184 if ( ! (((ecbs->classify) && (ecbs->class_delete)) || (ecbs->notify)) ||
185 (ecbs->c_interest && ecbs->classify == NULL) ||
186 (ecbs->n_interest && ecbs->notify == NULL) )
193 /* Is any other engine registered for this classtype ? */
194 if (ctype->ce_regd) {
200 ctype->ce_callbacks = *ecbs;
201 set_callbacks_active(ctype);
202 if (ctype->ce_callbacks.class_add)
203 (*ctype->ce_callbacks.class_add)(ctype->default_class->name,ctype->default_class);
204 return ctype->typeID;
208 * Unregistering a callback structure by the classification engine.
210 * Returns 0 on success -errno for failure.
213 ckrm_unregister_engine(const char *typename)
215 struct ckrm_classtype *ctype;
217 ctype = ckrm_find_classtype_by_name(typename);
221 ctype->ce_cb_active = 0;
223 if (atomic_dec_and_test(&ctype->ce_nr_users) != 1) {
224 // Somebody is currently using the engine, cannot deregister.
225 atomic_inc(&ctype->ce_nr_users);
230 memset(&ctype->ce_callbacks, 0, sizeof(ckrm_eng_callback_t));
234 /****************************************************************************
235 * Interfaces to manipulate class (core or resource) hierarchies
236 ****************************************************************************/
241 ckrm_add_child(struct ckrm_core_class *parent, struct ckrm_core_class *child)
243 struct ckrm_hnode *cnode = &child->hnode;
245 if (!ckrm_is_core_valid(child)) {
246 printk(KERN_ERR "Invalid child %p given in ckrm_add_child\n", child);
251 INIT_LIST_HEAD(&cnode->children);
252 INIT_LIST_HEAD(&cnode->siblings);
255 struct ckrm_hnode *pnode;
257 if (!ckrm_is_core_valid(parent)) {
258 printk(KERN_ERR "Invalid parent %p given in ckrm_add_child\n",
262 pnode = &parent->hnode;
263 write_lock(&parent->hnode_rwlock);
264 list_add(&cnode->siblings, &pnode->children);
265 write_unlock(&parent->hnode_rwlock);
268 cnode->parent = parent;
276 ckrm_remove_child(struct ckrm_core_class *child)
278 struct ckrm_hnode *cnode, *pnode;
279 struct ckrm_core_class *parent;
281 if (!ckrm_is_core_valid(child)) {
282 printk(KERN_ERR "Invalid child %p given in ckrm_remove_child\n", child);
286 cnode = &child->hnode;
287 parent = cnode->parent;
288 if (!ckrm_is_core_valid(parent)) {
289 printk(KERN_ERR "Invalid parent %p in ckrm_remove_child\n", parent);
293 pnode = &parent->hnode;
296 /* ensure that the node does not have children */
297 if (!list_empty(&cnode->children)) {
301 write_lock(&parent->hnode_rwlock);
302 list_del(&cnode->siblings);
303 write_unlock(&parent->hnode_rwlock);
304 cnode->parent = NULL;
310 ckrm_lock_hier(struct ckrm_core_class *parent)
312 if (ckrm_is_core_valid(parent)) {
313 read_lock(&parent->hnode_rwlock);
318 ckrm_unlock_hier(struct ckrm_core_class *parent)
320 if (ckrm_is_core_valid(parent)) {
321 read_unlock(&parent->hnode_rwlock);
326 * hnode_rwlock of the parent core class must held in read mode.
327 * external callers should 've called ckrm_lock_hier before calling this
330 #define hnode_2_core(ptr) ((ptr) ? container_of(ptr, struct ckrm_core_class, hnode) : NULL)
332 struct ckrm_core_class *
333 ckrm_get_next_child(struct ckrm_core_class *parent,
334 struct ckrm_core_class *child)
336 struct list_head *cnode;
337 struct ckrm_hnode *next_cnode;
338 struct ckrm_core_class *next_childcore;
340 if (!ckrm_is_core_valid(parent)) {
341 printk(KERN_ERR "Invalid parent %p in ckrm_get_next_child\n", parent);
344 if (list_empty(&parent->hnode.children)) {
349 if (!ckrm_is_core_valid(child)) {
350 printk(KERN_ERR "Invalid child %p in ckrm_get_next_child\n", child);
353 cnode = child->hnode.siblings.next;
355 cnode = parent->hnode.children.next;
358 if (cnode == &parent->hnode.children) { // back at the anchor
362 next_cnode = container_of(cnode, struct ckrm_hnode, siblings);
363 next_childcore = hnode_2_core(next_cnode);
365 if (!ckrm_is_core_valid(next_childcore)) {
366 printk(KERN_ERR "Invalid next child %p in ckrm_get_next_child\n",
370 return next_childcore;
373 EXPORT_SYMBOL(ckrm_lock_hier);
374 EXPORT_SYMBOL(ckrm_unlock_hier);
375 EXPORT_SYMBOL(ckrm_get_next_child);
378 ckrm_alloc_res_class(struct ckrm_core_class *core,
379 struct ckrm_core_class *parent,
383 struct ckrm_classtype *clstype;
386 * Allocate a resource class only if the resource controller has
387 * registered with core and the engine requests for the class.
390 if (!ckrm_is_core_valid(core))
393 clstype = core->classtype;
394 core->res_class[resid] = NULL;
396 if (test_bit(resid, &clstype->bit_res_ctlrs)) {
397 ckrm_res_ctlr_t *rcbs;
399 atomic_inc(&clstype->nr_resusers[resid]);
400 rcbs = clstype->res_ctlrs[resid];
402 if (rcbs && rcbs->res_alloc) {
403 core->res_class[resid] =(*rcbs->res_alloc)(core,parent);
404 if (core->res_class[resid])
406 printk(KERN_ERR "Error creating res class\n");
408 atomic_dec(&clstype->nr_resusers[resid]);
413 * Initialize a core class
417 #define CLS_DEBUG(fmt, args...) do { /* printk("%s: " fmt, __FUNCTION__ , ## args); */ } while (0)
421 ckrm_init_core_class(struct ckrm_classtype *clstype,
422 struct ckrm_core_class *dcore,
423 struct ckrm_core_class *parent,
426 // Hubertus ... should replace name with dentry or add dentry ?
429 // Hubertus .. how is this used in initialization
431 CLS_DEBUG("name %s => %p\n", name?name:"default",dcore);
433 if ((dcore != clstype->default_class) && ( !ckrm_is_core_valid(parent))) {
434 printk("error not a valid parent %p\n", parent);
437 #if 0 // Hubertus .. dynamic allocation still breaks when RCs registers. See def in ckrm_rc.h
438 dcore->res_class = NULL;
439 if (clstype->max_resid > 0) {
440 dcore->res_class = (void**)kmalloc(clstype->max_resid * sizeof(void*) , GFP_KERNEL);
441 if (dcore->res_class == NULL) {
442 printk("error no mem\n");
448 dcore->classtype = clstype;
449 dcore->magic = CKRM_CORE_MAGIC;
451 dcore->class_lock = SPIN_LOCK_UNLOCKED;
452 dcore->hnode_rwlock = RW_LOCK_UNLOCKED;
455 atomic_set(&dcore->refcnt, 0);
456 write_lock(&ckrm_class_lock);
458 INIT_LIST_HEAD(&dcore->objlist);
459 list_add(&dcore->clslist,&clstype->classes);
461 clstype->num_classes++;
462 set_callbacks_active(clstype);
464 write_unlock(&ckrm_class_lock);
465 ckrm_add_child(parent, dcore);
467 for (i = 0; i < clstype->max_resid; i++)
468 ckrm_alloc_res_class(dcore,parent,i);
470 // fix for race condition seen in stress with numtasks
472 ckrm_core_grab(parent);
474 ckrm_core_grab( dcore );
480 ckrm_free_res_class(struct ckrm_core_class *core, int resid)
483 * Free a resource class only if the resource controller has
484 * registered with core
487 if (core->res_class[resid]) {
488 ckrm_res_ctlr_t *rcbs;
489 struct ckrm_classtype *clstype = core->classtype;
491 atomic_inc(&clstype->nr_resusers[resid]);
492 rcbs = clstype->res_ctlrs[resid];
494 if (rcbs->res_free) {
495 (*rcbs->res_free)(core->res_class[resid]);
496 atomic_dec(&clstype->nr_resusers[resid]); // for inc in alloc
497 core->res_class[resid] = NULL;
499 atomic_dec(&clstype->nr_resusers[resid]);
506 * requires that all tasks were previously reassigned to another class
508 * Returns 0 on success -errno on failure.
512 ckrm_free_core_class(struct ckrm_core_class *core)
515 struct ckrm_classtype *clstype = core->classtype;
516 struct ckrm_core_class *parent = core->hnode.parent;
518 CLS_DEBUG("core=%p:%s parent=%p:%s\n",core,core->name,parent,parent->name);
520 /* this core was marked as late */
521 printk("class <%s> finally deleted %lu\n",core->name,jiffies);
523 if (ckrm_remove_child(core) == 0) {
524 printk("Core class removal failed. Chilren present\n");
527 for (i = 0; i < clstype->max_resid; i++) {
528 ckrm_free_res_class(core,i);
531 write_lock(&ckrm_class_lock);
533 // Clear the magic, so we would know if this core is reused.
535 #if 0 // Dynamic not yet enabled
536 core->res_class = NULL;
538 // Remove this core class from its linked list.
539 list_del(&core->clslist);
540 clstype->num_classes--;
541 set_callbacks_active(clstype);
542 write_unlock(&ckrm_class_lock);
544 // fix for race condition seen in stress with numtasks
546 ckrm_core_drop(parent);
552 ckrm_release_core_class(struct ckrm_core_class *core)
554 if (!ckrm_is_core_valid(core)) {
559 if (core == core->classtype->default_class)
562 /* need to make sure that the classgot really dropped */
563 if (atomic_read(&core->refcnt) != 1) {
564 CLS_DEBUG("class <%s> deletion delayed refcnt=%d jif=%ld\n",
565 core->name,atomic_read(&core->refcnt),jiffies);
566 core->delayed = 1; /* just so we have a ref point */
568 ckrm_core_drop(core);
572 /****************************************************************************
573 * Interfaces for the resource controller *
574 ****************************************************************************/
576 * Registering a callback structure by the resource controller.
578 * Returns the resource id(0 or +ve) on success, -errno for failure.
581 ckrm_register_res_ctlr_intern(struct ckrm_classtype *clstype, ckrm_res_ctlr_t *rcbs)
590 spin_lock(&clstype->res_ctlrs_lock);
592 printk(KERN_WARNING "resid is %d name is %s %s\n",
593 resid, rcbs->res_name,clstype->res_ctlrs[resid]->res_name);
596 if ((resid < CKRM_MAX_RES_CTLRS) && (clstype->res_ctlrs[resid] == NULL)) {
597 clstype->res_ctlrs[resid] = rcbs;
598 atomic_set(&clstype->nr_resusers[resid], 0);
599 set_bit(resid, &clstype->bit_res_ctlrs);
601 if (resid >= clstype->max_resid) {
602 clstype->max_resid = resid + 1;
607 spin_unlock(&clstype->res_ctlrs_lock);
611 for (i = clstype->resid_reserved; i < clstype->max_res_ctlrs; i++) {
612 if (clstype->res_ctlrs[i] == NULL) {
613 clstype->res_ctlrs[i] = rcbs;
615 atomic_set(&clstype->nr_resusers[i], 0);
616 set_bit(i, &clstype->bit_res_ctlrs);
617 if (i >= clstype->max_resid) {
618 clstype->max_resid = i + 1;
620 spin_unlock(&clstype->res_ctlrs_lock);
625 spin_unlock(&clstype->res_ctlrs_lock);
630 ckrm_register_res_ctlr(struct ckrm_classtype *clstype, ckrm_res_ctlr_t *rcbs)
632 struct ckrm_core_class *core;
635 resid = ckrm_register_res_ctlr_intern(clstype,rcbs);
638 /* run through all classes and create the resource class object and
639 * if necessary "initialize" class in context of this resource
641 read_lock(&ckrm_class_lock);
642 list_for_each_entry(core, &clstype->classes, clslist) {
643 printk("CKRM .. create res clsobj for resouce <%s> class <%s> par=%p\n",
644 rcbs->res_name, core->name, core->hnode.parent);
645 ckrm_alloc_res_class(core, core->hnode.parent, resid);
646 if (clstype->add_resctrl) // FIXME: this should be mandatory
647 (*clstype->add_resctrl)(core,resid);
649 read_unlock(&ckrm_class_lock);
655 * Unregistering a callback structure by the resource controller.
657 * Returns 0 on success -errno for failure.
660 ckrm_unregister_res_ctlr(struct ckrm_res_ctlr *rcbs)
662 struct ckrm_classtype *clstype = rcbs->classtype;
663 int resid = rcbs->resid;
665 if ((clstype == NULL) || (resid < 0))
668 if (atomic_read(&clstype->nr_resusers[resid]))
671 // FIXME: probably need to also call deregistration function
673 spin_lock(&clstype->res_ctlrs_lock);
674 clstype->res_ctlrs[resid] = NULL;
675 clear_bit(resid, &clstype->bit_res_ctlrs);
676 clstype->max_resid = fls(clstype->bit_res_ctlrs);
678 spin_unlock(&clstype->res_ctlrs_lock);
683 /*******************************************************************
684 * Class Type Registration
685 *******************************************************************/
687 /* Hubertus ... we got to do some locking here */
689 struct ckrm_classtype* ckrm_classtypes[CKRM_MAX_CLASSTYPES];
690 EXPORT_SYMBOL(ckrm_classtypes); // really should build a better interface for this
693 ckrm_register_classtype(struct ckrm_classtype *clstype)
695 int tid = clstype->typeID;
698 if ((tid < 0) || (tid > CKRM_MAX_CLASSTYPES) || (ckrm_classtypes[tid]))
702 for ( i=CKRM_RESV_CLASSTYPES ; i<CKRM_MAX_CLASSTYPES; i++) {
703 if (ckrm_classtypes[i] == NULL) {
711 clstype->typeID = tid;
712 ckrm_classtypes[tid] = clstype;
714 /* Hubertus .. we need to call the callbacks of the RCFS client */
715 if (rcfs_fn.register_classtype) {
716 (* rcfs_fn.register_classtype)(clstype);
717 // No error return for now ;
724 ckrm_unregister_classtype(struct ckrm_classtype *clstype)
726 int tid = clstype->typeID;
728 if ((tid < 0) || (tid > CKRM_MAX_CLASSTYPES) || (ckrm_classtypes[tid] != clstype))
731 if (rcfs_fn.deregister_classtype) {
732 (* rcfs_fn.deregister_classtype)(clstype);
733 // No error return for now
736 ckrm_classtypes[tid] = NULL;
737 clstype->typeID = -1;
741 struct ckrm_classtype*
742 ckrm_find_classtype_by_name(const char *name)
745 for ( i=0 ; i<CKRM_MAX_CLASSTYPES; i++) {
746 struct ckrm_classtype *ctype = ckrm_classtypes[i];
747 if (ctype && !strncmp(ctype->name,name,CKRM_MAX_TYPENAME_LEN))
754 /*******************************************************************
755 * Event callback invocation
756 *******************************************************************/
758 struct ckrm_hook_cb* ckrm_event_callbacks[CKRM_NONLATCHABLE_EVENTS];
760 /* Registration / Deregistration / Invocation functions */
763 ckrm_register_event_cb(enum ckrm_event ev, struct ckrm_hook_cb *cb)
765 struct ckrm_hook_cb **cbptr;
767 if ((ev < CKRM_LATCHABLE_EVENTS) || (ev >= CKRM_NONLATCHABLE_EVENTS))
769 cbptr = &ckrm_event_callbacks[ev];
770 while (*cbptr != NULL)
771 cbptr = &((*cbptr)->next);
777 ckrm_unregister_event_cb(enum ckrm_event ev, struct ckrm_hook_cb *cb)
779 struct ckrm_hook_cb **cbptr;
781 if ((ev < CKRM_LATCHABLE_EVENTS) || (ev >= CKRM_NONLATCHABLE_EVENTS))
783 cbptr = &ckrm_event_callbacks[ev];
784 while ((*cbptr != NULL) && (*cbptr != cb))
785 cbptr = &((*cbptr)->next);
787 (*cbptr)->next = cb->next;
788 return (*cbptr == NULL);
792 ckrm_register_event_set(struct ckrm_event_spec especs[])
794 struct ckrm_event_spec *espec = especs;
796 for ( espec = especs ; espec->ev != -1 ; espec++ )
797 ckrm_register_event_cb(espec->ev,&espec->cb);
802 ckrm_unregister_event_set(struct ckrm_event_spec especs[])
804 struct ckrm_event_spec *espec = especs;
806 for ( espec = especs ; espec->ev != -1 ; espec++ )
807 ckrm_unregister_event_cb(espec->ev,&espec->cb);
811 #define ECC_PRINTK(fmt, args...) // printk("%s: " fmt, __FUNCTION__ , ## args)
814 ckrm_invoke_event_cb_chain(enum ckrm_event ev, void *arg)
816 struct ckrm_hook_cb *cb, *anchor;
818 ECC_PRINTK("%d %x\n",current,ev,arg);
819 if ((anchor = ckrm_event_callbacks[ev]) != NULL) {
820 for ( cb = anchor ; cb ; cb = cb->next )
825 /*******************************************************************
826 * Generic Functions that can be used as default functions
827 * in almost all classtypes
828 * (a) function iterator over all resource classes of a class
829 * (b) function invoker on a named resource
830 *******************************************************************/
833 ckrm_class_show_shares(struct ckrm_core_class *core, struct seq_file *seq)
836 struct ckrm_res_ctlr *rcbs;
837 struct ckrm_classtype *clstype = core->classtype;
838 struct ckrm_shares shares;
840 for (i = 0; i < clstype->max_resid; i++) {
841 atomic_inc(&clstype->nr_resusers[i]);
842 rcbs = clstype->res_ctlrs[i];
843 if (rcbs && rcbs->get_share_values) {
844 (*rcbs->get_share_values)(core->res_class[i], &shares);
845 seq_printf(seq,"res=%s,guarantee=%d,limit=%d,total_guarantee=%d,max_limit=%d\n",
849 shares.total_guarantee,
852 atomic_dec(&clstype->nr_resusers[i]);
858 ckrm_class_show_stats(struct ckrm_core_class *core, struct seq_file *seq)
861 struct ckrm_res_ctlr *rcbs;
862 struct ckrm_classtype *clstype = core->classtype;
864 for (i = 0; i < clstype->max_resid; i++) {
865 atomic_inc(&clstype->nr_resusers[i]);
866 rcbs = clstype->res_ctlrs[i];
867 if (rcbs && rcbs->get_stats)
868 (*rcbs->get_stats)(core->res_class[i], seq);
869 atomic_dec(&clstype->nr_resusers[i]);
875 ckrm_class_show_config(struct ckrm_core_class *core, struct seq_file *seq)
878 struct ckrm_res_ctlr *rcbs;
879 struct ckrm_classtype *clstype = core->classtype;
881 for (i = 0; i < clstype->max_resid; i++) {
882 atomic_inc(&clstype->nr_resusers[i]);
883 rcbs = clstype->res_ctlrs[i];
884 if (rcbs && rcbs->show_config)
885 (*rcbs->show_config)(core->res_class[i], seq);
886 atomic_dec(&clstype->nr_resusers[i]);
892 ckrm_class_set_config(struct ckrm_core_class *core, const char *resname, const char *cfgstr)
894 struct ckrm_classtype *clstype = core->classtype;
895 struct ckrm_res_ctlr *rcbs = ckrm_resctlr_lookup(clstype,resname);
898 if (rcbs == NULL || rcbs->set_config == NULL)
900 rc = (*rcbs->set_config)(core->res_class[rcbs->resid],cfgstr);
905 ckrm_class_set_shares(struct ckrm_core_class *core, const char *resname,
906 struct ckrm_shares *shares)
908 struct ckrm_classtype *clstype = core->classtype;
909 struct ckrm_res_ctlr *rcbs;
912 printk("ckrm_class_set_shares(%s,%s)\n",core->name,resname);
913 rcbs = ckrm_resctlr_lookup(clstype,resname);
914 if (rcbs == NULL || rcbs->set_share_values == NULL)
916 rc = (*rcbs->set_share_values)(core->res_class[rcbs->resid],shares);
921 ckrm_class_reset_stats(struct ckrm_core_class *core, const char *resname, const char *unused)
923 struct ckrm_classtype *clstype = core->classtype;
924 struct ckrm_res_ctlr *rcbs = ckrm_resctlr_lookup(clstype,resname);
927 if (rcbs == NULL || rcbs->reset_stats == NULL)
929 rc = (*rcbs->reset_stats)(core->res_class[rcbs->resid]);
933 /*******************************************************************
935 *******************************************************************/
938 ckrm_cb_newtask(struct task_struct *tsk)
941 spin_lock_init(&tsk->ckrm_tsklock);
942 ckrm_invoke_event_cb_chain(CKRM_EVENT_NEWTASK,tsk);
946 ckrm_cb_exit(struct task_struct *tsk)
948 ckrm_invoke_event_cb_chain(CKRM_EVENT_EXIT,tsk);
955 printk("CKRM Initialization\n");
957 // register/initialize the Metatypes
959 #ifdef CONFIG_CKRM_TYPE_TASKCLASS
961 extern void ckrm_meta_init_taskclass(void);
962 ckrm_meta_init_taskclass();
965 #ifdef CONFIG_CKRM_TYPE_SOCKETCLASS
967 extern void ckrm_meta_init_sockclass(void);
968 ckrm_meta_init_sockclass();
971 // prepare init_task and then rely on inheritance of properties
972 ckrm_cb_newtask(&init_task);
973 printk("CKRM Initialization done\n");
976 EXPORT_SYMBOL(ckrm_register_engine);
977 EXPORT_SYMBOL(ckrm_unregister_engine);
979 EXPORT_SYMBOL(ckrm_register_res_ctlr);
980 EXPORT_SYMBOL(ckrm_unregister_res_ctlr);
982 EXPORT_SYMBOL(ckrm_init_core_class);
983 EXPORT_SYMBOL(ckrm_free_core_class);
984 EXPORT_SYMBOL(ckrm_release_core_class);
986 EXPORT_SYMBOL(ckrm_register_classtype);
987 EXPORT_SYMBOL(ckrm_unregister_classtype);
988 EXPORT_SYMBOL(ckrm_find_classtype_by_name);
990 EXPORT_SYMBOL(ckrm_core_grab);
991 EXPORT_SYMBOL(ckrm_core_drop);
992 EXPORT_SYMBOL(ckrm_is_core_valid);
993 EXPORT_SYMBOL(ckrm_validate_and_grab_core);
995 EXPORT_SYMBOL(ckrm_register_event_set);
996 EXPORT_SYMBOL(ckrm_unregister_event_set);
997 EXPORT_SYMBOL(ckrm_register_event_cb);
998 EXPORT_SYMBOL(ckrm_unregister_event_cb);
1000 EXPORT_SYMBOL(ckrm_class_show_stats);
1001 EXPORT_SYMBOL(ckrm_class_show_config);
1002 EXPORT_SYMBOL(ckrm_class_show_shares);
1004 EXPORT_SYMBOL(ckrm_class_set_config);
1005 EXPORT_SYMBOL(ckrm_class_set_shares);
1007 EXPORT_SYMBOL(ckrm_class_reset_stats);