Ruan TingQuan (ST-FIR/ENG1-Zhu)
2014-09-11 01:46:30 UTC
Hello Linux-can-team,
Several days ago, I got the solution of how to block application on CAN socket from document "SocketCAN and queueing disciplines:Final Report".
Here is the document link: http://rtime.felk.cvut.cz/can/socketcan-qdisc-final.pdf
Reference to chapter "3.4. Blocking the application when the queue is full":
"Therefore, the solution is to set SO_SNDBUF low enough that this limit is reached before tx queue len limit." ......
"the minimum value causes the application to block when there are about 15 frames queued. If we want all CAN applications in the system to block instead
of receiving ENOBUFS, it is necessary to set the txqueuelen (see Section 3.1.2) to the number of simultaneously used CAN sockets in the system multiplied by 15."
To verify this solution, a test program was made to send 64 frames to CAN socket. My test system : ubuntu 12.04 (kernel 3.11) + PEAK CAN controller (can0)
CAN socket was created with block mode and SO_SNDBUF is 163840 bytes (default setting). when continuously write more than 30 frames to CAN socket, Application got error return -ENOBUFS. That is expected. But, if the SO_SNDBUF was set to minimum value (4480 bytes), the application was blocked instead of return -ENOBUFS. This is different with description in above doc.
According to the description on above solution, if SO_SNDBUF limits at 4480 bytes, about 22 frames make SO_SNDBUF full. and, tx queue len keeps in 10. So, application should still get error return -ENOBUFS. Why application was blocked?
Attached file is my test program. The problem should be reproduced easily.
The print message from my test program are explained as below follow "//":
--------------------------------------------------
Default CAN socket send buffer size = 163840 (bytes) // Default (original) SO_SNDBUF value = 163840 bytes
****1**** Send 64 frames continuously to test block... // Start the testing original CAN socket (SO_SNDBUF=163840 bytes + tx queue=10)
-1- Write the 1th frame successfully.
-1- Write the 2th frame successfully.
-1- Write the 3th frame successfully.
-1- Write the 4th frame successfully.
-1- Write the 5th frame successfully.
-1- Write the 6th frame successfully.
-1- Write the 7th frame successfully.
-1- Write the 8th frame successfully.
-1- Write the 9th frame successfully.
-1- Write the 10th frame successfully.
-1- Write the 11th frame successfully.
-1- Write the 12th frame successfully.
-1- Write the 13th frame successfully.
-1- Write the 14th frame successfully.
-1- Write the 15th frame successfully.
-1- Write the 16th frame successfully.
-1- Write the 17th frame successfully.
-1- Write the 18th frame successfully.
-1- Write the 19th frame successfully.
-1- Write the 20th frame successfully.
-1- Write the 21th frame successfully.
-1- Write the 22th frame successfully.
-1- Write the 23th frame successfully.
-1- Write the 24th frame successfully.
-1- Write the 25th frame successfully.
-1- Write the 26th frame successfully.
-1- Write the 27th frame successfully.
-1- Write the 28th frame successfully.
-1- Write the 29th frame successfully.
-1- Write the 30th frame successfully.
-1- Write the 31th frame successfully.
-1- Write() return error :: No buffer space available // function write() return -ENOBUFS at the 31th frame sending
--------------------------------------------------
Set size of send buffer to minimum value = 4480 (bytes) // Change SO_SNDBUF to minimum = 4480 (bytes)
****2**** Send 64 frames continuously to test block again... // Start the second testing on CAN socket (SO_SNDBUF=4480 bytes + tx queue=10)
-2- All frames were send successfully! that means blocking works. // All frames are send successfully without error return.
Regards!
Leo Ruan
Several days ago, I got the solution of how to block application on CAN socket from document "SocketCAN and queueing disciplines:Final Report".
Here is the document link: http://rtime.felk.cvut.cz/can/socketcan-qdisc-final.pdf
Reference to chapter "3.4. Blocking the application when the queue is full":
"Therefore, the solution is to set SO_SNDBUF low enough that this limit is reached before tx queue len limit." ......
"the minimum value causes the application to block when there are about 15 frames queued. If we want all CAN applications in the system to block instead
of receiving ENOBUFS, it is necessary to set the txqueuelen (see Section 3.1.2) to the number of simultaneously used CAN sockets in the system multiplied by 15."
To verify this solution, a test program was made to send 64 frames to CAN socket. My test system : ubuntu 12.04 (kernel 3.11) + PEAK CAN controller (can0)
CAN socket was created with block mode and SO_SNDBUF is 163840 bytes (default setting). when continuously write more than 30 frames to CAN socket, Application got error return -ENOBUFS. That is expected. But, if the SO_SNDBUF was set to minimum value (4480 bytes), the application was blocked instead of return -ENOBUFS. This is different with description in above doc.
According to the description on above solution, if SO_SNDBUF limits at 4480 bytes, about 22 frames make SO_SNDBUF full. and, tx queue len keeps in 10. So, application should still get error return -ENOBUFS. Why application was blocked?
Attached file is my test program. The problem should be reproduced easily.
The print message from my test program are explained as below follow "//":
--------------------------------------------------
Default CAN socket send buffer size = 163840 (bytes) // Default (original) SO_SNDBUF value = 163840 bytes
****1**** Send 64 frames continuously to test block... // Start the testing original CAN socket (SO_SNDBUF=163840 bytes + tx queue=10)
-1- Write the 1th frame successfully.
-1- Write the 2th frame successfully.
-1- Write the 3th frame successfully.
-1- Write the 4th frame successfully.
-1- Write the 5th frame successfully.
-1- Write the 6th frame successfully.
-1- Write the 7th frame successfully.
-1- Write the 8th frame successfully.
-1- Write the 9th frame successfully.
-1- Write the 10th frame successfully.
-1- Write the 11th frame successfully.
-1- Write the 12th frame successfully.
-1- Write the 13th frame successfully.
-1- Write the 14th frame successfully.
-1- Write the 15th frame successfully.
-1- Write the 16th frame successfully.
-1- Write the 17th frame successfully.
-1- Write the 18th frame successfully.
-1- Write the 19th frame successfully.
-1- Write the 20th frame successfully.
-1- Write the 21th frame successfully.
-1- Write the 22th frame successfully.
-1- Write the 23th frame successfully.
-1- Write the 24th frame successfully.
-1- Write the 25th frame successfully.
-1- Write the 26th frame successfully.
-1- Write the 27th frame successfully.
-1- Write the 28th frame successfully.
-1- Write the 29th frame successfully.
-1- Write the 30th frame successfully.
-1- Write the 31th frame successfully.
-1- Write() return error :: No buffer space available // function write() return -ENOBUFS at the 31th frame sending
--------------------------------------------------
Set size of send buffer to minimum value = 4480 (bytes) // Change SO_SNDBUF to minimum = 4480 (bytes)
****2**** Send 64 frames continuously to test block again... // Start the second testing on CAN socket (SO_SNDBUF=4480 bytes + tx queue=10)
-2- All frames were send successfully! that means blocking works. // All frames are send successfully without error return.
Regards!
Leo Ruan