* [PATCH 1/2] net: nixge: Do not zero application specific fields in desc
From: Moritz Fischer @ 2018-08-11 1:19 UTC (permalink / raw)
To: davem; +Cc: keescook, netdev, linux-kernel, alex.williams, Moritz Fischer
In-Reply-To: <20180811011941.6187-1-mdf@kernel.org>
Do not zero application specific fields in DMA descriptors.
The hardware does ignore them, so should software.
Signed-off-by: Moritz Fischer <mdf@kernel.org>
---
drivers/net/ethernet/ni/nixge.c | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c
index 9ae4fcef725e..ac31b0d30415 100644
--- a/drivers/net/ethernet/ni/nixge.c
+++ b/drivers/net/ethernet/ni/nixge.c
@@ -739,22 +739,12 @@ static void nixge_dma_err_handler(unsigned long data)
cur_p->phys = 0;
cur_p->cntrl = 0;
cur_p->status = 0;
- cur_p->app0 = 0;
- cur_p->app1 = 0;
- cur_p->app2 = 0;
- cur_p->app3 = 0;
- cur_p->app4 = 0;
cur_p->sw_id_offset = 0;
}
for (i = 0; i < RX_BD_NUM; i++) {
cur_p = &lp->rx_bd_v[i];
cur_p->status = 0;
- cur_p->app0 = 0;
- cur_p->app1 = 0;
- cur_p->app2 = 0;
- cur_p->app3 = 0;
- cur_p->app4 = 0;
}
lp->tx_bd_ci = 0;
--
2.18.0
^ permalink raw reply related
* Re: [PATCH v2 bpf-next] BPF: helpers: New helper to obtain namespace data from current task
From: Alexei Starovoitov @ 2018-08-10 23:07 UTC (permalink / raw)
To: Carlos Neira; +Cc: netdev, ebiederm, quentin.monnet, ys114321, brouer
In-Reply-To: <20180810124104.1207-1-cneirabustos@gmail.com>
On Fri, Aug 10, 2018 at 08:41:04AM -0400, Carlos Neira wrote:
> This helper obtains the active namespace from current and returns pid, tgid,
> device and namespace id as seen from that namespace, allowing to instrument
> a process inside a container.
> Device is read from /proc/self/ns/pid, as in the future it's possible that
> different pid_ns files may belong to different devices, according
> to the discussion between Eric Biederman and Yonghong in 2017 linux plumbers
> conference.
>
> Currently bpf_get_current_pid_tgid(), is used to do pid filtering in bcc's
> scripts but this helper returns the pid as seen by the root namespace which is
> fine when a bcc script is not executed inside a container.
> When the process of interest is inside a container, pid filtering will not work
> if bpf_get_current_pid_tgid() is used. This helper addresses this limitation
> returning the pid as it's seen by the current namespace where the script is
> executing.
>
> This helper has the same use cases as bpf_get_current_pid_tgid() as it can be
> used to do pid filtering even inside a container.
>
> For example a bcc script using bpf_get_current_pid_tgid() (tools/funccount.py):
>
> u32 pid = bpf_get_current_pid_tgid() >> 32;
> if (pid != <pid_arg_passed_in>)
> return 0;
>
> Could be modified to use bpf_get_current_pidns_info() as follows:
>
> struct bpf_pidns pidns;
> bpf_get_current_pidns_info(&pidns, sizeof(struct bpf_pidns));
> u32 pid = pidns.tgid;
> u32 nsid = pidns.nsid;
> if ((pid != <pid_arg_passed_in>) && (nsid != <nsid_arg_passed_in>))
> return 0;
>
> To find out the name PID namespace id of a process, you could use this command:
>
> $ ps -h -o pidns -p <pid_of_interest>
>
> Or this other command:
>
> $ ls -Li /proc/<pid_of_interest>/ns/pid
>
> Signed-off-by: Carlos Antonio Neira Bustos <cneirabustos@gmail.com>
> ---
> include/linux/bpf.h | 1 +
> include/uapi/linux/bpf.h | 24 +++++++++++-
> kernel/bpf/core.c | 1 +
> kernel/bpf/helpers.c | 64 +++++++++++++++++++++++++++++++
> kernel/trace/bpf_trace.c | 2 +
> samples/bpf/Makefile | 3 ++
> samples/bpf/trace_ns_info_user.c | 35 +++++++++++++++++
> samples/bpf/trace_ns_info_user_kern.c | 45 ++++++++++++++++++++++
> tools/include/uapi/linux/bpf.h | 24 +++++++++++-
> tools/testing/selftests/bpf/bpf_helpers.h | 3 ++
> 10 files changed, 200 insertions(+), 2 deletions(-)
> create mode 100644 samples/bpf/trace_ns_info_user.c
> create mode 100644 samples/bpf/trace_ns_info_user_kern.c
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index cd8790d2c6ed..3f4b999f7c99 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -787,6 +787,7 @@ extern const struct bpf_func_proto bpf_get_stack_proto;
> extern const struct bpf_func_proto bpf_sock_map_update_proto;
> extern const struct bpf_func_proto bpf_sock_hash_update_proto;
> extern const struct bpf_func_proto bpf_get_current_cgroup_id_proto;
> +extern const struct bpf_func_proto bpf_get_current_pidns_info_proto;
>
> extern const struct bpf_func_proto bpf_get_local_storage_proto;
>
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index dd5758dc35d3..8462f9881465 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -2113,6 +2113,18 @@ union bpf_attr {
> * the shared data.
> * Return
> * Pointer to the local storage area.
> + *
> + * int bpf_get_current_pidns_info(struct bpf_pidns_info *pidns, u32 size_of_pidns)
> + * Description
> + * Copies into *pidns* pid, namespace id and tgid as seen by the
> + * current namespace and also device from /proc/self/ns/pid.
> + * *size_of_pidns* must be the size of *pidns*
> + *
> + * This helper is used when pid filtering is needed inside a
> + * container as bpf_get_current_tgid() helper returns always the
> + * pid id as seen by the root namespace.
> + * Return
> + * 0 on success -EINVAL on error.
> */
> #define __BPF_FUNC_MAPPER(FN) \
> FN(unspec), \
> @@ -2196,7 +2208,8 @@ union bpf_attr {
> FN(rc_keydown), \
> FN(skb_cgroup_id), \
> FN(get_current_cgroup_id), \
> - FN(get_local_storage),
> + FN(get_local_storage), \
> + FN(get_current_pidns_info),
>
> /* integer value in 'imm' field of BPF_CALL instruction selects which helper
> * function eBPF program intends to call
> @@ -2724,4 +2737,13 @@ enum bpf_task_fd_type {
> BPF_FD_TYPE_URETPROBE, /* filename + offset */
> };
>
> +/* helper bpf_get_current_pidns_info will store the following
> + * data, dev will contain major/minor from /proc/self/ns/pid.
> + */
> +struct bpf_pidns_info {
> + __u32 dev;
> + __u32 nsid;
> + __u32 tgid;
> + __u32 pid;
> +};
> #endif /* _UAPI__LINUX_BPF_H__ */
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index 4d09e610777f..98ce53ce2ea6 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -1796,6 +1796,7 @@ const struct bpf_func_proto bpf_sock_map_update_proto __weak;
> const struct bpf_func_proto bpf_sock_hash_update_proto __weak;
> const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;
> const struct bpf_func_proto bpf_get_local_storage_proto __weak;
> +const struct bpf_func_proto bpf_get_current_pidns_info __weak;
>
> const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
> {
> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> index 1991466b8327..d06d723b9cff 100644
> --- a/kernel/bpf/helpers.c
> +++ b/kernel/bpf/helpers.c
> @@ -18,6 +18,9 @@
> #include <linux/sched.h>
> #include <linux/uidgid.h>
> #include <linux/filter.h>
> +#include <linux/pid_namespace.h>
> +#include <linux/major.h>
> +#include <linux/stat.h>
>
> /* If kernel subsystem is allowing eBPF programs to call this function,
> * inside its own verifier_ops->get_func_proto() callback it should return
> @@ -214,3 +217,64 @@ const struct bpf_func_proto bpf_get_local_storage_proto = {
> .arg2_type = ARG_ANYTHING,
> };
> #endif
> +
> +BPF_CALL_2(bpf_get_current_pidns_info, struct bpf_pidns_info *, pidns_info, u32,
> + size)
> +{
> + const char *ppath = "/proc/self/ns/pid";
> + struct pid_namespace *pidns = NULL;
> + mm_segment_t oldsegfs;
> + struct kstat stat;
> + pid_t tgid = 0;
> + pid_t pid = 0;
> + int res = 0;
> +
> + if (unlikely(size != sizeof(struct bpf_pidns_info)))
> + goto clear;
> +
> + pidns = task_active_pid_ns(current);
> +
> + if (unlikely(!pidns))
> + goto clear;
> +
> + pidns_info->nsid = pidns->ns.inum;
> + pid = task_pid_nr_ns(current, pidns);
> +
> + if (unlikely(!pid))
> + goto clear;
> +
> + tgid = task_tgid_nr_ns(current, pidns);
> +
> + if (unlikely(!tgid))
> + goto clear;
> +
> + pidns_info->tgid = (u32) tgid;
> + pidns_info->pid = (u32) pid;
> +
> + oldsegfs = get_fs();
> + set_fs(KERNEL_DS);
> + res = vfs_stat((const char __user *)ppath, &stat);
> + set_fs(oldsegfs);
such fs magic cannot be done from the helper.
please find a way to retrieve device differently.
> +
> + if (unlikely(res))
> + goto clear;
> +
> + pidns_info->dev = stat.dev;
> +
> + return 0;
> +
> +clear:
> + if (pidns_info)
> + memset((void *)pidns, 0, (size_t) size);
> +
> + return -EINVAL;
> +}
> +
> +const struct bpf_func_proto bpf_get_current_pidns_info_proto = {
> + .func = bpf_get_current_pidns_info,
> + .gpl_only = false,
> + .ret_type = RET_INTEGER,
> + .arg1_type = ARG_PTR_TO_UNINIT_MEM,
> + .arg2_type = ARG_CONST_SIZE,
> +};
> +
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 0ae6829804bc..f70be29e49ab 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -568,6 +568,8 @@ tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
> case BPF_FUNC_get_current_cgroup_id:
> return &bpf_get_current_cgroup_id_proto;
> #endif
> + case BPF_FUNC_get_current_pidns_info:
> + return &bpf_get_current_pidns_info_proto;
> default:
> return NULL;
> }
> diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
> index f88d5683d6ee..fdcde00554ce 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 += trace_ns_info
>
> # 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)
> +trace_ns_info-objs := bpf_load.o trace_ns_info_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 += trace_ns_info_user_kern.o
>
> HOSTCFLAGS += -I$(objtree)/usr/include
> HOSTCFLAGS += -I$(srctree)/tools/lib/
> diff --git a/samples/bpf/trace_ns_info_user.c b/samples/bpf/trace_ns_info_user.c
> new file mode 100644
> index 000000000000..e06d08db6f30
> --- /dev/null
> +++ b/samples/bpf/trace_ns_info_user.c
please split addition of sample code into separate patch
and convert it into selftests.
> @@ -0,0 +1,35 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (c) 2018 Carlos Neira cneirabustos@gmail.com
> + *
> + * 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 <stdio.h>
> +#include <linux/bpf.h>
> +#include <unistd.h>
> +#include "bpf/libbpf.h"
> +#include "bpf_load.h"
> +
> +/* This code was taken verbatim from tracex1_user.c, it's used
> + * to exercize bpf_get_current_pidns_info() helper call.
> + */
> +int main(int ac, char **argv)
> +{
> + FILE *f;
> + char filename[256];
> +
> + snprintf(filename, sizeof(filename), "%s_user_kern.o", argv[0]);
> + printf("loading %s\n", filename);
> +
> + if (load_bpf_file(filename)) {
> + printf("%s", bpf_log_buf);
> + return 1;
> + }
> +
> + f = popen("taskset 1 ping localhost", "r");
> + (void) f;
> + read_trace_pipe();
> + return 0;
> +}
> diff --git a/samples/bpf/trace_ns_info_user_kern.c b/samples/bpf/trace_ns_info_user_kern.c
> new file mode 100644
> index 000000000000..ceaf3e83c8e7
> --- /dev/null
> +++ b/samples/bpf/trace_ns_info_user_kern.c
> @@ -0,0 +1,45 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (c) 2018 Carlos Neira cneirabustos@gmail.com
> + *
> + * 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 <linux/skbuff.h>
> +#include <linux/netdevice.h>
> +#include <linux/version.h>
> +#include <uapi/linux/bpf.h>
> +#include "bpf_helpers.h"
> +
> +typedef __u64 u64;
> +typedef __u32 u32;
> +
> +
> +/* kprobe is NOT a stable ABI
> + * kernel functions can be removed, renamed or completely change semantics.
> + * Number of arguments and their positions can change, etc.
> + * In such case this bpf+kprobe example will no longer be meaningful
> + */
> +
> +/* This will call bpf_get_current_pidns_info() to display pid and ns values
> + * as seen by the current namespace, on the far left you will see the pid as
> + * seen as by the root namespace.
> + */
> +
> +SEC("kprobe/__netif_receive_skb_core")
> +int bpf_prog1(struct pt_regs *ctx)
> +{
> + char fmt[] = "nsid:%u, dev: %u, pid:%u\n";
> + struct bpf_pidns_info nsinfo;
> + int ok = 0;
> +
> + ok = bpf_get_current_pidns_info(&nsinfo, sizeof(nsinfo));
> + if (ok == 0)
> + bpf_trace_printk(fmt, sizeof(fmt), (u32)nsinfo.nsid,
> + (u32) nsinfo.dev, (u32)nsinfo.pid);
> +
> + return 0;
> +}
> +
> +char _license[] SEC("license") = "GPL";
> +u32 _version SEC("version") = LINUX_VERSION_CODE;
> diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
> index dd5758dc35d3..8462f9881465 100644
> --- a/tools/include/uapi/linux/bpf.h
> +++ b/tools/include/uapi/linux/bpf.h
update to tools/../bpf.h should be separate patch as well.
At the end it should be:
p1 - feature introduction
p2 - update tools/.../bpf.h
p3 - selftest
^ permalink raw reply
* Re: [BUG] bpf: syscall: a possible sleep-in-atomic-context bug in map_update_elem()
From: Jia-Ju Bai @ 2018-08-11 1:57 UTC (permalink / raw)
To: Daniel Borkmann, ast; +Cc: netdev, Linux Kernel Mailing List, brouer
In-Reply-To: <97aa2e6b-1863-f123-af2c-24a2e6333ba5@iogearbox.net>
On 2018/8/10 22:22, Daniel Borkmann wrote:
> On 08/10/2018 04:07 PM, Jia-Ju Bai wrote:
>> The kernel may sleep with holding a rcu read lock.
>>
>> The function call paths (from bottom to top) in Linux-4.16 are:
>>
>> [FUNC] kmalloc(GFP_KERNEL)
>> kernel/kthread.c, 283: kmalloc in __kthread_create_on_node
>> kernel/kthread.c, 365: __kthread_create_on_node in kthread_create_on_node
>> kernel/bpf/cpumap.c, 368: kthread_create_on_node in __cpu_map_entry_alloc
>> kernel/bpf/cpumap.c, 490: __cpu_map_entry_alloc in cpu_map_update_elem
>> kernel/bpf/syscall.c, 724: [FUNC_PTR]cpu_map_update_elem in map_update_elem
>> kernel/bpf/syscall.c, 723: rcu_read_lock in map_update_elem
>>
>> Note that [FUNC_PTR] means a function pointer call is used.
>>
>> I do not find a good way to fix it, so I only report.
>> This is found by my static analysis tool (DSAC).
> Thanks for the report Jia-Ju! In the map_update_elem() from syscall
> path there's a check map->map_type == BPF_MAP_TYPE_CPUMAP, where we
> call the cpumap's map->ops->map_update_elem() while /not/ being under
> rcu_read_lock() as in other cases, so looks okay to me. Could you point
> out the case for being under rcu_read_lock() more specifically which
> the tool found?
Thanks for your reply :)
My tool cannot accurately track the case of map->map_type at present...
According to my code review, there is a indeed check on line 697 in
Linux-4.16:
else if (map->map_type == BPF_MAP_TYPE_CPUMAP) {
err = map->ops->map_update_elem(map, key, value, attr->flags);
goto out;
}
But there is a call to map->ops->map_update_elem() that is under
rcu_read_lock on line 724:
rcu_read_lock();
err = map->ops->map_update_elem(map, key, value, attr->flags);
rcu_read_unlock();
So I think if map->map_type is not equal to BPF_MAP_TYPE_CPUMAP,
map->ops->map_update_elem() can still be called under rcu_read_lock, is
it right?
Best wishes,
Jia-Ju Bai
^ permalink raw reply
* Re: [PATCH bpf-next 0/3] bpf: add bpffs pretty print for hash/lru_hash maps
From: Daniel Borkmann @ 2018-08-10 23:32 UTC (permalink / raw)
To: Yonghong Song, ast, netdev; +Cc: kernel-team
In-Reply-To: <20180809155521.1544888-1-yhs@fb.com>
On 08/09/2018 05:55 PM, Yonghong Song wrote:
> Commit a26ca7c982cb ("bpf: btf: Add pretty print support to
> the basic arraymap") added pretty print support to array map.
> This patch adds pretty print for hash and lru_hash maps.
>
> The following example shows the pretty-print result of a pinned hashmap.
> Without this patch set, user will get an error instead.
>
> struct map_value {
> int count_a;
> int count_b;
> };
>
> cat /sys/fs/bpf/pinned_hash_map:
>
> 87907: {87907,87908}
> 57354: {37354,57355}
> 76625: {76625,76626}
> ...
>
> Patch #1 fixed a bug in bpffs map_seq_next() function so that
> all elements in the hash table will be traversed.
> Patch #2 implemented map_seq_show_elem() and map_check_btf()
> callback functions for hash and lru hash maps.
> Patch #3 enhanced tools/testing/selftests/bpf/test_btf.c to
> test bpffs hash and lru hash map pretty print.
>
> Yonghong Song (3):
> bpf: fix bpffs non-array map seq_show issue
> bpf: btf: add pretty print for hash/lru_hash maps
> tools/bpf: add bpffs pretty print btf test for hash/lru_hash maps
>
> kernel/bpf/hashtab.c | 44 +++++++++++++++++
> kernel/bpf/inode.c | 8 ++--
> tools/testing/selftests/bpf/test_btf.c | 87 ++++++++++++++++++++++++++++------
> 3 files changed, 121 insertions(+), 18 deletions(-)
Applied to bpf-next, thanks Yonghong!
^ permalink raw reply
* Re: [PATCH net-next] net: mvneta: fix mvneta_config_rss on armada 3700
From: David Miller @ 2018-08-11 2:11 UTC (permalink / raw)
To: andrew
Cc: Jisheng.Zhang, thomas.petazzoni, linux-arm-kernel, netdev,
linux-kernel
In-Reply-To: <20180810222335.GD11955@lunn.ch>
From: Andrew Lunn <andrew@lunn.ch>
Date: Sat, 11 Aug 2018 00:23:35 +0200
> On Fri, Aug 10, 2018 at 02:40:31PM -0700, David Miller wrote:
>> From: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
>> Date: Fri, 10 Aug 2018 11:36:27 +0800
>>
>> > The mvneta Ethernet driver is used on a few different Marvell SoCs.
>> > Some SoCs have per cpu interrupts for Ethernet events, the driver uses
>> > a per CPU napi structure for this case. Some SoCs such as armada 3700
>> > have a single interrupt for Ethernet events, the driver uses a global
>> > napi structure for this case.
>> >
>> > Current mvneta_config_rss() always operates the per cpu napi structure.
>> > Fix it by operating a global napi for "single interrupt" case, and per
>> > cpu napi structure for remaining cases.
>> >
>> > Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
>> > Fixes: 2636ac3cc2b4 ("net: mvneta: Add network support for Armada 3700 SoC")
>>
>> Applied, thanks.
>
> Hi David
>
> Please can you queue up:
>
> Fixes: 7a86f05faf11 ("net: ethernet: mvneta: Fix napi structure mixup on armada 3700")
>
> and this patch for stable.
If you want things to go to -stable, don't mark them for net-next as this
patch was.
If it isn't appropriate for 'net' it isn't appropriate for -stable either.
^ permalink raw reply
* Re: [PATCH bpf-next 0/9] Introduce BPF_MAP_TYPE_REUSEPORT_SOCKARRAY and BPF_PROG_TYPE_SK_REUSEPORT
From: Daniel Borkmann @ 2018-08-11 0:32 UTC (permalink / raw)
To: Martin KaFai Lau, netdev; +Cc: Alexei Starovoitov, kernel-team
In-Reply-To: <20180808075917.3009181-1-kafai@fb.com>
On 08/08/2018 09:59 AM, Martin KaFai Lau wrote:
> This series introduces a new map type "BPF_MAP_TYPE_REUSEPORT_SOCKARRAY"
> and a new prog type BPF_PROG_TYPE_SK_REUSEPORT.
>
> Here is a snippet from a commit message:
>
> "To unleash the full potential of a bpf prog, it is essential for the
> userspace to be capable of directly setting up a bpf map which can then
> be consumed by the bpf prog to make decision. In this case, decide which
> SO_REUSEPORT sk to serve the incoming request.
>
> By adding BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, the userspace has total control
> and visibility on where a SO_REUSEPORT sk should be located in a bpf map.
> The later patch will introduce BPF_PROG_TYPE_SK_REUSEPORT such that
> the bpf prog can directly select a sk from the bpf map. That will
> raise the programmability of the bpf prog attached to a reuseport
> group (a group of sk serving the same IP:PORT).
>
> For example, in UDP, the bpf prog can peek into the payload (e.g.
> through the "data" pointer introduced in the later patch) to learn
> the application level's connection information and then decide which sk
> to pick from a bpf map. The userspace can tightly couple the sk's location
> in a bpf map with the application logic in generating the UDP payload's
> connection information. This connection info contact/API stays within the
> userspace.
>
> Also, when used with map-in-map, the userspace can switch the
> old-server-process's inner map to a new-server-process's inner map
> in one call "bpf_map_update_elem(outer_map, &index, &new_reuseport_array)".
> The bpf prog will then direct incoming requests to the new process instead
> of the old process. The old process can finish draining the pending
> requests (e.g. by "accept()") before closing the old-fds. [Note that
> deleting a fd from a bpf map does not necessary mean the fd is closed]"
>
> Please see individual patch for details
>
> Martin KaFai Lau (9):
> tcp: Avoid TCP syncookie rejected by SO_REUSEPORT socket
> net: Add ID (if needed) to sock_reuseport and expose reuseport_lock
> bpf: Introduce BPF_MAP_TYPE_REUSEPORT_SOCKARRAY
> bpf: Introduce BPF_PROG_TYPE_SK_REUSEPORT
> bpf: Enable BPF_PROG_TYPE_SK_REUSEPORT bpf prog in reuseport selection
> bpf: Refactor ARRAY_SIZE macro to bpf_util.h
> bpf: Sync bpf.h uapi to tools/
> bpf: test BPF_MAP_TYPE_REUSEPORT_SOCKARRAY
> bpf: Test BPF_PROG_TYPE_SK_REUSEPORT
Applied to bpf-next, thanks Martin!
^ permalink raw reply
* [PATCH 2/2] net: nixge: Don't store skb in app4 field of descriptor
From: Moritz Fischer @ 2018-08-11 1:19 UTC (permalink / raw)
To: davem; +Cc: keescook, netdev, linux-kernel, alex.williams, Moritz Fischer
In-Reply-To: <20180811011941.6187-1-mdf@kernel.org>
Don't store skb in app4 field of descriptor since it is
not being used anywhere (including hardware).
Signed-off-by: Moritz Fischer <mdf@kernel.org>
---
drivers/net/ethernet/ni/nixge.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c
index ac31b0d30415..76efed058f33 100644
--- a/drivers/net/ethernet/ni/nixge.c
+++ b/drivers/net/ethernet/ni/nixge.c
@@ -503,7 +503,6 @@ static int nixge_start_xmit(struct sk_buff *skb, struct net_device *ndev)
tx_skb->skb = skb;
cur_p->cntrl |= XAXIDMA_BD_CTRL_TXEOF_MASK;
- cur_p->app4 = (unsigned long)skb;
tail_p = priv->tx_bd_p + sizeof(*priv->tx_bd_v) * priv->tx_bd_tail;
/* Start the transfer */
--
2.18.0
^ permalink raw reply related
* Re: [PATCH net-next v2] bnxt_en: Fix strcpy() warnings in bnxt_ethtool.c
From: David Miller @ 2018-08-11 2:13 UTC (permalink / raw)
To: michael.chan; +Cc: netdev, dan.carpenter, vasundhara-v.volam
In-Reply-To: <1533939883-23768-1-git-send-email-michael.chan@broadcom.com>
From: Michael Chan <michael.chan@broadcom.com>
Date: Fri, 10 Aug 2018 18:24:43 -0400
> From: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
>
> This patch fixes following smatch warnings:
>
> drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c:2826 bnxt_fill_coredump_seg_hdr() error: strcpy() '"sEgM"' too large for 'seg_hdr->signature' (5 vs 4)
> drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c:2858 bnxt_fill_coredump_record() error: strcpy() '"cOrE"' too large for 'record->signature' (5 vs 4)
> drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c:2879 bnxt_fill_coredump_record() error: strcpy() 'utsname()->sysname' too large for 'record->os_name' (65 vs 32)
>
> Fixes: 6c5657d085ae ("bnxt_en: Add support for ethtool get dump.")
> Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
> Signed-off-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>
That seems to make them all go away, applied, thanks!
^ permalink raw reply
* Re: [net-next 01/12] net/mlx5e: Ethtool steering flow validation refactoring
From: David Miller @ 2018-08-11 2:22 UTC (permalink / raw)
To: saeedm; +Cc: netdev
In-Reply-To: <20180810222630.11688-2-saeedm@mellanox.com>
From: Saeed Mahameed <saeedm@mellanox.com>
Date: Fri, 10 Aug 2018 15:26:19 -0700
> +static int validate_tcpudp4(struct ethtool_rx_flow_spec *fs)
> +{
> + struct ethtool_tcpip4_spec *l4_mask = &fs->m_u.tcp_ip4_spec;
> + int ntuples = 0;
> +
> + if (fs->m_u.tcp_ip4_spec.tos)
^^^^^^^^^^^^^^^^^^^^^^^^
Since you've gone to the trouble of loading this object into
l4_mask before this statement, please use "if (l4_mask->tos)"
I know you're just moving existing code into a function, but it
looks silly now.
^ permalink raw reply
* Re: [net-next 03/12] net/mlx5e: Ethtool steering, ip6 support
From: David Miller @ 2018-08-11 2:25 UTC (permalink / raw)
To: saeedm; +Cc: netdev
In-Reply-To: <20180810222630.11688-4-saeedm@mellanox.com>
From: Saeed Mahameed <saeedm@mellanox.com>
Date: Fri, 10 Aug 2018 15:26:21 -0700
> +static bool is_zero_ip6(__be32 ip6[4])
> +{
> + int i;
> +
> + for (i = 0; i < 4; i++)
> + if (ip6[i] != 0)
> + return false;
> + return true;
> +}
This is ipv6_addr_any().
^ permalink raw reply
* Re: [BUG] bpf: syscall: a possible sleep-in-atomic-context bug in map_update_elem()
From: Y Song @ 2018-08-11 5:01 UTC (permalink / raw)
To: Jia-Ju Bai
Cc: Daniel Borkmann, Alexei Starovoitov, netdev,
Linux Kernel Mailing List, Jesper Dangaard Brouer
In-Reply-To: <4f9a083d-1498-8cfb-b54c-614abccb193e@gmail.com>
On Fri, Aug 10, 2018 at 6:57 PM, Jia-Ju Bai <baijiaju1990@gmail.com> wrote:
>
>
> On 2018/8/10 22:22, Daniel Borkmann wrote:
>>
>> On 08/10/2018 04:07 PM, Jia-Ju Bai wrote:
>>>
>>> The kernel may sleep with holding a rcu read lock.
>>>
>>> The function call paths (from bottom to top) in Linux-4.16 are:
>>>
>>> [FUNC] kmalloc(GFP_KERNEL)
>>> kernel/kthread.c, 283: kmalloc in __kthread_create_on_node
>>> kernel/kthread.c, 365: __kthread_create_on_node in kthread_create_on_node
>>> kernel/bpf/cpumap.c, 368: kthread_create_on_node in __cpu_map_entry_alloc
>>> kernel/bpf/cpumap.c, 490: __cpu_map_entry_alloc in cpu_map_update_elem
>>> kernel/bpf/syscall.c, 724: [FUNC_PTR]cpu_map_update_elem in
>>> map_update_elem
>>> kernel/bpf/syscall.c, 723: rcu_read_lock in map_update_elem
>>>
>>> Note that [FUNC_PTR] means a function pointer call is used.
>>>
>>> I do not find a good way to fix it, so I only report.
>>> This is found by my static analysis tool (DSAC).
Maybe your static analysis tool have false positives in this case?
>>
>> Thanks for the report Jia-Ju! In the map_update_elem() from syscall
>> path there's a check map->map_type == BPF_MAP_TYPE_CPUMAP, where we
>> call the cpumap's map->ops->map_update_elem() while /not/ being under
>> rcu_read_lock() as in other cases, so looks okay to me. Could you point
>> out the case for being under rcu_read_lock() more specifically which
>> the tool found?
>
>
> Thanks for your reply :)
> My tool cannot accurately track the case of map->map_type at present...
>
> According to my code review, there is a indeed check on line 697 in
> Linux-4.16:
> else if (map->map_type == BPF_MAP_TYPE_CPUMAP) {
> err = map->ops->map_update_elem(map, key, value, attr->flags);
> goto out;
> }
> But there is a call to map->ops->map_update_elem() that is under
> rcu_read_lock on line 724:
> rcu_read_lock();
> err = map->ops->map_update_elem(map, key, value, attr->flags);
> rcu_read_unlock();
>
> So I think if map->map_type is not equal to BPF_MAP_TYPE_CPUMAP,
> map->ops->map_update_elem() can still be called under rcu_read_lock, is it
> right?
map->ops->map_update_elem() can be called under rcu_read_lock(), but
since it is not type cpumap, the function should not be cpu_map_update_elem().
Could you double check your static analysis tool?
>
>
> Best wishes,
> Jia-Ju Bai
^ permalink raw reply
* [PATCH bpf-next 0/4] bpf_skb_ancestor_cgroup_id helper
From: Andrey Ignatov @ 2018-08-11 5:35 UTC (permalink / raw)
To: netdev; +Cc: Andrey Ignatov, ast, daniel, tj, guro, kernel-team
This patch set adds new BPF helper bpf_skb_ancestor_cgroup_id that returns
id of cgroup v2 that is ancestor of cgroup associated with the skb at the
ancestor_level.
The helper is useful to implement policies in TC based on cgroups that are
upper in hierarchy than immediate cgroup associated with skb.
Patch 0001 provides more details and describes use-cases.
Patch 0002 syncs UAPI changes to tools/.
Patch 0003 adds skb*cgroup_id helpers to bpf_helper.h header.
Patch 0004 adds selftest for the new helper and is an example of usage.
Andrey Ignatov (4):
bpf: Introduce bpf_skb_ancestor_cgroup_id helper
bpf: Sync bpf.h to tools/
selftests/bpf: Add cgroup id helpers to bpf_helpers.h
selftests/bpf: Selftest for bpf_skb_ancestor_cgroup_id
include/linux/cgroup.h | 30 +++
include/uapi/linux/bpf.h | 21 +-
net/core/filter.c | 28 +++
tools/include/uapi/linux/bpf.h | 21 +-
tools/testing/selftests/bpf/Makefile | 9 +-
tools/testing/selftests/bpf/bpf_helpers.h | 4 +
.../selftests/bpf/test_skb_cgroup_id.sh | 61 ++++++
.../selftests/bpf/test_skb_cgroup_id_kern.c | 47 +++++
.../selftests/bpf/test_skb_cgroup_id_user.c | 187 ++++++++++++++++++
9 files changed, 403 insertions(+), 5 deletions(-)
create mode 100755 tools/testing/selftests/bpf/test_skb_cgroup_id.sh
create mode 100644 tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
create mode 100644 tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
--
2.17.1
^ permalink raw reply
* [PATCH bpf-next 1/4] bpf: Introduce bpf_skb_ancestor_cgroup_id helper
From: Andrey Ignatov @ 2018-08-11 5:35 UTC (permalink / raw)
To: netdev; +Cc: Andrey Ignatov, ast, daniel, tj, guro, kernel-team
In-Reply-To: <cover.1533965421.git.rdna@fb.com>
== Problem description ==
It's useful to be able to identify cgroup associated with skb in TC so
that a policy can be applied to this skb, and existing bpf_skb_cgroup_id
helper can help with this.
Though in real life cgroup hierarchy and hierarchy to apply a policy to
don't map 1:1.
It's often the case that there is a container and corresponding cgroup,
but there are many more sub-cgroups inside container, e.g. because it's
delegated to containerized application to control resources for its
subsystems, or to separate application inside container from infra that
belongs to containerization system (e.g. sshd).
At the same time it may be useful to apply a policy to container as a
whole.
If multiple containers like this are run on a host (what is often the
case) and many of them have sub-cgroups, it may not be possible to apply
per-container policy in TC with existing helpers such as
bpf_skb_under_cgroup or bpf_skb_cgroup_id:
* bpf_skb_cgroup_id will return id of immediate cgroup associated with
skb, i.e. if it's a sub-cgroup inside container, it can't be used to
identify container's cgroup;
* bpf_skb_under_cgroup can work only with one cgroup and doesn't scale,
i.e. if there are N containers on a host and a policy has to be
applied to M of them (0 <= M <= N), it'd require M calls to
bpf_skb_under_cgroup, and, if M changes, it'd require to rebuild &
load new BPF program.
== Solution ==
The patch introduces new helper bpf_skb_ancestor_cgroup_id that can be
used to get id of cgroup v2 that is an ancestor of cgroup associated
with skb at specified level of cgroup hierarchy.
That way admin can place all containers on one level of cgroup hierarchy
(what is a good practice in general and already used in many
configurations) and identify specific cgroup on this level no matter
what sub-cgroup skb is associated with.
E.g. if there is a cgroup hierarchy:
root/
root/container1/
root/container1/app11/
root/container1/app11/sub-app-a/
root/container1/app12/
root/container2/
root/container2/app21/
root/container2/app22/
root/container2/app22/sub-app-b/
, then having skb associated with root/container1/app11/sub-app-a/ it's
possible to get ancestor at level 1, what is container1 and apply policy
for this container, or apply another policy if it's container2.
Policies can be kept e.g. in a hash map where key is a container cgroup
id and value is an action.
Levels where container cgroups are created are usually known in advance
whether cgroup hierarchy inside container may be hard to predict
especially in case when its creation is delegated to containerized
application.
== Implementation details ==
The helper gets ancestor by walking parents up to specified level.
Another option would be to get different kind of "id" from
cgroup->ancestor_ids[level] and use it with idr_find() to get struct
cgroup for ancestor. But that would require radix lookup what doesn't
seem to be better (at least it's not obviously better).
Format of return value of the new helper is same as that of
bpf_skb_cgroup_id.
Signed-off-by: Andrey Ignatov <rdna@fb.com>
---
include/linux/cgroup.h | 30 ++++++++++++++++++++++++++++++
include/uapi/linux/bpf.h | 21 ++++++++++++++++++++-
net/core/filter.c | 28 ++++++++++++++++++++++++++++
3 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index c9fdf6f57913..32c553556bbd 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -553,6 +553,36 @@ static inline bool cgroup_is_descendant(struct cgroup *cgrp,
return cgrp->ancestor_ids[ancestor->level] == ancestor->id;
}
+/**
+ * cgroup_ancestor - find ancestor of cgroup
+ * @cgrp: cgroup to find ancestor of
+ * @ancestor_level: level of ancestor to find starting from root
+ *
+ * Find ancestor of cgroup at specified level starting from root if it exists
+ * and return pointer to it. Return NULL if @cgrp doesn't have ancestor at
+ * @ancestor_level.
+ *
+ * This function is safe to call as long as @cgrp is accessible.
+ */
+static inline struct cgroup *cgroup_ancestor(struct cgroup *cgrp,
+ int ancestor_level)
+{
+ struct cgroup *ptr;
+
+ if (cgrp->level < ancestor_level)
+ return NULL;
+
+ for (ptr = cgrp;
+ ptr && ptr->level > ancestor_level;
+ ptr = cgroup_parent(ptr))
+ ;
+
+ if (ptr && ptr->level == ancestor_level)
+ return ptr;
+
+ return NULL;
+}
+
/**
* task_under_cgroup_hierarchy - test task's membership of cgroup ancestry
* @task: the task to be tested
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 3102a2a23c31..66917a4eba27 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -2093,6 +2093,24 @@ union bpf_attr {
* Return
* The id is returned or 0 in case the id could not be retrieved.
*
+ * u64 bpf_skb_ancestor_cgroup_id(struct sk_buff *skb, int ancestor_level)
+ * Description
+ * Return id of cgroup v2 that is ancestor of cgroup associated
+ * with the *skb* at the *ancestor_level*. The root cgroup is at
+ * *ancestor_level* zero and each step down the hierarchy
+ * increments the level. If *ancestor_level* == level of cgroup
+ * associated with *skb*, then return value will be same as that
+ * of **bpf_skb_cgroup_id**\ ().
+ *
+ * The helper is useful to implement policies based on cgroups
+ * that are upper in hierarchy than immediate cgroup associated
+ * with *skb*.
+ *
+ * The format of returned id and helper limitations are same as in
+ * **bpf_skb_cgroup_id**\ ().
+ * Return
+ * The id is returned or 0 in case the id could not be retrieved.
+ *
* u64 bpf_get_current_cgroup_id(void)
* Return
* A 64-bit integer containing the current cgroup id based
@@ -2207,7 +2225,8 @@ union bpf_attr {
FN(skb_cgroup_id), \
FN(get_current_cgroup_id), \
FN(get_local_storage), \
- FN(sk_select_reuseport),
+ FN(sk_select_reuseport), \
+ FN(skb_ancestor_cgroup_id),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
diff --git a/net/core/filter.c b/net/core/filter.c
index 22906b31d43f..15b9d2df92ca 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3778,6 +3778,32 @@ static const struct bpf_func_proto bpf_skb_cgroup_id_proto = {
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
};
+
+BPF_CALL_2(bpf_skb_ancestor_cgroup_id, const struct sk_buff *, skb, int,
+ ancestor_level)
+{
+ struct sock *sk = skb_to_full_sk(skb);
+ struct cgroup *ancestor;
+ struct cgroup *cgrp;
+
+ if (!sk || !sk_fullsock(sk))
+ return 0;
+
+ cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
+ ancestor = cgroup_ancestor(cgrp, ancestor_level);
+ if (!ancestor)
+ return 0;
+
+ return ancestor->kn->id.id;
+}
+
+static const struct bpf_func_proto bpf_skb_ancestor_cgroup_id_proto = {
+ .func = bpf_skb_ancestor_cgroup_id,
+ .gpl_only = false,
+ .ret_type = RET_INTEGER,
+ .arg1_type = ARG_PTR_TO_CTX,
+ .arg2_type = ARG_ANYTHING,
+};
#endif
static unsigned long bpf_xdp_copy(void *dst_buff, const void *src_buff,
@@ -4966,6 +4992,8 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
#ifdef CONFIG_SOCK_CGROUP_DATA
case BPF_FUNC_skb_cgroup_id:
return &bpf_skb_cgroup_id_proto;
+ case BPF_FUNC_skb_ancestor_cgroup_id:
+ return &bpf_skb_ancestor_cgroup_id_proto;
#endif
default:
return bpf_base_func_proto(func_id);
--
2.17.1
^ permalink raw reply related
* [PATCH bpf-next 3/4] selftests/bpf: Add cgroup id helpers to bpf_helpers.h
From: Andrey Ignatov @ 2018-08-11 5:35 UTC (permalink / raw)
To: netdev; +Cc: Andrey Ignatov, ast, daniel, tj, guro, kernel-team
In-Reply-To: <cover.1533965421.git.rdna@fb.com>
Add bpf_skb_cgroup_id and bpf_skb_ancestor_cgroup_id helpers to
bpf_helpers.h to use them in tests and samples.
Signed-off-by: Andrey Ignatov <rdna@fb.com>
---
tools/testing/selftests/bpf/bpf_helpers.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 5c32266c2c38..e4be7730222d 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -139,6 +139,10 @@ static unsigned long long (*bpf_get_current_cgroup_id)(void) =
(void *) BPF_FUNC_get_current_cgroup_id;
static void *(*bpf_get_local_storage)(void *map, unsigned long long flags) =
(void *) BPF_FUNC_get_local_storage;
+static unsigned long long (*bpf_skb_cgroup_id)(void *ctx) =
+ (void *) BPF_FUNC_skb_cgroup_id;
+static unsigned long long (*bpf_skb_ancestor_cgroup_id)(void *ctx, int level) =
+ (void *) BPF_FUNC_skb_ancestor_cgroup_id;
/* llvm builtin functions that eBPF C program may use to
* emit BPF_LD_ABS and BPF_LD_IND instructions
--
2.17.1
^ permalink raw reply related
* [PATCH bpf-next 2/4] bpf: Sync bpf.h to tools/
From: Andrey Ignatov @ 2018-08-11 5:35 UTC (permalink / raw)
To: netdev; +Cc: Andrey Ignatov, ast, daniel, tj, guro, kernel-team
In-Reply-To: <cover.1533965421.git.rdna@fb.com>
Sync skb_ancestor_cgroup_id() related bpf UAPI changes to tools/.
Signed-off-by: Andrey Ignatov <rdna@fb.com>
---
tools/include/uapi/linux/bpf.h | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 3102a2a23c31..66917a4eba27 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -2093,6 +2093,24 @@ union bpf_attr {
* Return
* The id is returned or 0 in case the id could not be retrieved.
*
+ * u64 bpf_skb_ancestor_cgroup_id(struct sk_buff *skb, int ancestor_level)
+ * Description
+ * Return id of cgroup v2 that is ancestor of cgroup associated
+ * with the *skb* at the *ancestor_level*. The root cgroup is at
+ * *ancestor_level* zero and each step down the hierarchy
+ * increments the level. If *ancestor_level* == level of cgroup
+ * associated with *skb*, then return value will be same as that
+ * of **bpf_skb_cgroup_id**\ ().
+ *
+ * The helper is useful to implement policies based on cgroups
+ * that are upper in hierarchy than immediate cgroup associated
+ * with *skb*.
+ *
+ * The format of returned id and helper limitations are same as in
+ * **bpf_skb_cgroup_id**\ ().
+ * Return
+ * The id is returned or 0 in case the id could not be retrieved.
+ *
* u64 bpf_get_current_cgroup_id(void)
* Return
* A 64-bit integer containing the current cgroup id based
@@ -2207,7 +2225,8 @@ union bpf_attr {
FN(skb_cgroup_id), \
FN(get_current_cgroup_id), \
FN(get_local_storage), \
- FN(sk_select_reuseport),
+ FN(sk_select_reuseport), \
+ FN(skb_ancestor_cgroup_id),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
--
2.17.1
^ permalink raw reply related
* [PATCH bpf-next 4/4] selftests/bpf: Selftest for bpf_skb_ancestor_cgroup_id
From: Andrey Ignatov @ 2018-08-11 5:35 UTC (permalink / raw)
To: netdev; +Cc: Andrey Ignatov, ast, daniel, tj, guro, kernel-team
In-Reply-To: <cover.1533965421.git.rdna@fb.com>
Add selftests for bpf_skb_ancestor_cgroup_id helper.
test_skb_cgroup_id.sh prepares testing interface and adds tc qdisc and
filter for it using BPF object compiled from test_skb_cgroup_id_kern.c
program.
BPF program in test_skb_cgroup_id_kern.c gets ancestor cgroup id using
the new helper at different levels of cgroup hierarchy that skb belongs
to, including root level and non-existing level, and saves it to the map
where the key is the level of corresponding cgroup and the value is its
id.
To trigger BPF program, user space program test_skb_cgroup_id_user is
run. It adds itself into testing cgroup and sends UDP datagram to
link-local multicast address of testing interface. Then it reads cgroup
ids saved in kernel for different levels from the BPF map and compares
them with those in user space. They must be equal for every level of
ancestry.
Example of run:
# ./test_skb_cgroup_id.sh
Wait for testing link-local IP to become available ... OK
Note: 8 bytes struct bpf_elf_map fixup performed due to size mismatch!
[PASS]
Signed-off-by: Andrey Ignatov <rdna@fb.com>
---
tools/testing/selftests/bpf/Makefile | 9 +-
.../selftests/bpf/test_skb_cgroup_id.sh | 61 ++++++
.../selftests/bpf/test_skb_cgroup_id_kern.c | 47 +++++
.../selftests/bpf/test_skb_cgroup_id_user.c | 187 ++++++++++++++++++
4 files changed, 301 insertions(+), 3 deletions(-)
create mode 100755 tools/testing/selftests/bpf/test_skb_cgroup_id.sh
create mode 100644 tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
create mode 100644 tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index daed162043c2..fff7fb1285fc 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -34,7 +34,8 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o test_tunnel_kern.o \
test_get_stack_rawtp.o test_sockmap_kern.o test_sockhash_kern.o \
test_lwt_seg6local.o sendmsg4_prog.o sendmsg6_prog.o test_lirc_mode2_kern.o \
- get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o
+ get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o \
+ test_skb_cgroup_id_kern.o
# Order correspond to 'make run_tests' order
TEST_PROGS := test_kmod.sh \
@@ -45,10 +46,11 @@ TEST_PROGS := test_kmod.sh \
test_sock_addr.sh \
test_tunnel.sh \
test_lwt_seg6local.sh \
- test_lirc_mode2.sh
+ test_lirc_mode2.sh \
+ test_skb_cgroup_id.sh
# Compile but not part of 'make run_tests'
-TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr
+TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr test_skb_cgroup_id_user
include ../lib.mk
@@ -59,6 +61,7 @@ $(TEST_GEN_PROGS): $(BPFOBJ)
$(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/libbpf.a
$(OUTPUT)/test_dev_cgroup: cgroup_helpers.c
+$(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c
$(OUTPUT)/test_sock: cgroup_helpers.c
$(OUTPUT)/test_sock_addr: cgroup_helpers.c
$(OUTPUT)/test_socket_cookie: cgroup_helpers.c
diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id.sh b/tools/testing/selftests/bpf/test_skb_cgroup_id.sh
new file mode 100755
index 000000000000..b75e9b52f06f
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_skb_cgroup_id.sh
@@ -0,0 +1,61 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2018 Facebook
+
+set -eu
+
+wait_for_ip()
+{
+ local _i
+ echo -n "Wait for testing link-local IP to become available "
+ for _i in $(seq ${MAX_PING_TRIES}); do
+ echo -n "."
+ if ping -6 -q -c 1 -W 1 ff02::1%${TEST_IF} >/dev/null 2>&1; then
+ echo " OK"
+ return
+ fi
+ done
+ echo 1>&2 "ERROR: Timeout waiting for test IP to become available."
+ exit 1
+}
+
+setup()
+{
+ # Create testing interfaces not to interfere with current environment.
+ ip link add dev ${TEST_IF} type veth peer name ${TEST_IF_PEER}
+ ip link set ${TEST_IF} up
+ ip link set ${TEST_IF_PEER} up
+
+ wait_for_ip
+
+ tc qdisc add dev ${TEST_IF} clsact
+ tc filter add dev ${TEST_IF} egress bpf obj ${BPF_PROG_OBJ} \
+ sec ${BPF_PROG_SECTION} da
+
+ BPF_PROG_ID=$(tc filter show dev ${TEST_IF} egress | \
+ awk '/ id / {sub(/.* id /, "", $0); print($1)}')
+}
+
+cleanup()
+{
+ ip link del ${TEST_IF} 2>/dev/null || :
+ ip link del ${TEST_IF_PEER} 2>/dev/null || :
+}
+
+main()
+{
+ trap cleanup EXIT 2 3 6 15
+ setup
+ ${PROG} ${TEST_IF} ${BPF_PROG_ID}
+}
+
+DIR=$(dirname $0)
+TEST_IF="test_cgid_1"
+TEST_IF_PEER="test_cgid_2"
+MAX_PING_TRIES=5
+BPF_PROG_OBJ="${DIR}/test_skb_cgroup_id_kern.o"
+BPF_PROG_SECTION="cgroup_id_logger"
+BPF_PROG_ID=0
+PROG="${DIR}/test_skb_cgroup_id_user"
+
+main
diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c b/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
new file mode 100644
index 000000000000..68cf9829f5a7
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_skb_cgroup_id_kern.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Facebook
+
+#include <linux/bpf.h>
+#include <linux/pkt_cls.h>
+
+#include <string.h>
+
+#include "bpf_helpers.h"
+
+#define NUM_CGROUP_LEVELS 4
+
+struct bpf_map_def SEC("maps") cgroup_ids = {
+ .type = BPF_MAP_TYPE_ARRAY,
+ .key_size = sizeof(__u32),
+ .value_size = sizeof(__u64),
+ .max_entries = NUM_CGROUP_LEVELS,
+};
+
+static __always_inline void log_nth_level(struct __sk_buff *skb, __u32 level)
+{
+ __u64 id;
+
+ /* [1] &level passed to external function that may change it, it's
+ * incompatible with loop unroll.
+ */
+ id = bpf_skb_ancestor_cgroup_id(skb, level);
+ bpf_map_update_elem(&cgroup_ids, &level, &id, 0);
+}
+
+SEC("cgroup_id_logger")
+int log_cgroup_id(struct __sk_buff *skb)
+{
+ /* Loop unroll can't be used here due to [1]. Unrolling manually.
+ * Number of calls should be in sync with NUM_CGROUP_LEVELS.
+ */
+ log_nth_level(skb, 0);
+ log_nth_level(skb, 1);
+ log_nth_level(skb, 2);
+ log_nth_level(skb, 3);
+
+ return TC_ACT_OK;
+}
+
+int _version SEC("version") = 1;
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c b/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
new file mode 100644
index 000000000000..c121cc59f314
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_skb_cgroup_id_user.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018 Facebook
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+
+#include <bpf/bpf.h>
+#include <bpf/libbpf.h>
+
+#include "bpf_rlimit.h"
+#include "cgroup_helpers.h"
+
+#define CGROUP_PATH "/skb_cgroup_test"
+#define NUM_CGROUP_LEVELS 4
+
+/* RFC 4291, Section 2.7.1 */
+#define LINKLOCAL_MULTICAST "ff02::1"
+
+static int mk_dst_addr(const char *ip, const char *iface,
+ struct sockaddr_in6 *dst)
+{
+ memset(dst, 0, sizeof(*dst));
+
+ dst->sin6_family = AF_INET6;
+ dst->sin6_port = htons(1025);
+
+ if (inet_pton(AF_INET6, ip, &dst->sin6_addr) != 1) {
+ log_err("Invalid IPv6: %s", ip);
+ return -1;
+ }
+
+ dst->sin6_scope_id = if_nametoindex(iface);
+ if (!dst->sin6_scope_id) {
+ log_err("Failed to get index of iface: %s", iface);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int send_packet(const char *iface)
+{
+ struct sockaddr_in6 dst;
+ char msg[] = "msg";
+ int err = 0;
+ int fd = -1;
+
+ if (mk_dst_addr(LINKLOCAL_MULTICAST, iface, &dst))
+ goto err;
+
+ fd = socket(AF_INET6, SOCK_DGRAM, 0);
+ if (fd == -1) {
+ log_err("Failed to create UDP socket");
+ goto err;
+ }
+
+ if (sendto(fd, &msg, sizeof(msg), 0, (const struct sockaddr *)&dst,
+ sizeof(dst)) == -1) {
+ log_err("Failed to send datagram");
+ goto err;
+ }
+
+ goto out;
+err:
+ err = -1;
+out:
+ if (fd >= 0)
+ close(fd);
+ return err;
+}
+
+int get_map_fd_by_prog_id(int prog_id)
+{
+ struct bpf_prog_info info = {};
+ __u32 info_len = sizeof(info);
+ __u32 map_ids[1];
+ int prog_fd = -1;
+ int map_fd = -1;
+
+ prog_fd = bpf_prog_get_fd_by_id(prog_id);
+ if (prog_fd < 0) {
+ log_err("Failed to get fd by prog id %d", prog_id);
+ goto err;
+ }
+
+ info.nr_map_ids = 1;
+ info.map_ids = (__u64) (unsigned long) map_ids;
+
+ if (bpf_obj_get_info_by_fd(prog_fd, &info, &info_len)) {
+ log_err("Failed to get info by prog fd %d", prog_fd);
+ goto err;
+ }
+
+ if (!info.nr_map_ids) {
+ log_err("No maps found for prog fd %d", prog_fd);
+ goto err;
+ }
+
+ map_fd = bpf_map_get_fd_by_id(map_ids[0]);
+ if (map_fd < 0)
+ log_err("Failed to get fd by map id %d", map_ids[0]);
+err:
+ if (prog_fd >= 0)
+ close(prog_fd);
+ return map_fd;
+}
+
+int check_ancestor_cgroup_ids(int prog_id)
+{
+ __u64 actual_ids[NUM_CGROUP_LEVELS], expected_ids[NUM_CGROUP_LEVELS];
+ __u32 level;
+ int err = 0;
+ int map_fd;
+
+ expected_ids[0] = 0x100000001; /* root cgroup */
+ expected_ids[1] = get_cgroup_id("");
+ expected_ids[2] = get_cgroup_id(CGROUP_PATH);
+ expected_ids[3] = 0; /* non-existent cgroup */
+
+ map_fd = get_map_fd_by_prog_id(prog_id);
+ if (map_fd < 0)
+ goto err;
+
+ for (level = 0; level < NUM_CGROUP_LEVELS; ++level) {
+ if (bpf_map_lookup_elem(map_fd, &level, &actual_ids[level])) {
+ log_err("Failed to lookup key %d", level);
+ goto err;
+ }
+ if (actual_ids[level] != expected_ids[level]) {
+ log_err("%llx (actual) != %llx (expected), level: %u\n",
+ actual_ids[level], expected_ids[level], level);
+ goto err;
+ }
+ }
+
+ goto out;
+err:
+ err = -1;
+out:
+ if (map_fd >= 0)
+ close(map_fd);
+ return err;
+}
+
+int main(int argc, char **argv)
+{
+ int cgfd = -1;
+ int err = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s iface prog_id\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ if (setup_cgroup_environment())
+ goto err;
+
+ cgfd = create_and_get_cgroup(CGROUP_PATH);
+ if (!cgfd)
+ goto err;
+
+ if (join_cgroup(CGROUP_PATH))
+ goto err;
+
+ if (send_packet(argv[1]))
+ goto err;
+
+ if (check_ancestor_cgroup_ids(atoi(argv[2])))
+ goto err;
+
+ goto out;
+err:
+ err = -1;
+out:
+ close(cgfd);
+ cleanup_cgroup_environment();
+ printf("[%s]\n", err ? "FAIL" : "PASS");
+ return err;
+}
--
2.17.1
^ permalink raw reply related
* Re: [PATCH bpf-next 0/4] Convert filter.txt to RST
From: Tobin C. Harding @ 2018-08-11 11:50 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Jonathan Corbet, Daniel Borkmann, Alexei Starovoitov,
David S. Miller, Kees Cook, Andy Lutomirski, Will Drewry,
linux-doc, Network Development, LKML
In-Reply-To: <CAADnVQL-ekJXQoP+Peuh1uBJ1RGxMJ0G0DVp-UoGcWOY9BATeQ@mail.gmail.com>
On Fri, Aug 10, 2018 at 10:51:28AM -0700, Alexei Starovoitov wrote:
> On Fri, Aug 10, 2018 at 5:57 AM Jonathan Corbet <corbet@lwn.net> wrote:
> >
> > The objective actually is to have SPDX tags in all files in the kernel.
> > That includes documentation, even though people, as always, care less
> > about the docs than they do the code.
>
> right, but let's do that as a separate patch set.
> In the current set I'd focus on reviewing the actual doc changes.
> In particular completely removing
> Documentation/networking/filter.txt
> feels wrong, since lots of websites point directly there.
> Can we have at least few words there pointing to new location?
Something like ...
------------ filter.txt
BPF documentation can now be found in the following places:
- Introduction to BPF (Linux Socket Filter) - Documentation/userspace-api/socket-filter.rst
- Classic BPF (cBPF) - Documentation/userspace-api/cBPF.rst
- Internal BPF (eBPF) - Documentation/userspace-api/eBPF.rst
- SECCOMP BPF - Documentation/userspace-api/seccomp_filter.rst
- BPF Design Q&A - Documentation/bpf/bpf_design_QA.rst
- BPF Development Q&A - Documentation/bpf/bpf_devel_QA.rst
-------------
Also this highlights that bpf/index.rst is not quite correct yet in this
set. The Q&A files are indexed but not explicitly mentioned. My
feeling is that bpf/index.rst should mirror the information above.
thanks,
Tobin.
^ permalink raw reply
* the photos is what you need
From: Jeff @ 2018-08-11 7:28 UTC (permalink / raw)
To: netdev
We would like to check if your photos need editing. We can do it for you.
Our image editing is for web store photos, jewelries images and beauty and
portrait photos etc.
It is including cut out and clipping path , and also retouching if it is
needed.
We can do test on your photos. Just send us a photo we will start to work
on it,
Thanks,
Jeff Allen
^ permalink raw reply
* imaging you need
From: Jeff @ 2018-08-11 7:15 UTC (permalink / raw)
To: netdev
We would like to check if your photos need editing. We can do it for you.
Our image editing is for web store photos, jewelries images and beauty and
portrait photos etc.
It is including cut out and clipping path , and also retouching if it is
needed.
We can do test on your photos. Just send us a photo we will start to work
on it,
Thanks,
Jeff Allen
^ permalink raw reply
* drivers/net/ethernet/atheros/atlx/atl2.c uses dead MODULE_PARM
From: Robert P. J. Day @ 2018-08-11 10:05 UTC (permalink / raw)
To: Linux kernel netdev mailing list; +Cc: jcliburn, chris.snook
just noticed this in that ATLX source file:
#ifndef module_param_array
/* Module Parameters are always initialized to -1, so that the driver
* can tell the difference between no user specified value or the
* user asking for the default value.
* The true default values are loaded in when atl2_check_options is called.
*
* This is a GCC extension to ANSI C.
* See the item "Labeled Elements in Initializers" in the section
* "Extensions to the C Language Family" of the GCC documentation.
*/
#define ATL2_PARAM(X, desc) \
static const int X[ATL2_MAX_NIC + 1] = ATL2_PARAM_INIT; \
MODULE_PARM(X, "1-" __MODULE_STRING(ATL2_MAX_NIC) "i"); \
... snip ...
the macro "MODULE_PARM" isn't even defined anymore, so that usage of
MODULE_PARM is not going to work well if the C preprocessor ever gets
ahold of it.
rday
--
========================================================================
Robert P. J. Day Ottawa, Ontario, CANADA
http://crashcourse.ca/dokuwiki
Twitter: http://twitter.com/rpjday
LinkedIn: http://ca.linkedin.com/in/rpjday
========================================================================
^ permalink raw reply
* Re: [net-next 03/12] net/mlx5e: Ethtool steering, ip6 support
From: Or Gerlitz @ 2018-08-11 11:53 UTC (permalink / raw)
To: Saeed Mahameed; +Cc: David S. Miller, Linux Netdev List
In-Reply-To: <20180810222630.11688-4-saeedm@mellanox.com>
On Sat, Aug 11, 2018 at 1:26 AM, Saeed Mahameed <saeedm@mellanox.com> wrote:
> Add ip6 support for ethtool flow steering.
>
> New supported flow types: ip6|tcp6|udp6|
> Supported fields: src-ip|dst-ip|src-port|dst-port
>
> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
> ---
> .../mellanox/mlx5/core/en_fs_ethtool.c | 138 ++++++++++++++++++
> 1 file changed, 138 insertions(+)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
> index f2fa189adc4f..646b659fe805 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
> @@ -66,11 +66,14 @@ static struct mlx5e_ethtool_table *get_flow_table(struct mlx5e_priv *priv,
> switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {
> case TCP_V4_FLOW:
> case UDP_V4_FLOW:
> + case TCP_V6_FLOW:
> + case UDP_V6_FLOW:
> max_tuples = ETHTOOL_NUM_L3_L4_FTS;
> prio = MLX5E_ETHTOOL_L3_L4_PRIO + (max_tuples - num_tuples);
> eth_ft = &priv->fs.ethtool.l3_l4_ft[prio];
> break;
> case IP_USER_FLOW:
> + case IPV6_USER_FLOW:
> max_tuples = ETHTOOL_NUM_L3_L4_FTS;
> prio = MLX5E_ETHTOOL_L3_L4_PRIO + (max_tuples - num_tuples);
> eth_ft = &priv->fs.ethtool.l3_l4_ft[prio];
> @@ -142,6 +145,39 @@ set_ip4(void *headers_c, void *headers_v, __be32 ip4src_m,
> MLX5E_FTE_SET(headers_v, ethertype, ETH_P_IP);
> }
>
> +static bool is_zero_ip6(__be32 ip6[4])
> +{
> + int i;
> +
> + for (i = 0; i < 4; i++)
> + if (ip6[i] != 0)
> + return false;
> + return true;
> +}
> +
> +static void
> +set_ip6(void *headers_c, void *headers_v, __be32 ip6src_m[4],
> + __be32 ip6src_v[4], __be32 ip6dst_m[4], __be32 ip6dst_v[4])
> +{
> + u8 ip6_sz = MLX5_FLD_SZ_BYTES(ipv6_layout, ipv6);
> +
> + if (!is_zero_ip6(ip6src_m)) {
> + memcpy(MLX5E_FTE_ADDR_OF(headers_v, src_ipv4_src_ipv6.ipv6_layout.ipv6),
> + ip6src_v, ip6_sz);
> + memset(MLX5E_FTE_ADDR_OF(headers_c, src_ipv4_src_ipv6.ipv6_layout.ipv6),
> + 0xff, ip6_sz);
ip6src_m is the mask provided by the user, right? so why not use it
instead of all-one (0xffs)?
^ permalink raw reply
* [PATCH 1/2] 9p: rename p9_free_req() function
From: Tomas Bortoli @ 2018-08-11 14:42 UTC (permalink / raw)
To: asmadeus, ericvh, rminnich, lucho
Cc: davem, v9fs-developer, netdev, linux-kernel, syzkaller,
Tomas Bortoli, Dominique Martinet
In sight of the next patch to add a refcount in p9_req_t, rename
the p9_free_req() function in p9_release_req().
In the next patch the actual kfree will be moved to another function.
Signed-off-by: Tomas Bortoli <tomasbortoli@gmail.com>
Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
---
net/9p/client.c | 100 ++++++++++++++++++++++++++++----------------------------
1 file changed, 50 insertions(+), 50 deletions(-)
diff --git a/net/9p/client.c b/net/9p/client.c
index 6c57ab1294d7..7942c0bfcc5b 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -344,13 +344,13 @@ struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
EXPORT_SYMBOL(p9_tag_lookup);
/**
- * p9_free_req - Free a request.
+ * p9_tag_remove - Remove a tag.
* @c: Client session.
- * @r: Request to free.
+ * @r: Request of reference.
*
* Context: Any context.
*/
-static void p9_free_req(struct p9_client *c, struct p9_req_t *r)
+static void p9_tag_remove(struct p9_client *c, struct p9_req_t *r)
{
unsigned long flags;
u16 tag = r->tc.tag;
@@ -379,7 +379,7 @@ static void p9_tag_cleanup(struct p9_client *c)
rcu_read_lock();
idr_for_each_entry(&c->reqs, req, id) {
pr_info("Tag %d still in use\n", id);
- p9_free_req(c, req);
+ p9_tag_remove(c, req);
}
rcu_read_unlock();
}
@@ -647,7 +647,7 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
if (c->trans_mod->cancelled)
c->trans_mod->cancelled(c, oldreq);
- p9_free_req(c, req);
+ p9_tag_remove(c, req);
return 0;
}
@@ -681,7 +681,7 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
trace_9p_client_req(c, type, req->tc.tag);
return req;
reterr:
- p9_free_req(c, req);
+ p9_tag_remove(c, req);
return ERR_PTR(err);
}
@@ -691,7 +691,7 @@ static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
* @type: type of request
* @fmt: protocol format string (see protocol.c)
*
- * Returns request structure (which client must free using p9_free_req)
+ * Returns request structure (which client must free using p9_tag_remove)
*/
static struct p9_req_t *
@@ -767,7 +767,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
if (!err)
return req;
reterr:
- p9_free_req(c, req);
+ p9_tag_remove(c, req);
return ERR_PTR(safe_errno(err));
}
@@ -782,7 +782,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
* @hdrlen: reader header size, This is the size of response protocol data
* @fmt: protocol format string (see protocol.c)
*
- * Returns request structure (which client must free using p9_free_req)
+ * Returns request structure (which client must free using p9_tag_remove)
*/
static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
struct iov_iter *uidata,
@@ -849,7 +849,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
if (!err)
return req;
reterr:
- p9_free_req(c, req);
+ p9_tag_remove(c, req);
return ERR_PTR(safe_errno(err));
}
@@ -952,7 +952,7 @@ static int p9_client_version(struct p9_client *c)
error:
kfree(version);
- p9_free_req(c, req);
+ p9_tag_remove(c, req);
return err;
}
@@ -1094,7 +1094,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
err = p9pdu_readf(&req->rc, clnt->proto_version, "Q", &qid);
if (err) {
trace_9p_protocol_dump(clnt, &req->rc);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
goto error;
}
@@ -1103,7 +1103,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
memmove(&fid->qid, &qid, sizeof(struct p9_qid));
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
return fid;
error:
@@ -1151,10 +1151,10 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
err = p9pdu_readf(&req->rc, clnt->proto_version, "R", &nwqids, &wqids);
if (err) {
trace_9p_protocol_dump(clnt, &req->rc);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
goto clunk_fid;
}
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
p9_debug(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids);
@@ -1229,7 +1229,7 @@ int p9_client_open(struct p9_fid *fid, int mode)
fid->iounit = iounit;
free_and_error:
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
}
@@ -1274,7 +1274,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32
ofid->iounit = iounit;
free_and_error:
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
}
@@ -1319,7 +1319,7 @@ int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
fid->iounit = iounit;
free_and_error:
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
}
@@ -1353,7 +1353,7 @@ int p9_client_symlink(struct p9_fid *dfid, const char *name,
qid->type, (unsigned long long)qid->path, qid->version);
free_and_error:
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
}
@@ -1373,7 +1373,7 @@ int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, const char *newna
return PTR_ERR(req);
p9_debug(P9_DEBUG_9P, "<<< RLINK\n");
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
return 0;
}
EXPORT_SYMBOL(p9_client_link);
@@ -1397,7 +1397,7 @@ int p9_client_fsync(struct p9_fid *fid, int datasync)
p9_debug(P9_DEBUG_9P, "<<< RFSYNC fid %d\n", fid->fid);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
@@ -1432,7 +1432,7 @@ int p9_client_clunk(struct p9_fid *fid)
p9_debug(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
/*
* Fid is not valid even after a failed clunk
@@ -1466,7 +1466,7 @@ int p9_client_remove(struct p9_fid *fid)
p9_debug(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
if (err == -ERESTARTSYS)
p9_client_clunk(fid);
@@ -1493,7 +1493,7 @@ int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
}
p9_debug(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
}
@@ -1545,7 +1545,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
"D", &count, &dataptr);
if (*err) {
trace_9p_protocol_dump(clnt, &req->rc);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
break;
}
if (rsize < count) {
@@ -1555,7 +1555,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
if (!count) {
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
break;
}
@@ -1565,7 +1565,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
offset += n;
if (n != count) {
*err = -EFAULT;
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
break;
}
} else {
@@ -1573,7 +1573,7 @@ p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err)
total += count;
offset += count;
}
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
}
return total;
}
@@ -1617,7 +1617,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
*err = p9pdu_readf(&req->rc, clnt->proto_version, "d", &count);
if (*err) {
trace_9p_protocol_dump(clnt, &req->rc);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
break;
}
if (rsize < count) {
@@ -1627,7 +1627,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
iov_iter_advance(from, count);
total += count;
offset += count;
@@ -1661,7 +1661,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
err = p9pdu_readf(&req->rc, clnt->proto_version, "wS", &ignored, ret);
if (err) {
trace_9p_protocol_dump(clnt, &req->rc);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
goto error;
}
@@ -1678,7 +1678,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
from_kgid(&init_user_ns, ret->n_gid),
from_kuid(&init_user_ns, ret->n_muid));
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
return ret;
error:
@@ -1714,7 +1714,7 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
err = p9pdu_readf(&req->rc, clnt->proto_version, "A", ret);
if (err) {
trace_9p_protocol_dump(clnt, &req->rc);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
goto error;
}
@@ -1739,7 +1739,7 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec,
ret->st_gen, ret->st_data_version);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
return ret;
error:
@@ -1808,7 +1808,7 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
p9_debug(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
}
@@ -1840,7 +1840,7 @@ int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr)
goto error;
}
p9_debug(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
}
@@ -1868,7 +1868,7 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
&sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
if (err) {
trace_9p_protocol_dump(clnt, &req->rc);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
goto error;
}
@@ -1879,7 +1879,7 @@ int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
sb->blocks, sb->bfree, sb->bavail, sb->files, sb->ffree,
sb->fsid, (long int)sb->namelen);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
}
@@ -1907,7 +1907,7 @@ int p9_client_rename(struct p9_fid *fid,
p9_debug(P9_DEBUG_9P, "<<< RRENAME fid %d\n", fid->fid);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
}
@@ -1937,7 +1937,7 @@ int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
p9_debug(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n",
newdirfid->fid, new_name);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
}
@@ -1974,10 +1974,10 @@ struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
err = p9pdu_readf(&req->rc, clnt->proto_version, "q", attr_size);
if (err) {
trace_9p_protocol_dump(clnt, &req->rc);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
goto clunk_fid;
}
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
p9_debug(P9_DEBUG_9P, "<<< RXATTRWALK fid %d size %llu\n",
attr_fid->fid, *attr_size);
return attr_fid;
@@ -2011,7 +2011,7 @@ int p9_client_xattrcreate(struct p9_fid *fid, const char *name,
goto error;
}
p9_debug(P9_DEBUG_9P, "<<< RXATTRCREATE fid %d\n", fid->fid);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
}
@@ -2074,11 +2074,11 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
if (non_zc)
memmove(data, dataptr, count);
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
return count;
free_and_error:
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
error:
return err;
}
@@ -2109,7 +2109,7 @@ int p9_client_mknod_dotl(struct p9_fid *fid, const char *name, int mode,
(unsigned long long)qid->path, qid->version);
error:
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
return err;
}
@@ -2140,7 +2140,7 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
(unsigned long long)qid->path, qid->version);
error:
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
return err;
}
@@ -2173,7 +2173,7 @@ int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
}
p9_debug(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
error:
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
return err;
}
@@ -2208,7 +2208,7 @@ int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
"proc_id %d client_id %s\n", glock->type, glock->start,
glock->length, glock->proc_id, glock->client_id);
error:
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
return err;
}
EXPORT_SYMBOL(p9_client_getlock_dotl);
@@ -2234,7 +2234,7 @@ int p9_client_readlink(struct p9_fid *fid, char **target)
}
p9_debug(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);
error:
- p9_free_req(clnt, req);
+ p9_tag_remove(clnt, req);
return err;
}
EXPORT_SYMBOL(p9_client_readlink);
--
2.11.0
^ permalink raw reply related
* the editing is that you need
From: Jeff @ 2018-08-11 7:20 UTC (permalink / raw)
To: netdev
We would like to check if your photos need editing. We can do it for you.
Our image editing is for web store photos, jewelries images and beauty and
portrait photos etc.
It is including cut out and clipping path , and also retouching if it is
needed.
We can do test on your photos. Just send us a photo we will start to work
on it,
Thanks,
Jeff Allen
^ permalink raw reply
* [PATCH v2] xen-netfront: fix warn message as irq device name has '/'
From: Xiao Liang @ 2018-08-11 15:21 UTC (permalink / raw)
To: netdev, xen-devel, davem, jgross, boris.ostrovsky
Cc: linux-kernel, Xiao Liang
There is a call trace generated after commit 2d408c0d4574b01b9ed45e02516888bf925e11a9(
xen-netfront: fix queue name setting). There is no 'device/vif/xx-q0-tx' file found
under /proc/irq/xx/.
This patch only picks up device type and id as its name.
With the patch, now /proc/interrupts looks like below and the warning message gone:
70: 21 0 0 0 xen-dyn -event vif0-q0-tx
71: 15 0 0 0 xen-dyn -event vif0-q0-rx
72: 14 0 0 0 xen-dyn -event vif0-q1-tx
73: 33 0 0 0 xen-dyn -event vif0-q1-rx
74: 12 0 0 0 xen-dyn -event vif0-q2-tx
75: 24 0 0 0 xen-dyn -event vif0-q2-rx
76: 19 0 0 0 xen-dyn -event vif0-q3-tx
77: 21 0 0 0 xen-dyn -event vif0-q3-rx
Below is call trace information without this patch:
name 'device/vif/0-q0-tx'
WARNING: CPU: 2 PID: 37 at fs/proc/generic.c:174 __xlate_proc_name+0x85/0xa0
RIP: 0010:__xlate_proc_name+0x85/0xa0
RSP: 0018:ffffb85c40473c18 EFLAGS: 00010286
RAX: 0000000000000000 RBX: 0000000000000006 RCX: 0000000000000006
RDX: 0000000000000007 RSI: 0000000000000096 RDI: ffff984c7f516930
RBP: ffffb85c40473cb8 R08: 000000000000002c R09: 0000000000000229
R10: 0000000000000000 R11: 0000000000000001 R12: ffffb85c40473c98
R13: ffffb85c40473cb8 R14: ffffb85c40473c50 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff984c7f500000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f69b6899038 CR3: 000000001c20a006 CR4: 00000000001606e0
Call Trace:
__proc_create+0x45/0x230
? snprintf+0x49/0x60
proc_mkdir_data+0x35/0x90
register_handler_proc+0xef/0x110
? proc_register+0xfc/0x110
? proc_create_data+0x70/0xb0
__setup_irq+0x39b/0x660
? request_threaded_irq+0xad/0x160
request_threaded_irq+0xf5/0x160
? xennet_tx_buf_gc+0x1d0/0x1d0 [xen_netfront]
bind_evtchn_to_irqhandler+0x3d/0x70
? xenbus_alloc_evtchn+0x41/0xa0
netback_changed+0xa46/0xcda [xen_netfront]
? find_watch+0x40/0x40
xenwatch_thread+0xc5/0x160
? finish_wait+0x80/0x80
kthread+0x112/0x130
? kthread_create_worker_on_cpu+0x70/0x70
ret_from_fork+0x35/0x40
Code: 81 5c 00 48 85 c0 75 cc 5b 49 89 2e 31 c0 5d 4d 89 3c 24 41 5c 41 5d 41 5e 41 5f c3 4c 89 ee 48 c7 c7 40 4f 0e b4 e8 65 ea d8 ff <0f> 0b b8 fe ff ff ff 5b 5d 41 5c 41 5d 41 5e 41 5f c3 66 0f 1f
---[ end trace 650e5561b0caab3a ]---
Signed-off-by: Xiao Liang <xiliang@redhat.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
---
drivers/net/xen-netfront.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 799cba4624a5..02f46237cfc6 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1604,14 +1604,16 @@ static int xennet_init_queue(struct netfront_queue *queue)
{
unsigned short i;
int err = 0;
+ int devid = 0;
spin_lock_init(&queue->tx_lock);
spin_lock_init(&queue->rx_lock);
timer_setup(&queue->rx_refill_timer, rx_refill_timeout, 0);
- snprintf(queue->name, sizeof(queue->name), "%s-q%u",
- queue->info->xbdev->nodename, queue->id);
+ kstrtoint(strrchr(queue->info->xbdev->nodename, '/') + 1, 10, &devid);
+ snprintf(queue->name, sizeof(queue->name), "vif%d-q%u",
+ devid, queue->id);
/* Initialise tx_skbs as a free chain containing every entry. */
queue->tx_skb_freelist = 0;
--
2.17.1
^ permalink raw reply related
* Re: [PATCH 0/2] net: ethernet: ti: cpsw: fix runtime pm while add/del reserved vid
From: David Miller @ 2018-08-11 16:39 UTC (permalink / raw)
To: ivan.khoronzhuk; +Cc: grygorii.strashko, linux-omap, netdev, linux-kernel
In-Reply-To: <20180810124709.25089-1-ivan.khoronzhuk@linaro.org>
From: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
Date: Fri, 10 Aug 2018 15:47:07 +0300
> Here 2 not critical fixes for:
> - vlan ale table leak while error if deleting vlan (simplifies next fix)
> - runtime pm while try to set reserved vlan
Series applied, thank you.
^ 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