*
*/
-/*
- * Changes
+/* Changes
*
* 28 Aug 2003
* Created.
#include <net/sock.h>
#include <linux/ip.h>
-rwlock_t ckrm_class_lock = RW_LOCK_UNLOCKED; /* protects classlists */
+rwlock_t ckrm_class_lock = RW_LOCK_UNLOCKED; // protect classlists
struct rcfs_functions rcfs_fn;
-EXPORT_SYMBOL_GPL(rcfs_fn);
+EXPORT_SYMBOL(rcfs_fn);
-int rcfs_engine_regd; /* rcfs state needed by another module */
-EXPORT_SYMBOL_GPL(rcfs_engine_regd);
+// rcfs state needed by another module
+int rcfs_engine_regd;
+EXPORT_SYMBOL(rcfs_engine_regd);
int rcfs_mounted;
-EXPORT_SYMBOL_GPL(rcfs_mounted);
+EXPORT_SYMBOL(rcfs_mounted);
+
+/**************************************************************************
+ * Helper Functions *
+ **************************************************************************/
/*
- * Helper Functions
+ * Return TRUE if the given core class pointer is valid.
*/
/*
);
}
-/*
- * Return TRUE if the given core class pointer is valid.
- */
-static struct ckrm_res_ctlr *ckrm_resctlr_lookup(struct ckrm_classtype *clstype,
+struct ckrm_res_ctlr *ckrm_resctlr_lookup(struct ckrm_classtype *clstype,
const char *resname)
{
int resid = -1;
return NULL;
}
+EXPORT_SYMBOL(ckrm_resctlr_lookup);
/* given a classname return the class handle and its classtype*/
-void *ckrm_classobj(const char *classname, int *classTypeID)
+void *ckrm_classobj(char *classname, int *classTypeID)
{
int i;
return NULL;
}
-EXPORT_SYMBOL_GPL(is_res_regd);
-EXPORT_SYMBOL_GPL(ckrm_classobj);
+EXPORT_SYMBOL(is_res_regd);
+EXPORT_SYMBOL(ckrm_classobj);
-/*
- * Internal Functions/macros
- */
+/**************************************************************************
+ * Internal Functions/macros *
+ **************************************************************************/
static inline void set_callbacks_active(struct ckrm_classtype *ctype)
{
return rc;
}
-/*
- * Interfaces for classification engine
- */
+/****************************************************************************
+ * Interfaces for classification engine *
+ ****************************************************************************/
/*
* Registering a callback structure by the classification engine.
return (-EBUSY);
}
- /*
- * One of the following must be set:
- * classify, class_delete (due to object reference) or
- * notify (case where notification supported but not classification)
- * The function pointer must be set the momement the mask is non-null
+ /* One of the following must be set:
+ classify, class_delete (due to object reference) or
+ notify (case where notification supported but not classification)
+ The function pointer must be set the momement the mask is non-null
*/
+
if (!(((ecbs->classify) && (ecbs->class_delete)) || (ecbs->notify)) ||
(ecbs->c_interest && ecbs->classify == NULL) ||
(ecbs->n_interest && ecbs->notify == NULL)) {
struct ckrm_core_class *core;
read_lock(&ckrm_class_lock);
+
list_for_each_entry(core, &ctype->classes, clslist) {
(*ctype->ce_callbacks.class_add) (core->name, core,
ctype->typeID);
return (-ENOENT);
ctype->ce_cb_active = 0;
+
if (atomic_read(&ctype->ce_nr_users) > 1) {
- /* Somebody is currently using the engine, cannot deregister. */
+ // Somebody is currently using the engine, cannot deregister.
return (-EAGAIN);
}
+
atomic_set(&ctype->ce_regd, 0);
memset(&ctype->ce_callbacks, 0, sizeof(ckrm_eng_callback_t));
return 0;
}
-/*
- * Interfaces to manipulate class (core or resource) hierarchies
- */
+/****************************************************************************
+ * Interfaces to manipulate class (core or resource) hierarchies
+ ****************************************************************************/
+/*
+ */
static void
ckrm_add_child(struct ckrm_core_class *parent, struct ckrm_core_class *child)
{
child);
return;
}
+
class_lock(child);
INIT_LIST_HEAD(&cnode->children);
INIT_LIST_HEAD(&cnode->siblings);
return;
}
+/*
+ */
static int ckrm_remove_child(struct ckrm_core_class *child)
{
struct ckrm_hnode *cnode, *pnode;
if (list_empty(&parent->hnode.children)) {
return NULL;
}
+
if (child) {
if (!ckrm_is_core_valid(child)) {
printk(KERN_ERR
cnode = parent->hnode.children.next;
}
- if (cnode == &parent->hnode.children) { /* back at the anchor */
+ if (cnode == &parent->hnode.children) { // back at the anchor
return NULL;
}
return next_childcore;
}
-EXPORT_SYMBOL_GPL(ckrm_lock_hier);
-EXPORT_SYMBOL_GPL(ckrm_unlock_hier);
-EXPORT_SYMBOL_GPL(ckrm_get_next_child);
+EXPORT_SYMBOL(ckrm_lock_hier);
+EXPORT_SYMBOL(ckrm_unlock_hier);
+EXPORT_SYMBOL(ckrm_get_next_child);
static void
ckrm_alloc_res_class(struct ckrm_core_class *core,
{
struct ckrm_classtype *clstype;
+
/*
* Allocate a resource class only if the resource controller has
* registered with core and the engine requests for the class.
*/
+
if (!ckrm_is_core_valid(core))
return;
+
clstype = core->classtype;
core->res_class[resid] = NULL;
struct ckrm_core_class *dcore,
struct ckrm_core_class *parent, const char *name)
{
- /* TODO: Should replace name with dentry or add dentry? */
+ // Hubertus ... should replace name with dentry or add dentry ?
int i;
- /* TODO: How is this used in initialization? */
+ // Hubertus .. how is this used in initialization
+
CLS_DEBUG("name %s => %p\n", name ? name : "default", dcore);
+
if ((dcore != clstype->default_class) && (!ckrm_is_core_valid(parent))){
printk(KERN_DEBUG "error not a valid parent %p\n", parent);
return -EINVAL;
}
+#if 0
+// Hubertus .. dynamic allocation still breaks when RCs registers.
+// See def in ckrm_rc.h
+ dcore->res_class = NULL;
+ if (clstype->max_resid > 0) {
+ dcore->res_class =
+ (void **)kmalloc(clstype->max_resid * sizeof(void *),
+ GFP_KERNEL);
+ if (dcore->res_class == NULL) {
+ printk(KERN_DEBUG "error no mem\n");
+ return -ENOMEM;
+ }
+ }
+#endif
+
dcore->classtype = clstype;
dcore->magic = CKRM_CORE_MAGIC;
dcore->name = name;
for (i = 0; i < clstype->max_resid; i++)
ckrm_alloc_res_class(dcore, parent, i);
- /* fix for race condition seen in stress with numtasks */
+ // fix for race condition seen in stress with numtasks
if (parent)
ckrm_core_grab(parent);
if (ckrm_remove_child(core) == 0) {
printk(KERN_DEBUG "Core class removal failed. Chilren present\n");
}
+
for (i = 0; i < clstype->max_resid; i++) {
ckrm_free_res_class(core, i);
}
write_lock(&ckrm_class_lock);
- /* Clear the magic, so we would know if this core is reused. */
+
+ // Clear the magic, so we would know if this core is reused.
core->magic = 0;
-#if 0 /* Dynamic not yet enabled */
+#if 0 // Dynamic not yet enabled
core->res_class = NULL;
#endif
- /* Remove this core class from its linked list. */
+ // Remove this core class from its linked list.
list_del(&core->clslist);
clstype->num_classes--;
set_callbacks_active(clstype);
write_unlock(&ckrm_class_lock);
- /* fix for race condition seen in stress with numtasks */
+ // fix for race condition seen in stress with numtasks
if (parent)
ckrm_core_drop(parent);
return 0;
}
-/*
- * Interfaces for the resource controller
- */
+/****************************************************************************
+ * Interfaces for the resource controller *
+ ****************************************************************************/
/*
* Registering a callback structure by the resource controller.
*
resid = rcbs->resid;
spin_lock(&clstype->res_ctlrs_lock);
+
printk(KERN_WARNING "resid is %d name is %s %s\n",
resid, rcbs->res_name, clstype->res_ctlrs[resid]->res_name);
+
if (resid >= 0) {
if ((resid < CKRM_MAX_RES_CTLRS)
&& (clstype->res_ctlrs[resid] == NULL)) {
spin_unlock(&clstype->res_ctlrs_lock);
return ret;
}
+
for (i = clstype->resid_reserved; i < clstype->max_res_ctlrs; i++) {
if (clstype->res_ctlrs[i] == NULL) {
clstype->res_ctlrs[i] = rcbs;
return i;
}
}
+
spin_unlock(&clstype->res_ctlrs_lock);
return (-ENOMEM);
}
ckrm_alloc_res_class(core, core->hnode.parent, resid);
if (clstype->add_resctrl) {
- /* FIXME: this should be mandatory */
+ // FIXME: this should be mandatory
(*clstype->add_resctrl) (core, resid);
}
}
if ((clstype == NULL) || (resid < 0)) {
return -EINVAL;
}
- /* TODO: probably need to also call deregistration function */
+ // FIXME: probably need to also call deregistration function
read_lock(&ckrm_class_lock);
- /* free up this resource from all the classes */
+ // free up this resource from all the classes
list_for_each_entry(core, &clstype->classes, clslist) {
ckrm_free_res_class(core, resid);
}
return 0;
}
-/*
- * Class Type Registration
- */
+/*******************************************************************
+ * Class Type Registration
+ *******************************************************************/
+
+/* Hubertus ... we got to do some locking here */
-/* TODO: What locking is needed here?*/
struct ckrm_classtype *ckrm_classtypes[CKRM_MAX_CLASSTYPES];
-EXPORT_SYMBOL_GPL(ckrm_classtypes);
+// really should build a better interface for this
+EXPORT_SYMBOL(ckrm_classtypes);
int ckrm_register_classtype(struct ckrm_classtype *clstype)
{
clstype->typeID = tid;
ckrm_classtypes[tid] = clstype;
- /* TODO: Need to call the callbacks of the RCFS client */
+ /* Hubertus .. we need to call the callbacks of the RCFS client */
if (rcfs_fn.register_classtype) {
(*rcfs_fn.register_classtype) (clstype);
- /* No error return for now. */
+ // No error return for now ;
}
+
return tid;
}
return NULL;
}
-/*
+/*******************************************************************
+ * Event callback invocation
+ *******************************************************************/
+
+struct ckrm_hook_cb *ckrm_event_callbacks[CKRM_NONLATCHABLE_EVENTS];
+
+/* Registration / Deregistration / Invocation functions */
+
+int ckrm_register_event_cb(enum ckrm_event ev, struct ckrm_hook_cb *cb)
+{
+ struct ckrm_hook_cb **cbptr;
+
+ if ((ev < CKRM_LATCHABLE_EVENTS) || (ev >= CKRM_NONLATCHABLE_EVENTS))
+ return 1;
+ cbptr = &ckrm_event_callbacks[ev];
+ while (*cbptr != NULL)
+ cbptr = &((*cbptr)->next);
+ *cbptr = cb;
+ return 0;
+}
+
+int ckrm_unregister_event_cb(enum ckrm_event ev, struct ckrm_hook_cb *cb)
+{
+ struct ckrm_hook_cb **cbptr;
+
+ if ((ev < CKRM_LATCHABLE_EVENTS) || (ev >= CKRM_NONLATCHABLE_EVENTS))
+ return -1;
+ cbptr = &ckrm_event_callbacks[ev];
+ while ((*cbptr != NULL) && (*cbptr != cb))
+ cbptr = &((*cbptr)->next);
+ if (*cbptr)
+ (*cbptr)->next = cb->next;
+ return (*cbptr == NULL);
+}
+
+int ckrm_register_event_set(struct ckrm_event_spec especs[])
+{
+ struct ckrm_event_spec *espec = especs;
+
+ for (espec = especs; espec->ev != -1; espec++)
+ ckrm_register_event_cb(espec->ev, &espec->cb);
+ return 0;
+}
+
+int ckrm_unregister_event_set(struct ckrm_event_spec especs[])
+{
+ struct ckrm_event_spec *espec = especs;
+
+ for (espec = especs; espec->ev != -1; espec++)
+ ckrm_unregister_event_cb(espec->ev, &espec->cb);
+ return 0;
+}
+
+#define ECC_PRINTK(fmt, args...) \
+// printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+
+void ckrm_invoke_event_cb_chain(enum ckrm_event ev, void *arg)
+{
+ struct ckrm_hook_cb *cb, *anchor;
+
+ ECC_PRINTK("%d %x\n", current, ev, arg);
+ if ((anchor = ckrm_event_callbacks[ev]) != NULL) {
+ for (cb = anchor; cb; cb = cb->next)
+ (*cb->fct) (arg);
+ }
+}
+
+/*******************************************************************
* Generic Functions that can be used as default functions
* in almost all classtypes
* (a) function iterator over all resource classes of a class
* (b) function invoker on a named resource
- */
+ *******************************************************************/
int ckrm_class_show_shares(struct ckrm_core_class *core, struct seq_file *seq)
{
struct ckrm_res_ctlr *rcbs;
int rc;
- /* Check for legal values */
+ // Check for legal values
if (!legalshare(shares->my_guarantee) || !legalshare(shares->my_limit)
|| !legalshare(shares->total_guarantee)
|| !legalshare(shares->max_limit))
return rc;
}
-/*
- * Initialization
- */
+/*******************************************************************
+ * Initialization
+ *******************************************************************/
void ckrm_cb_newtask(struct task_struct *tsk)
{
{
printk(KERN_DEBUG "CKRM Initialization\n");
- // prepare init_task and then rely on inheritance of properties
- ckrm_cb_newtask(&init_task);
-
// register/initialize the Metatypes
#ifdef CONFIG_CKRM_TYPE_TASKCLASS
ckrm_meta_init_sockclass();
}
#endif
- printk("CKRM Initialization done\n");
+ // prepare init_task and then rely on inheritance of properties
+ ckrm_cb_newtask(&init_task);
+ printk(KERN_DEBUG "CKRM Initialization done\n");
}
-EXPORT_SYMBOL_GPL(ckrm_register_engine);
-EXPORT_SYMBOL_GPL(ckrm_unregister_engine);
+EXPORT_SYMBOL(ckrm_register_engine);
+EXPORT_SYMBOL(ckrm_unregister_engine);
-EXPORT_SYMBOL_GPL(ckrm_register_res_ctlr);
-EXPORT_SYMBOL_GPL(ckrm_unregister_res_ctlr);
+EXPORT_SYMBOL(ckrm_register_res_ctlr);
+EXPORT_SYMBOL(ckrm_unregister_res_ctlr);
-EXPORT_SYMBOL_GPL(ckrm_init_core_class);
-EXPORT_SYMBOL_GPL(ckrm_free_core_class);
-EXPORT_SYMBOL_GPL(ckrm_release_core_class);
+EXPORT_SYMBOL(ckrm_init_core_class);
+EXPORT_SYMBOL(ckrm_free_core_class);
+EXPORT_SYMBOL(ckrm_release_core_class);
-EXPORT_SYMBOL_GPL(ckrm_register_classtype);
-EXPORT_SYMBOL_GPL(ckrm_unregister_classtype);
-EXPORT_SYMBOL_GPL(ckrm_find_classtype_by_name);
+EXPORT_SYMBOL(ckrm_register_classtype);
+EXPORT_SYMBOL(ckrm_unregister_classtype);
+EXPORT_SYMBOL(ckrm_find_classtype_by_name);
-EXPORT_SYMBOL_GPL(ckrm_core_grab);
-EXPORT_SYMBOL_GPL(ckrm_core_drop);
-EXPORT_SYMBOL_GPL(ckrm_is_core_valid);
-EXPORT_SYMBOL_GPL(ckrm_validate_and_grab_core);
+EXPORT_SYMBOL(ckrm_core_grab);
+EXPORT_SYMBOL(ckrm_core_drop);
+EXPORT_SYMBOL(ckrm_is_core_valid);
+EXPORT_SYMBOL(ckrm_validate_and_grab_core);
-EXPORT_SYMBOL_GPL(ckrm_register_event_set);
-EXPORT_SYMBOL_GPL(ckrm_unregister_event_set);
-EXPORT_SYMBOL_GPL(ckrm_register_event_cb);
-EXPORT_SYMBOL_GPL(ckrm_unregister_event_cb);
+EXPORT_SYMBOL(ckrm_register_event_set);
+EXPORT_SYMBOL(ckrm_unregister_event_set);
+EXPORT_SYMBOL(ckrm_register_event_cb);
+EXPORT_SYMBOL(ckrm_unregister_event_cb);
-EXPORT_SYMBOL_GPL(ckrm_class_show_stats);
-EXPORT_SYMBOL_GPL(ckrm_class_show_config);
-EXPORT_SYMBOL_GPL(ckrm_class_show_shares);
+EXPORT_SYMBOL(ckrm_class_show_stats);
+EXPORT_SYMBOL(ckrm_class_show_config);
+EXPORT_SYMBOL(ckrm_class_show_shares);
-EXPORT_SYMBOL_GPL(ckrm_class_set_config);
-EXPORT_SYMBOL_GPL(ckrm_class_set_shares);
+EXPORT_SYMBOL(ckrm_class_set_config);
+EXPORT_SYMBOL(ckrm_class_set_shares);
-EXPORT_SYMBOL_GPL(ckrm_class_reset_stats);
+EXPORT_SYMBOL(ckrm_class_reset_stats);