On question/comment inserted below. Cheers, -Matt
On Mon, 2005-05-30 at 23:32 -0700, Vivek Kashyap wrote: > signed-off by: Vivek Kashyap ([EMAIL PROTECTED]) > > --- a/init/Kconfig 2005-05-23 14:00:36.000000000 -0700 > +++ b/init/Kconfig 2005-05-23 14:50:27.000000000 -0700 > @@ -227,6 +227,19 @@ > to userspace tools through relayfs (requires RELAYFS_FS configured). > > If unsure, say N. > + > +config CKRM_RES_LISTENAQ > + tristate "Multiple Accept Queues Resource Manager" > + depends on CKRM_TYPE_SOCKETCLASS > + default m > + help > + Provides a resource controller for CKRM to prioritize inbound > + connection requests. See inbound control description for > + "IP: TCP Multiple accept queues support". If you choose multiple > + accept queues then choose this option to contorl the queue weights. > + > + If unsure, say N. > + > endmenu > > config SYSCTL > --- a/kernel/ckrm/ckrm_listenaq.c 1969-12-31 16:00:00.000000000 -0800 > +++ b/kernel/ckrm/ckrm_listenaq.c 2005-05-23 14:36:03.000000000 -0700 > @@ -0,0 +1,497 @@ > +/* ckrm_listenaq.c - accept queue resource controller > + * > + * Copyright (C) Vivek Kashyap, IBM Corp. 2004 > + * > + * 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 > + * Initial version > + */ > + > +/* Code Description: TBD > + * > + */ > + > +#include <linux/module.h> > +#include <linux/init.h> > +#include <linux/slab.h> > +#include <asm/errno.h> > +#include <linux/list.h> > +#include <linux/spinlock.h> > +#include <linux/ckrm_rc.h> > +#include <net/tcp.h> > +#include <linux/ckrm_net.h> > + > + > +#define hnode_2_core(ptr) \ > + ((ptr) ? container_of(ptr, struct ckrm_core_class, hnode) : > NULL) > + > + > +#define CKRM_SAQ_MAX_DEPTH 3 /* 0 => /rcfs > + * 1 => socket_aq > + * 2 => socket_aq/listen_class > + * 3 => socket_aq/listen_class/accept_queues > + * 4 => Not allowed > + */ > + > +typedef struct ckrm_laq_res { > + spinlock_t reslock; > + atomic_t refcnt; > + struct ckrm_shares shares; > + struct ckrm_core_class *core; > + struct ckrm_core_class *pcore; > + int my_depth; > + int my_id; > +} ckrm_laq_res_t; > + > +struct ckrm_res_ctlr laq_rcbs; > + > +extern struct ckrm_core_class *rcfs_create_under_netroot(char *, int, > int); > +extern struct ckrm_core_class *rcfs_make_core(struct dentry *, > + struct ckrm_core_class * ) ; > + > +void > +laq_res_hold(struct ckrm_laq_res *res) > +{ > + atomic_inc(&res->refcnt); > + return; > +} > + > +void > +laq_res_put(struct ckrm_laq_res *res) > +{ > + if (atomic_dec_and_test(&res->refcnt)) > + kfree(res); > + return; > +} > + > +/* Initialize rescls values > + */ > +static void > +laq_res_initcls(void *my_res) > +{ > + ckrm_laq_res_t *res = my_res; > + > + res->shares.my_guarantee = CKRM_SHARE_DONTCARE; > + res->shares.my_limit = CKRM_SHARE_DONTCARE; > + res->shares.total_guarantee = CKRM_SHARE_DFLT_TOTAL_GUARANTEE; > + res->shares.max_limit = CKRM_SHARE_DFLT_MAX_LIMIT; > + res->shares.unused_guarantee = CKRM_SHARE_DFLT_TOTAL_GUARANTEE; > + res->shares.cur_max_limit = 0; > +} > + > +static int > +atoi(char *s) > +{ > + int k = 0; > + while(*s) > + k = *s++ - '0' + (k * 10); > + return k; > +} Is there any reason you implemented your own atoi()? Any reason you didn't use sscanf? simple_strtol()? etc etc. There's no test to ensure all of the characters being parsed are digits. Is this intentional? skip_atoi() (lib/vsprintf.c), for instance, looks very similar to this except rather than checking for NUL it checks if the character is a digit. > +static char * > +laq_get_name(struct ckrm_core_class *c) > +{ > + char *p = (char *)c->name; > + > + while(*p) > + p++; > + while( *p != '/' && p != c->name) > + p--; > + > + return ++p; > +} > + > +static void * > +laq_res_alloc(struct ckrm_core_class *core, struct ckrm_core_class *parent) > +{ > + ckrm_laq_res_t *res; > + int pdepth; > + > + if (core == core->classtype->default_class) > + pdepth = 1; > + else { > + res = ckrm_get_res_class(parent, laq_rcbs.resid,ckrm_laq_res_t); > + if (!res) > + return NULL; > + pdepth = 1 + res->my_depth; > + } > + > + res = kmalloc(sizeof(ckrm_laq_res_t), GFP_ATOMIC); > + if (res) { > + memset(res, 0, sizeof(res)); > + spin_lock_init(&res->reslock); > + laq_res_hold(res); > + res->my_depth = pdepth; > + if (pdepth == 2) /* listen class */ > + res->my_id = 0; > + else if (pdepth == 3) > + res->my_id = atoi(laq_get_name(core)); > + res->core = core; > + res->pcore = parent; > + > + /* rescls in place, now initialize contents other than > + hierarchy pointers */ > + laq_res_initcls(res); /* acts as initialising value */ > + } > + > + return res; > +} > + > +static void > +laq_res_free(void *my_res) > +{ > + ckrm_laq_res_t *res = (ckrm_laq_res_t *)my_res; > + ckrm_laq_res_t *parent; > + > + if (!res) > + return; > + > + if (res->my_depth != 3) { > + kfree(res); > + return; > + } > + > + parent = ckrm_get_res_class(res->pcore, laq_rcbs.resid, ckrm_laq_res_t); > + if (!parent) > + return; > + > + spin_lock(&parent->reslock); > + spin_lock(&res->reslock); > + > + /* return child's guarantee to parent node */ > + /* Limits have no meaning for accept queue control */ > + child_guarantee_changed(&parent->shares, res->shares.my_guarantee, 0); > + > + spin_unlock(&res->reslock); > + laq_res_put(res); > + spin_unlock(&parent->reslock); > + return; > +} > + > +/************************************************************************** > + * SHARES *** > + **************************************************************************/ > + > +void > +laq_set_aq_value(struct ckrm_net_struct *ns, unsigned int *aq_ratio) > +{ > + int i; > + struct tcp_sock *tp; > + > + tp = tcp_sk(ns->ns_sk); > + for (i=0 ; i < NUM_ACCEPT_QUEUES; i++) > + tp->acceptq[i].aq_ratio = tp->acceptq[i].aq_cnt = aq_ratio[i]; > + > + return; > +} > + > +void > +laq_set_aq_values(ckrm_laq_res_t *parent, unsigned int *aq_ratio) > +{ > + > + struct ckrm_net_struct *ns; > + struct ckrm_core_class *core = parent->core; > + > + class_lock(core); > + list_for_each_entry(ns, &core->objlist,ckrm_link) { > + laq_set_aq_value(ns, aq_ratio); > + } > + class_unlock(core); > + return; > +} > + > +static void > +calculate_aq_ratios(ckrm_laq_res_t *res, unsigned int *aq_ratio) > +{ > + struct ckrm_hnode *chnode; > + ckrm_laq_res_t *child; > + > + aq_ratio[0] = > + ((unsigned int)res->shares.unused_guarantee * ACCEPTQ_PERCENTILE)/ > + res->shares.total_guarantee; > + > + list_for_each_entry(chnode, &res->core->hnode.children,siblings){ > + child=hnode_2_core(chnode)->res_class[laq_rcbs.resid]; > + if (!child) /* no resource structure allocated */ > + continue; > + if (child->shares.my_guarantee == CKRM_SHARE_DONTCARE) > + aq_ratio[child->my_id] = 0; > + else > + aq_ratio[child->my_id] = > + ((unsigned int)child->shares.my_guarantee * > + ACCEPTQ_PERCENTILE)/res->shares.total_guarantee; > + } > + > +} > + > + > +static int > +laq_set_share_values(void *my_res, struct ckrm_shares *shares) > +{ > + ckrm_laq_res_t *res = my_res; > + ckrm_laq_res_t *parent; > + unsigned int aq_ratio[NUM_ACCEPT_QUEUES]; > + int rc = 0; > + > + if (!res) > + return -EINVAL; > + > + if (!res->pcore) { > + /* something is badly wrong */ > + printk(KERN_ERR "socketaq internal inconsistency\n"); > + return -EBADF; > + } > + > + parent = ckrm_get_res_class(res->pcore, laq_rcbs.resid, ckrm_laq_res_t); > + if (!parent) /* socketclass does not have a share interface */ > + return -EINVAL; > + > + /* Ensure that we ignore limit values */ > + shares->my_limit = CKRM_SHARE_DONTCARE; > + shares->max_limit = CKRM_SHARE_UNCHANGED; > + > + if (res->my_depth == 0) { > + printk(KERN_ERR "socketaq bad entry\n"); > + return -EBADF; > + } > + else if (res->my_depth == 1) { > + /* can't be written to. This is an internal default. */ > + return -EINVAL; > + } > + else if (res->my_depth == 2) { > + /* nothing to inherit */ > + if (!shares->total_guarantee) { > + return -EINVAL; > + } > + parent = res; > + shares->my_guarantee = CKRM_SHARE_DONTCARE; > + } > + else if (res->my_depth == 3) { > + /* accept queue itself. */ > + shares->total_guarantee = CKRM_SHARE_UNCHANGED; > + } > + > + ckrm_lock_hier(parent->pcore); > + spin_lock(&parent->reslock); > + rc=set_shares(shares,&res->shares,(parent == res)?NULL:&parent->shares); > + if (rc) { > + spin_unlock(&parent->reslock); > + ckrm_unlock_hier(parent->pcore); > + return rc; > + } > + calculate_aq_ratios(parent,aq_ratio); > + laq_set_aq_values(parent,aq_ratio); > + spin_unlock(&parent->reslock); > + ckrm_unlock_hier(parent->pcore); > + > + return rc; > +} > + > +static int > +laq_get_share_values(void *my_res, struct ckrm_shares *shares) > +{ > + ckrm_laq_res_t *res = my_res; > + > + if (!res) > + return -EINVAL; > + *shares = res->shares; > + return 0; > +} > + > +/************************************************************************** > + * STATS *** > + **************************************************************************/ > + > +void > +laq_print_aq_stats(struct seq_file *sfile, struct tcp_acceptq_info *taq, int > i) > +{ > + seq_printf(sfile, "Class %d connections:\n\taccepted: %u\n\t" > + "queued: %u\n\twait_time: %u\n", > + i, taq->acceptq_count, taq->acceptq_qcount, > + jiffies_to_msecs(taq->acceptq_wait_time)); > + > + if (i) > + return; > + > + for (i = 1; i < NUM_ACCEPT_QUEUES; i++) { > + taq[0].acceptq_wait_time += taq[i].acceptq_wait_time; > + taq[0].acceptq_qcount += taq[i].acceptq_qcount; > + taq[0].acceptq_count += taq[i].acceptq_count; > + } > + > + seq_printf(sfile, "Totals :\n\taccepted: %u\n\t" > + "queued: %u\n\twait_time: %u\n", > + taq->acceptq_count, taq->acceptq_qcount, > + jiffies_to_msecs(taq->acceptq_wait_time)); > + > + return; > +} > + > +void > +laq_get_aq_stats(ckrm_laq_res_t *pres, ckrm_laq_res_t *mres, > + struct tcp_acceptq_info *taq) > +{ > + struct ckrm_net_struct *ns; > + struct ckrm_core_class *core = pres->core; > + struct tcp_sock *tp; > + int a = mres->my_id; > + int z; > + > + if (a == 0) > + z = NUM_ACCEPT_QUEUES; > + else > + z = a+1; > + > + class_lock(pres->core); > + list_for_each_entry(ns, &core->objlist,ckrm_link) { > + tp = tcp_sk(ns->ns_sk); > + for (; a< z; a++) { > + taq->acceptq_wait_time += tp->acceptq[a].aq_wait_time; > + taq->acceptq_qcount += tp->acceptq[a].aq_qcount; > + taq->acceptq_count += tp->acceptq[a].aq_tcount; > + taq++; > + } > + } > + class_unlock(pres->core); > +} > + > +static int > +laq_get_stats(void *my_res, struct seq_file *sfile) > +{ > + ckrm_laq_res_t *res = my_res; > + ckrm_laq_res_t *parent; > + struct tcp_acceptq_info taq[NUM_ACCEPT_QUEUES]; > + int rc = 0; > + > + if (!res) > + return -EINVAL; > + > + if (!res->pcore) { > + /* something is badly wrong */ > + printk(KERN_ERR "socketaq internal inconsistency\n"); > + return -EBADF; > + } > + > + parent = ckrm_get_res_class(res->pcore, laq_rcbs.resid, ckrm_laq_res_t); > + if (!parent) { /* socketclass does not have a stat interface */ > + printk(KERN_ERR "socketaq internal fs inconsistency\n"); > + return -EINVAL; > + } > + > + memset(taq, 0, sizeof(struct tcp_acceptq_info) * NUM_ACCEPT_QUEUES); > + > + switch (res->my_depth) { > + > + default: > + case 0: printk(KERN_ERR "socket class bad entry\n"); > + rc = -EBADF; > + break; > + > + case 1: /* can't be read from. this is internal default. */ > + rc = -EINVAL; > + break; > + > + case 2: /* return the default and total */ > + ckrm_lock_hier(res->core); > + laq_get_aq_stats(res, res, &taq[0]); > + laq_print_aq_stats(sfile, &taq[0], 0); > + ckrm_unlock_hier(res->core); > + break; > + > + case 3: > + ckrm_lock_hier(parent->core); > + laq_get_aq_stats(parent, res, &taq[res->my_id]); > + laq_print_aq_stats(sfile, &taq[res->my_id], res->my_id); > + ckrm_unlock_hier(parent->core); > + break; > + } > + > + return rc; > +} > + > +/* > + * The network connection is reclassified to this class. Update its shares. > + * The socket lock is held. > + */ > +static void > +laq_change_resclass(void *n, void *old, void *r) > +{ > + struct ckrm_net_struct *ns = (struct ckrm_net_struct *)n; > + struct ckrm_laq_res *res = (struct ckrm_laq_res *)r; > + unsigned int aq_ratio[NUM_ACCEPT_QUEUES]; > + > + > + if (res->my_depth != 2) > + return; > + > + /* a change to my_depth == 3 ie. the accept classes cannot happen. > + * there is no target file */ > + if (res->my_depth == 2) { > + ckrm_lock_hier(res->pcore); > + spin_lock(&res->reslock); > + calculate_aq_ratios(res, aq_ratio); > + class_lock(res->pcore); > + laq_set_aq_value(ns, aq_ratio); > + class_unlock(res->pcore); > + spin_unlock(&res->reslock); > + ckrm_unlock_hier(res->pcore); > + } > + > + return; > +} > + > +struct ckrm_res_ctlr laq_rcbs = { > + .res_name = "listenaq", > + .resid = -1 , /* dynamically assigned */ > + .res_alloc = laq_res_alloc, > + .res_free = laq_res_free, > + .set_share_values = laq_set_share_values, > + .get_share_values = laq_get_share_values, > + .get_stats = laq_get_stats, > + .change_resclass = laq_change_resclass, > +}; > + > + > +int __init > +init_ckrm_laq_res(void) > +{ > + struct ckrm_classtype *clstype; > + int resid = laq_rcbs.resid; > + > + clstype = ckrm_find_classtype_by_name("socketclass"); > + if (clstype == NULL) { > + printk(KERN_INFO " Unknown ckrm classtype <socketclass>"); > + return -ENOENT; > + } > + > + if (resid == -1) { > + resid = ckrm_register_res_ctlr(clstype,&laq_rcbs); > + if (resid >= 0) > + laq_rcbs.classtype = clstype; > + printk("........init_ckrm_listen_aq_res -> %d\n",resid); > + } > + return 0; > + > +} > + > +void __exit > +exit_ckrm_laq_res(void) > +{ > + ckrm_unregister_res_ctlr(&laq_rcbs); > + laq_rcbs.resid = -1; > +} > + > + > +module_init(init_ckrm_laq_res) > +module_exit(exit_ckrm_laq_res) > + > +MODULE_LICENSE("GPL"); > + > --- a/kernel/ckrm/ckrm_sockc.c 2005-05-23 14:00:36.000000000 -0700 > +++ b/kernel/ckrm/ckrm_sockc.c 2005-05-25 06:19:40.000000000 -0700 > @@ -196,7 +196,7 @@ > ckrm_ns_hold(ns); > > ns->ns_family = sk->sk_family; > - if (ns->ns_family == AF_INET6) // IPv6 not supported yet. > + if (ns->ns_family == AF_INET6) /* IPv6 not supported yet. */ > return; > > ns->ns_daddrv4 = inet_sk(sk)->rcv_saddr; > @@ -270,7 +270,7 @@ > sk->sk_ckrm_ns = NULL; > sock_put(sk); > > - // Should be the last count and free it > + /* Should be the last count and free it */ > ckrm_ns_put(ns); > return; > } > @@ -366,15 +366,18 @@ > return rc; > } > > + if (tns->ns_family == AF_INET6) > + return -EOPNOTSUPP; > + > newcls = class_type(struct ckrm_sock_class, core); > + > /* > * lookup the listening sockets > * returns with a reference count set on socket > */ > - if (tns->ns_family == AF_INET6) > - return -EOPNOTSUPP; > - > + local_bh_disable(); > sk = tcp_v4_lookup_listener(tns->ns_daddrv4, tns->ns_dport, 0); > + local_bh_enable(); > if (!sk) { > printk(KERN_INFO "No such listener 0x%x:%d\n", > tns->ns_daddrv4, tns->ns_dport); > --- a/kernel/ckrm/Makefile 2005-05-23 14:00:36.000000000 -0700 > +++ b/kernel/ckrm/Makefile 2005-05-23 14:51:23.000000000 -0700 > @@ -6,4 +6,6 @@ > obj-$(CONFIG_CKRM_TYPE_TASKCLASS) += ckrm_tc.o ckrm_numtasks_stub.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_RBCE) += rbce/ > + > > > > > ------------------------------------------------------- > This SF.Net email is sponsored by Yahoo. > Introducing Yahoo! Search Developer Network - Create apps using Yahoo! > Search APIs Find out how you can build Yahoo! directly into your own > Applications - visit http://developer.yahoo.net/?fr=offad-ysdn-ostg-q22005 > _______________________________________________ > ckrm-tech mailing list > https://lists.sourceforge.net/lists/listinfo/ckrm-tech > ------------------------------------------------------- This SF.Net email is sponsored by Yahoo. Introducing Yahoo! Search Developer Network - Create apps using Yahoo! Search APIs Find out how you can build Yahoo! directly into your own Applications - visit http://developer.yahoo.net/?fr=offad-ysdn-ostg-q22005 _______________________________________________ ckrm-tech mailing list https://lists.sourceforge.net/lists/listinfo/ckrm-tech