From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-10 18:38:58
The sockmap sample is pretty simple at the moment. All it does is open
a few sockets attach BPF programs/sockmaps and sends a few packets.
However, for testing and debugging I wanted to have more control over
the sendmsg format and data than provided by tools like iperf3/netperf,
etc. The reason is for testing BPF programs and stream parser it is
helpful to be able submit multiple sendmsg calls with different msg
layouts. For example lots of 1B iovs or a single large MB of data, etc.
Additionally, my current test setup requires an entire orchestration
layer (cilium) to run. As well as lighttpd and http traffic generators
or for kafka testing brokers and clients. This makes it a bit more
difficult when doing performance optimizations to incrementally test
small changes and come up with performance delta's and perf numbers.
By adding a few more options and an additional few tests the sockmap
sample program can show a more complete example and do some of the
above. Because the sample program is self contained it doesn't require
additional infrastructure to run either.
This series, although still fairly crude, does provide some nice
additions. They are
- a new sendmsg tests with a sender and recv threads
- a new base tests so we can get metrics/data without BPF
- multiple GBps of throughput on base and sendmsg tests
- automatically set rlimit and common variables
That said the UI is still primitive, more features could be added,
more tests might be useful, the reporting is bare bones, etc. But,
IMO lets push this now rather than sit on it for weeks until I get
time to do the above improvements. Additional patches can address
the other limitations/issues.
v2: removed bogus file added by patch 3/7
---
John Fastabend (7):
bpf: refactor sockmap sample program update for arg parsing
bpf: add sendmsg option for testing BPF programs
bpf: sockmap sample, use fork() for send and recv
bpf: sockmap sample, report bytes/sec
bpf: sockmap sample add base test without any BPF for comparison
bpf: sockmap put client sockets in blocking mode
bpf: sockmap set rlimit
samples/sockmap/Makefile | 2
samples/sockmap/sockmap_user.c | 357 ++++++++++++++++++++++++++++++++++++----
2 files changed, 318 insertions(+), 41 deletions(-)
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-10 18:39:15
sockmap sample program takes arguments from cmd line but it reads them
in using offsets into the array. Because we want to add more arguments
in the future lets do proper argument handling.
Also refactor code to pull apart sock init and ping/pong test. This
allows us to add new tests in the future.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 142 +++++++++++++++++++++++++++++-----------
1 file changed, 103 insertions(+), 39 deletions(-)
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-10 18:39:32
When testing BPF programs using sockmap I often want to have more
control over how sendmsg is exercised. This becomes even more useful
as new sockmap program types are added.
This adds a test type option to select type of test to run. Currently,
only "ping" and "sendmsg" are supported, but more can be added as
needed.
The new help argument gives the following,
Usage: ./sockmap --cgroup <cgroup_path>
options:
--help -h
--cgroup -c
--rate -r
--verbose -v
--iov_count -i
--length -l
--test -t
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 143 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 140 insertions(+), 3 deletions(-)
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-10 18:39:48
Currently for SENDMSG tests first send completes then recv runs. This
does not work well for large data sizes and/or many iterations. So
fork the recv and send handler so that we run both send and recv. In
the future we can add a parameter to do more than a single fork of
tx/rx.
With this we can get many GBps of data which helps exercise the
sockmap code.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/Makefile | 2 +
samples/sockmap/sockmap_user.c | 58 +++++++++++++++++++++++++++++-----------
2 files changed, 43 insertions(+), 17 deletions(-)
@@ -197,7 +198,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,{structmsghdrmsg={0};structiovec*iov;-inti,flags=0;+inti,flags=MSG_NOSIGNAL;iov=calloc(iov_count,sizeof(structiovec));if(!iov)
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-10 18:40:06
Report bytes/sec sent as well as total bytes. Useful to get rough
idea how different configurations and usage patterns perform with
sockmap.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 37 ++++++++++++++++++++++++++++++++-----
1 file changed, 32 insertions(+), 5 deletions(-)
@@ -191,14 +192,16 @@ static int sockmap_init_sockets(void)structmsg_stats{size_tbytes_sent;size_tbytes_recvd;+structtimespecstart;+structtimespecend;};staticintmsg_loop(intfd,intiov_count,intiov_length,intcnt,structmsg_stats*s,booltx){structmsghdrmsg={0};+interr,i,flags=MSG_NOSIGNAL;structiovec*iov;-inti,flags=MSG_NOSIGNAL;iov=calloc(iov_count,sizeof(structiovec));if(!iov)
@@ -220,6 +223,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,msg.msg_iovlen=iov_count;if(tx){+clock_gettime(CLOCK_MONOTONIC,&s->start);for(i=0;i<cnt;i++){intsent=sendmsg(fd,&msg,flags);
@@ -229,6 +233,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,}s->bytes_sent+=sent;}+clock_gettime(CLOCK_MONOTONIC,&s->end);}else{intslct,recv,max_fd=fd;structtimevaltimeout;
@@ -236,6 +241,9 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,fd_setw;total_bytes=(float)iov_count*(float)iov_length*(float)cnt;+err=clock_gettime(CLOCK_MONOTONIC,&s->start);+if(err<0)+perror("recv start time: ");while(s->bytes_recvd<total_bytes){timeout.tv_sec=1;timeout.tv_usec=0;
@@ -247,15 +255,18 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,slct=select(max_fd+1,&w,NULL,NULL,&timeout);if(slct==-1){perror("select()");+clock_gettime(CLOCK_MONOTONIC,&s->end);returnslct;}elseif(!slct){fprintf(stderr,"unexpected timeout\n");+clock_gettime(CLOCK_MONOTONIC,&s->end);returnslct;}recv=recvmsg(fd,&msg,flags);if(recv<0){if(errno!=EWOULDBLOCK){+clock_gettime(CLOCK_MONOTONIC,&s->end);perror("recv failed()\n");returnerrno;}
@@ -263,6 +274,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,s->bytes_recvd+=recv;}+clock_gettime(CLOCK_MONOTONIC,&s->end);}for(i=0;i<iov_count;i++)
@@ -271,11 +283,14 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,return0;}+staticfloatgiga=1000000000;+staticintsendmsg_test(intiov_count,intiov_buf,intcnt,intverbose){inttxpid,rxpid,err=0;structmsg_statss={0};intstatus;+floatsent_Bps=0,recvd_Bps=0;errno=0;
@@ -286,10 +301,16 @@ static int sendmsg_test(int iov_count, int iov_buf, int cnt, int verbose)fprintf(stderr,"msg_loop_rx: iov_count %i iov_buf %i cnt %i err %i\n",iov_count,iov_buf,cnt,err);-fprintf(stdout,"rx_sendmsg: TX_bytes %zu RX_bytes %zu\n",-s.bytes_sent,s.bytes_recvd);shutdown(p2,SHUT_RDWR);shutdown(p1,SHUT_RDWR);+if(s.end.tv_sec-s.start.tv_sec){+sent_Bps=s.bytes_sent/(s.end.tv_sec-s.start.tv_sec);+recvd_Bps=s.bytes_recvd/(s.end.tv_sec-s.start.tv_sec);+}+fprintf(stdout,+"rx_sendmsg: TX: %zuB %fB/s %fGB/s RX: %zuB %fB/s %fGB/s\n",+s.bytes_sent,sent_Bps,sent_Bps/giga,+s.bytes_recvd,recvd_Bps,recvd_Bps/giga);exit(1);}elseif(rxpid==-1){perror("msg_loop_rx: ");
@@ -303,9 +324,15 @@ static int sendmsg_test(int iov_count, int iov_buf, int cnt, int verbose)fprintf(stderr,"msg_loop_tx: iov_count %i iov_buf %i cnt %i err %i\n",iov_count,iov_buf,cnt,err);-fprintf(stdout,"tx_sendmsg: TX_bytes %zu RX_bytes %zu\n",-s.bytes_sent,s.bytes_recvd);shutdown(c1,SHUT_RDWR);+if(s.end.tv_sec-s.start.tv_sec){+sent_Bps=s.bytes_sent/(s.end.tv_sec-s.start.tv_sec);+recvd_Bps=s.bytes_recvd/(s.end.tv_sec-s.start.tv_sec);+}+fprintf(stdout,+"tx_sendmsg: TX: %zuB %fB/s %f GB/s RX: %zuB %fB/s %fGB/s\n",+s.bytes_sent,sent_Bps,sent_Bps/giga,+s.bytes_recvd,recvd_Bps,recvd_Bps/giga);exit(1);}elseif(txpid==-1){perror("msg_loop_tx: ");
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-10 18:40:22
Add a base test that does not use BPF hooks to test baseline case.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-10 18:40:38
Put client sockets in blocking mode otherwise with sendmsg tests
its easy to overrun the socket buffers which results in the test
being aborted.
The original non-blocking was added to handle listen/accept with
a single thread the client/accepted sockets do not need to be
non-blocking.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-10 18:40:53
Avoid extra step of setting limit from cmdline and do it directly in
the program.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 7 +++++++
1 file changed, 7 insertions(+)
From: Daniel Borkmann <daniel@iogearbox.net> Date: 2018-01-11 01:25:29
On 01/10/2018 07:39 PM, John Fastabend wrote:
sockmap sample program takes arguments from cmd line but it reads them
in using offsets into the array. Because we want to add more arguments
in the future lets do proper argument handling.
Also refactor code to pull apart sock init and ping/pong test. This
allows us to add new tests in the future.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 142 +++++++++++++++++++++++++++++-----------
1 file changed, 103 insertions(+), 39 deletions(-)
From: Daniel Borkmann <daniel@iogearbox.net> Date: 2018-01-11 01:28:26
On 01/10/2018 07:39 PM, John Fastabend wrote:
quoted hunk
When testing BPF programs using sockmap I often want to have more
control over how sendmsg is exercised. This becomes even more useful
as new sockmap program types are added.
This adds a test type option to select type of test to run. Currently,
only "ping" and "sendmsg" are supported, but more can be added as
needed.
The new help argument gives the following,
Usage: ./sockmap --cgroup <cgroup_path>
options:
--help -h
--cgroup -c
--rate -r
--verbose -v
--iov_count -i
--length -l
--test -t
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 143 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 140 insertions(+), 3 deletions(-)
From: Daniel Borkmann <daniel@iogearbox.net> Date: 2018-01-11 01:31:30
On 01/10/2018 07:39 PM, John Fastabend wrote:
quoted hunk
Currently for SENDMSG tests first send completes then recv runs. This
does not work well for large data sizes and/or many iterations. So
fork the recv and send handler so that we run both send and recv. In
the future we can add a parameter to do more than a single fork of
tx/rx.
With this we can get many GBps of data which helps exercise the
sockmap code.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/Makefile | 2 +
samples/sockmap/sockmap_user.c | 58 +++++++++++++++++++++++++++++-----------
2 files changed, 43 insertions(+), 17 deletions(-)
From: Martin KaFai Lau <hidden> Date: 2018-01-11 21:05:37
On Wed, Jan 10, 2018 at 10:39:04AM -0800, John Fastabend wrote:
quoted hunk
sockmap sample program takes arguments from cmd line but it reads them
in using offsets into the array. Because we want to add more arguments
in the future lets do proper argument handling.
Also refactor code to pull apart sock init and ping/pong test. This
allows us to add new tests in the future.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 142 +++++++++++++++++++++++++++++-----------
1 file changed, 103 insertions(+), 39 deletions(-)
From: Martin KaFai Lau <hidden> Date: 2018-01-11 21:08:38
On Wed, Jan 10, 2018 at 10:39:21AM -0800, John Fastabend wrote:
quoted hunk
When testing BPF programs using sockmap I often want to have more
control over how sendmsg is exercised. This becomes even more useful
as new sockmap program types are added.
This adds a test type option to select type of test to run. Currently,
only "ping" and "sendmsg" are supported, but more can be added as
needed.
The new help argument gives the following,
Usage: ./sockmap --cgroup <cgroup_path>
options:
--help -h
--cgroup -c
--rate -r
--verbose -v
--iov_count -i
--length -l
--test -t
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 143 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 140 insertions(+), 3 deletions(-)
From: Martin KaFai Lau <hidden> Date: 2018-01-11 21:09:09
On Wed, Jan 10, 2018 at 10:39:37AM -0800, John Fastabend wrote:
quoted hunk
Currently for SENDMSG tests first send completes then recv runs. This
does not work well for large data sizes and/or many iterations. So
fork the recv and send handler so that we run both send and recv. In
the future we can add a parameter to do more than a single fork of
tx/rx.
With this we can get many GBps of data which helps exercise the
sockmap code.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/Makefile | 2 +
samples/sockmap/sockmap_user.c | 58 +++++++++++++++++++++++++++++-----------
2 files changed, 43 insertions(+), 17 deletions(-)
@@ -197,7 +198,7 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,{structmsghdrmsg={0};structiovec*iov;-inti,flags=0;+inti,flags=MSG_NOSIGNAL;iov=calloc(iov_count,sizeof(structiovec));if(!iov)
@@ -272,25 +273,50 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,staticintsendmsg_test(intiov_count,intiov_buf,intcnt,intverbose){+inttxpid,rxpid,err=0;structmsg_statss={0};-interr;--err=msg_loop(c1,iov_count,iov_buf,cnt,&s,true);-if(err){-fprintf(stderr,-"msg_loop_tx: iov_count %i iov_buf %i cnt %i err %i\n",-iov_count,iov_buf,cnt,err);-returnerr;+intstatus;++errno=0;++rxpid=fork();+if(rxpid==0){+err=msg_loop(p2,iov_count,iov_buf,cnt,&s,false);+if(err)+fprintf(stderr,+"msg_loop_rx: iov_count %i iov_buf %i cnt %i err %i\n",+iov_count,iov_buf,cnt,err);+fprintf(stdout,"rx_sendmsg: TX_bytes %zu RX_bytes %zu\n",+s.bytes_sent,s.bytes_recvd);+shutdown(p2,SHUT_RDWR);+shutdown(p1,SHUT_RDWR);+exit(1);+}elseif(rxpid==-1){+perror("msg_loop_rx: ");+err=errno;
From: Martin KaFai Lau <hidden> Date: 2018-01-11 21:10:20
On Wed, Jan 10, 2018 at 10:40:11AM -0800, John Fastabend wrote:
quoted hunk
Add a base test that does not use BPF hooks to test baseline case.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
@@ -285,18 +285,24 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,staticfloatgiga=1000000000;-staticintsendmsg_test(intiov_count,intiov_buf,intcnt,intverbose)+staticintsendmsg_test(intiov_count,intiov_buf,intcnt,+intverbose,boolbase){-inttxpid,rxpid,err=0;+floatsent_Bps=0,recvd_Bps=0;+intrx_fd,txpid,rxpid,err=0;structmsg_statss={0};intstatus;-floatsent_Bps=0,recvd_Bps=0;errno=0;+if(base)+rx_fd=p1;+else+rx_fd=p2;+rxpid=fork();if(rxpid==0){-err=msg_loop(p2,iov_count,iov_buf,cnt,&s,false);+err=msg_loop(rx_fd,iov_count,iov_buf,cnt,&s,false);
I am likely missing something. After receiving from p1, should the
base-line case also send to c2 which then will be received by p2?
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-12 03:55:09
On 01/11/2018 01:05 PM, Martin KaFai Lau wrote:
On Wed, Jan 10, 2018 at 10:39:04AM -0800, John Fastabend wrote:
quoted
sockmap sample program takes arguments from cmd line but it reads them
in using offsets into the array. Because we want to add more arguments
in the future lets do proper argument handling.
Also refactor code to pull apart sock init and ping/pong test. This
allows us to add new tests in the future.
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-12 03:57:28
On 01/11/2018 01:08 PM, Martin KaFai Lau wrote:
On Wed, Jan 10, 2018 at 10:39:37AM -0800, John Fastabend wrote:
quoted
Currently for SENDMSG tests first send completes then recv runs. This
does not work well for large data sizes and/or many iterations. So
fork the recv and send handler so that we run both send and recv. In
the future we can add a parameter to do more than a single fork of
tx/rx.
With this we can get many GBps of data which helps exercise the
sockmap code.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-12 04:03:48
On 01/11/2018 01:10 PM, Martin KaFai Lau wrote:
On Wed, Jan 10, 2018 at 10:40:11AM -0800, John Fastabend wrote:
quoted
Add a base test that does not use BPF hooks to test baseline case.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
@@ -285,18 +285,24 @@ static int msg_loop(int fd, int iov_count, int iov_length, int cnt,staticfloatgiga=1000000000;-staticintsendmsg_test(intiov_count,intiov_buf,intcnt,intverbose)+staticintsendmsg_test(intiov_count,intiov_buf,intcnt,+intverbose,boolbase){-inttxpid,rxpid,err=0;+floatsent_Bps=0,recvd_Bps=0;+intrx_fd,txpid,rxpid,err=0;structmsg_statss={0};intstatus;-floatsent_Bps=0,recvd_Bps=0;errno=0;+if(base)+rx_fd=p1;+else+rx_fd=p2;+rxpid=fork();if(rxpid==0){-err=msg_loop(p2,iov_count,iov_buf,cnt,&s,false);+err=msg_loop(rx_fd,iov_count,iov_buf,cnt,&s,false);
I am likely missing something. After receiving from p1, should the
base-line case also send to c2 which then will be received by p2?
Well I wanted a test to check socket to socket rates and see what
max throughput we could get with this simple tool. It provides a
good reference point for any other 'perf' data, throughput numbers,
etc. The numbers I see here, probably as expected, are very close
to what I get with iperf tests.
Adding another test base_bounce or base_proxy or something along
those lines might be another test we can add. I think you were
expecting this to be a 1:1 comparison with the sendmsg BPF test
but its not. Probably can add it though.
Thanks,
John
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-12 04:31:45
On 01/10/2018 05:25 PM, Daniel Borkmann wrote:
On 01/10/2018 07:39 PM, John Fastabend wrote:
quoted
sockmap sample program takes arguments from cmd line but it reads them
in using offsets into the array. Because we want to add more arguments
in the future lets do proper argument handling.
Also refactor code to pull apart sock init and ping/pong test. This
allows us to add new tests in the future.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 142 +++++++++++++++++++++++++++++-----------
1 file changed, 103 insertions(+), 39 deletions(-)
Do we need this out of the sighandler instead of e.g. main loop when
we break out?
Not really let me just remove it. I'll do
another patch with documentation and fixup
error messages so we don't have this issue.
I agree its a bit clumsy.
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-12 04:33:39
On 01/10/2018 05:31 PM, Daniel Borkmann wrote:
On 01/10/2018 07:39 PM, John Fastabend wrote:
quoted
Currently for SENDMSG tests first send completes then recv runs. This
does not work well for large data sizes and/or many iterations. So
fork the recv and send handler so that we run both send and recv. In
the future we can add a parameter to do more than a single fork of
tx/rx.
With this we can get many GBps of data which helps exercise the
sockmap code.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/Makefile | 2 +
samples/sockmap/sockmap_user.c | 58 +++++++++++++++++++++++++++++-----------
2 files changed, 43 insertions(+), 17 deletions(-)
From: John Fastabend <john.fastabend@gmail.com> Date: 2018-01-12 04:58:49
On 01/11/2018 08:31 PM, John Fastabend wrote:
On 01/10/2018 05:25 PM, Daniel Borkmann wrote:
quoted
On 01/10/2018 07:39 PM, John Fastabend wrote:
quoted
sockmap sample program takes arguments from cmd line but it reads them
in using offsets into the array. Because we want to add more arguments
in the future lets do proper argument handling.
Also refactor code to pull apart sock init and ping/pong test. This
allows us to add new tests in the future.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
samples/sockmap/sockmap_user.c | 142 +++++++++++++++++++++++++++++-----------
1 file changed, 103 insertions(+), 39 deletions(-)
Maybe rather than setting err and goto out where we now just return
err anyway, return from those places directly.
Perhaps but how about doing this in another patch. This
patch is not changing the goto err pattern. I can send
a follow up.
OK I take it back. I went ahead an removed the goto as you
suggested. As Martin noticed the accept err was missing and
also most of those should have been errno instead of err.
v3 in-flight.
.John