Am 23.08.2011 14:10, schrieb Oliver Hartkopp:
> Am 23.08.2011 12:04, schrieb "Müller, René":
>> Am 22.08.2011 18:55, schrieb Oliver Hartkopp: 
>
>
>>> i would try move the problem into userspace.
>>>
>>> The skbuff struct contains indeed much more than just the 16 bytes used by 
>>> the
>>> can_frame. If you can make an estimation about how many frames you receive 
>>> in
>>> this 30 seconds, you could create a big array of struct can_frames in
>>> userspace that holds the (binary) CAN frames in userspace.
>>>
>>> After the 30 seconds, you can dump the binary frames into a file. IMO not
>>> getting the frames from the socket is the problem, but writing to a file.
>>>
>>> An increased socket buffer size still gives you some additional safety, that
>>> you don't lose frames, when writing the file.
>>>
>>> Do you also need the timestamps?
>>>
>>> If so, i would add them to an other new big array containing the the (64 
>>> bit)
>>> timestamps. I don't know if it's better to save timestamp offsets, as this
>>> would probably cost more CPU time than just copying the timestamps.
>>>
>>> What do you think about this idea? 
>> Hi Oliver,
>>
>> I like this idea. I liked it so much, that I just tried it :)
>>
>> But the results are not exactly what I want. I used candump as base and 
>> created a simple array, as you suggested (only for the frames, none for the 
>> timestamps. I need them, but for testing purposes I can life without them). 
>> Now the problem is the cpu load, again. I have ~18-20% idle time and ~60% 
>> for candump. Basically I can dump the frames this way, but in my application 
>> dumping the frames is not the only task. I need a bit more cpu time than the 
>> remaining 20%.
>>
>> When I used the increased socket buffer size I had plenty cpu time available 
>> (>70%), but no memory for my application left. With an simple buffer I have 
>> plenty of memory available (>90MB), but not enough cpu time left. :( 
>
> Ok, i must admit this is a bit like fishing in murky waters but i do not know 
> which impact the recvmsg() syscall hass in this game.
>
> When integrating the support for dropcounts i moved the receiption of CAN 
> frames from recvfrom() to recvmsg() to get all the information including 
> timestamps and dropcounts with one syscall:
>
> http://svn.berlios.de/wsvn/socketcan?op=comp&compare[]=/trunk/can-utils/candump.c@1110&compare[]=/trunk/can-utils/candump.c@1111
>
> This has an increased effort in setting and parsing cmsg structures.
>
> Maybe you can try to modify the rev1110 to your needs (with the CAN frame 
> array) or use the very simple socketcan/test/tst-raw.c source as a basis that 
> only uses read() without any multi-socket- nor select()-support.
>
> This would be interesting to see if we really can save remarkable amounts of 
> CPU time without having the full-featured candump mechanisms.
>
Hi Oliver,

I have a solution for my problem, but I must admit this is maybe not the 
cleanest. I did no more tests in the user space (time is running away), instead 
I cloned the CAN_RAW socket to an CAN_RCB (raw circular buffer) socket and 
implemented an circular buffer for can frames inside it (including timestamps).

By this way, I combine a low memory usage (no need to enlarge the overloaded 
socket rx buffer) with a low cpu usage (buffering in kernel context). When 
recvmsg() is called by a user space application, I copy the whole buffer and 
reduce the system calls to 1.

This only works with one very important prerequisite: before calling recvmsg I 
have to set a "nothing passes" can filter on the socket. This prevents a write 
access to my buffer while I read it, so I don't lose a frame from the last 30s. 
This is enough for my use case, because I have to dump only 30s and I don't 
need the can data while writing the buffered data to a file.

If it has any use for you, I can send the patch for a 2.6.35.7 kernel to the 
list.

> Best regards & thanks for the interesting CPU/MEM tradeoff problem ;-)
>
> Oliver
>
You are welcome ;)

René
>>
>> It seems, that I have to optimize either the memory consumption of the 
>> socket buffer or the cpu load of the frame fetching. Maybe the right 
>> tradeoff between user space and socket is the clue.
>>
>> I'm familiar with linux, but I'm no kernel hacker. I think, you have way 
>> more experience in this area (at least you implemented many stuff in kernel 
>> space for socketcan ;) ), so do you think I can get my application running 
>> with one of the three options from above? Or I'm missing some "simple" other 
>> option? (beside from switching the cpu, of course)
>>
>>
>> Best regards,
>> René
>>
> _______________________________________________
> Socketcan-users mailing list
> [email protected]
> https://lists.berlios.de/mailman/listinfo/socketcan-users
_______________________________________________
Socketcan-users mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-users

Reply via email to