Re: [RTnet-developers] Re: Common rt-buffers
Brought to you by:
bet-frogger,
kiszka
|
From: Jan K. <jan...@we...> - 2005-12-19 21:06:17
|
Hi Yuchen,
time to kick this discussion again ;) - no I didn't forget it!
Yuchen Zhang wrote:
> On 12/9/05, Jan Kiszka <jan...@we...> wrote:
>
>>Yuchen Zhang wrote:
>
>>>
>>>Ok, now time for real debating:)
>>>Let's first sketch the main frame code to support this service.
>>>
>>>struct Cap_struct {
>>> struct net_dev *fakedev; /*the fake ethernet dev to deliver
>>>captured packet to user-space*/
>>> struct rt-buffer-pool *cap_pool; /*where the buffers to
>>>compensate application memory come from*/
>>> int buffer_size; /* the size of buffer that can be captured here */
>>>}
>>
>>So, that structure describes a capturing instance, conceptually
>>something like rtcap service of RTnet?
>>
>
> Here the difference is, compared with rtcap in RTnet, every single
> Capturer has its own buffer pool and interface-to-userspace (the fake
> Ethernet). The latter can be seen the same in RTnet, as you have tap
> dev for each rtdev.
Ok, sounds interesting. But I guess this does not yet mean that there
can be multiple capturers for the same packet? I guess it means that you
decide later during the stack traversal (or earlier when looking at the
transmission path) if you want to grab a certain packet or not. Some
kind of in-kernel capturing filter instead of doing this later with
Ethereal&friends?
>
> But all in all, the new Capturing is oriented to application instead
> of network interface:
> when rtcap module in RTnet is loaded, it changes the xmit_hook&rx_hook
> of a certain rtdev with informing the applications, i.e. the
> capturing service is fully transparent to applications. (Fix me, if I
> am wrong:)) The new Capturing is new mainly because it lets
> applications take over the control of capturing.
>
Mmh, doesn't this confuse the user and make the management of all those
potential capturing sources a bit complicated? I already had problems to
explain users why there is also a "rteth0-mac" that additionally records
the queuing date of packets deferred by a RTmac discipline. Actually, I
haven't stumbled over a useful use case for this feature on my own so far...
>
>>>struct rt-buffer{
>>> .....
>>> struct Cap_struct *aCap;
>>>}
>>>
>>
>>And this link is needed as there can be multiple capturers, right? But
>>what about the additional fields required by rtcap to save the initial
>>buffer layout, the compensation buffer, timestamp, and other stuff? Note
>>that rtcap does deferred capturing. Does your service in RT-FireWire
>>work the same way?
>>
>
> My idea was also deferred capturing, but somehow it was not clearly expressed:)
> And yes, the timestamp will be in rt-buffer struct also. For
> compensation buffer, my initial idea was to only capture the rt-buffer
> when it is being freed. In that case, we dont need the compesation
> buffer pointer in rt-buffer struct, since the compensation buffer will
> be immediately given to the application buffer pool, i.e. buffer
> exchange between application and capturer. That's also why the
I think to remember having created such a variant in the early rtcap
days. It works well beside one "minor" ugliness: the queuing order in
the rtcap pseudo device became chaotic due to deferred buffer release of
certain NICs and other effects. This means that you will also see a
non-chronological list in Ethereal! Ok, one may try to reorder the
packets in rtcap before forwarding it, but this adds further complexity
and delay (you first have to collect for a while, then reorder, and
finally forward the packets).
> cap_rtbuffer function should return the pointer to compensation
> buffer. BUT now, I would rather choose to let application decide when
> to capture the packet: stamping the time, assigning the compensation
> packet and putting into the queue of captured packet. That is more
> similiar to rtcap in RTnet.
>
> So the rt-buffer struct will be
> struct rt-buffer{
> ..........
> struct Cap_struct *aCap;
> struct rt-buffer *comp_buf;
> }
>
>
>
>>>/*function to create a Cap_struct*/
>>>struct Cap_struct *create_cap( int size, // the buffer size
>>> struct kernel_slab_pool
>>>*parent_pool,
>>> char *name) // the name
>>>of fake ethernet dev, should be
>>>
>>>//specific about application
>>>{
>>> if(*name already exists){
>>> return (address of existing Cap_struct)
>>> }
>>> .............
>>>}
>>>
>>>/*function to remove a Cap_struct*/
>>>void remove_cap(struct Cap_struct *aCap_struct)
>>>
>>
>>Ok, this makes sense.
>>
>>
>>>/*function to capture a buffer*/
>>>struct rt-buffer *cap_rtbuffer(struct rt-buffer *abuffer, int
>>>buffer_size, struct cap_struct *aCap)
>>>{
>>> if(aCap->buffer_size != buffer_size)
>>> //print error msg and return
>>> else{
>>> //allocate a compesating buffer from the cap pool
>>> // exchange buffers
>>> //deliver the captured buffer to fake ethernet dev
>>
>>I hope you do NOT deliver immediately, just pend the delivery for Linux
>>to get in the CPU again.
>>
>
> I thought this would not be real-time killing, since the main work is
> done in the signal handler invoked via netif_rx, but I just realized
> it also should include one time dynamic memory allocation, so now it
> will be wrapped in a Linux signal handler. Again like in RTnet.
Yep, this is fine if it's just that non-RT signal.
[mail #2]
> Sorry, I sent the last mail by mistake, it has not been finished. So
> the story continues here:)
>
> The changed cap_rtbuffer is like:
>
> void cap_rtbuffer(struct rt-buffer *abuffer, int
> buffer_size, struct cap_struct *aCap)
> {
> if(aCap->buffer_size != buffer_size)
> //print error msg and return
> else{
> //allocate a compensating buffer from the cap pool
> if(failed)
> //out of memory failure and return
> //assign comp buffer to abuffer
> // stamp the time
> //put the buffer to the queue as captured packet
> }
> }
>
In terms of rtcap: would cat_rtbuffer be something like
rtcap_report_incoming and would it be called from the xmit-hook for
outgoing packets?
But we will certainly still have something like rtcap_mark_incoming to
save the real packet dimension, don't we?
> [...]
> Em...I would like to know more about this: how to move the capturing
> mark in RTnet from where it is now? Now, I see it only happens when
> packets is transmitted or received.
>
Well, the decision about capturing a packet or not is made for incoming
packets via rtmac_report_incoming. For outgoing ones, we have the hook
before the drivers transmission routing, a low intrusive approach
regarding code modification. To move to incoming capturing point would
be simple, but we would need a similar functions then also for outgoing
packets to gain more flexibility.
But this just raises the question for we what subsystems / packet
producer you want to instrument separately in this way? And how will the
user select the right one? Will there be bulks of pseudo network devices
for capturing?
> [...]
> I just created a new branch in RTFW svn. Now only copied the files
> from RTFW's rtpkbuff module, but can be compiled separately. A
> starting point.
>
That's a good step forward! Actually, I think we should keep all this
capturing discussion in min, but first start off with the "real" work.
RTnet's rtskbs and RT-FireWire's rtpks also began without capturing, so
we should also be able to easily extend the first common (and maybe
working) concept with this feature later.
Jan
|