Jamal,
Pls keep lkml and lse-tech on cc since some of this affects the usage
of delay accounting.
jamal wrote:
Hi Shailabh,
Apologies for taking a week to respond ..
On Mon, 2006-27-02 at 15:26 -0500, Shailabh Nagar wrote:
quoted
jamal wrote:
quoted
Yes, the current intent is to allow multiple listeners to receive the
responses sent by the kernel.
Responses or events? There is a difference:
Response implies the program in user space requested (ex a GET) for that
information and is receiving such info.
Event implies the program in user space asked to be informed of changes
in the kernel. Example an exit would be considered an event.
Events are received by virtue of registering to a multicast group.
[..]
My design was to have the listener get both responses (what I call
replies in the code)
as well as events (data sent on exit of pid)
quoted
Since this interface (taskstats) is currently designed for that
possibility, having multiple listeners, one for
each "component" such as delay accounting, is the model we're using.
We expect each component to have a pair of userspace programs, one for
sending commands and the other
to "listen" to all replies + data generated on task exits.
You need to have a sender of GETs essentially and a listener of events.
Those are two connections. The replies of a get from user1 will not be
sent to user2 as well - unless ... thats what you are trying to achieve;
the question is why?
Yes, I was trying to have an asymmetric model where the userspace sender
of GETs
doesn't receive the reply as a unicast. Rather the reply is sent by
multicast (alongwith all the
event data).
Reason for this unintuitive design was to make it easier to process the
returned data.
The expected usage of delay accounting is to periodically "sample" the
delays for all
tasks (or tgids) in the system. Also, get the delays from exiting pids
(lets forget how tgid exit
is handled for now...irrelevant to this discussion).
Using the above two pieces of data, userspace can aggregate the "delays"
seen by any
grouping of tasks that it chooses to implement.
In this usage scenario, its more efficient to have one receiver get both
response and event
data and process in a loop.
However, we could switch to the model you suggest and use a
multithreaded send/receive
userspace utility.
quoted
The listener
is expected to register/deregister interest through
TASKSTATS_CMD_LISTEN and IGNORE.
It is not necessary if you follow the model i described.
quoted
quoted
How does this correlate to TASKSTATS_CMD_LISTEN/IGNORE?
See above. Its mainly an optimization so that if no listener is present,
there's no need to generate the data.
Also not necessary - There is a recent netlink addition to make sure
that events dont get sent if no listeners exist.
genetlink needs to be extended. For now assume such a thing exists.
Ok. Will this addition work for both unicast and multicast modes ?
quoted
quoted
quoted
+
quoted
Good point. Should check for users sending it as a cmd and treat it as a
noop.
More like return an -EINVAL
Will this be necessary ? Isn't genl_rcv_msg() going to return a -EOPNOTSUPP
automatically for us since we've not registered the command ?
quoted
I'm just using
this as a placeholder for data thats returned without being requested.
So it is unconditional?
Yes.
quoted
Come to think of it, there's no real reason to have a genlmsghdr for
returned data, is there ?
All messages should be consistent whether they are sent from user
or kernel.
Ok. will retain genetlink header.
quoted
Other than to copy the genlmsghdr that was sent so user can identify
which command was sent
(and I'm doing that through the reply type, perhaps redundantly).
yes, that is a useful trick. Just make sure they are reflected
correctly.
quoted
Actually, the next iteration of the code will move to dynamically
generated ID. But yes, will need to check for that.
Also if you can provide feedback whether the doc i sent was any use
and what wasnt clear etc.
Will do.
quoted
Thanks for the review.
Couple of questions about general netlink:
is it intended to remain a size that will always be aligned to the
NLMSG_ALIGNTO so that (NLMSG_DATA(nlhdr) + GENL_HDRLEN) can always
be used as a pointer to the genlmsghdr ?
I am not sure i followed.
The whole message (nlhdr, genlhdr, optionalhdr, TLVs) has to be in
the end 32 bit aligned.
Ok , so separate padding isn't needed to make the genlhdr, optionalhdr
and TLV parts aligned
too.
quoted
Adding some macros like genlmsg_data(nlh) would be handy (currently I
just define and use it locally).
On Mon, 2006-06-03 at 12:00 -0500, Shailabh Nagar wrote:
My design was to have the listener get both responses (what I call
replies in the code) as well as events (data sent on exit of pid)
I think i may not be doing justice explaining this, so let me be more
elaborate so we can be in sync.
Here is the classical way of doing things:
- Assume several apps in user space and a target in the kernel (this
could be reversed or combined in many ways, but the sake of
simplicity/clarity make the above assumption).
- suppose we have five user space apps A, B, C, D, E; these processes
would typically do one of the following class of activities:
a) configure (ADD/NEW/DEL etc). This is issued towards the kernel to
set/create/delete/flush some scalar attribute or vector. These sorts of
commands are synchronous. i.e you issue them, you expect a response
(which may indicate success/failure etc). The response is unicast; the
effect of what they affected may cause an event which may be multicast.
b) query(GET). This is issued towards the kernel to query state of
configured items. These class of commands are also synchronous. There
are special cases of the query which dump everything in the target -
literally called "dumps". The response is unicast.
c) events. These are _asynchronous_ messages issued by the kernel to
indicate some happening in the kernel. The event may be caused by #a
above or any other activity in the kernel. Events are multicast.
To receive them you have to register for the multicast group. You do so
via sockets. You can register to many multicast group.
For clarity again assume we have a multicast group where announcements
of pids exiting is seen and C and D are registered to such a multicast
group.
Suppose process A exits. That would fall under #c above. C and D will be
notified.
Suppose B configures something in the kernel that forces the kernel to
have process E exit and that such an operation is successful. B will get
acknowledgement it succeeded (unicast). C and D will get notified
(multicast).
Suppose C issued a GET to find details about a specific pid, then only C
will get that info back (message is unicast).
[A response message to a GET is typically designed to be the same as an
ADD message i.e one should be able to take exactly the same message,
change one or two things and shove back into the kernel to configure].
Suppose D issued a GET with dump flag, then D will get the details of
all pids (message is unicast).
Is this clear? Is there more than the above you need?
There are no hard rules on what you need to be multicasting and as an
example you could send periodic(aka time based) samples from the kernel
on a multicast channel and that would be received by all. It did seem
odd that you want to have a semi-promiscous mode where a response to a
GET is multicast. If that is still what you want to achieve, then you
should.
However, we could switch to the model you suggest and use a
multithreaded send/receive userspace utility.
This is more of the classical way of doing things.
quoted
There is a recent netlink addition to make sure
that events dont get sent if no listeners exist.
genetlink needs to be extended. For now assume such a thing exists.
Ok. Will this addition work for both unicast and multicast modes ?
If you never open a connection to the kernel, nothing will be generated
towards user space.
There are other techniques to rate limit event generation as well (one
such technique is a nagle-like algorithm used by xfrm).
quoted
Will this be necessary ? Isn't genl_rcv_msg() going to return a -EOPNOTSUPP
automatically for us since we've not registered the command ?
Yes, please in your doc feedback remind me of this,
quoted
Also if you can provide feedback whether the doc i sent was any use
and what wasnt clear etc.
Will do.
also take a look at the excellent documentation Thomas Graf has put in
the kernel for all the utilities for manipulating netlink messages and
tell me if that should also be put in this doc (It is listed as a TODO).
cheers,
jamal
On Mon, 2006-06-03 at 12:00 -0500, Shailabh Nagar wrote:
quoted
My design was to have the listener get both responses (what I call
replies in the code) as well as events (data sent on exit of pid)
I think i may not be doing justice explaining this, so let me be more
elaborate so we can be in sync.
Here is the classical way of doing things:
- Assume several apps in user space and a target in the kernel (this
could be reversed or combined in many ways, but the sake of
simplicity/clarity make the above assumption).
- suppose we have five user space apps A, B, C, D, E; these processes
would typically do one of the following class of activities:
a) configure (ADD/NEW/DEL etc). This is issued towards the kernel to
set/create/delete/flush some scalar attribute or vector. These sorts of
commands are synchronous. i.e you issue them, you expect a response
(which may indicate success/failure etc). The response is unicast; the
effect of what they affected may cause an event which may be multicast.
b) query(GET). This is issued towards the kernel to query state of
configured items. These class of commands are also synchronous. There
are special cases of the query which dump everything in the target -
literally called "dumps". The response is unicast.
c) events. These are _asynchronous_ messages issued by the kernel to
indicate some happening in the kernel. The event may be caused by #a
above or any other activity in the kernel. Events are multicast.
To receive them you have to register for the multicast group. You do so
via sockets. You can register to many multicast group.
For clarity again assume we have a multicast group where announcements
of pids exiting is seen and C and D are registered to such a multicast
group.
Suppose process A exits. That would fall under #c above. C and D will be
notified.
Suppose B configures something in the kernel that forces the kernel to
have process E exit and that such an operation is successful. B will get
acknowledgement it succeeded (unicast). C and D will get notified
(multicast).
Suppose C issued a GET to find details about a specific pid, then only C
will get that info back (message is unicast).
[A response message to a GET is typically designed to be the same as an
ADD message i.e one should be able to take exactly the same message,
change one or two things and shove back into the kernel to configure].
Suppose D issued a GET with dump flag, then D will get the details of
all pids (message is unicast).
Is this clear? Is there more than the above you need?
Thanks for the clarification of the usage model. While our needs are
certainly much less complex,
it is useful to know the range of options.
There are no hard rules on what you need to be multicasting and as an
example you could send periodic(aka time based) samples from the kernel
on a multicast channel and that would be received by all. It did seem
odd that you want to have a semi-promiscous mode where a response to a
GET is multicast. If that is still what you want to achieve, then you
should.
Ok, we'll probably switch to the classical mode you suggest since the
"efficient processing"
rationale for choosing to operate in the semi-promiscous mode earlier
can be overcome by
writing a multi-threaded userspace utility.
quoted
However, we could switch to the model you suggest and use a
multithreaded send/receive userspace utility.
This is more of the classical way of doing things.
quoted
quoted
There is a recent netlink addition to make sure
that events dont get sent if no listeners exist.
genetlink needs to be extended. For now assume such a thing exists.
Ok. Will this addition work for both unicast and multicast modes ?
If you never open a connection to the kernel, nothing will be generated
towards user space.
There are other techniques to rate limit event generation as well (one
such technique is a nagle-like algorithm used by xfrm).
quoted
Will this be necessary ? Isn't genl_rcv_msg() going to return a -EOPNOTSUPP
automatically for us since we've not registered the command ?
Yes, please in your doc feedback remind me of this,
quoted
quoted
Also if you can provide feedback whether the doc i sent was any use
and what wasnt clear etc.
Will do.
also take a look at the excellent documentation Thomas Graf has put in
the kernel for all the utilities for manipulating netlink messages and
tell me if that should also be put in this doc (It is listed as a TODO).
Ok.
Thanks,
Shailabh
cheers,
jamal
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
Thanks for the clarification of the usage model. While our needs are
certainly much less complex,
it is useful to know the range of options.
quoted
There are no hard rules on what you need to be multicasting and as an
example you could send periodic(aka time based) samples from the kernel
on a multicast channel and that would be received by all. It did seem
odd that you want to have a semi-promiscous mode where a response to a
GET is multicast. If that is still what you want to achieve, then you
should.
quoted
quoted
Also if you can provide feedback whether the doc i sent was any use
and what wasnt clear etc.
also take a look at the excellent documentation Thomas Graf has put in
the kernel for all the utilities for manipulating netlink messages and
tell me if that should also be put in this doc (It is listed as a TODO).
Hello, Jamal,
Please find the latest version of the patch for review. The genetlink
code has been updated as per your review comments. The changelog is provided
below
1. Eliminated TASKSTATS_CMD_LISTEN and TASKSTATS_CMD_IGNORE
2. Provide generic functions called genlmsg_data() and genlmsg_len()
in linux/net/genetlink.h
3. Do not multicast all replies, multicast only events generated due
to task exit.
4. The taskstats and taskstats_reply structures are now 64 bit aligned.
5. Family id is dynamically generated.
Please let us know if we missed something out.
Thanks,
Balbir
Signed-off-by: Shailabh Nagar <redacted>
Signed-off-by: Balbir Singh <redacted>
---
include/linux/delayacct.h | 2
include/linux/taskstats.h | 128 ++++++++++++++++++++++++
include/net/genetlink.h | 20 +++
init/Kconfig | 16 ++-
kernel/Makefile | 1
kernel/delayacct.c | 56 ++++++++++
kernel/taskstats.c | 244 ++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 464 insertions(+), 3 deletions(-)
diff -puN include/linux/delayacct.h~delayacct-genetlink include/linux/delayacct.h
@@ -0,0 +1,128 @@+/* taskstats.h - exporting per-task statistics+*+*Copyright(C)ShailabhNagar,IBMCorp.2006+*(C)BalbirSingh,IBMCorp.2006+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodifyit+*underthetermsofversion2.1oftheGNULesserGeneralPublicLicense+*aspublishedbytheFreeSoftwareFoundation.+*+*Thisprogramisdistributedinthehopethatitwouldbeuseful,but+*WITHOUTANYWARRANTY;withouteventheimpliedwarrantyof+*MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.+*/++#ifndef _LINUX_TASKSTATS_H+#define _LINUX_TASKSTATS_H++/* Format for per-task data returned to userland when+*-ataskexits+*-listenerrequestsstatsforatask+*+*Thestructisversioned.Newerversionsshouldonlyaddfieldsto+*thebottomofthestructtomaintainbackwardcompatibility.+*+*Tocreatethenextversion,bumpupthetaskstats_versionvariable+*anddelineatethestartofnewlyaddedfieldswithacommentindicating+*theversionnumber.+*/++#define TASKSTATS_VERSION 1++structtaskstats{+/* Maintain 64-bit alignment while extending */++/* Version 1 */+#define TASKSTATS_NOPID -1+__s64pid;+__s64tgid;++/* XXX_count is number of delay values recorded.+*XXX_totaliscorrespondingcumulativedelayinnanoseconds+*/++#define TASKSTATS_NOCPUSTATS 1+__u64cpu_count;+__u64cpu_delay_total;/* wait, while runnable, for cpu */+__u64blkio_count;+__u64blkio_delay_total;/* sync,block io completion wait*/+__u64swapin_count;+__u64swapin_delay_total;/* swapin page fault wait*/++__u64cpu_run_total;/* cpu running time+*nocountavailable/provided*/+};+++#define TASKSTATS_LISTEN_GROUP 0x1++/*+*Commandssentfromuserspace+*Notversioned.Newcommandsshouldonlybeinsertedattheenum'send+*/++enum{+TASKSTATS_CMD_UNSPEC,/* Reserved */+TASKSTATS_CMD_NONE,/* Not a valid cmd to send+*Marksdatasentontask/tgidexit*/+TASKSTATS_CMD_LISTEN,/* Start listening */+TASKSTATS_CMD_IGNORE,/* Stop listening */+TASKSTATS_CMD_PID,/* Send stats for a pid */+TASKSTATS_CMD_TGID,/* Send stats for a tgid */+};++/* Parameters for commands+*Newparametersshouldonlybeinsertedatthestruct'send+*/++structtaskstats_cmd_param{+/* Maintain 64-bit alignment while extending */+union{+__s64pid;+__s64tgid;+}id;+};++enumouttype{+TASKSTATS_REPLY_NONE=1,/* Control cmd response */+TASKSTATS_REPLY_PID,/* per-pid data cmd response*/+TASKSTATS_REPLY_TGID,/* per-tgid data cmd response*/+TASKSTATS_REPLY_EXIT_PID,/* Exiting task's stats */+TASKSTATS_REPLY_EXIT_TGID,/* Exiting tgid's stats+*(sentoneachtid'sexit)*/+};++/*+*Replysentfromkernel+*Versionnumberaffectssize/formatofstructtaskstatsonly+*/++structtaskstats_reply{+/* Maintain 64-bit alignment while extending */+__u16outtype;/* Must be one of enum outtype */+__u16version;+__u32err;+structtaskstatsstats;/* Invalid if err != 0 */+};++/* NETLINK_GENERIC related info */++#define TASKSTATS_GENL_NAME "TASKSTATS"+#define TASKSTATS_GENL_VERSION 0x1++#define TASKSTATS_HDRLEN (NLMSG_SPACE(GENL_HDRLEN))+#define TASKSTATS_BODYLEN (sizeof(struct taskstats_reply))++#ifdef __KERNEL__++#include<linux/sched.h>++#ifdef CONFIG_TASKSTATS+externvoidtaskstats_exit_pid(structtask_struct*);+#else+staticinlinevoidtaskstats_exit_pid(structtask_struct*tsk)+{}+#endif++#endif /* __KERNEL__ */+#endif /* _LINUX_TASKSTATS_H */
@@ -35,6 +35,7 @@ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/obj-$(CONFIG_SECCOMP)+=seccomp.oobj-$(CONFIG_RCU_TORTURE_TEST)+=rcutorture.oobj-$(CONFIG_TASK_DELAY_ACCT)+=delayacct.o+obj-$(CONFIG_TASKSTATS)+=taskstats.oifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
@@ -0,0 +1,244 @@+/*+*taskstats.c-Exportper-taskstatisticstouserland+*+*Copyright(C)ShailabhNagar,IBMCorp.2006+*(C)BalbirSingh,IBMCorp.2006+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodify+*itunderthetermsoftheGNUGeneralPublicLicenseaspublishedby+*theFreeSoftwareFoundation;eitherversion2oftheLicense,or+*(atyouroption)anylaterversion.+*+*Thisprogramisdistributedinthehopethatitwillbeuseful,+*butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof+*MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe+*GNUGeneralPublicLicenseformoredetails.+*+*/++#include<linux/kernel.h>+#include<linux/taskstats.h>+#include<linux/delayacct.h>+#include<net/genetlink.h>+#include<asm/atomic.h>++constinttaskstats_version=TASKSTATS_VERSION;+staticDEFINE_PER_CPU(__u32,taskstats_seqnum)={0};+staticintfamily_registered=0;+++staticstructgenl_familyfamily={+.id=GENL_ID_GENERATE,+.name=TASKSTATS_GENL_NAME,+.version=TASKSTATS_GENL_VERSION,+.hdrsize=0,+.maxattr=0,+};++/* Taskstat specific functions */+staticintprepare_reply(structgenl_info*info,u8cmd,+structsk_buff**skbp,structtaskstats_reply**replyp)+{+structsk_buff*skb;+structtaskstats_reply*reply;++skb=nlmsg_new(TASKSTATS_HDRLEN+TASKSTATS_BODYLEN);+if(!skb)+return-ENOMEM;++if(!info){+intseq=get_cpu_var(taskstats_seqnum)++;+put_cpu_var(taskstats_seqnum);++reply=genlmsg_put(skb,0,seq,+family.id,0,NLM_F_REQUEST,+cmd,family.version);+}else+reply=genlmsg_put(skb,info->snd_pid,info->snd_seq,+family.id,0,info->nlhdr->nlmsg_flags,+info->genlhdr->cmd,family.version);+if(reply==NULL){+nlmsg_free(skb);+return-EINVAL;+}+skb_put(skb,TASKSTATS_BODYLEN);++memset(reply,0,sizeof(*reply));+reply->version=taskstats_version;+reply->err=0;++*skbp=skb;+*replyp=reply;+return0;+}++staticintsend_reply(structsk_buff*skb,intreplytype,pid_tpid,intevent)+{+structgenlmsghdr*genlhdr=nlmsg_data((structnlmsghdr*)skb->data);+structtaskstats_reply*reply;+intrc;++reply=(structtaskstats_reply*)genlmsg_data(genlhdr);+reply->outtype=replytype;++rc=genlmsg_end(skb,reply);+if(rc<0){+nlmsg_free(skb);+returnrc;+}++if(event)+returngenlmsg_multicast(skb,pid,TASKSTATS_LISTEN_GROUP);+else+returngenlmsg_unicast(skb,pid);+}++staticinlinevoidfill_pid(structtaskstats_reply*reply,pid_tpid,+structtask_struct*pidtsk)+{+intrc;+structtask_struct*tsk=pidtsk;++if(!pidtsk){+read_lock(&tasklist_lock);+tsk=find_task_by_pid(pid);+if(!tsk){+read_unlock(&tasklist_lock);+reply->err=EINVAL;+return;+}+get_task_struct(tsk);+read_unlock(&tasklist_lock);+}else+get_task_struct(tsk);++rc=delayacct_add_tsk(reply,tsk);+if(!rc){+reply->stats.pid=(s64)tsk->pid;+reply->stats.tgid=(s64)tsk->tgid;+}else+reply->err=(rc<0)?-rc:rc;++put_task_struct(tsk);+}++staticinttaskstats_send_pid(structsk_buff*skb,structgenl_info*info)+{+intrc;+structsk_buff*rep_skb;+structtaskstats_reply*reply;+structtaskstats_cmd_param*param=info->userhdr;++rc=prepare_reply(info,info->genlhdr->cmd,&rep_skb,&reply);+if(rc)+returnrc;+fill_pid(reply,param->id.pid,NULL);+returnsend_reply(rep_skb,TASKSTATS_REPLY_PID,info->snd_pid,0);+}++staticinlinevoidfill_tgid(structtaskstats_reply*reply,pid_ttgid,+structtask_struct*tgidtsk)+{+intrc;+structtask_struct*tsk,*first;++first=tgidtsk;+read_lock(&tasklist_lock);+if(!first){+first=find_task_by_pid(tgid);+if(!first){+read_unlock(&tasklist_lock);+reply->err=EINVAL;+return;+}+}+tsk=first;+do{+rc=delayacct_add_tsk(reply,tsk);+if(rc)+break;+}while_each_thread(first,tsk);+read_unlock(&tasklist_lock);++if(!rc){+reply->stats.pid=(s64)TASKSTATS_NOPID;+reply->stats.tgid=(s64)tgid;+}else+reply->err=(rc<0)?-rc:rc;+}++staticinttaskstats_send_tgid(structsk_buff*skb,structgenl_info*info)+{+intrc;+structsk_buff*rep_skb;+structtaskstats_reply*reply;+structtaskstats_cmd_param*param=info->userhdr;++rc=prepare_reply(info,info->genlhdr->cmd,&rep_skb,&reply);+if(rc)+returnrc;+fill_tgid(reply,param->id.tgid,NULL);+returnsend_reply(rep_skb,TASKSTATS_REPLY_TGID,info->snd_pid,0);+}++/* Send pid data out on exit */+voidtaskstats_exit_pid(structtask_struct*tsk)+{+intrc;+structsk_buff*rep_skb;+structtaskstats_reply*reply;++/*+*taskscanstarttoexitveryearly.Ensurethatthefamily+*isregisteredbeforenotificationsaresentout+*/+if(!family_registered)+return;++rc=prepare_reply(NULL,TASKSTATS_CMD_NONE,&rep_skb,&reply);+if(rc)+return;+fill_pid(reply,tsk->pid,tsk);+rc=send_reply(rep_skb,TASKSTATS_REPLY_EXIT_PID,0,1);++if(rc||thread_group_empty(tsk))+return;++/* Send tgid data too */+rc=prepare_reply(NULL,TASKSTATS_CMD_NONE,&rep_skb,&reply);+if(rc)+return;+fill_tgid(reply,tsk->tgid,tsk);+send_reply(rep_skb,TASKSTATS_REPLY_EXIT_TGID,0,1);+}++staticstructgenl_opspid_ops={+.cmd=TASKSTATS_CMD_PID,+.doit=taskstats_send_pid,+};++staticstructgenl_opstgid_ops={+.cmd=TASKSTATS_CMD_TGID,+.doit=taskstats_send_tgid,+};++staticint__inittaskstats_init(void)+{+if(genl_register_family(&family))+return-EFAULT;+family_registered=1;++if(genl_register_ops(&family,&pid_ops))+gotoerr;+if(genl_register_ops(&family,&tgid_ops))+gotoerr;++return0;+err:+genl_unregister_family(&family);+family_registered=0;+return-EFAULT;+}++late_initcall(taskstats_init);+
_
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
Hello, Jamal,
Please find the latest version of the patch for review. The genetlink
code has been updated as per your review comments. The changelog is provided
below
1. Eliminated TASKSTATS_CMD_LISTEN and TASKSTATS_CMD_IGNORE
2. Provide generic functions called genlmsg_data() and genlmsg_len()
in linux/net/genetlink.h
Balbir,
it might be a good idea to split 2. out separately, since it has generic
value beyond the
delay accounting patches (just like we did for the timespec_diff_ns change)
Thanks,
Shailabh
3. Do not multicast all replies, multicast only events generated due
to task exit.
4. The taskstats and taskstats_reply structures are now 64 bit aligned.
5. Family id is dynamically generated.
Please let us know if we missed something out.
Thanks,
Balbir
Signed-off-by: Shailabh Nagar <redacted>
Signed-off-by: Balbir Singh <redacted>
---
include/linux/delayacct.h | 2
include/linux/taskstats.h | 128 ++++++++++++++++++++++++
include/net/genetlink.h | 20 +++
init/Kconfig | 16 ++-
kernel/Makefile | 1
kernel/delayacct.c | 56 ++++++++++
kernel/taskstats.c | 244 ++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 464 insertions(+), 3 deletions(-)
<snip>
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
On Thu, 2006-09-03 at 20:07 +0530, Balbir Singh wrote:
Please find the latest version of the patch for review. The genetlink
code has been updated as per your review comments. The changelog is provided
below
1. Eliminated TASKSTATS_CMD_LISTEN and TASKSTATS_CMD_IGNORE
2. Provide generic functions called genlmsg_data() and genlmsg_len()
in linux/net/genetlink.h
3. Do not multicast all replies, multicast only events generated due
to task exit.
4. The taskstats and taskstats_reply structures are now 64 bit aligned.
5. Family id is dynamically generated.
Please let us know if we missed something out.
Design still shaky IMO - now that i think i may understand what your end
goal is.
Using the principles i described in earlier email, the problem you are
trying to solve is:
a) shipping of the taskstats from kernel to user-space asynchronously to
all listeners on multicast channel/group TASKSTATS_LISTEN_GRP
at the point when some process exits.
b) responding to queries issued by the user to the kernel for taskstats
of a particular defined tgid and/or pid combination.
Did i summarize your goals correctly?
So lets stat with #b:
i) the message is multicast; there has to be a user space app registered
to the multicast group otherwise nothing goes to user space.
ii) user space issues a GET and it seems to me the appropriate naming
for the response is a NEW.
Lets go to #a:
The issued multicast messages are also NEW and no different from the
ones sent in response to a GET.
Having said that then, you have the following commands:
enum {
TASKSTATS_CMD_UNSPEC, /* Reserved */
TASKSTATS_CMD_GET, /* user -> kernel query*/
TASKSTATS_CMD_NEW, /* kernel -> user update */
};
You also need the following TLVs
enum {
TASKSTATS_TYPE_UNSPEC, /* Reserved */
TASKSTATS_TYPE_TGID, /* The TGID */
TASKSTATS_TYPE_PID, /* The PID */
TASKSTATS_TYPE_STATS, /* carries the taskstats */
TASKSTATS_TYPE_VERS, /* carries the version */
};
Refer to the doc i passed you and provide feedback if how to use the
above is not obvious.
The use of TLVs above implies that any of these can be optionally
appearing.
So when you are going from user->kernel with a GET a in #a above, then
you can specify the PID and/or TGID and you dont need to specify the
STATS and this would be perfectly legal.
On kernel->user (in the case of response to #a or async notifiation as
in #b) you really dont need to specify the TG/PID since they appear in
the STATS etc.
I take it you dont want to configure the values of taskstats from user
space, otherwise user->kernel will send a NEW as well.
I also take it dumping doesnt apply to you, so you dont need a dump
callback in your kernel code.
From what i described so far, you dont really need a header for yourself
either (maybe you need one to just store the VERSION?)
I didnt understand the point to the err field you had in the reply.
Netlink already does issue errors which can be read via perror. If this
is different from what you need, it may be an excuse to have your own
header.
I hope this helps.
cheers,
jamal
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
a) shipping of the taskstats from kernel to user-space asynchronously to
all listeners on multicast channel/group TASKSTATS_LISTEN_GRP
at the point when some process exits.
b) responding to queries issued by the user to the kernel for taskstats
of a particular defined tgid and/or pid combination.
Did i summarize your goals correctly?
So lets stat with #b:
i) the message is multicast; there has to be a user space app registered
to the multicast group otherwise nothing goes to user space.
I mispoke:
The above applies to #a.
For #b, the message from/to kernel to user is unicast.
cheers,
jamal
On Fri, Mar 10, 2006 at 09:53:53AM -0500, jamal wrote:
On Thu, 2006-09-03 at 20:07 +0530, Balbir Singh wrote:
quoted
Please let us know if we missed something out.
Design still shaky IMO - now that i think i may understand what your end
goal is.
Using the principles i described in earlier email, the problem you are
trying to solve is:
a) shipping of the taskstats from kernel to user-space asynchronously to
all listeners on multicast channel/group TASKSTATS_LISTEN_GRP
at the point when some process exits.
b) responding to queries issued by the user to the kernel for taskstats
of a particular defined tgid and/or pid combination.
Did i summarize your goals correctly?
Yes, you did.
So lets stat with #b:
i) the message is multicast; there has to be a user space app registered
to the multicast group otherwise nothing goes to user space.
ii) user space issues a GET and it seems to me the appropriate naming
for the response is a NEW.
Lets go to #a:
The issued multicast messages are also NEW and no different from the
ones sent in response to a GET.
Having said that then, you have the following commands:
enum {
TASKSTATS_CMD_UNSPEC, /* Reserved */
TASKSTATS_CMD_GET, /* user -> kernel query*/
TASKSTATS_CMD_NEW, /* kernel -> user update */
};
You also need the following TLVs
enum {
TASKSTATS_TYPE_UNSPEC, /* Reserved */
TASKSTATS_TYPE_TGID, /* The TGID */
TASKSTATS_TYPE_PID, /* The PID */
TASKSTATS_TYPE_STATS, /* carries the taskstats */
TASKSTATS_TYPE_VERS, /* carries the version */
};
Refer to the doc i passed you and provide feedback if how to use the
above is not obvious.
I will look at the document, just got hold of it.
The use of TLVs above implies that any of these can be optionally
appearing.
So when you are going from user->kernel with a GET a in #a above, then
you can specify the PID and/or TGID and you dont need to specify the
STATS and this would be perfectly legal.
On kernel->user (in the case of response to #a or async notifiation as
in #b) you really dont need to specify the TG/PID since they appear in
the STATS etc.
I see your point now. I am looking at other users of netlink like
rtnetlink and I see the classical usage.
We can implement TLV's in our code, but for the most part the data we exchange
between the user <-> kernel has all the TLV's listed in the enum above.
The major differnece is the type (pid/tgid). Hence we created a structure
(taskstats) instead of using TLV's.
I take it you dont want to configure the values of taskstats from user
space, otherwise user->kernel will send a NEW as well.
Your understanding is correct.
I also take it dumping doesnt apply to you, so you dont need a dump
callback in your kernel code.
Yes, this is correct as well.
quoted
From what i described so far, you dont really need a header for yourself
either (maybe you need one to just store the VERSION?)
True, we do not need a header.
I didnt understand the point to the err field you had in the reply.
Netlink already does issue errors which can be read via perror. If this
is different from what you need, it may be an excuse to have your own
header.
Hmm.. Will look into this.
I hope this helps.
Yes, it does immensely. Thanks for the detailed feedback.
cheers,
jamal
Warm Regards,
Balbir
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
On Fri, 2006-10-03 at 22:09 +0530, Balbir Singh wrote:
On Fri, Mar 10, 2006 at 09:53:53AM -0500, jamal wrote:
quoted
On kernel->user (in the case of response to #a or async notifiation as
in #b) you really dont need to specify the TG/PID since they appear in
the STATS etc.
I see your point now. I am looking at other users of netlink like
rtnetlink and I see the classical usage.
We can implement TLV's in our code, but for the most part the data we exchange
between the user <-> kernel has all the TLV's listed in the enum above.
The major differnece is the type (pid/tgid). Hence we created a structure
(taskstats) instead of using TLV's.
Something to remember:
1) TLVs are essentially giving you the flexibility to send optionally
appearing elements. It is up to the receiver (in the kernel or user
space) to check for the presence of mandatory elements or execute things
depending on the presence of certain TLVs. Example in your case:
if the tgid TLV appears then the user is requesting for that TLV
if the pid appears then they are requesting for that
if both appear then it is the && of the two.
You should always ignore TLVs you dont understand - to allow for forward
compatibility.
2) The "T" part is essentially also encoding (semantically) what size
the value is; the "L" part is useful for validation. So the receiver
will always know what the size of the TLV is by definition and uses the
L to make sure it is the right size. Reject what is of the wrong size.
cheers,
jamal
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
On Sat, Mar 11, 2006 at 08:30:49AM -0500, jamal wrote:
On Fri, 2006-10-03 at 22:09 +0530, Balbir Singh wrote:
quoted
On Fri, Mar 10, 2006 at 09:53:53AM -0500, jamal wrote:
quoted
quoted
On kernel->user (in the case of response to #a or async notifiation as
in #b) you really dont need to specify the TG/PID since they appear in
the STATS etc.
I see your point now. I am looking at other users of netlink like
rtnetlink and I see the classical usage.
We can implement TLV's in our code, but for the most part the data we exchange
between the user <-> kernel has all the TLV's listed in the enum above.
The major differnece is the type (pid/tgid). Hence we created a structure
(taskstats) instead of using TLV's.
Something to remember:
1) TLVs are essentially giving you the flexibility to send optionally
appearing elements. It is up to the receiver (in the kernel or user
space) to check for the presence of mandatory elements or execute things
depending on the presence of certain TLVs. Example in your case:
if the tgid TLV appears then the user is requesting for that TLV
if the pid appears then they are requesting for that
if both appear then it is the && of the two.
You should always ignore TLVs you dont understand - to allow for forward
compatibility.
2) The "T" part is essentially also encoding (semantically) what size
the value is; the "L" part is useful for validation. So the receiver
will always know what the size of the TLV is by definition and uses the
L to make sure it is the right size. Reject what is of the wrong size.
cheers,
jamal
Thanks for the clarification, I will try and adapt our genetlink to use
TLV's, I can see the benefits - we will work on this as an evolutionary change
to our code.
Warm Regards,
Balbir