Thread: [RTnet-developers] rtskb_acquire
Brought to you by:
bet-frogger,
kiszka
|
From: Jorge A. <j-a...@cr...> - 2006-08-31 12:49:26
|
Hello Jan.
Can you please give me a description of wath is done in the rtskb_acquire function in the rtskb.c file line 463.
The rtnet is crashing with an SIG=11 in this function when i pass the cloned rtskb to the ETH_P_ALL socket.
My clone function is the following:
/** Clone a rtskb to another, allocating a rtskb for the copy */
int rtskb_clone(struct rtskb *rtskb_1,struct rtskb *rtskb_2,struct rtskb_queue *pool)
{
rtskb_1 = alloc_rtskb(rtskb_2->len,pool);
if(rtskb_1 == NULL)
return -ENOMEM;
memcpy(rtskb_1->data, rtskb_2->data, rtskb_2->len );
rtskb_1->len = rtskb_2->len;
rtskb_1->time_stamp = rtskb_2->time_stamp;
rtskb_1->rtdev = rtskb_2->rtdev;
rtskb_1->protocol = rtskb_2->protocol;
return 0;
}
I check the path between the driver and the stack manager and only find that these fields are necessary.
the task manager does the following for the clone rtskb:
list_for_each_entry(pt_entry, &rt_packets[hash], list_entry)
{
rt_printk("List entry protocol= %d %d name = %d\n",
ntohs(pt_entry->type),hash,strncmp(pt_entry->name,"PACKET_SOCKET",13));
//the "PACKET_SOCKET" string is defined in line 188 of file af_packet.c
//this string should be replaced by a #define declaration
if ( likely(ntohs(pt_entry->type) == hash &&
(strncmp(pt_entry->name,"PACKET_SOCKET",13) == 0 )))
{
rtdm_lock_put_irqrestore(&rt_packets_lock, context);
// rt_printk("List entry 1 \n");
sock = container_of(pt_entry, struct rtsocket,
prot.packet.packet_type);
rtdm_lock_get_irqsave(&rt_packets_lock, context);
err = rtskb_clone(clone_skb, skb, &sock->skb_pool);
rtdm_lock_put_irqrestore(&rt_packets_lock, context);
if(err != 0)
{
break;
}
rtskb_queue_head(&sock->skb_pool,clone_skb);
//queue the message to fifo head here
rtdm_lock_get_irqsave(&rt_packets_lock, context);
pt_entry->refcount++;
rtdm_lock_put_irqrestore(&rt_packets_lock, context);
// rt_printk("List entry 2 \n");
err = pt_entry->handler(clone_skb, pt_entry);
// rt_printk("List entry 3 \n");
rtdm_lock_get_irqsave(&rt_packets_lock, context);
pt_entry->refcount--;
rtdm_lock_put_irqrestore(&rt_packets_lock, context);
}
}
I'm not sure if the cloned rtskb shoul be inserted in the queue head or not.
thanks
--
Jorge Almeida
j-a...@cr...
DISCLAIMER: This message may contain confidential information or privileged material and is intended only for the individual(s) named. If you are not a named addressee and mistakenly received this message you should not copy or otherwise disseminate it: please delete this e-mail from your system and notify the sender immediately. E-mail transmissions are not guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete or contain viruses. Therefore, the sender does not accept liability for any errors or omissions in the contents of this message that arise as a result of e-mail transmissions. Please request a hard copy version if verification is required. Critical Software, SA.
|
|
From: Jan K. <jan...@we...> - 2006-08-31 16:12:31
Attachments:
signature.asc
|
Hi Jorge,
Jorge Almeida wrote:
> Hello Jan.
>=20
> Can you please give me a description of wath is done in the rtskb_acqui=
re function in the rtskb.c file line 463.
That function passes the ownership of a rtskb from rtskb->pool to
comp_pool (compensation pool). For this purpose, an empty rtskb is
dequeued from comp_pool and enqueued in rtskb->pool, then rtskb->pool is
set to comp_pool.
>=20
> The rtnet is crashing with an SIG=3D11 in this function when i pass the=
cloned rtskb to the ETH_P_ALL socket.
Where precisely? Already considered to install kgdb for such development?=
>=20
> My clone function is the following:
> /** Clone a rtskb to another, allocating a rtskb for the copy */
> int rtskb_clone(struct rtskb *rtskb_1,struct rtskb *rtskb_2,struct rtsk=
b_queue *pool)
> {
>=20
> rtskb_1 =3D alloc_rtskb(rtskb_2->len,pool);
> if(rtskb_1 =3D=3D NULL)
> return -ENOMEM;
> =20
> =20
> memcpy(rtskb_1->data, rtskb_2->data, rtskb_2->len );
> rtskb_1->len =3D rtskb_2->len;
> rtskb_1->time_stamp =3D rtskb_2->time_stamp;
> rtskb_1->rtdev =3D rtskb_2->rtdev;
> rtskb_1->protocol =3D rtskb_2->protocol;
What about the things that happen in rt_eth_type_trans (except for
rtcap_mark_incoming)? Should case the crash above, but will cause
troubles when processing the rtskb.
> =20
> return 0;
> }
>=20
> I check the path between the driver and the stack manager and only find=
that these fields are necessary.
>=20
> the task manager does the following for the clone rtskb:
>=20
> list_for_each_entry(pt_entry, &rt_packets[hash], list_entry=
)
> {
> rt_printk("List entry protocol=3D %d %d name =3D %d\n",=
> ntohs(pt_entry->type),hash,strncmp(pt_entry->=
name,"PACKET_SOCKET",13));
> //the "PACKET_SOCKET" string is defined in line 188 of =
file af_packet.c
> //this string should be replaced by a #define declarati=
on
> if ( likely(ntohs(pt_entry->type) =3D=3D hash &&=20
> (strncmp(pt_entry->name,"PACKET_SOCKET",13)=
=3D=3D 0 )))
> {
> rtdm_lock_put_irqrestore(&rt_packets_lock, context)=
;
Don't drop the lock here when taking it two lines later again.
> // rt_printk("List entry 1 \n");
> =20
> sock =3D container_of(pt_entry, struct rtsocket,
> prot.packet.packet_type);
Fatal layering violation! This is a hack, the actual cloning should
rather take place inside the invoked handler. Same is true for the
enqueuing. This way you could also avoid to acquire an rtskb that was
already taken from the socket queue (redundant work).
> =20
> rtdm_lock_get_irqsave(&rt_packets_lock, context);
> err =3D rtskb_clone(clone_skb, skb, &sock->skb_pool=
);
> rtdm_lock_put_irqrestore(&rt_packets_lock, context)=
;
> if(err !=3D 0)
> {
> break;
> }
> =20
> rtskb_queue_head(&sock->skb_pool,clone_skb);
> //queue the message to fifo head here
> =20
> =20
> rtdm_lock_get_irqsave(&rt_packets_lock, context);
> pt_entry->refcount++;
> rtdm_lock_put_irqrestore(&rt_packets_lock, context)=
;
> // rt_printk("List entry 2 \n");
> err =3D pt_entry->handler(clone_skb, pt_entry);
> // rt_printk("List entry 3 \n");
> rtdm_lock_get_irqsave(&rt_packets_lock, context);
> pt_entry->refcount--;
> rtdm_lock_put_irqrestore(&rt_packets_lock, context)=
;
>=20
> }
> }
>=20
>=20
> I'm not sure if the cloned rtskb shoul be inserted in the queue head or=
not.
>=20
Move that stuff to af_packet.c.
Jan
|
|
From: Jorge A. <j-a...@cr...> - 2006-09-01 13:50:49
|
Hi Jan,
Just one small question.
When the rtskb are created the memory indicated by the pointers present in the struct rtskb are allocated too?
For example the rtdev pointer points to one area of allocated memory for this rtskb, or this pointer points to a unique area that refers to the rtdev struct of the real device?
Thanks for an answer.
Em Quinta, 31 de Agosto de 2006 17:12, o Jan Kiszka escreveu:
> Hi Jorge,
>
> Jorge Almeida wrote:
> > Hello Jan.
> >
> > Can you please give me a description of wath is done in the rtskb_acquire function in the rtskb.c file line 463.
>
> That function passes the ownership of a rtskb from rtskb->pool to
> comp_pool (compensation pool). For this purpose, an empty rtskb is
> dequeued from comp_pool and enqueued in rtskb->pool, then rtskb->pool is
> set to comp_pool.
>
> >
> > The rtnet is crashing with an SIG=11 in this function when i pass the cloned rtskb to the ETH_P_ALL socket.
>
> Where precisely? Already considered to install kgdb for such development?
>
> >
> > My clone function is the following:
> > /** Clone a rtskb to another, allocating a rtskb for the copy */
> > int rtskb_clone(struct rtskb *rtskb_1,struct rtskb *rtskb_2,struct rtskb_queue *pool)
> > {
> >
> > rtskb_1 = alloc_rtskb(rtskb_2->len,pool);
> > if(rtskb_1 == NULL)
> > return -ENOMEM;
> >
> >
> > memcpy(rtskb_1->data, rtskb_2->data, rtskb_2->len );
> > rtskb_1->len = rtskb_2->len;
> > rtskb_1->time_stamp = rtskb_2->time_stamp;
> > rtskb_1->rtdev = rtskb_2->rtdev;
> > rtskb_1->protocol = rtskb_2->protocol;
>
> What about the things that happen in rt_eth_type_trans (except for
> rtcap_mark_incoming)? Should case the crash above, but will cause
> troubles when processing the rtskb.
>
> >
> > return 0;
> > }
> >
> > I check the path between the driver and the stack manager and only find that these fields are necessary.
> >
> > the task manager does the following for the clone rtskb:
> >
> > list_for_each_entry(pt_entry, &rt_packets[hash], list_entry)
> > {
> > rt_printk("List entry protocol= %d %d name = %d\n",
> > ntohs(pt_entry->type),hash,strncmp(pt_entry->name,"PACKET_SOCKET",13));
> > //the "PACKET_SOCKET" string is defined in line 188 of file af_packet.c
> > //this string should be replaced by a #define declaration
> > if ( likely(ntohs(pt_entry->type) == hash &&
> > (strncmp(pt_entry->name,"PACKET_SOCKET",13) == 0 )))
> > {
> > rtdm_lock_put_irqrestore(&rt_packets_lock, context);
>
> Don't drop the lock here when taking it two lines later again.
>
> > // rt_printk("List entry 1 \n");
> >
> > sock = container_of(pt_entry, struct rtsocket,
> > prot.packet.packet_type);
>
> Fatal layering violation! This is a hack, the actual cloning should
> rather take place inside the invoked handler. Same is true for the
> enqueuing. This way you could also avoid to acquire an rtskb that was
> already taken from the socket queue (redundant work).
>
> >
> > rtdm_lock_get_irqsave(&rt_packets_lock, context);
> > err = rtskb_clone(clone_skb, skb, &sock->skb_pool);
> > rtdm_lock_put_irqrestore(&rt_packets_lock, context);
> > if(err != 0)
> > {
> > break;
> > }
> >
> > rtskb_queue_head(&sock->skb_pool,clone_skb);
> > //queue the message to fifo head here
> >
> >
> > rtdm_lock_get_irqsave(&rt_packets_lock, context);
> > pt_entry->refcount++;
> > rtdm_lock_put_irqrestore(&rt_packets_lock, context);
> > // rt_printk("List entry 2 \n");
> > err = pt_entry->handler(clone_skb, pt_entry);
> > // rt_printk("List entry 3 \n");
> > rtdm_lock_get_irqsave(&rt_packets_lock, context);
> > pt_entry->refcount--;
> > rtdm_lock_put_irqrestore(&rt_packets_lock, context);
> >
> > }
> > }
> >
> >
> > I'm not sure if the cloned rtskb shoul be inserted in the queue head or not.
> >
>
> Move that stuff to af_packet.c.
>
> Jan
>
>
--
Jorge Almeida
j-a...@cr...
DISCLAIMER: This message may contain confidential information or privileged material and is intended only for the individual(s) named. If you are not a named addressee and mistakenly received this message you should not copy or otherwise disseminate it: please delete this e-mail from your system and notify the sender immediately. E-mail transmissions are not guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete or contain viruses. Therefore, the sender does not accept liability for any errors or omissions in the contents of this message that arise as a result of e-mail transmissions. Please request a hard copy version if verification is required. Critical Software, SA.
|
|
From: Jan K. <jan...@we...> - 2006-09-01 14:00:41
Attachments:
signature.asc
|
Jorge Almeida wrote: > Hi Jan, >=20 > Just one small question. > When the rtskb are created the memory indicated by the pointers present= in the struct rtskb are allocated too? In contrast to Linux skbs, rtskbs consist of a single piece: the control head + the buffer tail. >=20 > For example the rtdev pointer points to one area of allocated memory fo= r this rtskb, or this pointer points to a unique area that refers to the = rtdev struct of the real device? The buffer pointers (head, tail, end, ...) are initialised to point at their own buffer. rtdev is an external reference to the unique associated networking device. It's no buffer, it's the control structure of that device! Jan >=20 > Thanks for an answer. >=20 > Em Quinta, 31 de Agosto de 2006 17:12, o Jan Kiszka escreveu: > ... PS: Please don't cite what you do not comment on. |
|
From: Jorge A. <j-a...@cr...> - 2006-09-01 14:18:15
|
Em Sexta, 1 de Setembro de 2006 15:00, o Jan Kiszka escreveu: > Jorge Almeida wrote: > > Hi Jan, > > > > Just one small question. > > When the rtskb are created the memory indicated by the pointers present in the struct rtskb are allocated too? > > In contrast to Linux skbs, rtskbs consist of a single piece: the control > head + the buffer tail. > > > > > For example the rtdev pointer points to one area of allocated memory for this rtskb, or this pointer points to a unique area that refers to the rtdev struct of the real device? > > The buffer pointers (head, tail, end, ...) are initialised to point at > their own buffer. rtdev is an external reference to the unique > associated networking device. It's no buffer, it's the control structure > of that device! So all the pointers, except rtdev, have allocated memory for each rtskb? I make these questions because the rtskb_clone function that i'm doing. > > Jan > > > > > Thanks for an answer. > > > > Em Quinta, 31 de Agosto de 2006 17:12, o Jan Kiszka escreveu: > > ... > > PS: Please don't cite what you do not comment on. > > -- Jorge Almeida j-a...@cr... DISCLAIMER: This message may contain confidential information or privileged material and is intended only for the individual(s) named. If you are not a named addressee and mistakenly received this message you should not copy or otherwise disseminate it: please delete this e-mail from your system and notify the sender immediately. E-mail transmissions are not guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete or contain viruses. Therefore, the sender does not accept liability for any errors or omissions in the contents of this message that arise as a result of e-mail transmissions. Please request a hard copy version if verification is required. Critical Software, SA. |
|
From: Jan K. <jan...@we...> - 2006-09-01 14:26:19
Attachments:
signature.asc
|
Jorge Almeida wrote: > Em Sexta, 1 de Setembro de 2006 15:00, o Jan Kiszka escreveu: >> Jorge Almeida wrote: >>> Hi Jan, >>> >>> Just one small question. >>> When the rtskb are created the memory indicated by the pointers prese= nt in the struct rtskb are allocated too? >> In contrast to Linux skbs, rtskbs consist of a single piece: the contr= ol >> head + the buffer tail. >> >>> For example the rtdev pointer points to one area of allocated memory = for this rtskb, or this pointer points to a unique area that refers to th= e rtdev struct of the real device? >> The buffer pointers (head, tail, end, ...) are initialised to point at= >> their own buffer. rtdev is an external reference to the unique >> associated networking device. It's no buffer, it's the control structu= re >> of that device! >=20 > So all the pointers, except rtdev, have allocated memory for each rtskb= ? >=20 > I make these questions because the rtskb_clone function that i'm doing.= >=20 All uncommented stuff of struct rtskb in rtskb.h point to the data region of the respective rtskb. Jan |