* [PATCH bpf-next 2/3] selftests/bpf: add test cases for BPF_MAP_TYPE_QUEUE
From: Mauricio Vasquez B @ 2018-08-06 13:58 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann; +Cc: netdev
In-Reply-To: <153356387977.6981.12236150594041620482.stgit@kernel>
Signed-off-by: Mauricio Vasquez B <mauricio.vasquez@polito.it>
---
tools/include/uapi/linux/bpf.h | 5 ++
tools/testing/selftests/bpf/test_maps.c | 72 +++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+)
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 0ebaaf7f3568..2c171c40eb45 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -120,6 +120,7 @@ enum bpf_map_type {
BPF_MAP_TYPE_CPUMAP,
BPF_MAP_TYPE_XSKMAP,
BPF_MAP_TYPE_SOCKHASH,
+ BPF_MAP_TYPE_QUEUE,
};
enum bpf_prog_type {
@@ -255,6 +256,10 @@ enum bpf_attach_type {
/* Flag for stack_map, store build_id+offset instead of pointer */
#define BPF_F_STACK_BUILD_ID (1U << 5)
+/* Flags for queue_map, type of queue */
+#define BPF_F_QUEUE_FIFO (1U << 16)
+#define BPF_F_QUEUE_LIFO (2U << 16)
+
enum bpf_stack_build_id_status {
/* user space need an empty entry to identify end of a trace */
BPF_STACK_BUILD_ID_EMPTY = 0,
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c
index 6c253343a6f9..34567b017dbb 100644
--- a/tools/testing/selftests/bpf/test_maps.c
+++ b/tools/testing/selftests/bpf/test_maps.c
@@ -457,6 +457,77 @@ static void test_devmap(int task, void *data)
close(fd);
}
+static void test_queuemap(int task, void *data)
+{
+ __u32 value;
+ int fd, i;
+
+ /* test FIFO */
+ fd = bpf_create_map(BPF_MAP_TYPE_QUEUE, 0, sizeof(value), 32,
+ BPF_F_QUEUE_FIFO);
+ if (fd < 0) {
+ printf("Failed to create queuemap '%s'!\n", strerror(errno));
+ exit(1);
+ }
+
+ /* Push 32 elements */
+ for (i = 0; i < 32; i++) {
+ value = 1000 - i * 3;
+ assert(bpf_map_update_elem(fd, NULL, &value, 0) == 0);
+ }
+
+ /* Check that element cannot be pushed due to max_entries limit */
+ value = 1000;
+ assert(bpf_map_update_elem(fd, NULL, &value, 0) == -1 &&
+ errno == E2BIG);
+
+ /* Pop all elements */
+ for (i = 0; i < 32; i++)
+ assert(bpf_map_lookup_elem(fd, NULL, &value) == 0 &&
+ value == (1000 - i * 3));
+
+ /* Check that there are not elements left */
+ assert(bpf_map_lookup_elem(fd, NULL, &value) == -1 && errno == ENOENT);
+
+ assert(bpf_map_delete_elem(fd, NULL) == -1 && errno == EINVAL);
+ assert(bpf_map_get_next_key(fd, NULL, NULL) == -1 && errno == EINVAL);
+
+ close(fd);
+
+ /* test LIFO */
+ fd = bpf_create_map(BPF_MAP_TYPE_QUEUE, 0, sizeof(value), 32,
+ BPF_F_QUEUE_LIFO);
+ if (fd < 0) {
+ printf("Failed to create queuemap '%s'!\n", strerror(errno));
+ exit(1);
+ }
+
+ /* Push 32 elements */
+ for (i = 0; i < 32; i++) {
+ value = 1000 - i * 3;
+ assert(bpf_map_update_elem(fd, NULL, &value, 0) == 0);
+ }
+
+ /* Check that element cannot be pushed due to max_entries limit */
+ value = 1000;
+ assert(bpf_map_update_elem(fd, NULL, &value, 0) == -1 &&
+ errno == E2BIG);
+
+ /* Pop all elements */
+ for (i = 31; i >= 0; i--)
+ assert(bpf_map_lookup_elem(fd, NULL, &value) == 0 &&
+ value == (1000 - i * 3));
+
+ /* Check that there are not elements left */
+ assert(bpf_map_lookup_elem(fd, NULL, &value) == -1 &&
+ errno == ENOENT);
+
+ assert(bpf_map_delete_elem(fd, NULL) == -1 && errno == EINVAL);
+ assert(bpf_map_get_next_key(fd, NULL, NULL) == -1 && errno == EINVAL);
+
+ close(fd);
+}
+
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
@@ -1162,6 +1233,7 @@ static void run_all_tests(void)
test_arraymap_percpu_many_keys();
test_devmap(0, NULL);
+ test_queuemap(0, NULL);
test_sockmap(0, NULL);
test_map_large();
^ permalink raw reply related
* [PATCH bpf-next 3/3] bpf: add sample for BPF_MAP_TYPE_QUEUE
From: Mauricio Vasquez B @ 2018-08-06 13:58 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann; +Cc: netdev
In-Reply-To: <153356387977.6981.12236150594041620482.stgit@kernel>
The example is made by two parts, a eBPF program that consumes elements
from a FIFO queue and prints them in the screen and a user space
application that inserts new elements into the queue each time this is
executed.
Signed-off-by: Mauricio Vasquez B <mauricio.vasquez@polito.it>
---
samples/bpf/.gitignore | 1 +
samples/bpf/Makefile | 3 ++
samples/bpf/test_map_in_map_user.c | 9 +-----
samples/bpf/test_queuemap.sh | 37 +++++++++++++++++++++++++
samples/bpf/test_queuemap_kern.c | 51 +++++++++++++++++++++++++++++++++++
samples/bpf/test_queuemap_user.c | 53 ++++++++++++++++++++++++++++++++++++
6 files changed, 147 insertions(+), 7 deletions(-)
create mode 100755 samples/bpf/test_queuemap.sh
create mode 100644 samples/bpf/test_queuemap_kern.c
create mode 100644 samples/bpf/test_queuemap_user.c
diff --git a/samples/bpf/.gitignore b/samples/bpf/.gitignore
index 8ae4940025f8..d7e518c1b3ed 100644
--- a/samples/bpf/.gitignore
+++ b/samples/bpf/.gitignore
@@ -26,6 +26,7 @@ test_lru_dist
test_map_in_map
test_overhead
test_probe_write_user
+test_queuemap
trace_event
trace_output
tracex1
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index f88d5683d6ee..624f4f4b81db 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -53,6 +53,7 @@ hostprogs-y += xdpsock
hostprogs-y += xdp_fwd
hostprogs-y += task_fd_query
hostprogs-y += xdp_sample_pkts
+hostprogs-y += test_queuemap
# Libbpf dependencies
LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a
@@ -109,6 +110,7 @@ xdpsock-objs := xdpsock_user.o
xdp_fwd-objs := xdp_fwd_user.o
task_fd_query-objs := bpf_load.o task_fd_query_user.o $(TRACE_HELPERS)
xdp_sample_pkts-objs := xdp_sample_pkts_user.o $(TRACE_HELPERS)
+test_queuemap-objs := bpf_load.o test_queuemap_user.o
# Tell kbuild to always build the programs
always := $(hostprogs-y)
@@ -166,6 +168,7 @@ always += xdpsock_kern.o
always += xdp_fwd_kern.o
always += task_fd_query_kern.o
always += xdp_sample_pkts_kern.o
+always += test_queuemap_kern.o
HOSTCFLAGS += -I$(objtree)/usr/include
HOSTCFLAGS += -I$(srctree)/tools/lib/
diff --git a/samples/bpf/test_map_in_map_user.c b/samples/bpf/test_map_in_map_user.c
index e308858f7bcf..28edac94234e 100644
--- a/samples/bpf/test_map_in_map_user.c
+++ b/samples/bpf/test_map_in_map_user.c
@@ -1,10 +1,5 @@
-/*
- * Copyright (c) 2017 Facebook
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- */
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018 Politecnico di Torino */
#include <sys/resource.h>
#include <sys/socket.h>
#include <arpa/inet.h>
diff --git a/samples/bpf/test_queuemap.sh b/samples/bpf/test_queuemap.sh
new file mode 100755
index 000000000000..ed08c1fa8c2c
--- /dev/null
+++ b/samples/bpf/test_queuemap.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+[[ -z $TC ]] && TC='tc'
+[[ -z $IP ]] && IP='ip'
+
+TEST_QUEUE_USER='./test_queuemap'
+TEST_QUEUE_BPF='./test_queuemap_kern.o'
+
+function config {
+ $IP netns add ns1
+ $IP link add ve1 type veth peer name vens1
+ $IP link set dev ve1 up
+ $IP link set dev ve1 mtu 1500
+ $IP link set dev vens1 netns ns1
+
+ $IP -n ns1 link set dev lo up
+ $IP -n ns1 link set dev vens1 up
+ $IP -n ns1 addr add 10.1.1.101/24 dev vens1
+
+ $IP addr add 10.1.1.1/24 dev ve1
+ $TC qdisc add dev ve1 clsact
+ $TC filter add dev ve1 ingress bpf da obj $TEST_QUEUE_BPF sec test_queue
+}
+
+function cleanup {
+ set +e
+ [[ -z $DEBUG ]] || set +x
+ $IP netns delete ns1 >& /dev/null
+ $IP link del ve1 >& /dev/null
+ rm -f /sys/fs/bpf/tc/globals/queue
+ [[ -z $DEBUG ]] || set -x
+ set -e
+}
+
+cleanup
+config
diff --git a/samples/bpf/test_queuemap_kern.c b/samples/bpf/test_queuemap_kern.c
new file mode 100644
index 000000000000..2b496dafaffd
--- /dev/null
+++ b/samples/bpf/test_queuemap_kern.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018 Politecnico di Torino */
+#define KBUILD_MODNAME "foo"
+#include <linux/ptrace.h>
+#include <linux/version.h>
+#include <uapi/linux/bpf.h>
+#include <uapi/linux/in6.h>
+#include <uapi/linux/pkt_cls.h>
+#include "bpf_helpers.h"
+
+#define PIN_GLOBAL_NS 2
+
+struct bpf_elf_map {
+ __u32 type;
+ __u32 key_size;
+ __u32 value_size;
+ __u32 max_entries;
+ __u32 flags;
+ __u32 id;
+ __u32 pinning;
+};
+
+/* map #0 */
+struct bpf_elf_map SEC("maps") queue = {
+ .type = BPF_MAP_TYPE_QUEUE,
+ .key_size = 0,
+ .value_size = sizeof(u32),
+ .flags = BPF_F_QUEUE_FIFO,
+ .max_entries = 1024,
+ .pinning = PIN_GLOBAL_NS,
+};
+
+SEC("test_queue")
+int _test_queue(struct __sk_buff *skb)
+{
+ char msg[] = "element is %u\n";
+ char msg_no[] = "there are not elements\n";
+
+ u32 *val = bpf_map_lookup_elem(&queue, NULL);
+
+ if (!val) {
+ bpf_trace_printk(msg_no, sizeof(msg_no));
+ return TC_ACT_OK;
+ }
+
+ bpf_trace_printk(msg, sizeof(msg), *val);
+ return TC_ACT_OK;
+}
+
+char _license[] SEC("license") = "GPL";
+u32 _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/test_queuemap_user.c b/samples/bpf/test_queuemap_user.c
new file mode 100644
index 000000000000..68f9a5d54596
--- /dev/null
+++ b/samples/bpf/test_queuemap_user.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 Politecnico di Torino
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <stdint.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <bpf/bpf.h>
+#include "bpf_load.h"
+
+int queue_map;
+
+static void test_queue_map(void)
+{
+ int ret;
+ uint32_t i;
+
+ queue_map = bpf_obj_get("/sys/fs/bpf/tc/globals/queue");
+ if (queue_map < 0) {
+ fprintf(stderr, "error getting map");
+ return;
+ }
+
+ for (i = 0; i < 256; i++) {
+ uint32_t v = 1000 - i*3;
+
+ ret = bpf_map_update_elem(queue_map, NULL, &v, 0);
+ if (ret)
+ fprintf(stderr, "ret is %d\n", ret);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
+ char filename[256];
+
+ assert(!setrlimit(RLIMIT_MEMLOCK, &r));
+
+ snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+
+ test_queue_map();
+
+ return 0;
+}
^ permalink raw reply related
* [PATCH net] packet: refine ring v3 block size test to hold one frame
From: Willem de Bruijn @ 2018-08-06 14:38 UTC (permalink / raw)
To: netdev; +Cc: davem, eric.dumazet, loke.chetan, Willem de Bruijn
From: Willem de Bruijn <willemb@google.com>
TPACKET_V3 stores variable length frames in fixed length blocks.
Blocks must be able to store a block header, optional private space
and at least one minimum sized frame.
Frames, even for a zero snaplen packet, store metadata headers and
optional reserved space.
In the block size bounds check, ensure that the frame of the
chosen configuration fits. This includes sockaddr_ll and optional
tp_reserve.
Syzbot was able to construct a ring with insuffient room for the
sockaddr_ll in the header of a zero-length frame, triggering an
out-of-bounds write in dev_parse_header.
Convert the comparison to less than, as zero is a valid snap len.
This matches the test for minimum tp_frame_size immediately below.
Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.")
Fixes: eb73190f4fbe ("net/packet: refine check for priv area size")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Willem de Bruijn <willemb@google.com>
---
net/packet/af_packet.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 9b27d0cd766d5..e6445d8f3f57f 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -4226,6 +4226,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
}
if (req->tp_block_nr) {
+ unsigned int min_frame_size;
+
/* Sanity tests and some calculations */
err = -EBUSY;
if (unlikely(rb->pg_vec))
@@ -4248,12 +4250,12 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
goto out;
if (unlikely(!PAGE_ALIGNED(req->tp_block_size)))
goto out;
+ min_frame_size = po->tp_hdrlen + po->tp_reserve;
if (po->tp_version >= TPACKET_V3 &&
- req->tp_block_size <=
- BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + sizeof(struct tpacket3_hdr))
+ req->tp_block_size <
+ BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + min_frame_size)
goto out;
- if (unlikely(req->tp_frame_size < po->tp_hdrlen +
- po->tp_reserve))
+ if (unlikely(req->tp_frame_size < min_frame_size))
goto out;
if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1)))
goto out;
--
2.18.0.597.ga71716f1ad-goog
^ permalink raw reply related
* [PATCH] net: thunderx: check for failed allocation lmac->dmacs
From: Colin King @ 2018-08-06 16:50 UTC (permalink / raw)
To: Sunil Goutham, Robert Richter, David S . Miller, linux-arm-kernel,
netdev
Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
The allocation of lmac->dmacs is not being checked for allocation
failure. Add the check.
Fixes: 3a34ecfd9d3f ("net: thunderx: add MAC address filter tracking for LMAC")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 5d08d2aeb172..e337da6ba2a4 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -1083,6 +1083,8 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid)
lmac->dmacs_count = (RX_DMAC_COUNT / bgx->lmac_count);
lmac->dmacs = kcalloc(lmac->dmacs_count, sizeof(*lmac->dmacs),
GFP_KERNEL);
+ if (!lmac->dmacs)
+ return -ENOMEM;
/* Enable lmac */
bgx_reg_modify(bgx, lmacid, BGX_CMRX_CFG, CMR_EN);
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v4] selftests: add headers_install to lib.mk
From: Shuah Khan @ 2018-08-06 17:03 UTC (permalink / raw)
To: Anders Roxell
Cc: Masahiro Yamada, Michal Marek, Bamvor Zhang, brgl, Paolo Bonzini,
Andrew Morton, Mike Rapoport, aarcange, linux-kbuild,
Linux Kernel Mailing List, open list:KERNEL SELFTEST FRAMEWORK,
Networking, Shuah Khan
In-Reply-To: <CADYN=9LSA60E4mFwrbeY-RGi4kZV6hO0ygz0-C6QB3+KKaoxQg@mail.gmail.com>
Hi Anders,
On 07/25/2018 10:08 AM, Anders Roxell wrote:
> On Tue, 24 Jul 2018 at 19:11, Shuah Khan <shuah@kernel.org> wrote:
>>
>> On 07/23/2018 02:49 PM, Anders Roxell wrote:
>>> On Thu, 7 Jun 2018 at 13:09, Anders Roxell <anders.roxell@linaro.org> wrote:
>>>>
>>>> If the kernel headers aren't installed we can't build all the tests.
>>>> Add a new make target rule 'khdr' in the file lib.mk to generate the
>>>> kernel headers and that gets include for every test-dir Makefile that
>>>> includes lib.mk If the testdir in turn have its own sub-dirs the
>>>> top_srcdir needs to be set to the linux-rootdir to be able to generate
>>>> the kernel headers.
>>>>
>>>> Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
>>>> Reviewed-by: Fathi Boudra <fathi.boudra@linaro.org>
>>>> ---
>>>> Makefile | 14 +-------------
>>>> scripts/subarch.include | 13 +++++++++++++
>>>> tools/testing/selftests/android/Makefile | 2 +-
>>>> tools/testing/selftests/android/ion/Makefile | 2 ++
>>>> tools/testing/selftests/futex/functional/Makefile | 1 +
>>>> tools/testing/selftests/gpio/Makefile | 7 ++-----
>>>> tools/testing/selftests/kvm/Makefile | 7 ++-----
>>>> tools/testing/selftests/lib.mk | 12 ++++++++++++
>>>> tools/testing/selftests/net/Makefile | 1 +
>>>> .../selftests/networking/timestamping/Makefile | 1 +
>>>> tools/testing/selftests/vm/Makefile | 4 ----
>>>> 11 files changed, 36 insertions(+), 28 deletions(-)
>>>> create mode 100644 scripts/subarch.include
>>>>
>>>> diff --git a/Makefile b/Makefile
>>>> index 6b9aea95ae3a..8050072300fa 100644
>>>> --- a/Makefile
>>>> +++ b/Makefile
>>>> @@ -286,19 +286,7 @@ KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
>>>> KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
>>>> export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
>>>>
>>>> -# SUBARCH tells the usermode build what the underlying arch is. That is set
>>>> -# first, and if a usermode build is happening, the "ARCH=um" on the command
>>>> -# line overrides the setting of ARCH below. If a native build is happening,
>>>> -# then ARCH is assigned, getting whatever value it gets normally, and
>>>> -# SUBARCH is subsequently ignored.
>>>> -
>>>> -SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
>>>> - -e s/sun4u/sparc64/ \
>>>> - -e s/arm.*/arm/ -e s/sa110/arm/ \
>>>> - -e s/s390x/s390/ -e s/parisc64/parisc/ \
>>>> - -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
>>>> - -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
>>>> - -e s/riscv.*/riscv/)
>>>> +include scripts/subarch.include
>>
>> What is the reason for this SUBARCH block move to to scripts/subarch.include?
>> Is this necessary for adding headers install dependency to lib.mk?
>
> This is needed to create headers for cross build.
>
I am sorry for the delay on this patch. I am going to get this into 4.19.
If anybody has objections, please let me.
Anders! Will be able to rebase the patch and send me the latest. I think
I have Acks from kvm, android, and vm so far.
thanks,
-- Shuah
^ permalink raw reply
* Re: [PATCH v2] net/bridge/br_multicast: remove redundant variable "err"
From: David Miller @ 2018-08-06 17:34 UTC (permalink / raw)
To: zhongjiang; +Cc: stephen, netdev, linux-kernel
In-Reply-To: <1533524843-51236-1-git-send-email-zhongjiang@huawei.com>
From: zhong jiang <zhongjiang@huawei.com>
Date: Mon, 6 Aug 2018 11:07:23 +0800
> The err is not modified after initalization, So remove it and make
> it to be void function.
>
> Signed-off-by: zhong jiang <zhongjiang@huawei.com>
> ---
> v1->v2:
> - The initalization of err to '0' is unnecesary. so drop the change
Applied, thank you.
^ permalink raw reply
* Re: [PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2
From: Florian Fainelli @ 2018-08-06 15:25 UTC (permalink / raw)
To: Jose Abreu, netdev
Cc: David S. Miller, Joao Pinto, Giuseppe Cavallaro, Alexandre Torgue,
Andrew Lunn
In-Reply-To: <982b8bed-e11c-2f94-4f7d-21e358ffc0c0@synopsys.com>
On August 6, 2018 12:59:54 AM PDT, Jose Abreu <Jose.Abreu@synopsys.com> wrote:
>On 03-08-2018 20:06, Florian Fainelli wrote:
>> On 08/03/2018 08:50 AM, Jose Abreu wrote:
>>> Add the MDIO related funcionalities for the new IP block XGMAC2.
>>>
>>> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
>>> Cc: David S. Miller <davem@davemloft.net>
>>> Cc: Joao Pinto <jpinto@synopsys.com>
>>> Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
>>> Cc: Alexandre Torgue <alexandre.torgue@st.com>
>>> Cc: Andrew Lunn <andrew@lunn.ch>
>>> ---
>>> +satic int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int
>phyaddr,
>>> + int phyreg, u32 *hw_addr)
>>> +{
>>> + unsigned int mii_data = priv->hw->mii.data;
>>> + u32 tmp;
>>> +
>>> + /* HW does not support C22 addr >= 4 */
>>> + if (phyaddr >= 4)
>>> + return -ENODEV;
>> It would be nice if this could be moved at probe time so you don't
>have
>> to wait until you connect to the PHY, read its PHY OUI and find out
>it
>> has a MDIO address >= 4. Not a blocker, but something that could be
>> improved further on.
>>
>> In premise you could even scan the MDIO bus' device tree node, and
>find
>> that out ahead of time.
>
>Oh, but I use phylib ... I only provide the read/write callbacks
>so I think we should avoid duplicating the code that's already in
>the phylib ... No?
You can always extract the code that scans a MDIO bus into a helper function and make it parametrized with a callback of some kind. In that case I would be fine with you open coding the MDIO bus scan to find out if there is an address >= 4.
>
>>
>>> + /* Wait until any existing MII operation is complete */
>>> + if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
>>> + !(tmp & MII_XGMAC_BUSY), 100, 10000))
>>> + return -EBUSY;
>>> +
>>> + /* Set port as Clause 22 */
>>> + tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
>>> + tmp |= BIT(phyaddr);
>> Since the registers are being Read/Modify/Write here, don't you need
>to
>> clear the previous address bits as well?
>>
>> You probably did not encounter any problems in your testing if you
>had
>> only one PHY on the MDIO bus, but this is not something that is
>> necessarily true, e.g: if you have an Ethernet switch, several MDIO
>bus
>> addresses are going to be responding.
>>
>> Your MDIO bus implementation must be able to support one transaction
>> with one PHY address and the next transaction with another PHY
>address ,
>> etc...
>>
>> That is something that should be easy to fix and be resubmitted as
>part
>> of v4.
>
>I'm not following you here... I only set/unset the bit for the
>corresponding phyaddr that phylib wants to read/write. Why would
>I clear the remaining addresses?
Because this is all about transactions, the HW must be in a state that it will be able to perform that transaction correctly. So here for instance if you needed to support a C45 transaction you would have to clear that bit for that particular PHY address. Since you don't appear to support those yet then yes the code appears fine though it would not hurt if you did clear all other PHY's c22 bits to make it clear what this does.
--
Florian
^ permalink raw reply
* Re: [PATCH net-next V2] vhost: switch to use new message format
From: David Miller @ 2018-08-06 17:41 UTC (permalink / raw)
To: jasowang; +Cc: mst, kvm, virtualization, netdev, linux-kernel
In-Reply-To: <1533525467-17787-1-git-send-email-jasowang@redhat.com>
From: Jason Wang <jasowang@redhat.com>
Date: Mon, 6 Aug 2018 11:17:47 +0800
> We use to have message like:
>
> struct vhost_msg {
> int type;
> union {
> struct vhost_iotlb_msg iotlb;
> __u8 padding[64];
> };
> };
>
> Unfortunately, there will be a hole of 32bit in 64bit machine because
> of the alignment. This leads a different formats between 32bit API and
> 64bit API. What's more it will break 32bit program running on 64bit
> machine.
>
> So fixing this by introducing a new message type with an explicit
> 32bit reserved field after type like:
>
> struct vhost_msg_v2 {
> __u32 type;
> __u32 reserved;
> union {
> struct vhost_iotlb_msg iotlb;
> __u8 padding[64];
> };
> };
>
> We will have a consistent ABI after switching to use this. To enable
> this capability, introduce a new ioctl (VHOST_SET_BAKCEND_FEATURE) for
> userspace to enable this feature (VHOST_BACKEND_F_IOTLB_V2).
>
> Fixes: 6b1e6cc7855b ("vhost: new device IOTLB API")
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> Changes from V1:
> - use __u32 instead of int for type
Applied, thanks Jason.
^ permalink raw reply
* Re: [PATCH net-next] net: avoid unnecessary sock_flag() check when enable timestamp
From: David Miller @ 2018-08-06 17:43 UTC (permalink / raw)
To: laoar.shao; +Cc: netdev, linux-kernel
In-Reply-To: <1533527822-3324-1-git-send-email-laoar.shao@gmail.com>
From: Yafang Shao <laoar.shao@gmail.com>
Date: Mon, 6 Aug 2018 11:57:02 +0800
> The sock_flag() check is alreay inside sock_enable_timestamp(), so it is
> unnecessary checking it in the caller.
>
> void sock_enable_timestamp(struct sock *sk, int flag)
> {
> if (!sock_flag(sk, flag)) {
> ...
> }
> }
>
> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH] ptp_qoriq: use div_u64/div_u64_rem for 64-bit division
From: David Miller @ 2018-08-06 17:43 UTC (permalink / raw)
To: yangbo.lu; +Cc: netdev, richardcochran, linux-kernel
In-Reply-To: <20180806043911.15437-1-yangbo.lu@nxp.com>
From: Yangbo Lu <yangbo.lu@nxp.com>
Date: Mon, 6 Aug 2018 12:39:11 +0800
> This is a fix-up patch for below build issue with multi_v7_defconfig.
>
> drivers/ptp/ptp_qoriq.o: In function `qoriq_ptp_probe':
> ptp_qoriq.c:(.text+0xd0c): undefined reference to `__aeabi_uldivmod'
>
> Fixes: 91305f281262 ("ptp_qoriq: support automatic configuration for ptp timer")
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
Applied.
^ permalink raw reply
* [PATCH iproute2-next 0/3] support delivering packets in delayed
From: Yousuk Seung @ 2018-08-06 17:09 UTC (permalink / raw)
To: netdev
Cc: Stephen Hemminger, David Ahern, Michael McLennan, Priyaranjan Jha,
Yousuk Seung
This series adds support for the new "slot" netem parameter for
slotting. Slotting is an approximation of shared media that gather up
packets within a varying delay window before delivering them nearly at
once.
Dave Taht (2):
tc: support conversions to or from 64 bit nanosecond-based time
q_netem: support delivering packets in delayed time slots
Yousuk Seung (1):
q_netem: slotting with non-uniform distribution
man/man8/tc-netem.8 | 40 +++++++++++++++-
tc/q_netem.c | 112 +++++++++++++++++++++++++++++++++++++++++++-
tc/tc_core.h | 4 ++
tc/tc_util.c | 55 ++++++++++++++++++++++
tc/tc_util.h | 3 ++
5 files changed, 212 insertions(+), 2 deletions(-)
--
2.18.0.597.ga71716f1ad-goog
^ permalink raw reply
* [PATCH iproute2-next 1/3] tc: support conversions to or from 64 bit nanosecond-based time
From: Yousuk Seung @ 2018-08-06 17:09 UTC (permalink / raw)
To: netdev
Cc: Stephen Hemminger, David Ahern, Michael McLennan, Priyaranjan Jha,
Dave Taht, Yousuk Seung, Neal Cardwell
In-Reply-To: <20180806170953.164776-1-ysseung@google.com>
From: Dave Taht <dave.taht@gmail.com>
Using a 32 bit field to represent time in nanoseconds results in a
maximum value of about 4.3 seconds, which is well below many observed
delays in WiFi and LTE, and barely in the ballpark for a trip past the
Earth's moon, Luna.
Using 64 bit time fields in nanoseconds allows us to simulate
network diameters of several hundred light-years. However, only
conversions to and from ns, us, ms, and seconds are provided.
Signed-off-by: Yousuk Seung <ysseung@google.com>
Signed-off-by: Dave Taht <dave.taht@gmail.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
---
tc/tc_core.h | 4 ++++
tc/tc_util.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tc/tc_util.h | 3 +++
3 files changed, 62 insertions(+)
diff --git a/tc/tc_core.h b/tc/tc_core.h
index 1dfa9a4f773b..a0fe0923d171 100644
--- a/tc/tc_core.h
+++ b/tc/tc_core.h
@@ -7,6 +7,10 @@
#define TIME_UNITS_PER_SEC 1000000
+#define NSEC_PER_USEC 1000
+#define NSEC_PER_MSEC 1000000
+#define NSEC_PER_SEC 1000000000LL
+
enum link_layer {
LINKLAYER_UNSPEC,
LINKLAYER_ETHERNET,
diff --git a/tc/tc_util.c b/tc/tc_util.c
index d7578528a31b..c39c9046dcae 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -385,6 +385,61 @@ char *sprint_ticks(__u32 ticks, char *buf)
return sprint_time(tc_core_tick2time(ticks), buf);
}
+/* 64 bit times are represented internally in nanoseconds */
+int get_time64(__s64 *time, const char *str)
+{
+ double nsec;
+ char *p;
+
+ nsec = strtod(str, &p);
+ if (p == str)
+ return -1;
+
+ if (*p) {
+ if (strcasecmp(p, "s") == 0 ||
+ strcasecmp(p, "sec") == 0 ||
+ strcasecmp(p, "secs") == 0)
+ nsec *= NSEC_PER_SEC;
+ else if (strcasecmp(p, "ms") == 0 ||
+ strcasecmp(p, "msec") == 0 ||
+ strcasecmp(p, "msecs") == 0)
+ nsec *= NSEC_PER_MSEC;
+ else if (strcasecmp(p, "us") == 0 ||
+ strcasecmp(p, "usec") == 0 ||
+ strcasecmp(p, "usecs") == 0)
+ nsec *= NSEC_PER_USEC;
+ else if (strcasecmp(p, "ns") == 0 ||
+ strcasecmp(p, "nsec") == 0 ||
+ strcasecmp(p, "nsecs") == 0)
+ nsec *= 1;
+ else
+ return -1;
+ }
+
+ *time = nsec;
+ return 0;
+}
+
+void print_time64(char *buf, int len, __s64 time)
+{
+ double nsec = time;
+
+ if (time >= NSEC_PER_SEC)
+ snprintf(buf, len, "%.3fs", nsec/NSEC_PER_SEC);
+ else if (time >= NSEC_PER_MSEC)
+ snprintf(buf, len, "%.3fms", nsec/NSEC_PER_MSEC);
+ else if (time >= NSEC_PER_USEC)
+ snprintf(buf, len, "%.3fus", nsec/NSEC_PER_USEC);
+ else
+ snprintf(buf, len, "%lldns", time);
+}
+
+char *sprint_time64(__s64 time, char *buf)
+{
+ print_time64(buf, SPRINT_BSIZE-1, time);
+ return buf;
+}
+
int get_size(unsigned int *size, const char *str)
{
double sz;
diff --git a/tc/tc_util.h b/tc/tc_util.h
index 6632c4f9c528..87be951c622d 100644
--- a/tc/tc_util.h
+++ b/tc/tc_util.h
@@ -82,12 +82,14 @@ int get_percent_rate64(__u64 *rate, const char *str, const char *dev);
int get_size(unsigned int *size, const char *str);
int get_size_and_cell(unsigned int *size, int *cell_log, char *str);
int get_time(unsigned int *time, const char *str);
+int get_time64(__s64 *time, const char *str);
int get_linklayer(unsigned int *val, const char *arg);
void print_rate(char *buf, int len, __u64 rate);
void print_size(char *buf, int len, __u32 size);
void print_qdisc_handle(char *buf, int len, __u32 h);
void print_time(char *buf, int len, __u32 time);
+void print_time64(char *buf, int len, __s64 time);
void print_linklayer(char *buf, int len, unsigned int linklayer);
void print_devname(enum output_type type, int ifindex);
@@ -96,6 +98,7 @@ char *sprint_size(__u32 size, char *buf);
char *sprint_qdisc_handle(__u32 h, char *buf);
char *sprint_tc_classid(__u32 h, char *buf);
char *sprint_time(__u32 time, char *buf);
+char *sprint_time64(__s64 time, char *buf);
char *sprint_ticks(__u32 ticks, char *buf);
char *sprint_linklayer(unsigned int linklayer, char *buf);
--
2.18.0.597.ga71716f1ad-goog
^ permalink raw reply related
* [PATCH iproute2-next 2/3] q_netem: support delivering packets in delayed time slots
From: Yousuk Seung @ 2018-08-06 17:09 UTC (permalink / raw)
To: netdev
Cc: Stephen Hemminger, David Ahern, Michael McLennan, Priyaranjan Jha,
Dave Taht, Yousuk Seung, Neal Cardwell
In-Reply-To: <20180806170953.164776-1-ysseung@google.com>
From: Dave Taht <dave.taht@gmail.com>
Slotting is a crude approximation of the behaviors of shared media such
as cable, wifi, and LTE, which gather up a bunch of packets within a
varying delay window and deliver them, relative to that, nearly all at
once.
It works within the existing loss, duplication, jitter and delay
parameters of netem. Some amount of inherent latency must be specified,
regardless.
The new "slot" parameter specifies a minimum and maximum delay between
transmission attempts.
The "bytes" and "packets" parameters can be used to limit the amount of
information transferred per slot.
Examples of use:
tc qdisc add dev eth0 root netem delay 200us \
slot 800us 10ms bytes 64k packets 42
A more correct example, using stacked netem instances and a packet limit
to emulate a tail drop wifi queue with slots and variable packet
delivery, with a 200Mbit isochronous underlying rate, and 20ms path
delay:
tc qdisc add dev eth0 root handle 1: netem delay 20ms rate 200mbit \
limit 10000
tc qdisc add dev eth0 parent 1:1 handle 10:1 netem delay 200us \
slot 800us 10ms bytes 64k packets 42 limit 512
Signed-off-by: Yousuk Seung <ysseung@google.com>
Signed-off-by: Dave Taht <dave.taht@gmail.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
---
man/man8/tc-netem.8 | 32 ++++++++++++++++++++++-
tc/q_netem.c | 63 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 93 insertions(+), 2 deletions(-)
diff --git a/man/man8/tc-netem.8 b/man/man8/tc-netem.8
index f2cd86b6ed8a..8d485b026751 100644
--- a/man/man8/tc-netem.8
+++ b/man/man8/tc-netem.8
@@ -8,7 +8,8 @@ NetEm \- Network Emulator
.I OPTIONS
.IR OPTIONS " := [ " LIMIT " ] [ " DELAY " ] [ " LOSS \
-" ] [ " CORRUPT " ] [ " DUPLICATION " ] [ " REORDERING " ][ " RATE " ]"
+" ] [ " CORRUPT " ] [ " DUPLICATION " ] [ " REORDERING " ] [ " RATE \
+" ] [ " SLOT " ]"
.IR LIMIT " := "
.B limit
@@ -51,6 +52,14 @@ NetEm \- Network Emulator
.B rate
.IR RATE " [ " PACKETOVERHEAD " [ " CELLSIZE " [ " CELLOVERHEAD " ]]]]"
+.IR SLOT " := "
+.BR slot
+.IR MIN_DELAY " [ " MAX_DELAY " ] ["
+.BR packets
+.IR PACKETS " ] [ "
+.BR bytes
+.IR BYTES " ]"
+
.SH DESCRIPTION
NetEm is an enhancement of the Linux traffic control facilities
@@ -162,6 +171,27 @@ granularity avoid a perfect shaping at a specific level. This will show up in
an artificial packet compression (bursts). Another influence factor are network
adapter buffers which can also add artificial delay.
+.SS slot
+defer delivering accumulated packets to within a slot, with each available slot
+configured with a minimum delay to acquire, and an optional maximum delay. Slot
+delays can be specified in nanoseconds, microseconds, milliseconds or seconds
+(e.g. 800us). Values for the optional parameters
+.I BYTES
+will limit the number of bytes delivered per slot, and/or
+.I PACKETS
+will limit the number of packets delivered per slot.
+
+These slot options can provide a crude approximation of bursty MACs such as
+DOCSIS, WiFi, and LTE.
+
+Note that slotting is limited by several factors: the kernel clock granularity,
+as with a rate, and attempts to deliver many packets within a slot will be
+smeared by the timer resolution, and by the underlying native bandwidth also.
+
+It is possible to combine slotting with a rate, in which case complex behaviors
+where either the rate, or the slot limits on bytes or packets per slot, govern
+the actual delivered rate.
+
.SH LIMITATIONS
The main known limitation of Netem are related to timer granularity, since
Linux is not a real-time operating system.
diff --git a/tc/q_netem.c b/tc/q_netem.c
index 9f9a9b3df255..f52a36b6c31c 100644
--- a/tc/q_netem.c
+++ b/tc/q_netem.c
@@ -40,7 +40,10 @@ static void explain(void)
" [ loss gemodel PERCENT [R [1-H [1-K]]]\n" \
" [ ecn ]\n" \
" [ reorder PRECENT [CORRELATION] [ gap DISTANCE ]]\n" \
-" [ rate RATE [PACKETOVERHEAD] [CELLSIZE] [CELLOVERHEAD]]\n");
+" [ rate RATE [PACKETOVERHEAD] [CELLSIZE] [CELLOVERHEAD]]\n" \
+" [ slot MIN_DELAY [MAX_DELAY] [packets MAX_PACKETS]" \
+" [bytes MAX_BYTES]]\n" \
+ );
}
static void explain1(const char *arg)
@@ -164,6 +167,7 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
struct tc_netem_gimodel gimodel;
struct tc_netem_gemodel gemodel;
struct tc_netem_rate rate = {};
+ struct tc_netem_slot slot = {};
__s16 *dist_data = NULL;
__u16 loss_type = NETEM_LOSS_UNSPEC;
int present[__TCA_NETEM_MAX] = {};
@@ -412,6 +416,44 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
return -1;
}
}
+ } else if (matches(*argv, "slot") == 0) {
+ NEXT_ARG();
+ present[TCA_NETEM_SLOT] = 1;
+ if (get_time64(&slot.min_delay, *argv)) {
+ explain1("slot min_delay");
+ return -1;
+ }
+ if (NEXT_IS_NUMBER()) {
+ NEXT_ARG();
+ if (get_time64(&slot.max_delay, *argv)) {
+ explain1("slot min_delay max_delay");
+ return -1;
+ }
+ }
+ if (slot.max_delay < slot.min_delay)
+ slot.max_delay = slot.min_delay;
+ if (NEXT_ARG_OK() &&
+ matches(*(argv+1), "packets") == 0) {
+ NEXT_ARG();
+ if (!NEXT_ARG_OK() ||
+ get_s32(&slot.max_packets, *(argv+1), 0)) {
+ explain1("slot packets");
+ return -1;
+ }
+ NEXT_ARG();
+ }
+ if (NEXT_ARG_OK() &&
+ matches(*(argv+1), "bytes") == 0) {
+ unsigned int max_bytes;
+ NEXT_ARG();
+ if (!NEXT_ARG_OK() ||
+ get_size(&max_bytes, *(argv+1))) {
+ explain1("slot bytes");
+ return -1;
+ }
+ slot.max_bytes = (int) max_bytes;
+ NEXT_ARG();
+ }
} else if (strcmp(*argv, "help") == 0) {
explain();
return -1;
@@ -472,6 +514,10 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
addattr_l(n, 1024, TCA_NETEM_CORRUPT, &corrupt, sizeof(corrupt)) < 0)
return -1;
+ if (present[TCA_NETEM_SLOT] &&
+ addattr_l(n, 1024, TCA_NETEM_SLOT, &slot, sizeof(slot)) < 0)
+ return -1;
+
if (loss_type != NETEM_LOSS_UNSPEC) {
struct rtattr *start;
@@ -526,6 +572,7 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
int *ecn = NULL;
struct tc_netem_qopt qopt;
const struct tc_netem_rate *rate = NULL;
+ const struct tc_netem_slot *slot = NULL;
int len;
__u64 rate64 = 0;
@@ -586,6 +633,11 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
return -1;
rate64 = rta_getattr_u64(tb[TCA_NETEM_RATE64]);
}
+ if (tb[TCA_NETEM_SLOT]) {
+ if (RTA_PAYLOAD(tb[TCA_NETEM_SLOT]) < sizeof(*slot))
+ return -1;
+ slot = RTA_DATA(tb[TCA_NETEM_SLOT]);
+ }
}
fprintf(f, "limit %d", qopt.limit);
@@ -659,6 +711,15 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
fprintf(f, " celloverhead %d", rate->cell_overhead);
}
+ if (slot) {
+ fprintf(f, " slot %s", sprint_time64(slot->min_delay, b1));
+ fprintf(f, " %s", sprint_time64(slot->max_delay, b1));
+ if(slot->max_packets)
+ fprintf(f, " packets %d", slot->max_packets);
+ if(slot->max_bytes)
+ fprintf(f, " bytes %d", slot->max_bytes);
+ }
+
if (ecn)
fprintf(f, " ecn ");
--
2.18.0.597.ga71716f1ad-goog
^ permalink raw reply related
* [PATCH iproute2-next 3/3] q_netem: slotting with non-uniform distribution
From: Yousuk Seung @ 2018-08-06 17:09 UTC (permalink / raw)
To: netdev
Cc: Stephen Hemminger, David Ahern, Michael McLennan, Priyaranjan Jha,
Yousuk Seung, Neal Cardwell, Dave Taht
In-Reply-To: <20180806170953.164776-1-ysseung@google.com>
Extend slotting with support for non-uniform distributions. This is
similar to netem's non-uniform distribution delay feature.
Syntax:
slot distribution DISTRIBUTION DELAY JITTER [packets MAX_PACKETS] \
[bytes MAX_BYTES]
The syntax and use of the distribution table is the same as in the
non-uniform distribution delay feature. A file DISTRIBUTION must be
present in TC_LIB_DIR (e.g. /usr/lib/tc) containing numbers scaled by
NETEM_DIST_SCALE. A random value x is selected from the table and it
takes DELAY + ( x * JITTER ) as delay. Correlation between values is not
supported.
Examples:
Normal distribution delay with mean = 800us and stdev = 100us.
> tc qdisc add dev eth0 root netem slot distribution normal \
800us 100us
Optionally set the max slot size in bytes and/or packets.
> tc qdisc add dev eth0 root netem slot distribution normal \
800us 100us bytes 64k packets 42
Signed-off-by: Yousuk Seung <ysseung@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Dave Taht <dave.taht@gmail.com>
---
man/man8/tc-netem.8 | 20 ++++++++----
tc/q_netem.c | 75 +++++++++++++++++++++++++++++++++++++--------
2 files changed, 76 insertions(+), 19 deletions(-)
diff --git a/man/man8/tc-netem.8 b/man/man8/tc-netem.8
index 8d485b026751..111109cf042f 100644
--- a/man/man8/tc-netem.8
+++ b/man/man8/tc-netem.8
@@ -53,9 +53,13 @@ NetEm \- Network Emulator
.IR RATE " [ " PACKETOVERHEAD " [ " CELLSIZE " [ " CELLOVERHEAD " ]]]]"
.IR SLOT " := "
-.BR slot
-.IR MIN_DELAY " [ " MAX_DELAY " ] ["
-.BR packets
+.BR slot " { "
+.IR MIN_DELAY " [ " MAX_DELAY " ] |"
+.br
+.RB " " distribution " { "uniform " | " normal " | " pareto " | " paretonormal " | "
+.IR FILE " } " DELAY " " JITTER " } "
+.br
+.RB " [ " packets
.IR PACKETS " ] [ "
.BR bytes
.IR BYTES " ]"
@@ -172,9 +176,13 @@ an artificial packet compression (bursts). Another influence factor are network
adapter buffers which can also add artificial delay.
.SS slot
-defer delivering accumulated packets to within a slot, with each available slot
-configured with a minimum delay to acquire, and an optional maximum delay. Slot
-delays can be specified in nanoseconds, microseconds, milliseconds or seconds
+defer delivering accumulated packets to within a slot. Each available slot can be
+configured with a minimum delay to acquire, and an optional maximum delay.
+Alternatively it can be configured with the distribution similar to
+.BR distribution
+for
+.BR delay
+option. Slot delays can be specified in nanoseconds, microseconds, milliseconds or seconds
(e.g. 800us). Values for the optional parameters
.I BYTES
will limit the number of bytes delivered per slot, and/or
diff --git a/tc/q_netem.c b/tc/q_netem.c
index f52a36b6c31c..e655e1a82e12 100644
--- a/tc/q_netem.c
+++ b/tc/q_netem.c
@@ -43,7 +43,9 @@ static void explain(void)
" [ rate RATE [PACKETOVERHEAD] [CELLSIZE] [CELLOVERHEAD]]\n" \
" [ slot MIN_DELAY [MAX_DELAY] [packets MAX_PACKETS]" \
" [bytes MAX_BYTES]]\n" \
- );
+" [ slot distribution" \
+" {uniform|normal|pareto|paretonormal|custom} DELAY JITTER" \
+" [packets MAX_PACKETS] [bytes MAX_BYTES]]\n");
}
static void explain1(const char *arg)
@@ -159,6 +161,7 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
struct nlmsghdr *n, const char *dev)
{
int dist_size = 0;
+ int slot_dist_size = 0;
struct rtattr *tail;
struct tc_netem_qopt opt = { .limit = 1000 };
struct tc_netem_corr cor = {};
@@ -169,6 +172,7 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
struct tc_netem_rate rate = {};
struct tc_netem_slot slot = {};
__s16 *dist_data = NULL;
+ __s16 *slot_dist_data = NULL;
__u16 loss_type = NETEM_LOSS_UNSPEC;
int present[__TCA_NETEM_MAX] = {};
__u64 rate64 = 0;
@@ -417,21 +421,53 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
}
}
} else if (matches(*argv, "slot") == 0) {
- NEXT_ARG();
- present[TCA_NETEM_SLOT] = 1;
- if (get_time64(&slot.min_delay, *argv)) {
- explain1("slot min_delay");
- return -1;
- }
if (NEXT_IS_NUMBER()) {
NEXT_ARG();
- if (get_time64(&slot.max_delay, *argv)) {
- explain1("slot min_delay max_delay");
+ present[TCA_NETEM_SLOT] = 1;
+ if (get_time64(&slot.min_delay, *argv)) {
+ explain1("slot min_delay");
+ return -1;
+ }
+ if (NEXT_IS_NUMBER()) {
+ NEXT_ARG();
+ if (get_time64(&slot.max_delay, *argv)) {
+ explain1("slot min_delay max_delay");
+ return -1;
+ }
+ }
+ if (slot.max_delay < slot.min_delay)
+ slot.max_delay = slot.min_delay;
+ } else {
+ NEXT_ARG();
+ if (strcmp(*argv, "distribution") == 0) {
+ present[TCA_NETEM_SLOT] = 1;
+ NEXT_ARG();
+ slot_dist_data = calloc(sizeof(slot_dist_data[0]), MAX_DIST);
+ slot_dist_size = get_distribution(*argv, slot_dist_data, MAX_DIST);
+ if (slot_dist_size <= 0) {
+ free(slot_dist_data);
+ return -1;
+ }
+ NEXT_ARG();
+ if (get_time64(&slot.dist_delay, *argv)) {
+ explain1("slot delay");
+ return -1;
+ }
+ NEXT_ARG();
+ if (get_time64(&slot.dist_jitter, *argv)) {
+ explain1("slot jitter");
+ return -1;
+ }
+ if (slot.dist_jitter <= 0) {
+ fprintf(stderr, "Non-positive jitter\n");
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "Unknown slot parameter: %s\n",
+ *argv);
return -1;
}
}
- if (slot.max_delay < slot.min_delay)
- slot.max_delay = slot.min_delay;
if (NEXT_ARG_OK() &&
matches(*(argv+1), "packets") == 0) {
NEXT_ARG();
@@ -558,6 +594,14 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv,
return -1;
free(dist_data);
}
+
+ if (slot_dist_data) {
+ if (addattr_l(n, MAX_DIST * sizeof(slot_dist_data[0]),
+ TCA_NETEM_SLOT_DIST,
+ slot_dist_data, slot_dist_size * sizeof(slot_dist_data[0])) < 0)
+ return -1;
+ free(slot_dist_data);
+ }
tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
return 0;
}
@@ -712,8 +756,13 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
}
if (slot) {
- fprintf(f, " slot %s", sprint_time64(slot->min_delay, b1));
- fprintf(f, " %s", sprint_time64(slot->max_delay, b1));
+ if (slot->dist_jitter > 0) {
+ fprintf(f, " slot distribution %s", sprint_time64(slot->dist_delay, b1));
+ fprintf(f, " %s", sprint_time64(slot->dist_jitter, b1));
+ } else {
+ fprintf(f, " slot %s", sprint_time64(slot->min_delay, b1));
+ fprintf(f, " %s", sprint_time64(slot->max_delay, b1));
+ }
if(slot->max_packets)
fprintf(f, " packets %d", slot->max_packets);
if(slot->max_bytes)
--
2.18.0.597.ga71716f1ad-goog
^ permalink raw reply related
* Re: [PATCH] mellanox: fix the dport endianness in call of __inet6_lookup_established()
From: David Miller @ 2018-08-06 17:32 UTC (permalink / raw)
To: viro; +Cc: borisp, netdev
In-Reply-To: <20180804204127.GC15082@ZenIV.linux.org.uk>
From: Al Viro <viro@ZenIV.linux.org.uk>
Date: Sat, 4 Aug 2018 21:41:27 +0100
> __inet6_lookup_established() expect th->dport passed in host-endian,
> not net-endian. The reason is microoptimization in __inet6_lookup(),
> but if you use the lower-level helpers, you have to play by their
> rules...
>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Applied to net-next, thanks Al.
^ permalink raw reply
* [Patch net] vsock: split dwork to avoid reinitializations
From: Cong Wang @ 2018-08-06 18:06 UTC (permalink / raw)
To: netdev; +Cc: Cong Wang, Andy king, Stefan Hajnoczi, Jorgen Hansen
syzbot reported that we reinitialize an active delayed
work in vsock_stream_connect():
ODEBUG: init active (active state 0) object type: timer_list hint:
delayed_work_timer_fn+0x0/0x90 kernel/workqueue.c:1414
WARNING: CPU: 1 PID: 11518 at lib/debugobjects.c:329
debug_print_object+0x16a/0x210 lib/debugobjects.c:326
The pattern is apparently wrong, we should only initialize
the dealyed work once and could repeatly schedule it. So we
have to move out the initializations to allocation side.
And to avoid confusion, we can split the shared dwork
into two, instead of re-using the same one.
Fixes: d021c344051a ("VSOCK: Introduce VM Sockets")
Reported-by: <syzbot+8a9b1bd330476a4f3db6@syzkaller.appspotmail.com>
Cc: Andy king <acking@vmware.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Jorgen Hansen <jhansen@vmware.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
include/net/af_vsock.h | 4 ++--
net/vmw_vsock/af_vsock.c | 15 ++++++++-------
net/vmw_vsock/vmci_transport.c | 3 +--
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index 9324ac2d9ff2..43913ae79f64 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -64,7 +64,8 @@ struct vsock_sock {
struct list_head pending_links;
struct list_head accept_queue;
bool rejected;
- struct delayed_work dwork;
+ struct delayed_work connect_work;
+ struct delayed_work pending_work;
struct delayed_work close_work;
bool close_work_scheduled;
u32 peer_shutdown;
@@ -77,7 +78,6 @@ struct vsock_sock {
s64 vsock_stream_has_data(struct vsock_sock *vsk);
s64 vsock_stream_has_space(struct vsock_sock *vsk);
-void vsock_pending_work(struct work_struct *work);
struct sock *__vsock_create(struct net *net,
struct socket *sock,
struct sock *parent,
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index c1076c19b858..ab27a2872935 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -451,14 +451,14 @@ static int vsock_send_shutdown(struct sock *sk, int mode)
return transport->shutdown(vsock_sk(sk), mode);
}
-void vsock_pending_work(struct work_struct *work)
+static void vsock_pending_work(struct work_struct *work)
{
struct sock *sk;
struct sock *listener;
struct vsock_sock *vsk;
bool cleanup;
- vsk = container_of(work, struct vsock_sock, dwork.work);
+ vsk = container_of(work, struct vsock_sock, pending_work.work);
sk = sk_vsock(vsk);
listener = vsk->listener;
cleanup = true;
@@ -498,7 +498,6 @@ void vsock_pending_work(struct work_struct *work)
sock_put(sk);
sock_put(listener);
}
-EXPORT_SYMBOL_GPL(vsock_pending_work);
/**** SOCKET OPERATIONS ****/
@@ -597,6 +596,8 @@ static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr)
return retval;
}
+static void vsock_connect_timeout(struct work_struct *work);
+
struct sock *__vsock_create(struct net *net,
struct socket *sock,
struct sock *parent,
@@ -638,6 +639,8 @@ struct sock *__vsock_create(struct net *net,
vsk->sent_request = false;
vsk->ignore_connecting_rst = false;
vsk->peer_shutdown = 0;
+ INIT_DELAYED_WORK(&vsk->connect_work, vsock_connect_timeout);
+ INIT_DELAYED_WORK(&vsk->pending_work, vsock_pending_work);
psk = parent ? vsock_sk(parent) : NULL;
if (parent) {
@@ -1117,7 +1120,7 @@ static void vsock_connect_timeout(struct work_struct *work)
struct vsock_sock *vsk;
int cancel = 0;
- vsk = container_of(work, struct vsock_sock, dwork.work);
+ vsk = container_of(work, struct vsock_sock, connect_work.work);
sk = sk_vsock(vsk);
lock_sock(sk);
@@ -1221,9 +1224,7 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
* timeout fires.
*/
sock_hold(sk);
- INIT_DELAYED_WORK(&vsk->dwork,
- vsock_connect_timeout);
- schedule_delayed_work(&vsk->dwork, timeout);
+ schedule_delayed_work(&vsk->connect_work, timeout);
/* Skip ahead to preserve error code set above. */
goto out_wait;
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index a7a73ffe675b..cb332adb84cd 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -1094,8 +1094,7 @@ static int vmci_transport_recv_listen(struct sock *sk,
vpending->listener = sk;
sock_hold(sk);
sock_hold(pending);
- INIT_DELAYED_WORK(&vpending->dwork, vsock_pending_work);
- schedule_delayed_work(&vpending->dwork, HZ);
+ schedule_delayed_work(&vpending->pending_work, HZ);
out:
return err;
--
2.14.4
^ permalink raw reply related
* Re: SLAB_TYPESAFE_BY_RCU without constructors (was Re: [PATCH v4 13/17] khwasan: add hooks implementation)
From: Jan Kara @ 2018-08-06 20:20 UTC (permalink / raw)
To: Dmitry Vyukov
Cc: Dave Airlie, DRI, linux-mm, Eric Dumazet, Christoph Lameter,
Gerrit Renker, dccp, coreteam, Jozsef Kadlecsik, Andrey Ryabinin,
linux-ext4, Alexey Kuznetsov, Pablo Neira Ayuso, linux-s390,
Andrey Konovalov, intel-gfx, Jan Kara, Ursula Braun, Rodrigo Vivi,
Theodore Ts'o, Hideaki YOSHIFUJI, Network Development,
Florian Westphal, Linux Kernel Mailing List
In-Reply-To: <CACT4Y+aYZumcc-Od5T1AnP4mwn8-FaWfxvfb93MnNwQPqG8TDw@mail.gmail.com>
On Wed 01-08-18 10:46:35, Dmitry Vyukov wrote:
> I guess it would be useful to have such extensive comment for each
> SLAB_TYPESAFE_BY_RCU use explaining why it is needed and how all the
> tricky aspects are handled.
>
> For example, the one in jbd2 is interesting because it memsets the
> whole object before freeing it into SLAB_TYPESAFE_BY_RCU slab:
>
> memset(jh, JBD2_POISON_FREE, sizeof(*jh));
> kmem_cache_free(jbd2_journal_head_cache, jh);
>
> I guess there are also tricky ways how it can all work in the end
> (type-stable state is only a byte, or we check for all possible
> combinations of being overwritten with JBD2_POISON_FREE). But at first
> sight it does look fishy.
The RCU access is used from a single place:
fs/jbd2/transaction.c: jbd2_write_access_granted()
There are also quite some comments explaining why what it does is safe. The
overwrite by JBD2_POISON_FREE is much older than this RCU stuff (honestly I
didn't know about it until this moment) and has nothing to do with the
safety of RCU access.
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH net-next] tcp: fix the calculation of sysctl_max_tw_buckets in tcp_sk_init()
From: David Miller @ 2018-08-06 20:41 UTC (permalink / raw)
To: laoar.shao; +Cc: edumazet, yanhaishuang, netdev, linux-kernel
In-Reply-To: <1533556020-20778-1-git-send-email-laoar.shao@gmail.com>
From: Yafang Shao <laoar.shao@gmail.com>
Date: Mon, 6 Aug 2018 19:47:00 +0800
> tcp_hashinfo.ehash_mask is always an odd number, which is set in function
> alloc_large_system_hash(). See bellow,
> if (_hash_mask)
> *_hash_mask = (1 << log2qty) - 1; <<< always odd number
>
> Hence the local variable 'cnt' is a even number, as a result of that it is
> no difference to do the incrementation here.
>
> Maybe the compiler could also optimize it, but this code is a little ugly.
>
> Fix: fee83d09 ("ipv4: Namespaceify tcp_max_syn_backlog knob")
The correct tag is "Fixes: "
> @@ -2543,7 +2543,7 @@ static int __net_init tcp_sk_init(struct net *net)
> net->ipv4.sysctl_tcp_tw_reuse = 2;
>
> cnt = tcp_hashinfo.ehash_mask + 1;
> - net->ipv4.tcp_death_row.sysctl_max_tw_buckets = (cnt + 1) / 2;
> + net->ipv4.tcp_death_row.sysctl_max_tw_buckets = cnt / 2;
> net->ipv4.tcp_death_row.hashinfo = &tcp_hashinfo;
This is completely harmless, and does no harm.
You aren't "fixing" anything.
^ permalink raw reply
* [PATCH net-next,v2] net/tls: Calculate nsg for zerocopy path without skb_cow_data.
From: Doron Roberts-Kedes @ 2018-08-06 18:25 UTC (permalink / raw)
To: David S . Miller
Cc: Vakul Garg, Dave Watson, Boris Pismenny, Aviad Yehezkel, netdev,
Doron Roberts-Kedes
decrypt_skb fails if the number of sg elements required to map is
greater than MAX_SKB_FRAGS. As noted by Vakul Garg, nsg must always be
calculated, but skb_cow_data adds unnecessary memcpy's for the zerocopy
case.
The new function skb_nsg calculates the number of scatterlist elements
required to map the skb without the extra overhead of skb_cow_data. This
function mimics the structure of skb_to_sgvec.
Fixes: c46234ebb4d1 ("tls: RX path for ktls")
Signed-off-by: Doron Roberts-Kedes <doronrk@fb.com>
---
net/tls/tls_sw.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 90 insertions(+), 3 deletions(-)
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index ff3a6904a722..e1c465a2ce0b 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -43,6 +43,76 @@
#define MAX_IV_SIZE TLS_CIPHER_AES_GCM_128_IV_SIZE
+static int __skb_nsg(struct sk_buff *skb, int offset, int len,
+ unsigned int recursion_level)
+{
+ int start = skb_headlen(skb);
+ int i, copy = start - offset;
+ struct sk_buff *frag_iter;
+ int elt = 0;
+
+ if (unlikely(recursion_level >= 24))
+ return -EMSGSIZE;
+
+ if (copy > 0) {
+ if (copy > len)
+ copy = len;
+ elt++;
+ if ((len -= copy) == 0)
+ return elt;
+ offset += copy;
+ }
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ int end;
+
+ WARN_ON(start > offset + len);
+
+ end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]);
+ if ((copy = end - offset) > 0) {
+ if (copy > len)
+ copy = len;
+ elt++;
+ if (!(len -= copy))
+ return elt;
+ offset += copy;
+ }
+ start = end;
+ }
+
+ skb_walk_frags(skb, frag_iter) {
+ int end, ret;
+
+ WARN_ON(start > offset + len);
+
+ end = start + frag_iter->len;
+ if ((copy = end - offset) > 0) {
+
+ if (copy > len)
+ copy = len;
+ ret = __skb_nsg(frag_iter, offset - start, copy,
+ recursion_level + 1);
+ if (unlikely(ret < 0))
+ return ret;
+ elt += ret;
+ if ((len -= copy) == 0)
+ return elt;
+ offset += copy;
+ }
+ start = end;
+ }
+ BUG_ON(len);
+ return elt;
+}
+
+/* Return the number of scatterlist elements required to completely map the
+ * skb, or -EMSGSIZE if the recursion depth is exceeded.
+ */
+static int skb_nsg(struct sk_buff *skb, int offset, int len)
+{
+ return __skb_nsg(skb, offset, len, 0);
+}
+
static int tls_do_decryption(struct sock *sk,
struct scatterlist *sgin,
struct scatterlist *sgout,
@@ -693,7 +763,7 @@ int decrypt_skb(struct sock *sk, struct sk_buff *skb,
struct scatterlist sgin_arr[MAX_SKB_FRAGS + 2];
struct scatterlist *sgin = &sgin_arr[0];
struct strp_msg *rxm = strp_msg(skb);
- int ret, nsg = ARRAY_SIZE(sgin_arr);
+ int ret, nsg;
struct sk_buff *unused;
ret = skb_copy_bits(skb, rxm->offset + TLS_HEADER_SIZE,
@@ -704,11 +774,28 @@ int decrypt_skb(struct sock *sk, struct sk_buff *skb,
memcpy(iv, tls_ctx->rx.iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
if (!sgout) {
- nsg = skb_cow_data(skb, 0, &unused) + 1;
+ nsg = skb_cow_data(skb, 0, &unused);
+ } else {
+ nsg = skb_nsg(skb,
+ rxm->offset + tls_ctx->rx.prepend_size,
+ rxm->full_len - tls_ctx->rx.prepend_size);
+ if (nsg <= 0)
+ return nsg;
+ }
+
+ // We need one extra for ctx->rx_aad_ciphertext
+ nsg++;
+
+ if (nsg > ARRAY_SIZE(sgin_arr)) {
sgin = kmalloc_array(nsg, sizeof(*sgin), sk->sk_allocation);
- sgout = sgin;
+ if (!sgin)
+ return -ENOMEM;
}
+
+ if (!sgout)
+ sgout = sgin;
+
sg_init_table(sgin, nsg);
sg_set_buf(&sgin[0], ctx->rx_aad_ciphertext, TLS_AAD_SPACE_SIZE);
--
2.17.1
^ permalink raw reply related
* Re: [PATCH net-next] net/tls: Calculate nsg for zerocopy path without skb_cow_data.
From: Doron Roberts-Kedes @ 2018-08-06 18:32 UTC (permalink / raw)
To: Vakul Garg
Cc: David S . Miller, Dave Watson, Boris Pismenny, Aviad Yehezkel,
netdev@vger.kernel.org
In-Reply-To: <20180803184902.GA27063@doronrk-mbp.dhcp.thefacebook.com>
On Fri, Aug 03, 2018 at 11:49:02AM -0700, Doron Roberts-Kedes wrote:
> On Fri, Aug 03, 2018 at 01:23:33AM +0000, Vakul Garg wrote:
> >
> >
> > > -----Original Message-----
> > > From: Doron Roberts-Kedes [mailto:doronrk@fb.com]
> > > Sent: Friday, August 3, 2018 6:00 AM
> > > To: David S . Miller <davem@davemloft.net>
> > > Cc: Dave Watson <davejwatson@fb.com>; Vakul Garg
> > > <vakul.garg@nxp.com>; Boris Pismenny <borisp@mellanox.com>; Aviad
> > > Yehezkel <aviadye@mellanox.com>; netdev@vger.kernel.org; Doron
> > > Roberts-Kedes <doronrk@fb.com>
> > > Subject: [PATCH net-next] net/tls: Calculate nsg for zerocopy path without
> > > skb_cow_data.
> > >
> > > decrypt_skb fails if the number of sg elements required to map is greater
> > > than MAX_SKB_FRAGS. As noted by Vakul Garg, nsg must always be
> > > calculated, but skb_cow_data adds unnecessary memcpy's for the zerocopy
> > > case.
> > >
> > > The new function skb_nsg calculates the number of scatterlist elements
> > > required to map the skb without the extra overhead of skb_cow_data. This
> > > function mimics the structure of skb_to_sgvec.
> > >
> > > Fixes: c46234ebb4d1 ("tls: RX path for ktls")
> > > Signed-off-by: Doron Roberts-Kedes <doronrk@fb.com>
> > > ---
> > > net/tls/tls_sw.c | 89
> > > ++++++++++++++++++++++++++++++++++++++++++++++--
> > > 1 file changed, 86 insertions(+), 3 deletions(-)
> > >
> > > memcpy(iv, tls_ctx->rx.iv, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
> > > if (!sgout) {
> > > - nsg = skb_cow_data(skb, 0, &unused) + 1;
> > > + nsg = skb_cow_data(skb, 0, &unused);
> > > + } else {
> > > + nsg = skb_nsg(skb,
> > > + rxm->offset + tls_ctx->rx.prepend_size,
> > > + rxm->full_len - tls_ctx->rx.prepend_size);
> > > + if (nsg <= 0)
> > > + return nsg;
> > Comparison should be (nsg < 1). TLS forbids '0' sized records.
>
> Yes true, v2 incoming
>
Glancing at this a second time, I actually don't believe this should be
changed. nsg <= 0 is equivalent to nsg < 1. Returning 0 if the record is
0 sized is the proper behavior here, since decrypting a zero-length skb
is a no-op. It is true that zero sized TLS records are forbidden, but it
is confusing to enforce that in this part of the code. I would be
surpised to learn that tls_sw_recvmsg could be invoked with a len equal
to 0, but if I'm wrong, and that case does need to be handled, then it
should be in a different patch.
^ permalink raw reply
* [PATCH bpf-next] bpf: introduce update_effective_progs()
From: Roman Gushchin @ 2018-08-06 21:27 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel-team, Roman Gushchin, Alexei Starovoitov,
Daniel Borkmann
__cgroup_bpf_attach() and __cgroup_bpf_detach() functions have
a good amount of duplicated code, which is possible to eliminate
by introducing the update_effective_progs() helper function.
The update_effective_progs() calls compute_effective_progs()
and then in case of success it calls activate_effective_progs()
for each descendant cgroup. In case of failure (OOM), it releases
allocated prog arrays and return the error code.
Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Song Liu <songliubraving@fb.com>
---
kernel/bpf/cgroup.c | 99 ++++++++++++++++++++++++-----------------------------
1 file changed, 45 insertions(+), 54 deletions(-)
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 0a4fe5a7dc91..6a7d931bbc55 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -177,6 +177,45 @@ int cgroup_bpf_inherit(struct cgroup *cgrp)
return -ENOMEM;
}
+static int update_effective_progs(struct cgroup *cgrp,
+ enum bpf_attach_type type)
+{
+ struct cgroup_subsys_state *css;
+ int err;
+
+ /* allocate and recompute effective prog arrays */
+ css_for_each_descendant_pre(css, &cgrp->self) {
+ struct cgroup *desc = container_of(css, struct cgroup, self);
+
+ err = compute_effective_progs(desc, type, &desc->bpf.inactive);
+ if (err)
+ goto cleanup;
+ }
+
+ /* all allocations were successful. Activate all prog arrays */
+ css_for_each_descendant_pre(css, &cgrp->self) {
+ struct cgroup *desc = container_of(css, struct cgroup, self);
+
+ activate_effective_progs(desc, type, desc->bpf.inactive);
+ desc->bpf.inactive = NULL;
+ }
+
+ return 0;
+
+cleanup:
+ /* oom while computing effective. Free all computed effective arrays
+ * since they were not activated
+ */
+ css_for_each_descendant_pre(css, &cgrp->self) {
+ struct cgroup *desc = container_of(css, struct cgroup, self);
+
+ bpf_prog_array_free(desc->bpf.inactive);
+ desc->bpf.inactive = NULL;
+ }
+
+ return err;
+}
+
#define BPF_CGROUP_MAX_PROGS 64
/**
@@ -194,7 +233,6 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
struct list_head *progs = &cgrp->bpf.progs[type];
struct bpf_prog *old_prog = NULL;
struct bpf_cgroup_storage *storage, *old_storage = NULL;
- struct cgroup_subsys_state *css;
struct bpf_prog_list *pl;
bool pl_was_allocated;
int err;
@@ -261,22 +299,9 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
cgrp->bpf.flags[type] = flags;
- /* allocate and recompute effective prog arrays */
- css_for_each_descendant_pre(css, &cgrp->self) {
- struct cgroup *desc = container_of(css, struct cgroup, self);
-
- err = compute_effective_progs(desc, type, &desc->bpf.inactive);
- if (err)
- goto cleanup;
- }
-
- /* all allocations were successful. Activate all prog arrays */
- css_for_each_descendant_pre(css, &cgrp->self) {
- struct cgroup *desc = container_of(css, struct cgroup, self);
-
- activate_effective_progs(desc, type, desc->bpf.inactive);
- desc->bpf.inactive = NULL;
- }
+ err = update_effective_progs(cgrp, type);
+ if (err)
+ goto cleanup;
static_branch_inc(&cgroup_bpf_enabled_key);
if (old_storage)
@@ -289,16 +314,6 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
return 0;
cleanup:
- /* oom while computing effective. Free all computed effective arrays
- * since they were not activated
- */
- css_for_each_descendant_pre(css, &cgrp->self) {
- struct cgroup *desc = container_of(css, struct cgroup, self);
-
- bpf_prog_array_free(desc->bpf.inactive);
- desc->bpf.inactive = NULL;
- }
-
/* and cleanup the prog list */
pl->prog = old_prog;
bpf_cgroup_storage_free(pl->storage);
@@ -326,7 +341,6 @@ int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
struct list_head *progs = &cgrp->bpf.progs[type];
u32 flags = cgrp->bpf.flags[type];
struct bpf_prog *old_prog = NULL;
- struct cgroup_subsys_state *css;
struct bpf_prog_list *pl;
int err;
@@ -365,22 +379,9 @@ int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
pl->prog = NULL;
}
- /* allocate and recompute effective prog arrays */
- css_for_each_descendant_pre(css, &cgrp->self) {
- struct cgroup *desc = container_of(css, struct cgroup, self);
-
- err = compute_effective_progs(desc, type, &desc->bpf.inactive);
- if (err)
- goto cleanup;
- }
-
- /* all allocations were successful. Activate all prog arrays */
- css_for_each_descendant_pre(css, &cgrp->self) {
- struct cgroup *desc = container_of(css, struct cgroup, self);
-
- activate_effective_progs(desc, type, desc->bpf.inactive);
- desc->bpf.inactive = NULL;
- }
+ err = update_effective_progs(cgrp, type);
+ if (err)
+ goto cleanup;
/* now can actually delete it from this cgroup list */
list_del(&pl->node);
@@ -396,16 +397,6 @@ int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
return 0;
cleanup:
- /* oom while computing effective. Free all computed effective arrays
- * since they were not activated
- */
- css_for_each_descendant_pre(css, &cgrp->self) {
- struct cgroup *desc = container_of(css, struct cgroup, self);
-
- bpf_prog_array_free(desc->bpf.inactive);
- desc->bpf.inactive = NULL;
- }
-
/* and restore back old_prog */
pl->prog = old_prog;
return err;
--
2.14.4
^ permalink raw reply related
* [PATCH net-next] ipv4: frags: precedence bug in ip_expire()
From: Dan Carpenter @ 2018-08-06 19:17 UTC (permalink / raw)
To: David S. Miller, Peter Oskolkov
Cc: Alexey Kuznetsov, Hideaki YOSHIFUJI, netdev, kernel-janitors
We accidentally removed the parentheses here, but they are required
because '!' has higher precedence than '&'.
Fixes: fa0f527358bd ("ip: use rb trees for IP frag queue.")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 0e8f8de77e71..7cb7ed761d8c 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -154,7 +154,7 @@ static void ip_expire(struct timer_list *t)
__IP_INC_STATS(net, IPSTATS_MIB_REASMFAILS);
__IP_INC_STATS(net, IPSTATS_MIB_REASMTIMEOUT);
- if (!qp->q.flags & INET_FRAG_FIRST_IN)
+ if (!(qp->q.flags & INET_FRAG_FIRST_IN))
goto out;
/* sk_buff::dev and sk_buff::rbnode are unionized. So we
^ permalink raw reply related
* Re: [PATCH mlx5-next] RDMA/mlx5: Don't use cached IRQ affinity mask
From: Steve Wise @ 2018-08-06 19:20 UTC (permalink / raw)
To: Max Gurtovoy, Sagi Grimberg, Jason Gunthorpe
Cc: 'Leon Romanovsky', 'Doug Ledford',
'RDMA mailing list', 'Saeed Mahameed',
'linux-netdev'
In-Reply-To: <f1442839-ff32-ab80-9eab-6923456fe272@mellanox.com>
On 8/1/2018 9:27 AM, Max Gurtovoy wrote:
>
>
> On 8/1/2018 8:12 AM, Sagi Grimberg wrote:
>> Hi Max,
>
> Hi,
>
>>
>>> Yes, since nvmf is the only user of this function.
>>> Still waiting for comments on the suggested patch :)
>>>
>>
>> Sorry for the late response (but I'm on vacation so I have
>> an excuse ;))
>
> NP :) currently the code works..
>
>>
>> I'm thinking that we should avoid trying to find an assignment
>> when stuff like irqbalance daemon is running and changing
>> the affinitization.
>
> but this is exactly what Steve complained and Leon try to fix (and
> break the connection establishment).
> If this is the case and we all agree then we're good without Leon's
> patch and without our suggestions.
>
I don't agree. Currently setting certain affinity mappings breaks nvme
connectivity. I don't think that is desirable. And mlx5 is broken in
that it doesn't allow changing the affinity but silently ignores the
change, which misleads the admin or irqbalance...
>>
>> This extension was made to apply optimal affinity assignment
>> when the device irq affinity is lined up in a vector per
>> core.
>>
>> I'm thinking that when we identify this is not the case, we immediately
>> fallback to the default mapping.
>>
>> 1. when we get a mask, if its weight != 1, we fallback.
>> 2. if a queue was left unmapped, we fallback.
>>
>> Maybe something like the following:
>
> did you test it ? I think it will not work since you need to map all
> the queues and all the CPUs.
>
>> --
>> diff --git a/block/blk-mq-rdma.c b/block/blk-mq-rdma.c
>> index 996167f1de18..1ada6211c55e 100644
>> --- a/block/blk-mq-rdma.c
>> +++ b/block/blk-mq-rdma.c
>> @@ -35,17 +35,26 @@ int blk_mq_rdma_map_queues(struct blk_mq_tag_set
>> *set,
>> const struct cpumask *mask;
>> unsigned int queue, cpu;
>>
>> + /* reset all CPUs mapping */
>> + for_each_possible_cpu(cpu)
>> + set->mq_map[cpu] = UINT_MAX;
>> +
>> for (queue = 0; queue < set->nr_hw_queues; queue++) {
>> mask = ib_get_vector_affinity(dev, first_vec + queue);
>> if (!mask)
>> goto fallback;
>>
>> - for_each_cpu(cpu, mask)
>> - set->mq_map[cpu] = queue;
>> + if (cpumask_weight(mask) != 1)
>> + goto fallback;
>> +
>> + cpu = cpumask_first(mask);
>> + if (set->mq_map[cpu] != UINT_MAX)
>> + goto fallback;
>> +
>> + set->mq_map[cpu] = queue;
>> }
>>
>> return 0;
>> -
>> fallback:
>> return blk_mq_map_queues(set);
>> }
>> --
>
> see attached another algorithem that can improve the mapping (although
> it's not a short one)...
>
> it will try to map according to affinity mask, and also in case the
> mask weight > 1 it will try to be better than the naive mapping I
> suggest in the previous email.
>
Let me know if you want me to try this or any particular fix.
Steve.
^ permalink raw reply
* Re: [PATCH net-next] ipv4: frags: precedence bug in ip_expire()
From: Peter Oskolkov @ 2018-08-06 19:29 UTC (permalink / raw)
To: dan.carpenter; +Cc: davem, kuznet, yoshfuji, netdev, kernel-janitors
In-Reply-To: <20180806191735.c5miffnrhl2w2ljh@kili.mountain>
Ack. Thanks, Dan!
On Mon, Aug 6, 2018 at 12:17 PM Dan Carpenter <dan.carpenter@oracle.com> wrote:
>
> We accidentally removed the parentheses here, but they are required
> because '!' has higher precedence than '&'.
>
> Fixes: fa0f527358bd ("ip: use rb trees for IP frag queue.")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
>
> diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
> index 0e8f8de77e71..7cb7ed761d8c 100644
> --- a/net/ipv4/ip_fragment.c
> +++ b/net/ipv4/ip_fragment.c
> @@ -154,7 +154,7 @@ static void ip_expire(struct timer_list *t)
> __IP_INC_STATS(net, IPSTATS_MIB_REASMFAILS);
> __IP_INC_STATS(net, IPSTATS_MIB_REASMTIMEOUT);
>
> - if (!qp->q.flags & INET_FRAG_FIRST_IN)
> + if (!(qp->q.flags & INET_FRAG_FIRST_IN))
> goto out;
>
> /* sk_buff::dev and sk_buff::rbnode are unionized. So we
^ permalink raw reply
* Re: [PATCH] rtlwifi: btcoex: Fix if == else warnings in halbtc8723b2ant.c
From: valdis.kletnieks-PjAqaU27lzQ @ 2018-08-06 21:42 UTC (permalink / raw)
To: YueHaibing
Cc: pkshih-Rasf1IRRPZFBDgjK7y7TUQ, kvalo-sgV2jX0FEOL9JmXXK+q4OQ,
Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
colin.king-Z7WLFzj8eWMS+FvcfC7Uqw,
linux-wireless-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20180806045440.11920-1-yuehaibing-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1336 bytes --]
On Mon, 06 Aug 2018 12:54:40 +0800, YueHaibing said:
> Fix following coccinelle warning:
>
> ./drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c:2952:2-4: WARNING: possible condition with no effect (if == else)
> /* sw mechanism */
> if (BTC_WIFI_BW_HT40 == wifi_bw) {
> - if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
> - (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
> - btc8723b2ant_sw_mechanism(btcoexist, true, true,
> - false, false);
> - } else {
> - btc8723b2ant_sw_mechanism(btcoexist, true, true,
> - false, false);
> - }
> + btc8723b2ant_sw_mechanism(btcoexist, true, true,
> + false, false);
> } else {
Rather than blindly fixing this, perhaps a bit of thought needs to be
applied to why this code looks like this in the first place.
See commit c6821613e653a (which looks like the bletcherous "do too many
things at once" commit indeed), although the actual diff appears to be a
"no harm, no foul" against this commit, where the issue already existed.
commit aa45a673b291fd761275493bc15316d79555ed55
Author: Larry Finger <Larry.Finger-tQ5ms3gMjBLk1uMJSBkQmQ@public.gmane.org>
Date: Fri Feb 28 15:16:43 2014 -0600
rtlwifi: btcoexist: Add new mini driver
Larry? Can you reach back to 2014 and remember why this code
looked like this in the first place?
[-- Attachment #2: Type: application/pgp-signature, Size: 486 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox