#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/rmap.h>
-#include <linux/ckrm.h>
+#include <linux/ckrm_events.h>
#include <linux/ckrm_mem_inline.h>
#include <linux/vs_memory.h>
atomic_set(&newsighand->count, 1);
memcpy(newsighand->action, oldsighand->action,
sizeof(newsighand->action));
-
write_lock_irq(&tasklist_lock);
spin_lock(&oldsighand->siglock);
spin_lock(&newsighand->siglock);
-
current->sighand = newsighand;
recalc_sigpending();
-
spin_unlock(&newsighand->siglock);
spin_unlock(&oldsighand->siglock);
write_unlock_irq(&tasklist_lock);
int res;
res = sprintf(buffer,"%u %llu %llu %u %llu %u %llu\n",
- get_delay(task,runs),
- (unsigned long long)get_delay(task,runcpu_total),
- (unsigned long long)get_delay(task,waitcpu_total),
- get_delay(task,num_iowaits),
- (unsigned long long)get_delay(task,iowait_total),
- get_delay(task,num_memwaits),
- (unsigned long long)get_delay(task,mem_iowait_total)
+ (unsigned int) get_delay(task,runs),
+ (uint64_t) get_delay(task,runcpu_total),
+ (uint64_t) get_delay(task,waitcpu_total),
+ (unsigned int) get_delay(task,num_iowaits),
+ (uint64_t) get_delay(task,iowait_total),
+ (unsigned int) get_delay(task,num_memwaits),
+ (uint64_t) get_delay(task,mem_iowait_total)
);
return res;
}
#endif
PROC_TID_VX_INFO,
PROC_TID_IP_INFO,
-#ifdef CONFIG_DELAY_ACCT
- PROC_TID_DELAY_ACCT,
- PROC_TGID_DELAY_ACCT,
-#endif
PROC_TID_FD_DIR = 0x8000, /* 0x8000-0xffff */
};
#ifdef CONFIG_SECURITY
E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
#endif
-#ifdef CONFIG_DELAY_ACCT
- E(PROC_TGID_DELAY_ACCT,"delay", S_IFREG|S_IRUGO),
-#endif
#ifdef CONFIG_KALLSYMS
E(PROC_TGID_WCHAN, "wchan", S_IFREG|S_IRUGO),
#endif
#endif
E(PROC_TGID_VX_INFO, "vinfo", S_IFREG|S_IRUGO),
E(PROC_TGID_IP_INFO, "ninfo", S_IFREG|S_IRUGO),
-#ifdef CONFIG_SCHEDSTATS
- E(PROC_TGID_SCHEDSTAT, "schedstat", S_IFREG|S_IRUGO),
-#endif
{0,0,NULL,0}
};
static struct pid_entry tid_base_stuff[] = {
#ifdef CONFIG_SECURITY
E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
#endif
-#ifdef CONFIG_DELAY_ACCT
- E(PROC_TGID_DELAY_ACCT,"delay", S_IFREG|S_IRUGO),
-#endif
#ifdef CONFIG_KALLSYMS
E(PROC_TID_WCHAN, "wchan", S_IFREG|S_IRUGO),
#endif
#endif
E(PROC_TID_VX_INFO, "vinfo", S_IFREG|S_IRUGO),
E(PROC_TID_IP_INFO, "ninfo", S_IFREG|S_IRUGO),
-#ifdef CONFIG_SCHEDSTATS
- E(PROC_TID_SCHEDSTAT, "schedstat",S_IFREG|S_IRUGO),
-#endif
{0,0,NULL,0}
};
int proc_tgid_stat(struct task_struct*,char*);
int proc_pid_status(struct task_struct*,char*);
int proc_pid_statm(struct task_struct*,char*);
-#ifdef CONFIG_DELAY_ACCT
-int proc_pid_delay(struct task_struct*,char*);
-#endif
static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
{
case PROC_TID_DELAY_ACCT:
case PROC_TGID_DELAY_ACCT:
inode->i_fop = &proc_info_file_operations;
- ei->op.proc_read = proc_pid_delay;
+ ei->op.proc_read = proc_pid_schedstat;
break;
#endif
#ifdef CONFIG_SCHEDSTATS
* File operations for common magic files in rcfs,
* the user interface for CKRM.
*
- *
* Latest version, more details at http://ckrm.sf.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
*/
-/* Changes
+/*
+ * Changes
*
* 23 Apr 2004
* Created from code kept earlier in fs/rcfs/magic_*.c
- *
*/
#include <linux/module.h>
#include <linux/rcfs.h>
-/******************************************************
+/*
* Macros
*
* generic macros to assist in writing magic fileops
*
- *****************************************************/
+ */
#define MAGIC_SHOW(FUNC) \
static int \
}; \
EXPORT_SYMBOL(FUNC ## _fileops);
-/******************************************************************************
- * Shared function used by Target / Reclassify
- *
- *
- *****************************************************************************/
+/*
+ * Shared function used by Members / Reclassify
+ */
-#define TARGET_MAX_INPUT_SIZE 100
+#define MEMBERS_MAX_INPUT_SIZE 100
static ssize_t
-target_reclassify_write(struct file *file, const char __user * buf,
+members_reclassify_write(struct file *file, const char __user * buf,
size_t count, loff_t * ppos, int manual)
{
struct rcfs_inode_info *ri = RCFS_I(file->f_dentry->d_inode);
int rc = -EINVAL;
ckrm_classtype_t *clstype;
- if ((ssize_t) count < 0 || (ssize_t) count > TARGET_MAX_INPUT_SIZE)
+ if ((ssize_t) count < 0 || (ssize_t) count > MEMBERS_MAX_INPUT_SIZE)
return -EINVAL;
-
if (!access_ok(VERIFY_READ, buf, count))
return -EFAULT;
-
down(&(ri->vfs_inode.i_sem));
-
- optbuf = kmalloc(TARGET_MAX_INPUT_SIZE, GFP_KERNEL);
+ optbuf = kmalloc(MEMBERS_MAX_INPUT_SIZE, GFP_KERNEL);
__copy_from_user(optbuf, buf, count);
if (optbuf[count - 1] == '\n')
optbuf[count - 1] = '\0';
-
clstype = ri->core->classtype;
if (clstype->forced_reclassify)
rc = (*clstype->forced_reclassify) (manual ? ri->core: NULL, optbuf);
-
up(&(ri->vfs_inode.i_sem));
kfree(optbuf);
return (!rc ? count : rc);
}
-/******************************************************************************
- * Target
- *
- * pseudo file for manually reclassifying members to a class
- *
- *****************************************************************************/
-
-static ssize_t
-target_write(struct file *file, const char __user * buf,
- size_t count, loff_t * ppos)
-{
- return target_reclassify_write(file,buf,count,ppos,1);
-}
-
-struct file_operations target_fileops = {
- .write = target_write,
-};
-
-EXPORT_SYMBOL(target_fileops);
-
-/******************************************************************************
+/*
* Reclassify
*
* pseudo file for reclassification of an object through CE
- *
- *****************************************************************************/
+ */
static ssize_t
reclassify_write(struct file *file, const char __user * buf,
size_t count, loff_t * ppos)
{
- return target_reclassify_write(file,buf,count,ppos,0);
+ return members_reclassify_write(file,buf,count,ppos,0);
}
struct file_operations reclassify_fileops = {
.write = reclassify_write,
};
-EXPORT_SYMBOL(reclassify_fileops);
+EXPORT_SYMBOL_GPL(reclassify_fileops);
-/******************************************************************************
+/*
* Config
*
* Set/get configuration parameters of a class.
- *
- *****************************************************************************/
+ */
-/* Currently there are no per-class config parameters defined.
+/*
+ * Currently there are no per-class config parameters defined.
* Use existing code as a template
*/
MAGIC_RDWR_FILEOPS(config);
-/******************************************************************************
+/*
* Members
*
* List members of a class
- *
- *****************************************************************************/
+ */
MAGIC_SHOW(members);
MAGIC_OPEN(members);
MAGIC_CLOSE(members);
-MAGIC_RD_FILEOPS(members);
+static ssize_t
+members_write(struct file *file, const char __user * buf,
+ size_t count, loff_t * ppos)
+{
+ return members_reclassify_write(file,buf,count,ppos,1);
+}
+
+MAGIC_RDWR_FILEOPS(members);
-/******************************************************************************
+/*
* Stats
*
* Get/reset class statistics
* No standard set of stats defined. Each resource controller chooses
* its own set of statistics to maintain and export.
- *
- *****************************************************************************/
+ */
#define stats_max_input_size 50
MAGIC_RDWR_FILEOPS(stats);
-/******************************************************************************
+/*
* Shares
*
* Set/get shares of a taskclass.
* Share types and semantics are defined by rcfs and ckrm core
- *
- *****************************************************************************/
+ */
#define SHARES_MAX_INPUT_SIZE 300
-/* The enums for the share types should match the indices expected by
- array parameter to ckrm_set_resshare */
-
-/* Note only the first NUM_SHAREVAL enums correspond to share types,
- the remaining ones are for token matching purposes */
+/*
+ * The enums for the share types should match the indices expected by
+ * array parameter to ckrm_set_resshare
+ *
+ * Note only the first NUM_SHAREVAL enums correspond to share types,
+ * the remaining ones are for token matching purposes
+ */
enum share_token_t {
MY_GUAR, MY_LIM, TOT_GUAR, MAX_LIM, SHARE_RES_TYPE, SHARE_ERR
if (!options)
return 1;
-
while ((p = strsep(&options, ",")) != NULL) {
-
substring_t args[MAX_OPT_ARGS];
int token;
if (!*p)
continue;
-
token = match_token(p, shares_tokens, args);
switch (token) {
case SHARE_RES_TYPE:
default:
return 0;
}
-
}
return 1;
}
CKRM_SHARE_UNCHANGED,
CKRM_SHARE_UNCHANGED
};
-
if ((ssize_t) count < 0 || (ssize_t) count > SHARES_MAX_INPUT_SIZE)
return -EINVAL;
-
if (!access_ok(VERIFY_READ, buf, count))
return -EFAULT;
-
ri = RCFS_I(file->f_dentry->d_parent->d_inode);
-
if (!ri || !ckrm_is_core_valid((ckrm_core_class_t *) (ri->core))) {
printk(KERN_ERR "shares_write: Error accessing core class\n");
return -EFAULT;
}
-
down(&inode->i_sem);
-
core = ri->core;
optbuf = kmalloc(SHARES_MAX_INPUT_SIZE, GFP_KERNEL);
if (!optbuf) {
up(&inode->i_sem);
return -ENOMEM;
}
-
__copy_from_user(optbuf, buf, count);
if (optbuf[count - 1] == '\n')
optbuf[count - 1] = '\0';
-
done = shares_parse(optbuf, &resname, &newshares);
if (!done) {
printk(KERN_ERR "Error parsing shares\n");
rc = -EINVAL;
goto write_out;
}
-
if (core->classtype->set_shares) {
rc = (*core->classtype->set_shares) (core, resname, &newshares);
if (rc) {
goto write_out;
}
}
-
- printk(KERN_DEBUG "Set %s shares to %d %d %d %d\n",
+ printk(KERN_ERR "Set %s shares to %d %d %d %d\n",
resname,
newshares.my_guarantee,
newshares.my_limit,
newshares.total_guarantee, newshares.max_limit);
-
rc = count;
- write_out:
-
+write_out:
up(&inode->i_sem);
kfree(optbuf);
kfree(resname);
/*
* magic file creation/deletion
- *
*/
int rcfs_clear_magic(struct dentry *parent)
struct dentry *mftmp, *mfdentry;
list_for_each_entry_safe(mfdentry, mftmp, &parent->d_subdirs, d_child) {
-
if (!rcfs_is_magic(mfdentry))
continue;
-
if (rcfs_delete_internal(mfdentry))
printk(KERN_ERR
"rcfs_clear_magic: error deleting one\n");
}
-
return 0;
-
}
-EXPORT_SYMBOL(rcfs_clear_magic);
+EXPORT_SYMBOL_GPL(rcfs_clear_magic);
int rcfs_create_magic(struct dentry *parent, struct rcfs_magf magf[], int count)
{
return 0;
}
-EXPORT_SYMBOL(rcfs_create_magic);
+EXPORT_SYMBOL_GPL(rcfs_create_magic);
*
*/
-/* Changes
+/*
+ * Changes
*
* 08 April 2004
* Created.
return 0;
}
-EXPORT_SYMBOL(rcfs_register_engine);
+EXPORT_SYMBOL_GPL(rcfs_register_engine);
int rcfs_unregister_engine(rbce_eng_callback_t * rcbs)
{
EXPORT_SYMBOL(rcfs_unregister_engine);
-/* rcfs_mkroot
+/*
+ * rcfs_mkroot
* Create and return a "root" dentry under /rcfs.
* Also create associated magic files
*
printk(KERN_ERR "Could not create %s\n", rootdesc->name);
return -ENOMEM;
}
-
rootri = RCFS_I(dentry->d_inode);
sz = strlen(rootdesc->name) + strlen(RCFS_ROOT) + 2;
rootri->name = kmalloc(sz, GFP_KERNEL);
return -ENOMEM;
}
snprintf(rootri->name, sz, "%s/%s", RCFS_ROOT, rootdesc->name);
-
if (rootdesc->i_fop)
dentry->d_inode->i_fop = rootdesc->i_fop;
if (rootdesc->i_op)
dentry->d_inode->i_op = rootdesc->i_op;
- // set output parameters
+ /* set output parameters */
*rootde = dentry;
return 0;
}
-EXPORT_SYMBOL(rcfs_mkroot);
+EXPORT_SYMBOL_GPL(rcfs_mkroot);
int rcfs_rmroot(struct dentry *rootde)
{
return 0;
}
-EXPORT_SYMBOL(rcfs_rmroot);
+EXPORT_SYMBOL_GPL(rcfs_rmroot);
int rcfs_register_classtype(ckrm_classtype_t * clstype)
{
struct rcfs_inode_info *rootri;
struct rcfs_magf *mfdesc;
- // Initialize mfdesc, mfcount
+ if (genmfdesc[clstype->mfidx] == NULL) {
+ return -ENOMEM;
+ }
+
clstype->mfdesc = (void *)genmfdesc[clstype->mfidx]->rootmf;
clstype->mfcount = genmfdesc[clstype->mfidx]->rootmflen;
(struct dentry **)&(clstype->rootde));
if (rc)
return rc;
-
rootri = RCFS_I(((struct dentry *)(clstype->rootde))->d_inode);
rootri->core = clstype->default_class;
clstype->default_class->name = rootri->name;
ckrm_core_grab(clstype->default_class);
- // Create magic files under root
+ /* Create magic files under root */
if ((rc = rcfs_create_magic(clstype->rootde, &mfdesc[1],
clstype->mfcount - 1))) {
kfree(rootri->name);
rcfs_delete_internal(clstype->rootde);
return rc;
}
-
return rc;
}
-EXPORT_SYMBOL(rcfs_register_classtype);
+EXPORT_SYMBOL_GPL(rcfs_register_classtype);
int rcfs_deregister_classtype(ckrm_classtype_t * clstype)
{
return rc;
}
-EXPORT_SYMBOL(rcfs_deregister_classtype);
-
-// Common root and magic file entries.
-// root name, root permissions, magic file names and magic file permissions
-// are needed by all entities (classtypes and classification engines) existing
-// under the rcfs mount point
-
-// The common sets of these attributes are listed here as a table. Individual
-// classtypes and classification engines can simple specify the index into the
-// table to initialize their magf entries.
-//
+EXPORT_SYMBOL_GPL(rcfs_deregister_classtype);
#ifdef CONFIG_CKRM_TYPE_TASKCLASS
extern struct rcfs_mfdesc tc_mfdesc;
#endif
-#ifdef CONFIG_CKRM_TYPE_TASKCLASS
+#ifdef CONFIG_CKRM_TYPE_SOCKETCLASS
extern struct rcfs_mfdesc sock_mfdesc;
#endif
-// extern struct rcfs_magf rbce_mfdesc;
+/* Common root and magic file entries.
+ * root name, root permissions, magic file names and magic file permissions
+ * are needed by all entities (classtypes and classification engines) existing
+ * under the rcfs mount point
+ *
+ * The common sets of these attributes are listed here as a table. Individual
+ * classtypes and classification engines can simple specify the index into the
+ * table to initialize their magf entries.
+ */
-struct rcfs_mfdesc *genmfdesc[] = {
+struct rcfs_mfdesc *genmfdesc[CKRM_MAX_CLASSTYPES] = {
#ifdef CONFIG_CKRM_TYPE_TASKCLASS
&tc_mfdesc,
#else
#else
NULL,
#endif
+
};
*
*/
-/* Changes
+/*
+ * Changes
*
* 08 Mar 2004
* Created.
#include <asm/uaccess.h>
#include <linux/rcfs.h>
-#include <linux/ckrm.h>
#include <linux/ckrm_rc.h>
#include <linux/ckrm_ce.h>
return container_of(inode, struct rcfs_inode_info, vfs_inode);
}
-EXPORT_SYMBOL(RCFS_I);
+EXPORT_SYMBOL_GPL(RCFS_I);
static struct inode *rcfs_alloc_inode(struct super_block *sb)
{
}
sb->s_root = root;
- // Link inode and core class
+ /* Link inode and core class */
rootri = RCFS_I(inode);
rootri->name = kmalloc(strlen(RCFS_ROOT) + 1, GFP_KERNEL);
if (!rootri->name) {
rcfs_rootde = root;
rcfs_rootri = rootri;
- // register metatypes
+ /* register metatypes */
for (i = 0; i < CKRM_MAX_CLASSTYPES; i++) {
clstype = ckrm_classtypes[i];
if (clstype == NULL)
printk(KERN_DEBUG "A non null classtype\n");
if ((rc = rcfs_register_classtype(clstype)))
- continue; // could return with an error too
+ continue; /* could return with an error too */
}
- // do post-mount initializations needed by CE
- // this is distinct from CE registration done on rcfs module load
+ /*
+ * do post-mount initializations needed by CE
+ * this is distinct from CE registration done on rcfs module load
+ */
if (rcfs_engine_regd) {
if (rcfs_eng_callbacks.mnt)
if ((rc = (*rcfs_eng_callbacks.mnt) ())) {
printk(KERN_ERR "Error in CE mnt %d\n", rc);
}
}
- // Following comment handled by code above; keep nonetheless if it
- // can be done better
- //
- // register CE's with rcfs
- // check if CE loaded
- // call rcfs_register_engine for each classtype
- // AND rcfs_mkroot (preferably subsume latter in former)
-
+ /*
+ * Following comment handled by code above; keep nonetheless if it
+ * can be done better
+ *
+ * register CE's with rcfs
+ * check if CE loaded
+ * call rcfs_register_engine for each classtype
+ * AND rcfs_mkroot (preferably subsume latter in former)
+ */
return 0;
}
rcfs_mounted--;
for (i = 0; i < CKRM_MAX_CLASSTYPES; i++) {
-
clstype = ckrm_classtypes[i];
if (clstype == NULL || clstype->rootde == NULL)
continue;
if ((rc = rcfs_deregister_classtype(clstype))) {
printk(KERN_ERR "Error removing classtype %s\n",
clstype->name);
- // return ; // can also choose to stop here
}
}
- // do pre-umount shutdown needed by CE
- // this is distinct from CE deregistration done on rcfs module unload
+ /*
+ * do pre-umount shutdown needed by CE
+ * this is distinct from CE deregistration done on rcfs module unload
+ */
if (rcfs_engine_regd) {
if (rcfs_eng_callbacks.umnt)
if ((rc = (*rcfs_eng_callbacks.umnt) ())) {
printk(KERN_ERR "Error in CE umnt %d\n", rc);
- // return ; until error handling improves
+ /* TODO: return ; until error handling improves */
}
}
- // Following comment handled by code above; keep nonetheless if it
- // can be done better
- //
- // deregister CE with rcfs
- // Check if loaded
- // if ce is in one directory /rcfs/ce,
- // rcfs_deregister_engine for all classtypes within above
- // codebase
- // followed by
- // rcfs_rmroot here
- // if ce in multiple (per-classtype) directories
- // call rbce_deregister_engine within ckrm_deregister_classtype
-
- // following will automatically clear rcfs root entry including its
- // rcfs_inode_info
+ /*
+ * Following comment handled by code above; keep nonetheless if it
+ * can be done better
+ *
+ * deregister CE with rcfs
+ * Check if loaded
+ * if ce is in one directory /rcfs/ce,
+ * rcfs_deregister_engine for all classtypes within above
+ * codebase
+ * followed by
+ * rcfs_rmroot here
+ * if ce in multiple (per-classtype) directories
+ * call rbce_deregister_engine within ckrm_deregister_classtype
+ *
+ * following will automatically clear rcfs root entry including its
+ * rcfs_inode_info
+ */
generic_shutdown_super(sb);
-
- // printk(KERN_ERR "Removed all entries\n");
}
static struct file_system_type rcfs_fs_type = {
ret = register_filesystem(&rcfs_fs_type);
if (ret)
goto init_register_err;
-
ret = rcfs_init_inodecache();
if (ret)
goto init_cache_err;
-
rcfs_fn = my_rcfs_fn;
-
- // Due to tight coupling of this module with ckrm
- // do not allow this module to be removed.
+ /*
+ * Due to tight coupling of this module with ckrm
+ * do not allow this module to be removed.
+ */
try_module_get(THIS_MODULE);
return ret;
- init_cache_err:
+init_cache_err:
unregister_filesystem(&rcfs_fs_type);
- init_register_err:
+init_register_err:
return ret;
}
}
module_init(init_rcfs_fs)
- module_exit(exit_rcfs_fs)
+module_exit(exit_rcfs_fs)
- MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL");
+++ /dev/null
-/* ckrm.h - Class-based Kernel Resource Management (CKRM)
- *
- * Copyright (C) Hubertus Franke, IBM Corp. 2003,2004
- * (C) Shailabh Nagar, IBM Corp. 2003
- * (C) Chandra Seetharaman, IBM Corp. 2003
- *
- *
- * Provides a base header file including macros and basic data structures.
- *
- * Latest version, more details at http://ckrm.sf.net
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-/* Changes
- *
- * 28 Aug 2003
- * Created.
- * 06 Nov 2003
- * Made modifications to suit the new RBCE module.
- * 10 Nov 2003
- * Added callbacks_active and surrounding logic. Added task paramter
- * for all CE callbacks.
- * 19 Nov 2004
- * New Event callback structure
- */
-
-#ifndef _LINUX_CKRM_H
-#define _LINUX_CKRM_H
-
-#ifdef CONFIG_CKRM
-
-// Data structure and function to get the list of registered
-// resource controllers.
-
-// #include <linux/sched.h>
-
-/* CKRM defines a set of events at particular points in the kernel
- * at which callbacks registered by various class types are called
- */
-
-enum ckrm_event {
- /* we distinguish various events types
- *
- * (a) CKRM_LATCHABLE_EVENTS
- * events can be latched for event callbacks by classtypes
- *
- * (b) CKRM_NONLATACHBLE_EVENTS
- * events can not be latched but can be used to call classification
- *
- * (c) event that are used for notification purposes
- * range: [ CKRM_EVENT_CANNOT_CLASSIFY .. )
- */
-
- /* events (a) */
-
- CKRM_LATCHABLE_EVENTS,
-
- CKRM_EVENT_NEWTASK = CKRM_LATCHABLE_EVENTS,
- CKRM_EVENT_FORK,
- CKRM_EVENT_EXIT,
- CKRM_EVENT_EXEC,
- CKRM_EVENT_UID,
- CKRM_EVENT_GID,
- CKRM_EVENT_XID,
- CKRM_EVENT_LOGIN,
- CKRM_EVENT_USERADD,
- CKRM_EVENT_USERDEL,
- CKRM_EVENT_LISTEN_START,
- CKRM_EVENT_LISTEN_STOP,
- CKRM_EVENT_APPTAG,
-
- /* events (b) */
-
- CKRM_NONLATCHABLE_EVENTS,
-
- CKRM_EVENT_RECLASSIFY = CKRM_NONLATCHABLE_EVENTS,
-
- /* events (c) */
- CKRM_NOTCLASSIFY_EVENTS,
-
- CKRM_EVENT_MANUAL = CKRM_NOTCLASSIFY_EVENTS,
-
- CKRM_NUM_EVENTS
-};
-#endif
-
-#ifdef __KERNEL__
-#ifdef CONFIG_CKRM
-
-extern void ckrm_invoke_event_cb_chain(enum ckrm_event ev, void *arg);
-
-typedef void (*ckrm_event_cb) (void *arg);
-
-struct ckrm_hook_cb {
- ckrm_event_cb fct;
- struct ckrm_hook_cb *next;
-};
-
-#define CKRM_DEF_CB(EV,fct) \
-static inline void ckrm_cb_##fct(void) \
-{ \
- ckrm_invoke_event_cb_chain(CKRM_EVENT_##EV,NULL); \
-}
-
-#define CKRM_DEF_CB_ARG(EV,fct,argtp) \
-static inline void ckrm_cb_##fct(argtp arg) \
-{ \
- ckrm_invoke_event_cb_chain(CKRM_EVENT_##EV,(void*)arg); \
-}
-
-#else // !CONFIG_CKRM
-
-#define CKRM_DEF_CB(EV,fct) \
-static inline void ckrm_cb_##fct(void) { }
-
-#define CKRM_DEF_CB_ARG(EV,fct,argtp) \
-static inline void ckrm_cb_##fct(argtp arg) { }
-
-#endif // CONFIG_CKRM
-
-/*-----------------------------------------------------------------
- * define the CKRM event functions
- * EVENT FCT ARG
- *-----------------------------------------------------------------*/
-
-// types we refer at
-struct task_struct;
-struct sock;
-struct user_struct;
-
-CKRM_DEF_CB_ARG(FORK, fork, struct task_struct *);
-CKRM_DEF_CB_ARG(EXEC, exec, const char *);
-CKRM_DEF_CB(UID, uid);
-CKRM_DEF_CB(GID, gid);
-CKRM_DEF_CB_ARG(XID, xid, struct task_struct *);
-CKRM_DEF_CB(APPTAG, apptag);
-CKRM_DEF_CB(LOGIN, login);
-CKRM_DEF_CB_ARG(USERADD, useradd, struct user_struct *);
-CKRM_DEF_CB_ARG(USERDEL, userdel, struct user_struct *);
-CKRM_DEF_CB_ARG(LISTEN_START, listen_start, struct sock *);
-CKRM_DEF_CB_ARG(LISTEN_STOP, listen_stop, struct sock *);
-
-// some other functions required
-#ifdef CONFIG_CKRM
-extern void ckrm_init(void);
-void ckrm_cb_newtask(struct task_struct *);
-void ckrm_cb_exit(struct task_struct *);
-#else
-#define ckrm_init(x) do { } while (0)
-#define ckrm_cb_newtask(x) do { } while (0)
-#define ckrm_cb_exit(x) do { } while (0)
-#endif
-
-extern int get_exe_path_name(struct task_struct *, char *, int);
-
-#endif // __KERNEL__
-
-#endif // _LINUX_CKRM_H
-/* ckrm_ce.h - Header file to be used by Classification Engine of CKRM
+/*
+ * ckrm_ce.h - Header file to be used by Classification Engine of CKRM
*
* Copyright (C) Hubertus Franke, IBM Corp. 2003
* (C) Shailabh Nagar, IBM Corp. 2003
#ifdef CONFIG_CKRM
-#include <linux/ckrm.h> // getting the event names
+#include <linux/ckrm_events.h>
-/* Action parameters identifying the cause of a task<->class notify callback
+/*
+ * Action parameters identifying the cause of a task<->class notify callback
* these can perculate up to user daemon consuming records send by the
* classification engine
*/
int always_callback; /* set if CE should always be called back
regardless of numclasses */
-
-
-
/* callbacks which are called without holding locks */
unsigned long c_interest; /* set of classification events of
- interest to CE
- */
+ * interest to CE
+ */
/* generic classify */
- ce_classify_fct_t classify;
+ ce_classify_fct_t classify;
+
/* class added */
void (*class_add) (const char *name, void *core, int classtype);
+
/* class deleted */
void (*class_delete) (const char *name, void *core, int classtype);
-
/* callbacks which are called while holding task_lock(tsk) */
-
unsigned long n_interest; /* set of notification events of
- interest to CE
- */
+ * interest to CE
+ */
/* notify on class switch */
ce_notify_fct_t notify;
-
} ckrm_eng_callback_t;
struct inode;
struct dentry;
typedef struct rbce_eng_callback {
- int (*mkdir) (struct inode *, struct dentry *, int); // mkdir
- int (*rmdir) (struct inode *, struct dentry *); // rmdir
+ int (*mkdir) (struct inode *, struct dentry *, int); /* mkdir */
+ int (*rmdir) (struct inode *, struct dentry *); /* rmdir */
int (*mnt) (void);
int (*umnt) (void);
} rbce_eng_callback_t;
extern int ckrm_register_engine(const char *name, ckrm_eng_callback_t *);
extern int ckrm_unregister_engine(const char *name);
-extern void *ckrm_classobj(char *, int *classtype);
+extern void *ckrm_classobj(const char *, int *classtype);
extern int get_exe_path_name(struct task_struct *t, char *filename,
int max_size);
extern int ckrm_reclassify(int pid);
#ifndef _LINUX_CKRM_RC_H
-// ckrm kernel has inlined functions for this which are exported
+
extern void ckrm_core_grab(void *);
extern void ckrm_core_drop(void *);
#endif
-#endif // CONFIG_CKRM
-
-#endif // __KERNEL__
-
-#endif // _LINUX_CKRM_CE_H
+#endif /* CONFIG_CKRM */
+#endif /* __KERNEL__ */
+#endif /* _LINUX_CKRM_CE_H */
CKRM_EVENT_EXEC,
CKRM_EVENT_UID,
CKRM_EVENT_GID,
+ CKRM_EVENT_XID,
CKRM_EVENT_LOGIN,
CKRM_EVENT_USERADD,
CKRM_EVENT_USERDEL,
CKRM_DEF_CB_ARG(EXEC, exec, const char *);
CKRM_DEF_CB(UID, uid);
CKRM_DEF_CB(GID, gid);
+CKRM_DEF_CB_ARG(XID, xid, struct task_struct *);
CKRM_DEF_CB(APPTAG, apptag);
CKRM_DEF_CB(LOGIN, login);
CKRM_DEF_CB_ARG(USERADD, useradd, struct user_struct *);
-/* ckrm_rc.h - Header file to be used by Resource controllers of CKRM
+/*
+ * ckrm_rc.h - Header file to be used by Resource controllers of CKRM
*
* Copyright (C) Hubertus Franke, IBM Corp. 2003
* (C) Shailabh Nagar, IBM Corp. 2003
* Provides data structures, macros and kernel API of CKRM for
* resource controllers.
*
- * Latest version, more details at http://ckrm.sf.net
+ * More details at http://ckrm.sf.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*
*/
-/* Changes
+/*
+ * Changes
*
* 12 Nov 2003
* Created.
#ifdef CONFIG_CKRM
#include <linux/list.h>
-#include <linux/ckrm.h>
+#include <linux/ckrm_events.h>
#include <linux/ckrm_ce.h>
#include <linux/seq_file.h>
-/* maximum number of class types */
-#define CKRM_MAX_CLASSTYPES 32
-/* maximum classtype name length */
-#define CKRM_MAX_CLASSTYPE_NAME 32
+#define CKRM_MAX_CLASSTYPES 32 /* maximum number of class types */
+#define CKRM_MAX_CLASSTYPE_NAME 32 /* maximum classtype name length */
-/* maximum resource controllers per classtype */
-#define CKRM_MAX_RES_CTLRS 8
-/* maximum resource controller name length */
-#define CKRM_MAX_RES_NAME 128
+#define CKRM_MAX_RES_CTLRS 8 /* maximum resource controllers per classtype */
+#define CKRM_MAX_RES_NAME 128 /* maximum resource controller name length */
struct ckrm_core_class;
struct ckrm_classtype;
-/*****************************************************************************
+/*
* Share specifications
- *****************************************************************************/
+ */
typedef struct ckrm_shares {
int my_guarantee;
int my_limit;
int total_guarantee;
int max_limit;
- int unused_guarantee; // not used as parameters
- int cur_max_limit; // not used as parameters
+ int unused_guarantee; /* not used as parameters */
+ int cur_max_limit; /* not used as parameters */
} ckrm_shares_t;
#define CKRM_SHARE_UNCHANGED (-1)
#define CKRM_SHARE_DFLT_TOTAL_GUARANTEE (100)
#define CKRM_SHARE_DFLT_MAX_LIMIT (100)
-/******************************************************************************
+/*
* RESOURCE CONTROLLERS
- *****************************************************************************/
+ */
/* resource controller callback structure */
typedef struct ckrm_res_ctlr {
char res_name[CKRM_MAX_RES_NAME];
- int res_hdepth; // maximum hierarchy
- int resid; // (for now) same as the enum resid
- struct ckrm_classtype *classtype; // classtype owning this res ctlr
+ int res_hdepth; /* maximum hierarchy */
+ int resid; /* (for now) same as the enum resid */
+ struct ckrm_classtype *classtype; /* classtype owning this res ctlr */
/* allocate/free new resource class object for resource controller */
void *(*res_alloc) (struct ckrm_core_class * this,
int (*set_config) (void *, const char *cfgstr);
void (*change_resclass) (void *, void *, void *);
-
} ckrm_res_ctlr_t;
-/******************************************************************************
+/*
* CKRM_CLASSTYPE
*
* A <struct ckrm_classtype> object describes a dimension for CKRM to classify
* along. Need to provide methods to create and manipulate class objects in
* this dimension
- *****************************************************************************/
+ */
/* list of predefined class types, we always recognize */
#define CKRM_CLASSTYPE_TASK_CLASS 0
#define CKRM_MAX_TYPENAME_LEN 32
typedef struct ckrm_classtype {
- /* Hubertus: Rearrange slots later for cache friendliness */
+ /* TODO: Review for cache alignment */
/* resource controllers */
- spinlock_t res_ctlrs_lock; // protect res ctlr related data
- int max_res_ctlrs; // max number of res ctlrs allowed
- int max_resid; // max resid used
- int resid_reserved; // max number of reserved controllers
- long bit_res_ctlrs; // bitmap of resource ID used
+
+ spinlock_t res_ctlrs_lock; /* protect res ctlr related data */
+ int max_res_ctlrs; /* max number of res ctlrs allowed */
+ int max_resid; /* max resid used */
+ int resid_reserved; /* max number of reserved controllers */
+ long bit_res_ctlrs; /* bitmap of resource ID used */
atomic_t nr_resusers[CKRM_MAX_RES_CTLRS];
ckrm_res_ctlr_t *res_ctlrs[CKRM_MAX_RES_CTLRS];
-
/* state about my classes */
struct ckrm_core_class *default_class;
- struct list_head classes; // link all classes of this classtype
+ struct list_head classes; /* link all classes of this classtype */
int num_classes;
/* state about my ce interaction */
- atomic_t ce_regd; // if CE registered
- int ce_cb_active; // if Callbacks active
- atomic_t ce_nr_users; // number of active transient calls
- struct ckrm_eng_callback ce_callbacks; // callback engine
-
- // Begin classtype-rcfs private data. No rcfs/fs specific types used.
- int mfidx; // Index into genmfdesc array used to initialize
- void *mfdesc; // Array of descriptors of root and magic files
- int mfcount; // length of above array
- void *rootde; // root dentry created by rcfs
- // End rcfs private data
-
- char name[CKRM_MAX_TYPENAME_LEN]; // currently same as mfdesc[0]->name
- // but could be different
- int typeID; // unique TypeID
- int maxdepth; // maximum depth supported
+ atomic_t ce_regd; /* if CE registered */
+ int ce_cb_active; /* if Callbacks active */
+ atomic_t ce_nr_users; /* number of active transient calls */
+ struct ckrm_eng_callback ce_callbacks; /* callback engine */
+
+ /* Begin classtype-rcfs private data. No rcfs/fs specific types used. */
+
+ int mfidx; /* Index into genmfdesc array used to initialize */
+ void *mfdesc; /* Array of descriptors of root and magic files */
+ int mfcount; /* length of above array */
+ void *rootde; /* root dentry created by rcfs */
+ /* End rcfs private data */
+
+ char name[CKRM_MAX_TYPENAME_LEN]; /* currently same as mfdesc[0]->name */
+ /* but could be different */
+ int typeID; /* unique TypeID */
+ int maxdepth; /* maximum depth supported */
/* functions to be called on any class type by external API's */
/* class initialization for new RC */
void (*add_resctrl) (struct ckrm_core_class *, int resid);
-
} ckrm_classtype_t;
-/******************************************************************************
+/*
* CKRM CORE CLASS
* common part to any class structure (i.e. instance of a classtype)
- ******************************************************************************/
+ */
-/* basic definition of a hierarchy that is to be used by the the CORE classes
+/*
+ * basic definition of a hierarchy that is to be used by the the CORE classes
* and can be used by the resource class objects
*/
typedef struct ckrm_core_class {
struct ckrm_classtype *classtype;
- void *res_class[CKRM_MAX_RES_CTLRS]; // resource classes
- spinlock_t class_lock; // protects list,array above
+ void *res_class[CKRM_MAX_RES_CTLRS]; /* resource classes */
+ spinlock_t class_lock; /* protects list,array above */
-
- struct list_head objlist; // generic object list
- struct list_head clslist; // peer classtype classes
- struct dentry *dentry; // dentry of inode in the RCFS
+ struct list_head objlist; /* generic object list */
+ struct list_head clslist; /* peer classtype classes */
+ struct dentry *dentry; /* dentry of inode in the RCFS */
int magic;
- struct ckrm_hnode hnode; // hierarchy
- rwlock_t hnode_rwlock; // protects hnode above.
+ struct ckrm_hnode hnode; /* hierarchy */
+ rwlock_t hnode_rwlock; /* protects hnode above. */
atomic_t refcnt;
const char *name;
- int delayed; // core deletion delayed
- // because of race conditions
+ int delayed; /* core deletion delayed */
+ /* because of race conditions */
} ckrm_core_class_t;
/* type coerce between derived class types and ckrm core class type */
/* what type is a class of ISA */
#define class_isa(clsptr) (class_core(clsptr)->classtype)
-/******************************************************************************
+/*
* OTHER
- ******************************************************************************/
+ */
#define ckrm_get_res_class(rescls, resid, type) \
((type*) (((resid != -1) && ((rescls) != NULL) \
struct ckrm_core_class *parent,
const char *name);
extern int ckrm_release_core_class(struct ckrm_core_class *);
-// Hubertus .. can disappear after cls del debugging
-extern struct ckrm_res_ctlr *ckrm_resctlr_lookup(struct ckrm_classtype *type,
- const char *resname);
-#if 0
+/* TODO: can disappear after cls del debugging */
-// Hubertus ... need to straighten out all these I don't think we will even
-// call this or are we
-
-/* interface to the RCFS filesystem */
-extern struct ckrm_core_class *ckrm_alloc_core_class(struct ckrm_core_class *,
- const char *, int);
-
-// Reclassify the given pid to the given core class by force
-extern void ckrm_forced_reclassify_pid(int, struct ckrm_core_class *);
-
-// Reclassify the given net_struct to the given core class by force
-extern void ckrm_forced_reclassify_laq(struct ckrm_net_struct *,
- struct ckrm_core_class *);
-
-#endif
+extern struct ckrm_res_ctlr *ckrm_resctlr_lookup(struct ckrm_classtype *type,
+ const char *resname);
extern void ckrm_lock_hier(struct ckrm_core_class *);
extern void ckrm_unlock_hier(struct ckrm_core_class *);
extern int ckrm_class_reset_stats(struct ckrm_core_class *core,
const char *resname, const char *unused);
-#if 0
-extern void ckrm_ns_hold(struct ckrm_net_struct *);
-extern void ckrm_ns_put(struct ckrm_net_struct *);
-extern void *ckrm_set_rootcore_byname(char *, void *);
-#endif
-
static inline void ckrm_core_grab(struct ckrm_core_class *core)
{
if (core)
static inline void ckrm_core_drop(struct ckrm_core_class *core)
{
- // only make definition available in this context
+ /* only make definition available in this context */
extern void ckrm_free_core_class(struct ckrm_core_class *core);
if (core && (atomic_dec_and_test(&core->refcnt)))
ckrm_free_core_class(core);
return (core && (core->magic == CKRM_CORE_MAGIC));
}
-// iterate through all associate resource controllers:
-// requires following arguments (ckrm_core_class *cls,
-// ckrm_res_ctrl *ctlr,
-// void *robj,
-// int bmap)
+/*
+ * iterate through all associate resource controllers:
+ * requires following arguments (ckrm_core_class *cls,
+ * ckrm_res_ctrl *ctlr,
+ * void *robj,
+ * int bmap)
+ */
+
#define forall_class_resobjs(cls,rcbs,robj,bmap) \
for ( bmap=((cls->classtype)->bit_res_ctlrs) ; \
({ int rid; ((rid=ffs(bmap)-1) >= 0) && \
)
extern struct ckrm_classtype *ckrm_classtypes[];
-/* should provide a different interface */
-
-/*-----------------------------------------------------------------------------
- * CKRM event callback specification for the classtypes or resource controllers
- * typically an array is specified using CKRM_EVENT_SPEC terminated with
- * CKRM_EVENT_SPEC_LAST and then that array is registered using
- * ckrm_register_event_set.
- * Individual registration of event_cb is also possible
- *-----------------------------------------------------------------------------*/
-
-struct ckrm_event_spec {
- enum ckrm_event ev;
- struct ckrm_hook_cb cb;
-};
-#define CKRM_EVENT_SPEC(EV,FCT) { CKRM_EVENT_##EV, \
- { (ckrm_event_cb)FCT, NULL } }
-
-int ckrm_register_event_set(struct ckrm_event_spec especs[]);
-int ckrm_unregister_event_set(struct ckrm_event_spec especs[]);
-int ckrm_register_event_cb(enum ckrm_event ev, struct ckrm_hook_cb *cb);
-int ckrm_unregister_event_cb(enum ckrm_event ev, struct ckrm_hook_cb *cb);
-
-/******************************************************************************
+
+/*
* CE Invocation interface
- ******************************************************************************/
+ */
#define ce_protect(ctype) (atomic_inc(&((ctype)->ce_nr_users)))
#define ce_release(ctype) (atomic_dec(&((ctype)->ce_nr_users)))
-// CE Classification callbacks with
+/* CE Classification callbacks with */
#define CE_CLASSIFY_NORET(ctype, event, objs_to_classify...) \
do { \
cls,objs_to_classify); \
} while (0)
-/***************
+/*
* RCFS related
- ***************/
+ */
/* vars needed by other modules/core */
extern int rcfs_mounted;
extern int rcfs_engine_regd;
-#endif // CONFIG_CKRM
-
-#endif // __KERNEL__
-
-#endif // _LINUX_CKRM_RC_H
+#endif /* CONFIG_CKRM */
+#endif /* __KERNEL__ */
+#endif /* _LINUX_CKRM_RC_H */
+/* ckrm_tc.h - Header file to be used by task class users
+ *
+ * Copyright (C) Hubertus Franke, IBM Corp. 2003, 2004
+ *
+ * Provides data structures, macros and kernel API for the
+ * classtype, taskclass.
+ *
+ * Latest version, more details at http://ckrm.sf.net
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+/* Changes
+ *
+ * 12 Apr 2004
+ * Created.
+ */
+
+#ifndef _LINUX_CKRM_TC_H_
+#define _LINUX_CKRM_TC_H_
+
+#ifdef CONFIG_CKRM_TYPE_TASKCLASS
#include <linux/ckrm_rc.h>
#define TASK_CLASS_TYPE_NAME "taskclass"
// which has the mfdesc entry that taskclass wants to use
#define TC_MF_IDX 0
-extern int ckrm_forced_reclassify_pid(int pid, struct ckrm_task_class *cls);
+extern int ckrm_forced_reclassify_pid(int, struct ckrm_task_class *);
+
+#else // CONFIG_CKRM_TYPE_TASKCLASS
+
+#define ckrm_forced_reclassify_pid(a, b) (0)
+
+#endif
+
+#endif // _LINUX_CKRM_TC_H_
#include <linux/kernel.h>
#include <linux/fs.h>
-#include <linux/ckrm.h>
+#include <linux/ckrm_events.h>
#include <linux/ckrm_rc.h>
#include <linux/ckrm_ce.h>
-/* The following declarations cannot be included in any of ckrm*.h files
- without jumping hoops. Remove later when rearrangements done */
-
-// Hubertus .. taken out
-//extern ckrm_res_callback_t ckrm_res_ctlrs[CKRM_MAX_RES_CTLRS];
+/*
+ * The following declarations cannot be included in any of ckrm*.h files
+ * without jumping hoops. Remove later when rearrangements done
+ */
#define RCFS_MAGIC 0x4feedbac
#define RCFS_MAGF_NAMELEN 20
};
struct rcfs_mfdesc {
- struct rcfs_magf *rootmf; // Root directory and its magic files
- int rootmflen; // length of above array
- // Can have a different magf describing magic files
- // for non-root entries too
+ struct rcfs_magf *rootmf; /* Root directory and its magic files */
+ int rootmflen; /* length of above array */
+ /*
+ * Can have a different magf describing magic files
+ * for non-root entries too.
+ */
};
extern struct rcfs_mfdesc *genmfdesc[];
extern struct file_operations reclassify_fileops;
extern struct file_operations rcfs_file_operations;
-// Callbacks into rcfs from ckrm
+/* Callbacks into rcfs from ckrm */
typedef struct rcfs_functions {
int (*mkroot) (struct rcfs_magf *, int, struct dentry **);
int rcfs_mkroot(struct rcfs_magf *, int, struct dentry **);
int rcfs_rmroot(struct dentry *);
-#define RCFS_ROOT "/rcfs" // Hubertus .. we should use the mount point
- // instead of hardcoded
+#define RCFS_ROOT "/rcfs" /* TODO: Should use the mount point */
extern struct dentry *rcfs_rootde;
extern rbce_eng_callback_t rcfs_eng_callbacks;
-#endif /* _LINUX_RCFS_H */
+#endif /* _LINUX_RCFS_H */
you want to run the DOS emulator dosemu under Linux (read the
DOSEMU-HOWTO, available from <http://www.tldp.org/docs.html#howto>),
you'll need to say Y here.
- DOSEMU-HOWTO, available from <http://www.tldp.org/docs.html#howto>),
- you'll need to say Y here.
You can find documentation about IPC with "info ipc" and also in
section 6.4 of the Linux Programmer's Guide, available from
one of the resource controllers below. Say N if you are unsure.
config RCFS_FS
- tristate "Resource Class File System (User API)"
- depends on CKRM
- help
+ tristate "Resource Class File System (User API)"
+ depends on CKRM
+ help
RCFS is the filesystem API for CKRM. This separate configuration
option is provided only for debugging and will eventually disappear
since rcfs will be automounted whenever CKRM is configured.
- Say N if unsure, Y if you've enabled CKRM, M to debug rcfs
+ Say N if unsure, Y if you've enabled CKRM, M to debug rcfs
initialization.
config CKRM_TYPE_TASKCLASS
bool "Class Manager for Task Groups"
- depends on CKRM
+ depends on CKRM && RCFS_FS
help
TASKCLASS provides the extensions for CKRM to track task classes
This is the base to enable task class based resource control for
Say N if unsure, Y to use the feature.
+
config CKRM_RES_NUMTASKS
tristate "Number of Tasks Resource Manager"
depends on CKRM_TYPE_TASKCLASS
If unsure, say N.
+choice
+ prompt "Classification Engine"
+ depends on CKRM && RCFS_FS
+ optional
+ help
+ Select a classification engine (CE) that assists in
+ automatic classification of kernel objects managed by CKRM when
+ they are created. Without a CE, a user must manually
+ classify objects into classes. Processes inherit their parent's
+ classification.
+
+ Only one engine can be built into the kernel though all can be
+ built as modules (only one will load).
+
+ If unsure, say N.
+
config CKRM_RBCE
- tristate "Vanilla Rule-based Classification Engine (RBCE)"
- depends on CKRM && RCFS_FS
- default m
+ tristate "Vanilla RBCE"
help
- Provides an optional module to support creation of rules for automatic
- classification of kernel objects. Rules are created/deleted/modified
- through an rcfs interface. RBCE is not required for CKRM.
-
- If unsure, say N.
+ Vanilla Rule-based Classification Engine (RBCE). Rules for
+ classifying kernel objects are created/deleted/modified through
+ a RCFS directory using a filesystem interface.
+
+ Any CE is optional. If unsure, say N.
config CKRM_CRBCE
- tristate "Enhanced Rule-based Classification Engine (RBCE)"
- depends on CKRM && RCFS_FS && RELAYFS_FS && DELAY_ACCT
- default m
+ tristate "Enhanced RBCE"
+ depends on DELAY_ACCT && RELAYFS_FS
help
- Provides an optional module to support creation of rules for automatic
- classification of kernel objects, just like RBCE above. In addition,
- CRBCE provides per-process delay data (requires DELAY_ACCT configured)
- enabled) and makes information on significant kernel events available
- to userspace tools through relayfs (requires RELAYFS_FS configured).
+ Enhanced Rule-based Classification Engine (CRBCE). Like the Vanilla
+ RBCE, rules for classifying kernel objects are created, deleted and
+ modified through a RCFS directory using a filesystem interface
+ (requires CKRM_RCFS configured).
+
+ In addition, CRBCE provides per-process delay data
+ (requires DELAY_ACCT configured) and makes information on significant
+ kernel events available to userspace tools through relayfs
+ (requires RELAYFS_FS configured).
- If unsure, say N.
+ Any CE is optional. If unsure, say N.
+
+endchoice
endmenu
I/O delays are recorded for memory and regular I/O.
Information is accessible through /proc/<pid>/delay.
-
config KALLSYMS
bool "Load all symbols for debugging/kksymoops" if EMBEDDED
default y
#include <linux/rmap.h>
#include <linux/mempolicy.h>
#include <linux/key.h>
+#include <linux/ckrm_events.h>
+#include <linux/ckrm_sched.h>
#include <asm/io.h>
#include <asm/bugs.h>
#include <asm/setup.h>
-#include <linux/ckrm.h>
-#ifdef CONFIG_CKRM_CPU_SCHEDULE
-int __init init_ckrm_sched_res(void);
-#else
-#define init_ckrm_sched_res() ((void)0)
-#endif
-//#include <linux/ckrm_sched.h>
-
/*
* This is one of the first .c files built. Error out early
* if we have compiler trouble..
#
ifeq ($(CONFIG_CKRM),y)
- obj-y = ckrm.o ckrmutils.o ckrm_numtasks_stub.o rbce/
+ obj-y = ckrm_events.o ckrm.o ckrmutils.o ckrm_numtasks_stub.o rbce/
endif
- obj-$(CONFIG_CKRM_TYPE_TASKCLASS) += ckrm_tc.o
- obj-$(CONFIG_CKRM_RES_NUMTASKS) += ckrm_numtasks.o
- obj-$(CONFIG_CKRM_TYPE_SOCKETCLASS) += ckrm_sockc.o
- obj-$(CONFIG_CKRM_RES_LISTENAQ) += ckrm_listenaq.o
- obj-$(CONFIG_CKRM_CPU_SCHEDULE) += ckrm_cpu_class.o ckrm_cpu_monitor.o
- obj-$(CONFIG_CKRM_RES_MEM) += ckrm_mem.o
- obj-$(CONFIG_CKRM_RES_NULL) += ckrm_null_class.o
+
+obj-$(CONFIG_CKRM_TYPE_TASKCLASS) += ckrm_tc.o
+obj-$(CONFIG_CKRM_TYPE_SOCKETCLASS) += ckrm_sockc.o
+obj-$(CONFIG_CKRM_RES_NUMTASKS) += ckrm_numtasks.o
+obj-$(CONFIG_CKRM_RES_LISTENAQ) += ckrm_listenaq.o
+obj-$(CONFIG_CKRM_CPU_SCHEDULE) += ckrm_cpu_class.o ckrm_cpu_monitor.o
+obj-$(CONFIG_CKRM_RES_MEM) += ckrm_mem.o
+obj-$(CONFIG_CKRM_RES_NULL) += ckrm_null_class.o
*
*/
-/* Changes
+/*
+ * Changes
*
* 28 Aug 2003
* Created.
#include <net/sock.h>
#include <linux/ip.h>
-rwlock_t ckrm_class_lock = RW_LOCK_UNLOCKED; // protect classlists
+rwlock_t ckrm_class_lock = RW_LOCK_UNLOCKED; /* protects classlists */
struct rcfs_functions rcfs_fn;
-EXPORT_SYMBOL(rcfs_fn);
+EXPORT_SYMBOL_GPL(rcfs_fn);
-// rcfs state needed by another module
-int rcfs_engine_regd;
-EXPORT_SYMBOL(rcfs_engine_regd);
+int rcfs_engine_regd; /* rcfs state needed by another module */
+EXPORT_SYMBOL_GPL(rcfs_engine_regd);
int rcfs_mounted;
-EXPORT_SYMBOL(rcfs_mounted);
-
-/**************************************************************************
- * Helper Functions *
- **************************************************************************/
+EXPORT_SYMBOL_GPL(rcfs_mounted);
/*
- * Return TRUE if the given core class pointer is valid.
+ * Helper Functions
*/
/*
);
}
-struct ckrm_res_ctlr *ckrm_resctlr_lookup(struct ckrm_classtype *clstype,
+/*
+ * Return TRUE if the given core class pointer is valid.
+ */
+static 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(char *classname, int *classTypeID)
+void *ckrm_classobj(const char *classname, int *classTypeID)
{
int i;
return NULL;
}
-EXPORT_SYMBOL(is_res_regd);
-EXPORT_SYMBOL(ckrm_classobj);
+EXPORT_SYMBOL_GPL(is_res_regd);
+EXPORT_SYMBOL_GPL(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(ckrm_lock_hier);
-EXPORT_SYMBOL(ckrm_unlock_hier);
-EXPORT_SYMBOL(ckrm_get_next_child);
+EXPORT_SYMBOL_GPL(ckrm_lock_hier);
+EXPORT_SYMBOL_GPL(ckrm_unlock_hier);
+EXPORT_SYMBOL_GPL(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)
{
- // Hubertus ... should replace name with dentry or add dentry ?
+ /* TODO: Should replace name with dentry or add dentry? */
int i;
- // Hubertus .. how is this used in initialization
-
+ /* TODO: 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;
}
- // FIXME: probably need to also call deregistration function
+ /* TODO: 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
- *******************************************************************/
-
-/* Hubertus ... we got to do some locking here */
+/*
+ * Class Type Registration
+ */
+/* TODO: What locking is needed here?*/
struct ckrm_classtype *ckrm_classtypes[CKRM_MAX_CLASSTYPES];
-// really should build a better interface for this
-EXPORT_SYMBOL(ckrm_classtypes);
+EXPORT_SYMBOL_GPL(ckrm_classtypes);
int ckrm_register_classtype(struct ckrm_classtype *clstype)
{
clstype->typeID = tid;
ckrm_classtypes[tid] = clstype;
- /* Hubertus .. we need to call the callbacks of the RCFS client */
+ /* TODO: 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
- // prepare init_task and then rely on inheritance of properties
- ckrm_cb_newtask(&init_task);
- printk(KERN_DEBUG "CKRM Initialization done\n");
+ printk("CKRM Initialization done\n");
}
-EXPORT_SYMBOL(ckrm_register_engine);
-EXPORT_SYMBOL(ckrm_unregister_engine);
+EXPORT_SYMBOL_GPL(ckrm_register_engine);
+EXPORT_SYMBOL_GPL(ckrm_unregister_engine);
-EXPORT_SYMBOL(ckrm_register_res_ctlr);
-EXPORT_SYMBOL(ckrm_unregister_res_ctlr);
+EXPORT_SYMBOL_GPL(ckrm_register_res_ctlr);
+EXPORT_SYMBOL_GPL(ckrm_unregister_res_ctlr);
-EXPORT_SYMBOL(ckrm_init_core_class);
-EXPORT_SYMBOL(ckrm_free_core_class);
-EXPORT_SYMBOL(ckrm_release_core_class);
+EXPORT_SYMBOL_GPL(ckrm_init_core_class);
+EXPORT_SYMBOL_GPL(ckrm_free_core_class);
+EXPORT_SYMBOL_GPL(ckrm_release_core_class);
-EXPORT_SYMBOL(ckrm_register_classtype);
-EXPORT_SYMBOL(ckrm_unregister_classtype);
-EXPORT_SYMBOL(ckrm_find_classtype_by_name);
+EXPORT_SYMBOL_GPL(ckrm_register_classtype);
+EXPORT_SYMBOL_GPL(ckrm_unregister_classtype);
+EXPORT_SYMBOL_GPL(ckrm_find_classtype_by_name);
-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_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_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_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_class_show_stats);
-EXPORT_SYMBOL(ckrm_class_show_config);
-EXPORT_SYMBOL(ckrm_class_show_shares);
+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_set_config);
-EXPORT_SYMBOL(ckrm_class_set_shares);
+EXPORT_SYMBOL_GPL(ckrm_class_set_config);
+EXPORT_SYMBOL_GPL(ckrm_class_set_shares);
-EXPORT_SYMBOL(ckrm_class_reset_stats);
+EXPORT_SYMBOL_GPL(ckrm_class_reset_stats);
#include <linux/slab.h>
#include <asm/errno.h>
#include <linux/sched.h>
-#include <linux/ckrm.h>
+#include <linux/ckrm_events.h>
#include <linux/ckrm_rc.h>
#include <linux/ckrm_tc.h>
#include <linux/ckrm_sched.h>
#include <asm/errno.h>
#include <linux/list.h>
#include <linux/spinlock.h>
-#include <linux/ckrm.h>
+#include <linux/ckrm_events.h>
#include <linux/ckrm_rc.h>
#include <linux/ckrm_tc.h>
#include <asm/div64.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/errno.h>
-#include <linux/ckrm.h>
+#include <linux/ckrm_events.h>
#include <linux/ckrm_rc.h>
#include <linux/ckrm_tc.h>
#include <linux/ckrm_classqueue.h>
#include <asm/div64.h>
#include <linux/list.h>
#include <linux/spinlock.h>
-#include <linux/ckrm.h>
+#include <linux/parser.h>
#include <linux/ckrm_rc.h>
#include <linux/ckrm_tc.h>
#include <linux/ckrm_tsk.h>
-#define TOTAL_NUM_TASKS (131072) // 128 K
+#define DEF_TOTAL_NUM_TASKS (131072) // 128 K
+#define DEF_FORKRATE (1000000) // 1 million tasks
+#define DEF_FORKRATE_INTERVAL (3600) // per hour
#define NUMTASKS_DEBUG
#define NUMTASKS_NAME "numtasks"
+#define SYS_TOTAL_TASKS "sys_total_tasks"
+#define FORKRATE "forkrate"
+#define FORKRATE_INTERVAL "forkrate_interval"
+
+static int total_numtasks = DEF_TOTAL_NUM_TASKS;
+static int total_cnt_alloc = 0;
+static int forkrate = DEF_FORKRATE;
+static int forkrate_interval = DEF_FORKRATE_INTERVAL;
+static ckrm_core_class_t *root_core;
typedef struct ckrm_numtasks {
struct ckrm_core_class *core; // the core i am part of...
int tot_limit_failures;
int tot_borrow_sucesses;
int tot_borrow_failures;
+
+ // fork rate fields
+ int forks_in_period;
+ unsigned long period_start;
} ckrm_numtasks_t;
struct ckrm_res_ctlr numtasks_rcbs;
res->tot_borrow_sucesses = 0;
res->tot_borrow_failures = 0;
+ res->forks_in_period = 0;
+ res->period_start = jiffies;
+
atomic_set(&res->cnt_cur_alloc, 0);
atomic_set(&res->cnt_borrowed, 0);
return;
static int numtasks_get_ref_local(void *arg, int force)
{
- int rc, resid = numtasks_rcbs.resid;
+ int rc, resid = numtasks_rcbs.resid, borrowed = 0;
+ unsigned long now = jiffies, chg_at;
ckrm_numtasks_t *res;
ckrm_core_class_t *core = arg;
if (res == NULL)
return 1;
+ // force is not associated with fork. So, if force is specified
+ // we don't have to bother about forkrate.
+ if (!force) {
+ // Take care of wraparound situation
+ chg_at = res->period_start + forkrate_interval * HZ;
+ if (chg_at < res->period_start) {
+ chg_at += forkrate_interval * HZ;
+ now += forkrate_interval * HZ;
+ }
+ if (chg_at <= now) {
+ res->period_start = now;
+ res->forks_in_period = 0;
+ }
+
+ if (res->forks_in_period >= forkrate) {
+ return 0;
+ }
+ }
+
atomic_inc(&res->cnt_cur_alloc);
rc = 1;
res->borrow_sucesses++;
res->tot_borrow_sucesses++;
res->over_guarantee = 1;
+ borrowed++;
} else {
res->borrow_failures++;
res->tot_borrow_failures++;
if (!rc) {
atomic_dec(&res->cnt_cur_alloc);
+ } else if (!borrowed) {
+ total_cnt_alloc++;
+ if (!force) { // force is not associated with a real fork.
+ res->forks_in_period++;
+ }
}
return rc;
}
if (atomic_read(&res->cnt_borrowed) > 0) {
atomic_dec(&res->cnt_borrowed);
numtasks_put_ref_local(res->parent);
+ } else {
+ total_cnt_alloc--;
}
+
return;
}
if (parent == NULL) {
// I am part of root class. So set the max tasks
// to available default
- res->cnt_guarantee = TOTAL_NUM_TASKS;
- res->cnt_unused = TOTAL_NUM_TASKS;
- res->cnt_limit = TOTAL_NUM_TASKS;
+ res->cnt_guarantee = total_numtasks;
+ res->cnt_unused = total_numtasks;
+ res->cnt_limit = total_numtasks;
+ root_core = core; // store the root core.
}
try_module_get(THIS_MODULE);
} else {
return;
}
+
/*
* Recalculate the guarantee and limit in real units... and propagate the
* same to children.
ckrm_lock_hier(res->core);
while ((child = ckrm_get_next_child(res->core, child)) != NULL) {
childres = ckrm_get_res_class(child, resid, ckrm_numtasks_t);
-
- spin_lock(&childres->cnt_lock);
- recalc_and_propagate(childres, res);
- spin_unlock(&childres->cnt_lock);
+ if (childres) {
+ spin_lock(&childres->cnt_lock);
+ recalc_and_propagate(childres, res);
+ spin_unlock(&childres->cnt_lock);
+ } else {
+ printk(KERN_ERR "%s: numtasks resclass missing\n",__FUNCTION__);
+ }
}
ckrm_unlock_hier(res->core);
return;
if (!res)
return -EINVAL;
- seq_printf(sfile, "res=%s,parameter=somevalue\n", NUMTASKS_NAME);
+ seq_printf(sfile, "res=%s,%s=%d,%s=%d,%s=%d\n", NUMTASKS_NAME,
+ SYS_TOTAL_TASKS, total_numtasks,
+ FORKRATE, forkrate,
+ FORKRATE_INTERVAL, forkrate_interval);
return 0;
}
+enum numtasks_token_t {
+ numtasks_token_total,
+ numtasks_token_forkrate,
+ numtasks_token_interval,
+ numtasks_token_err
+};
+
+static match_table_t numtasks_tokens = {
+ {numtasks_token_total, SYS_TOTAL_TASKS "=%d"},
+ {numtasks_token_forkrate, FORKRATE "=%d"},
+ {numtasks_token_interval, FORKRATE_INTERVAL "=%d"},
+ {numtasks_token_err, NULL},
+};
+
+static void reset_forkrates(ckrm_core_class_t *parent, unsigned long now)
+{
+ ckrm_numtasks_t *parres;
+ ckrm_core_class_t *child = NULL;
+
+ parres = ckrm_get_res_class(parent, numtasks_rcbs.resid,
+ ckrm_numtasks_t);
+ if (!parres) {
+ return;
+ }
+ parres->forks_in_period = 0;
+ parres->period_start = now;
+
+ ckrm_lock_hier(parent);
+ while ((child = ckrm_get_next_child(parent, child)) != NULL) {
+ reset_forkrates(child, now);
+ }
+ ckrm_unlock_hier(parent);
+}
+
static int numtasks_set_config(void *my_res, const char *cfgstr)
{
+ char *p;
ckrm_numtasks_t *res = my_res;
+ int new_total, fr = 0, itvl = 0, err = 0;
if (!res)
return -EINVAL;
- printk(KERN_DEBUG "numtasks config='%s'\n", cfgstr);
- return 0;
+
+ while ((p = strsep((char**)&cfgstr, ",")) != NULL) {
+ substring_t args[MAX_OPT_ARGS];
+ int token;
+ if (!*p)
+ continue;
+
+ token = match_token(p, numtasks_tokens, args);
+ switch (token) {
+ case numtasks_token_total:
+ if (match_int(args, &new_total) ||
+ (new_total < total_cnt_alloc)) {
+ err = -EINVAL;
+ } else {
+ total_numtasks = new_total;
+
+ // res is the default class, as config is present only
+ // in that directory
+ spin_lock(&res->cnt_lock);
+ res->cnt_guarantee = total_numtasks;
+ res->cnt_unused = total_numtasks;
+ res->cnt_limit = total_numtasks;
+ recalc_and_propagate(res, NULL);
+ spin_unlock(&res->cnt_lock);
+ }
+ break;
+ case numtasks_token_forkrate:
+ if (match_int(args, &fr) || (fr <= 0)) {
+ err = -EINVAL;
+ } else {
+ forkrate = fr;
+ }
+ break;
+ case numtasks_token_interval:
+ if (match_int(args, &itvl) || (itvl <= 0)) {
+ err = -EINVAL;
+ } else {
+ forkrate_interval = itvl;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ }
+ }
+ if ((fr > 0) || (itvl > 0)) {
+ reset_forkrates(root_core, jiffies);
+ }
+ return err;
}
static void numtasks_change_resclass(void *task, void *old, void *new)
// note registeration of all resource controllers will be done
// later dynamically as these are specified as modules
+
+ // prepare init_task and then rely on inheritance of properties
+ ckrm_set_taskclass(&init_task, NULL, NULL, CKRM_EVENT_NEWTASK);
}
static int tc_show_members(struct ckrm_core_class *core, struct seq_file *seq)
-/* ckrmutils.c - Utility functions for CKRM
+/*
+ * ckrmutils.c - Utility functions for CKRM
*
* Copyright (C) Chandra Seetharaman, IBM Corp. 2003
* (C) Hubertus Franke , IBM Corp. 2004
*
*/
-/* Changes
+/*
+ * Changes
*
* 13 Nov 2003
* Created
if (!mm) {
return -EINVAL;
}
-
down_read(&mm->mmap_sem);
vma = mm->mmap;
while (vma) {
else
increase_by = new->my_guarantee - cur->my_guarantee;
- // Check total_guarantee for correctness
+ /* Check total_guarantee for correctness */
if (new->total_guarantee <= CKRM_SHARE_DONTCARE) {
goto set_share_err;
} else if (new->total_guarantee == CKRM_SHARE_UNCHANGED) {
- ; // do nothing
+ /* do nothing */;
} else if (cur_usage_guar > new->total_guarantee) {
goto set_share_err;
}
- // Check max_limit for correctness
+ /* Check max_limit for correctness */
if (new->max_limit <= CKRM_SHARE_DONTCARE) {
goto set_share_err;
} else if (new->max_limit == CKRM_SHARE_UNCHANGED) {
- ; // do nothing
+ /* do nothing */;
} else if (cur->cur_max_limit > new->max_limit) {
goto set_share_err;
}
- // Check my_guarantee for correctness
+ /* Check my_guarantee for correctness */
if (new->my_guarantee == CKRM_SHARE_UNCHANGED) {
- ; // do nothing
+ /* do nothing */;
} else if (new->my_guarantee == CKRM_SHARE_DONTCARE) {
- ; // do nothing
+ /* do nothing */;
} else if (par && increase_by > par->unused_guarantee) {
goto set_share_err;
}
- // Check my_limit for correctness
+ /* Check my_limit for correctness */
if (new->my_limit == CKRM_SHARE_UNCHANGED) {
- ; // do nothing
+ /* do nothing */;
} else if (new->my_limit == CKRM_SHARE_DONTCARE) {
- ; // do nothing
+ /* do nothing */;
} else if (par && new->my_limit > par->max_limit) {
- // I can't get more limit than my parent's limit
+ /* I can't get more limit than my parent's limit */
goto set_share_err;
}
- // make sure guarantee is lesser than limit
+ /* make sure guarantee is lesser than limit */
if (new->my_limit == CKRM_SHARE_DONTCARE) {
- ; // do nothing
+ /* do nothing */;
} else if (new->my_limit == CKRM_SHARE_UNCHANGED) {
if (new->my_guarantee == CKRM_SHARE_DONTCARE) {
- ; // do nothing
+ /* do nothing */;
} else if (new->my_guarantee == CKRM_SHARE_UNCHANGED) {
- ; // do nothing earlier setting would've
- // taken care of it
+ /*
+ * do nothing; earlier setting would have
+ * taken care of it
+ */;
} else if (new->my_guarantee > cur->my_limit) {
goto set_share_err;
}
- } else { // new->my_limit has a valid value
+ } else { /* new->my_limit has a valid value */
if (new->my_guarantee == CKRM_SHARE_DONTCARE) {
- ; // do nothing
+ /* do nothing */;
} else if (new->my_guarantee == CKRM_SHARE_UNCHANGED) {
if (cur->my_guarantee > new->my_limit) {
goto set_share_err;
goto set_share_err;
}
}
-
if (new->my_guarantee != CKRM_SHARE_UNCHANGED) {
child_guarantee_changed(par, cur->my_guarantee,
new->my_guarantee);
cur->my_guarantee = new->my_guarantee;
}
-
if (new->my_limit != CKRM_SHARE_UNCHANGED) {
child_maxlimit_changed(par, new->my_limit);
cur->my_limit = new->my_limit;
}
-
if (new->total_guarantee != CKRM_SHARE_UNCHANGED) {
cur->unused_guarantee = new->total_guarantee - cur_usage_guar;
cur->total_guarantee = new->total_guarantee;
}
-
if (new->max_limit != CKRM_SHARE_UNCHANGED) {
cur->max_limit = new->max_limit;
}
-
rc = 0;
- set_share_err:
+set_share_err:
return rc;
}
-EXPORT_SYMBOL(get_exe_path_name);
-EXPORT_SYMBOL(child_guarantee_changed);
-EXPORT_SYMBOL(child_maxlimit_changed);
-EXPORT_SYMBOL(set_shares);
+EXPORT_SYMBOL_GPL(get_exe_path_name);
+EXPORT_SYMBOL_GPL(child_guarantee_changed);
+EXPORT_SYMBOL_GPL(child_maxlimit_changed);
+EXPORT_SYMBOL_GPL(set_shares);
}
// printk("kernel read |%s|\n", line);
// printk("kernel read-2 |%s|\n", line+1000);
- // printk prints only 1024 bytes once :)
+ // printk prints only 1024 bytes once :)
//
kfree(line);
return len;
*/
static int reinsert_rule(struct rbce_rule *rule, int order)
{
- list_del(&rule->obj.link);
- gl_num_rules--;
- gl_rules_version++;
- module_put(THIS_MODULE);
+ if (!list_empty(&rule->obj.link)) {
+ list_del_init(&rule->obj.link);
+ gl_num_rules--;
+ gl_rules_version++;
+ module_put(THIS_MODULE);
+ }
return insert_rule(rule, order);
}
return cls;
}
-static struct rbce_class *get_class(char *classname, int *classtype)
+static struct rbce_class *get_class(const char *classname, int *classtype)
{
struct rbce_class *cls;
void *classobj;
struct rbce_class *cls;
write_lock(&global_rwlock);
- cls = find_class_name((char *)classname);
+ cls = get_class(classname, &classtype);
if (cls) {
cls->classobj = clsobj;
- } else {
- cls = create_rbce_class(classname, classtype, clsobj);
- }
- if (cls)
notify_class_action(cls, 1);
+ }
write_unlock(&global_rwlock);
return;
}
write_lock(&global_rwlock);
cls = find_class_name(classname);
if (cls) {
+#ifdef RBCE_EXTENSION
+ put_class(cls);
+#endif
if (cls->classobj != classobj) {
printk(KERN_ERR "rbce: class %s changed identity\n",
classname);
static inline int __delete_rule(struct rbce_rule *rule)
{
// make sure we are not referenced by other rules
+ if (list_empty(&rule->obj.link)) {
+ return 0;
+ }
if (GET_REF(rule)) {
return -EBUSY;
}
__release_rule(rule);
put_class(rule->target_class);
release_term_index(rule->index);
- list_del(&rule->obj.link);
+ list_del_init(&rule->obj.link);
gl_num_rules--;
gl_rules_version++;
module_put(THIS_MODULE);
******************************************************************************/
#include <linux/relayfs_fs.h>
+#include <linux/jiffies.h>
#define PSAMPLE(pdata) (&((pdata)->ext_data.sample))
#define UKCC_N_SUB_BUFFERS (4)
#define rec_set_hdr(r,t,p) ((r)->hdr.type = (t), (r)->hdr.pid = (p))
#define rec_set_timehdr(r,t,p,c) (rec_set_hdr(r,t,p), \
-(r)->hdr.jiffies = jiffies, (r)->hdr.cls=(unsigned long)(c) )
+(r)->hdr.timestamp = jiffies_to_msecs(jiffies), (r)->hdr.cls=(unsigned long)(c) )
+
#if CHANNEL_AUTO_CONT
#include <linux/mount.h>
#include <linux/proc_fs.h>
#include <linux/mempolicy.h>
-#include <linux/ckrm.h>
+#include <linux/ckrm_events.h>
#include <linux/ckrm_tsk.h>
#include <linux/ckrm_mem_inline.h>
#include <linux/syscalls.h>
#include <linux/audit.h>
#include <linux/profile.h>
#include <linux/rmap.h>
-#include <linux/ckrm.h>
+#include <linux/ckrm_events.h>
#include <linux/ckrm_tsk.h>
#include <linux/ckrm_mem_inline.h>
#include <linux/vs_network.h>
clone_flags |= CLONE_PTRACE;
}
-#ifdef CONFIG_CKRM_TYPE_TASKCLASS
if (numtasks_get_ref(current->taskclass, 0) == 0) {
return -ENOMEM;
}
-#endif
-
p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, pid);
+
/*
* Do this prior waking up the new thread - the thread pointer
* might get invalid after that point, if the thread exits quickly.
ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
}
} else {
-#ifdef CONFIG_CKRM_TYPE_TASKCLASS
numtasks_put_ref(current->taskclass);
-#endif
free_pidmap(pid);
pid = PTR_ERR(p);
}
#include <linux/security.h>
#include <linux/dcookies.h>
#include <linux/suspend.h>
-#include <linux/ckrm.h>
+#include <linux/ckrm_events.h>
#include <linux/tty.h>
#include <linux/vs_cvirt.h>
#include <linux/compat.h>
out_unlock:
read_unlock(&tasklist_lock);
- return retval;
+ key_fsgid_changed(current);
+ return 0;
}
long vs_reboot(unsigned int, void *);
}
+
/*
* Unprivileged users may change the real gid to the effective gid
* or vice versa. (BSD-style)
current->egid = new_egid;
current->gid = new_rgid;
- ckrm_cb_gid();
-
key_fsgid_changed(current);
+ ckrm_cb_gid();
return 0;
}
else
return -EPERM;
+ key_fsgid_changed(current);
ckrm_cb_gid();
- key_fsgid_changed(current);
return 0;
}
current->suid = current->euid;
current->fsuid = current->euid;
- ckrm_cb_uid();
-
key_fsuid_changed(current);
+ ckrm_cb_uid();
return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RE);
}
current->fsuid = current->euid = uid;
current->suid = new_suid;
- ckrm_cb_uid();
-
key_fsuid_changed(current);
+ ckrm_cb_uid();
return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_ID);
}
if (suid != (uid_t) -1)
current->suid = suid;
- ckrm_cb_uid();
-
key_fsuid_changed(current);
+ ckrm_cb_uid();
return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RES);
}
if (sgid != (gid_t) -1)
current->sgid = sgid;
- ckrm_cb_gid();
-
-
key_fsgid_changed(current);
+ ckrm_cb_gid();
return 0;
}
#include <linux/vserver/debug.h>
#include <linux/vs_context.h>
#include <linux/vserver/context_cmd.h>
-#include <linux/ckrm.h> /* needed for ckrm_cb_xid() */
+#include <linux/ckrm_events.h> /* needed for ckrm_cb_xid() */
#include <asm/errno.h>
#include <linux/random.h>
#ifdef CONFIG_CKRM
-#include <linux/ckrm.h>
+#include <linux/ckrm_events.h>
#endif
#include <net/icmp.h>