xdp-project / xdp-tutorial

XDP tutorial
2.49k stars 579 forks source link

xsk_socket__create_shared #305

Closed tjcw closed 1 week ago

tjcw commented 2 years ago

Is there an example of how to use this function ? I am trying to write a test case which receives packets from 2 interfaces and sends each packet out of the other interface. This is with a view to extending the test case to filter the packets in user space. I am modelling the test case on advanced03-AF_XDP. I want to use 2 AF_XDP sockets with a single umem, because I want to avoid the 'memcpy' which is necessary with 2 umems. When I look at the documentation, it seems that I have the choice between making a call to xsk_socketcreate for the first socket and xsk_socketcreate_shared for the second, or xsk_socketcreate_shared for both sockets. At the moment I am choosing the second option. The problem I have is how to set up the completion and fill queues for thte xsk_socketcreate_shared call. When using one socket per umem and calling xsk_socketcreate, the completion and fill queues are in the umem and are initialised by the xsk_umemcreate call. But this is not done for standalone fill and completion queues, and in my case the xsk_socketcreate_shared call does not produce a viable socket. I would be most grateful if someone would post another tutorial showing how to use xsk_socketcreate_shared .

tohojo commented 2 years ago

Ping @magnus-karlsson

tjcw commented 2 years ago

After some debugging, I now have a test case which calls xsk_socket__create for the first socket and xsk_socket__create_shared for the second socket which works.

tjcw commented 2 years ago

Correction, the test case still does not work properly. A few 'ping' packets are transferred OK, but 'iperf3' soon trips an assert in the test case because one of the sockets runs out of umem buffers. I will continue debugging.

tjcw commented 2 years ago

I have my test case working now. My problem was that I had 2 lists of free umem buffers, one associated with each socket. It looks to be that the kernel ( Ubuntu 20.04 with 5.15.0-46-generic ) sometimes puts an arriving packet into a buffer from the 'wrong' socket's fq (but then sends it to the 'right' rx queue), which (in my initial code) resulted in extra refills to the 'wrong' fq when refilling in handle_receive_packets (and fewer than expected refills to the 'right' fq). When I changed my test case to have 1 list of free umem buffers, it worked. My test case is here https://github.com/tjcw/xdp-tutorial/tree/master/reflector-shared-splitcreate if anyone is interested. While looking at code, line https://github.com/xdp-project/xdp-tutorial/blob/master/advanced03-AF_XDP/af_xdp_user.c#L362 seems suspicious; it looks as if the second parameter to xsk_ring_prod_reserve ought to be 'stock_frames' rather than 'rcvd'.

I will leave this issue open for now in case of any comments.

tjcw commented 2 years ago

After converting my other test case (where both sockets are opened with xsk_socket__create_shared) to use a single umem free list, this test case also works. This test case is here https://github.com/tjcw/xdp-tutorial/tree/master/reflector-shared .