From patchwork Fri Jan 12 05:06:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Fastabend X-Patchwork-Id: 859503 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="vbw5KOz3"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zHrML5LQZz9t2l for ; Fri, 12 Jan 2018 16:06:54 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754175AbeALFGu (ORCPT ); Fri, 12 Jan 2018 00:06:50 -0500 Received: from mail-pf0-f194.google.com ([209.85.192.194]:38223 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754134AbeALFGt (ORCPT ); Fri, 12 Jan 2018 00:06:49 -0500 Received: by mail-pf0-f194.google.com with SMTP id k19so3614039pfj.5 for ; Thu, 11 Jan 2018 21:06:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=OqJNhjlApXtEtPt6AZIeHLljIMcNWcuJcrQpSoFIGxA=; b=vbw5KOz3SVyr82i+ERMN9apaY10Cc7CIt/8/rkUiBMgmIAqEyMDw7QiWuewypQMMOP z20Lyjeec+6aPpEZiKDQYSUp3Hs0CnVBOOPUozB6kWDCvIIJ365Xd8nJgfqV0BMFEKto a3X8jXRgSyItIEGv2MkIecZqUT0tp0BTnMmMhzHc9ERGJ4qapQSTZHODgT2dN8u33JuW kvO3v3fOgyMf2mdok4tc7tnU1TEJlgV97a34wVNlxp/Eu+/rhjHdq/2TUG4gswsglh2U zuWpjMwAgx+EIdJaxVOYlgY3IwHErdN84jBNLBkhqrSdnCGwgTbSlIMx+4Rkg37rsUTj AmEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:date:message-id:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=OqJNhjlApXtEtPt6AZIeHLljIMcNWcuJcrQpSoFIGxA=; b=rTWw879w9kEZrWbhuQ9jW4QuPhCm8MLZAkjQSKfC/iGWIjdK7a9SKHcotcTSln229f SFHAp+8gUF8oDrBxWUbMOPFDTSkWXIM1J04RWZ7F5TIW9HI8jgak21CnvWfMNu4kFolP Tk5jgZOFYaa7ay7WPFYhI1yXPJCsLDMwyuUbXcd7Vx+VvjmsRQeBO24HAWMMPrQ6Qk7o L0QUBu6gF5DDzop5OV4PdBiB27s2/d7pf4Y6IXsoaUq/5+ffhe9wt4y4nCmAxnqs9pvl XGC4EuB6wusrsBp4D4XMhHnIKWk5wCBzPhyO4lgTfxbtQ6697F0mN0YaPiiEWcv2bneC pBJw== X-Gm-Message-State: AKGB3mIwZvpqKFKzVAA71oGzHmH2QEWxq9yE+v/P70CfuaDiVgiyz5Z5 C0pimvvImZUwZq0rAT0k9azqxw== X-Google-Smtp-Source: ACJfBos5OlkFmrLQDOOL1IH2vfbGXnFPrNnNa0DMQrpfj65OoXHXgdNRo79O/HGnwbDRG4qf2ZeRSg== X-Received: by 10.159.241.1 with SMTP id q1mr16919425plr.378.1515733608308; Thu, 11 Jan 2018 21:06:48 -0800 (PST) Received: from [127.0.1.1] ([75.106.27.153]) by smtp.gmail.com with ESMTPSA id e26sm39512317pfi.10.2018.01.11.21.06.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 11 Jan 2018 21:06:47 -0800 (PST) Subject: [bpf-next PATCH v3 2/7] bpf: add sendmsg option for testing BPF programs From: John Fastabend To: borkmann@iogearbox.net, john.fastabend@gmail.com, ast@kernel.org, kafai@fb.com Cc: netdev@vger.kernel.org Date: Thu, 11 Jan 2018 21:06:34 -0800 Message-ID: <20180112050634.5823.81340.stgit@john-Precision-Tower-5810> In-Reply-To: <20180112050243.5823.85987.stgit@john-Precision-Tower-5810> References: <20180112050243.5823.85987.stgit@john-Precision-Tower-5810> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 options: --help -h --cgroup -c --rate -r --verbose -v --iov_count -i --length -l --test -t Signed-off-by: John Fastabend --- samples/sockmap/sockmap_user.c | 147 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 3 deletions(-) diff --git a/samples/sockmap/sockmap_user.c b/samples/sockmap/sockmap_user.c index 17400d4..8ec7dbf 100644 --- a/samples/sockmap/sockmap_user.c +++ b/samples/sockmap/sockmap_user.c @@ -56,6 +56,9 @@ {"cgroup", required_argument, NULL, 'c' }, {"rate", required_argument, NULL, 'r' }, {"verbose", no_argument, NULL, 'v' }, + {"iov_count", required_argument, NULL, 'i' }, + {"length", required_argument, NULL, 'l' }, + {"test", required_argument, NULL, 't' }, {0, 0, NULL, 0 } }; @@ -182,6 +185,117 @@ static int sockmap_init_sockets(void) return 0; } +struct msg_stats { + size_t bytes_sent; + size_t bytes_recvd; +}; + +static int msg_loop(int fd, int iov_count, int iov_length, int cnt, + struct msg_stats *s, bool tx) +{ + struct msghdr msg = {0}; + struct iovec *iov; + int i, flags = 0; + + iov = calloc(iov_count, sizeof(struct iovec)); + if (!iov) + return -ENOMEM; + + for (i = 0; i < iov_count; i++) { + char *d = calloc(iov_length, sizeof(char)); + + if (!d) { + fprintf(stderr, "iov_count %i/%i OOM\n", i, iov_count); + free(iov); + return -ENOMEM; + } + iov[i].iov_base = d; + iov[i].iov_len = iov_length; + } + + msg.msg_iov = iov; + msg.msg_iovlen = iov_count; + + if (tx) { + for (i = 0; i < cnt; i++) { + int sent = sendmsg(fd, &msg, flags); + + if (sent < 0) { + perror("send loop error:"); + free(iov); + return sent; + } + s->bytes_sent += sent; + } + } else { + int slct, recv, max_fd = fd; + struct timeval timeout; + float total_bytes; + fd_set w; + + total_bytes = (float)iov_count * (float)iov_length * (float)cnt; + while (s->bytes_recvd < total_bytes) { + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + /* FD sets */ + FD_ZERO(&w); + FD_SET(fd, &w); + + slct = select(max_fd + 1, &w, NULL, NULL, &timeout); + if (slct == -1) { + perror("select()"); + goto out_errno; + } else if (!slct) { + fprintf(stderr, "unexpected timeout\n"); + goto out_errno; + } + + recv = recvmsg(fd, &msg, flags); + if (recv < 0) { + if (errno != EWOULDBLOCK) { + perror("recv failed()\n"); + goto out_errno; + } + } + + s->bytes_recvd += recv; + } + } + + for (i = 0; i < iov_count; i++) + free(iov[i].iov_base); + free(iov); + return 0; +out_errno: + free(iov); + return errno; +} + +static int sendmsg_test(int iov_count, int iov_buf, int cnt, int verbose) +{ + struct msg_stats s = {0}; + int err; + + 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); + return 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, "sendmsg: TX_bytes %zu RX_bytes %zu\n", + s.bytes_sent, s.bytes_recvd); + return err; +} + static int forever_ping_pong(int rate, int verbose) { struct timeval timeout; @@ -257,13 +371,19 @@ static int forever_ping_pong(int rate, int verbose) return 0; } +enum { + PING_PONG, + SENDMSG, +}; + int main(int argc, char **argv) { - int rate = 1, verbose = 0; + int iov_count = 1, length = 1024, rate = 1, verbose = 0; int opt, longindex, err, cg_fd = 0; + int test = PING_PONG; char filename[256]; - while ((opt = getopt_long(argc, argv, "hvc:r:", + while ((opt = getopt_long(argc, argv, "hvc:r:i:l:t:", long_options, &longindex)) != -1) { switch (opt) { /* Cgroup configuration */ @@ -282,6 +402,22 @@ int main(int argc, char **argv) case 'v': verbose = 1; break; + case 'i': + iov_count = atoi(optarg); + break; + case 'l': + length = atoi(optarg); + break; + case 't': + if (memcmp(optarg, "ping", 4) == 0) { + test = PING_PONG; + } else if (memcmp(optarg, "sendmsg", 7) == 0) { + test = SENDMSG; + } else { + usage(argv); + return -1; + } + break; case 'h': default: usage(argv); @@ -339,7 +475,12 @@ int main(int argc, char **argv) goto out; } - err = forever_ping_pong(rate, verbose); + if (test == PING_PONG) + err = forever_ping_pong(rate, verbose); + else if (test == SENDMSG) + err = sendmsg_test(iov_count, length, rate, verbose); + else + fprintf(stderr, "unknown test\n"); out: close(s1); close(s2);