Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next v6 01/23] asm: simd context helper API
From: Ard Biesheuvel @ 2018-09-28 14:00 UTC (permalink / raw)
  To: Jason A. Donenfeld
  Cc: Joe Perches, LKML, Netdev, Linux Crypto Mailing List,
	David Miller, Greg Kroah-Hartman, Samuel Neves, Andrew Lutomirski,
	Thomas Gleixner, linux-arch
In-Reply-To: <CAHmME9owF+3aQaZUkK4KkfnJna+DK=GoWV8yf-Wb+gH4w3y9eg@mail.gmail.com>

On 28 September 2018 at 15:59, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> On Fri, Sep 28, 2018 at 3:58 PM Ard Biesheuvel
> <ard.biesheuvel@linaro.org> wrote:
>>
>> On 28 September 2018 at 15:47, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
>> > On Fri, Sep 28, 2018 at 10:49 AM Ard Biesheuvel
>> > <ard.biesheuvel@linaro.org> wrote:
>> >> >> +typedef enum {
>> >> >> +       HAVE_NO_SIMD = 1 << 0,
>> >> >> +       HAVE_FULL_SIMD = 1 << 1,
>> >> >> +       HAVE_SIMD_IN_USE = 1 << 31
>> >> >> +} simd_context_t;
>> >> >> +
>> >>
>> >> Oh, and another thing (and I'm surprised checkpatch.pl didn't complain
>> >> about it): the use of typedef in new code is strongly discouraged.
>> >> This policy predates my involvement, so perhaps Joe can elaborate on
>> >> the rationale?
>> >
>> > In case it matters, the motivation for making this a typedef is I
>> > could imagine this at some point turning into a more complicated
>> > struct on certain platforms and that would make refactoring easier. I
>> > could just make it `struct simd_context` now with 1 member though...
>>
>> Yes that makes sense
>
> The rationale for it being a typedef or moving to a struct now?

Yes just switch to a struct.

^ permalink raw reply

* Re: [PATCH net-next v6 01/23] asm: simd context helper API
From: Jason A. Donenfeld @ 2018-09-28 14:01 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Joe Perches, LKML, Netdev, Linux Crypto Mailing List,
	David Miller, Greg Kroah-Hartman, Samuel Neves, Andrew Lutomirski,
	Thomas Gleixner, linux-arch
In-Reply-To: <CAKv+Gu9FAVVOiYyGovYZ19-107_6sK9Ya6LnK=AQkTgctMmu5A@mail.gmail.com>

On Fri, Sep 28, 2018 at 4:00 PM Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:
>
> On 28 September 2018 at 15:59, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> > On Fri, Sep 28, 2018 at 3:58 PM Ard Biesheuvel
> > <ard.biesheuvel@linaro.org> wrote:
> >>
> >> On 28 September 2018 at 15:47, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> >> > On Fri, Sep 28, 2018 at 10:49 AM Ard Biesheuvel
> >> > <ard.biesheuvel@linaro.org> wrote:
> >> >> >> +typedef enum {
> >> >> >> +       HAVE_NO_SIMD = 1 << 0,
> >> >> >> +       HAVE_FULL_SIMD = 1 << 1,
> >> >> >> +       HAVE_SIMD_IN_USE = 1 << 31
> >> >> >> +} simd_context_t;
> >> >> >> +
> >> >>
> >> >> Oh, and another thing (and I'm surprised checkpatch.pl didn't complain
> >> >> about it): the use of typedef in new code is strongly discouraged.
> >> >> This policy predates my involvement, so perhaps Joe can elaborate on
> >> >> the rationale?
> >> >
> >> > In case it matters, the motivation for making this a typedef is I
> >> > could imagine this at some point turning into a more complicated
> >> > struct on certain platforms and that would make refactoring easier. I
> >> > could just make it `struct simd_context` now with 1 member though...
> >>
> >> Yes that makes sense
> >
> > The rationale for it being a typedef or moving to a struct now?
>
> Yes just switch to a struct.

Okay. No problem with that, but will wait to hear from Joe first.

^ permalink raw reply

* Re: [PATCH 1/2] net: dpaa2: move DPAA2 PTP driver out of staging/
From: Richard Cochran @ 2018-09-28 14:16 UTC (permalink / raw)
  To: Ioana Ciocoi Radulescu
  Cc: Y.b. Lu, Andrew Lunn, linux-kernel@vger.kernel.org,
	devel@driverdev.osuosl.org, netdev@vger.kernel.org,
	David S . Miller, Greg Kroah-Hartman
In-Reply-To: <DBXPR04MB3490DB9A1EF2D814568843B94EC0@DBXPR04MB349.eurprd04.prod.outlook.com>

On Fri, Sep 28, 2018 at 10:20:55AM +0000, Ioana Ciocoi Radulescu wrote:
> Generally speaking, I think it's better to remove unused code from the current
> driver and re-add it along with the feature actually using it.

+1

Thanks,
Richard

^ permalink raw reply

* Re: [PATCH 11/15] octeontx2-af: Add Marvell OcteonTX2 CGX driver
From: Arnd Bergmann @ 2018-09-28  8:14 UTC (permalink / raw)
  To: Sunil Kovvuri; +Cc: Networking, David Miller, linux-soc, sgoutham
In-Reply-To: <1538114872-10820-12-git-send-email-sunil.kovvuri@gmail.com>

On Fri, Sep 28, 2018 at 8:09 AM <sunil.kovvuri@gmail.com> wrote:
>
> From: Sunil Goutham <sgoutham@marvell.com>
>
> This patch adds basic template for Marvell OcteonTX2's
> CGX ethernet interface driver. Just the probe.
> RVU AF driver will use APIs exported by this driver
> for various things like PF to physical interface mapping,
> loopback mode, interface stats etc. Hence marged both
> drivers into a single module.
>
> Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
> ---
>  drivers/net/ethernet/marvell/octeontx2/af/Makefile |   2 +-
>  drivers/net/ethernet/marvell/octeontx2/af/cgx.c    | 100 +++++++++++++++++++++
>  drivers/net/ethernet/marvell/octeontx2/af/cgx.h    |  22 +++++
>  drivers/net/ethernet/marvell/octeontx2/af/rvu.c    |  14 ++-
>  4 files changed, 136 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/cgx.c
>  create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/cgx.h
>
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/Makefile b/drivers/net/ethernet/marvell/octeontx2/af/Makefile
> index ac17cb9..8646421 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/af/Makefile
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/Makefile
> @@ -7,4 +7,4 @@ obj-$(CONFIG_OCTEONTX2_MBOX) += octeontx2_mbox.o
>  obj-$(CONFIG_OCTEONTX2_AF) += octeontx2_af.o
>
>  octeontx2_mbox-y := mbox.o
> -octeontx2_af-y := rvu.o
> +octeontx2_af-y := cgx.o rvu.o
> diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
> new file mode 100644
> index 0000000..cfd80d2
> --- /dev/null
> +++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c

> +MODULE_AUTHOR("Marvell International Ltd.");
> +MODULE_DESCRIPTION(DRV_STRING);
> +MODULE_LICENSE("GPL v2");
> +MODULE_DEVICE_TABLE(pci, cgx_id_table);

Since you now link both pci_driver instances in one module, I think
you need to remove the duplicate author/description/license tags.
Multiple device tables are fine I think.

       Arnd

^ permalink raw reply

* [PATCH net-next] hv_netvsc: Fix rndis_per_packet_info internal field initialization
From: Haiyang Zhang @ 2018-09-28 14:41 UTC (permalink / raw)
  To: davem, netdev
  Cc: haiyangz, kys, sthemmin, olaf, vkuznets, devel, linux-kernel

From: Haiyang Zhang <haiyangz@microsoft.com>

The RSC feature -- a bit field "internal" was added here with total
size unchanged:
struct rndis_per_packet_info {
	u32 size;
	u32 type:31;
	u32 internal:1;
	u32 ppi_offset;
};

On TX path, we put rndis msg into skb head room, which is not zeroed
before passing to us. We do not use the "internal" field in TX path,
but it may impact older hosts which use the entire 32 bits as "type".

To fix the bug, this patch sets the field "internal" to zero.

Fixes: c8e4eff4675f ("hv_netvsc: Add support for LRO/RSC in the vSwitch")
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/net/hyperv/netvsc_drv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index ec699741170b..005cbaa2fa3b 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -226,6 +226,7 @@ static inline void *init_ppi_data(struct rndis_message *msg,
 
 	ppi->size = ppi_size;
 	ppi->type = pkt_type;
+	ppi->internal = 0;
 	ppi->ppi_offset = sizeof(struct rndis_per_packet_info);
 
 	rndis_pkt->per_pkt_info_len += ppi_size;
-- 
2.18.0

^ permalink raw reply related

* Re: [PATCH 13/15] octeontx2-af: Add support for CGX link management
From: Arnd Bergmann @ 2018-09-28  8:19 UTC (permalink / raw)
  To: Sunil Kovvuri; +Cc: Networking, David Miller, linux-soc, lcherian, nmani
In-Reply-To: <1538114872-10820-14-git-send-email-sunil.kovvuri@gmail.com>

On Fri, Sep 28, 2018 at 8:09 AM <sunil.kovvuri@gmail.com> wrote:
>
> +/* scratchx(0) CSR used for ATF->non-secure SW communication.
> + * This acts as the status register
> + * Provides details on command ack/status, link status, error details
> + */
> +struct cgx_evt_sts {
> +       uint64_t ack:1;
> +       uint64_t evt_type:1;            /* cgx_evt_type */
> +       uint64_t stat:1;                /* cgx_stat */
> +       uint64_t id:6;                  /* cgx_evt_id/cgx_cmd_id */
> +       uint64_t reserved:55;
> +};
> +
> +/* Response to command IDs with command status as CGX_STAT_FAIL
> + *
> + * Not applicable for commands :
> + * CGX_CMD_LINK_BRING_UP/DOWN/CGX_EVT_LINK_CHANGE
> + * check struct cgx_lnk_sts comments
> + */
> +struct cgx_err_sts_s {
> +       uint64_t reserved1:9;
> +       uint64_t type:10;               /* cgx_error_type */
> +       uint64_t reserved2:35;
> +};
> +
> +/* Response to cmd ID as CGX_CMD_GET_FW_VER with cmd status as
> + * CGX_STAT_SUCCESS
> + */
> +struct cgx_ver_s {
> +       uint64_t reserved1:9;
> +       uint64_t major_ver:4;
> +       uint64_t minor_ver:4;
> +       uint64_t reserved2:47;
> +};

>From what I can tell, you pass these structures to the device, so they
are a binary interface. I don't think you can rely on bitfields to work
correctly here, they are generally not portable and I wouldn't rely
on them doing the right thing if you build a big-endian kernel.

It's better to use bitmasks on a u64 value instead to make it obviously
portable.

       Arnd

^ permalink raw reply

* [PATCH v4 bpf-next 00/10] bpf: per-cpu cgroup local storage
From: Roman Gushchin @ 2018-09-28 14:45 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: linux-kernel@vger.kernel.org, Kernel Team, Roman Gushchin

This patchset implements per-cpu cgroup local storage and provides
an example how per-cpu and shared cgroup local storage can be used
for efficient accounting of network traffic.

v4->v3:
  1) incorporated Alexei's feedback

v3->v2:
  1) incorporated Song's feedback
  2) rebased on top of current bpf-next

v2->v1:
  1) added a selftest implementing network counters
  2) added a missing free() in cgroup local storage selftest

Roman Gushchin (10):
  bpf: extend cgroup bpf core to allow multiple cgroup storage types
  bpf: rework cgroup storage pointer passing
  bpf: introduce per-cpu cgroup local storage
  bpf: don't allow create maps of per-cpu cgroup local storages
  bpf: sync include/uapi/linux/bpf.h to tools/include/uapi/linux/bpf.h
  bpftool: add support for PERCPU_CGROUP_STORAGE maps
  selftests/bpf: add verifier per-cpu cgroup storage tests
  selftests/bpf: extend the storage test to test per-cpu cgroup storage
  samples/bpf: extend test_cgrp2_attach2 test to use per-cpu cgroup
    storage
  selftests/bpf: cgroup local storage-based network counters

 include/linux/bpf-cgroup.h                    |  55 ++++--
 include/linux/bpf.h                           |  12 +-
 include/linux/bpf_types.h                     |   1 +
 include/uapi/linux/bpf.h                      |   1 +
 kernel/bpf/cgroup.c                           |  74 +++++---
 kernel/bpf/helpers.c                          |  25 ++-
 kernel/bpf/local_storage.c                    | 169 +++++++++++++++---
 kernel/bpf/map_in_map.c                       |   3 +-
 kernel/bpf/syscall.c                          |  20 ++-
 kernel/bpf/verifier.c                         |  23 ++-
 net/bpf/test_run.c                            |  20 ++-
 samples/bpf/test_cgrp2_attach2.c              |  19 +-
 tools/bpf/bpftool/map.c                       |   4 +-
 tools/include/uapi/linux/bpf.h                |   1 +
 tools/testing/selftests/bpf/Makefile          |   6 +-
 tools/testing/selftests/bpf/netcnt_common.h   |  24 +++
 tools/testing/selftests/bpf/netcnt_prog.c     |  71 ++++++++
 .../selftests/bpf/test_cgroup_storage.c       |  60 ++++++-
 tools/testing/selftests/bpf/test_netcnt.c     | 158 ++++++++++++++++
 tools/testing/selftests/bpf/test_verifier.c   | 139 +++++++++++++-
 20 files changed, 786 insertions(+), 99 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/netcnt_common.h
 create mode 100644 tools/testing/selftests/bpf/netcnt_prog.c
 create mode 100644 tools/testing/selftests/bpf/test_netcnt.c

-- 
2.17.1

^ permalink raw reply

* [PATCH v4 bpf-next 01/10] bpf: extend cgroup bpf core to allow multiple cgroup storage types
From: Roman Gushchin @ 2018-09-28 14:45 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: linux-kernel@vger.kernel.org, Kernel Team, Roman Gushchin,
	Daniel Borkmann, Alexei Starovoitov
In-Reply-To: <20180928144452.5284-1-guro@fb.com>

In order to introduce per-cpu cgroup storage, let's generalize
bpf cgroup core to support multiple cgroup storage types.
Potentially, per-node cgroup storage can be added later.

This commit is mostly a formal change that replaces
cgroup_storage pointer with a array of cgroup_storage pointers.
It doesn't actually introduce a new storage type,
it will be done later.

Each bpf program is now able to have one cgroup storage of each type.

Signed-off-by: Roman Gushchin <guro@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
---
 include/linux/bpf-cgroup.h | 38 ++++++++++++++------
 include/linux/bpf.h        | 11 ++++--
 kernel/bpf/cgroup.c        | 74 ++++++++++++++++++++++++++------------
 kernel/bpf/helpers.c       | 15 ++++----
 kernel/bpf/local_storage.c | 18 ++++++----
 kernel/bpf/syscall.c       |  9 +++--
 kernel/bpf/verifier.c      |  8 +++--
 net/bpf/test_run.c         | 20 +++++++----
 8 files changed, 136 insertions(+), 57 deletions(-)

diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index f91b0f8ff3a9..e9871b012dac 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -2,6 +2,7 @@
 #ifndef _BPF_CGROUP_H
 #define _BPF_CGROUP_H
 
+#include <linux/bpf.h>
 #include <linux/errno.h>
 #include <linux/jump_label.h>
 #include <linux/percpu.h>
@@ -22,7 +23,10 @@ struct bpf_cgroup_storage;
 extern struct static_key_false cgroup_bpf_enabled_key;
 #define cgroup_bpf_enabled static_branch_unlikely(&cgroup_bpf_enabled_key)
 
-DECLARE_PER_CPU(void*, bpf_cgroup_storage);
+DECLARE_PER_CPU(void*, bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]);
+
+#define for_each_cgroup_storage_type(stype) \
+	for (stype = 0; stype < MAX_BPF_CGROUP_STORAGE_TYPE; stype++)
 
 struct bpf_cgroup_storage_map;
 
@@ -43,7 +47,7 @@ struct bpf_cgroup_storage {
 struct bpf_prog_list {
 	struct list_head node;
 	struct bpf_prog *prog;
-	struct bpf_cgroup_storage *storage;
+	struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE];
 };
 
 struct bpf_prog_array;
@@ -101,18 +105,29 @@ int __cgroup_bpf_run_filter_sock_ops(struct sock *sk,
 int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
 				      short access, enum bpf_attach_type type);
 
-static inline void bpf_cgroup_storage_set(struct bpf_cgroup_storage *storage)
+static inline enum bpf_cgroup_storage_type cgroup_storage_type(
+	struct bpf_map *map)
 {
+	return BPF_CGROUP_STORAGE_SHARED;
+}
+
+static inline void bpf_cgroup_storage_set(struct bpf_cgroup_storage
+					  *storage[MAX_BPF_CGROUP_STORAGE_TYPE])
+{
+	enum bpf_cgroup_storage_type stype;
 	struct bpf_storage_buffer *buf;
 
-	if (!storage)
-		return;
+	for_each_cgroup_storage_type(stype) {
+		if (!storage[stype])
+			continue;
 
-	buf = READ_ONCE(storage->buf);
-	this_cpu_write(bpf_cgroup_storage, &buf->data[0]);
+		buf = READ_ONCE(storage[stype]->buf);
+		this_cpu_write(bpf_cgroup_storage[stype], &buf->data[0]);
+	}
 }
 
-struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(struct bpf_prog *prog);
+struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(struct bpf_prog *prog,
+					enum bpf_cgroup_storage_type stype);
 void bpf_cgroup_storage_free(struct bpf_cgroup_storage *storage);
 void bpf_cgroup_storage_link(struct bpf_cgroup_storage *storage,
 			     struct cgroup *cgroup,
@@ -265,13 +280,14 @@ static inline int cgroup_bpf_prog_query(const union bpf_attr *attr,
 	return -EINVAL;
 }
 
-static inline void bpf_cgroup_storage_set(struct bpf_cgroup_storage *storage) {}
+static inline void bpf_cgroup_storage_set(
+	struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE]) {}
 static inline int bpf_cgroup_storage_assign(struct bpf_prog *prog,
 					    struct bpf_map *map) { return 0; }
 static inline void bpf_cgroup_storage_release(struct bpf_prog *prog,
 					      struct bpf_map *map) {}
 static inline struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(
-	struct bpf_prog *prog) { return 0; }
+	struct bpf_prog *prog, enum bpf_cgroup_storage_type stype) { return 0; }
 static inline void bpf_cgroup_storage_free(
 	struct bpf_cgroup_storage *storage) {}
 
@@ -293,6 +309,8 @@ static inline void bpf_cgroup_storage_free(
 #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
 #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type,major,minor,access) ({ 0; })
 
+#define for_each_cgroup_storage_type(stype) for (; false; )
+
 #endif /* CONFIG_CGROUP_BPF */
 
 #endif /* _BPF_CGROUP_H */
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 988a00797bcd..b457fbe7b70b 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -272,6 +272,13 @@ struct bpf_prog_offload {
 	u32			jited_len;
 };
 
+enum bpf_cgroup_storage_type {
+	BPF_CGROUP_STORAGE_SHARED,
+	__BPF_CGROUP_STORAGE_MAX
+};
+
+#define MAX_BPF_CGROUP_STORAGE_TYPE __BPF_CGROUP_STORAGE_MAX
+
 struct bpf_prog_aux {
 	atomic_t refcnt;
 	u32 used_map_cnt;
@@ -289,7 +296,7 @@ struct bpf_prog_aux {
 	struct bpf_prog *prog;
 	struct user_struct *user;
 	u64 load_time; /* ns since boottime */
-	struct bpf_map *cgroup_storage;
+	struct bpf_map *cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE];
 	char name[BPF_OBJ_NAME_LEN];
 #ifdef CONFIG_SECURITY
 	void *security;
@@ -358,7 +365,7 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
  */
 struct bpf_prog_array_item {
 	struct bpf_prog *prog;
-	struct bpf_cgroup_storage *cgroup_storage;
+	struct bpf_cgroup_storage *cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE];
 };
 
 struct bpf_prog_array {
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 549f6fbcc461..00f6ed2e4f9a 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -25,6 +25,7 @@ EXPORT_SYMBOL(cgroup_bpf_enabled_key);
  */
 void cgroup_bpf_put(struct cgroup *cgrp)
 {
+	enum bpf_cgroup_storage_type stype;
 	unsigned int type;
 
 	for (type = 0; type < ARRAY_SIZE(cgrp->bpf.progs); type++) {
@@ -34,8 +35,10 @@ void cgroup_bpf_put(struct cgroup *cgrp)
 		list_for_each_entry_safe(pl, tmp, progs, node) {
 			list_del(&pl->node);
 			bpf_prog_put(pl->prog);
-			bpf_cgroup_storage_unlink(pl->storage);
-			bpf_cgroup_storage_free(pl->storage);
+			for_each_cgroup_storage_type(stype) {
+				bpf_cgroup_storage_unlink(pl->storage[stype]);
+				bpf_cgroup_storage_free(pl->storage[stype]);
+			}
 			kfree(pl);
 			static_branch_dec(&cgroup_bpf_enabled_key);
 		}
@@ -97,6 +100,7 @@ static int compute_effective_progs(struct cgroup *cgrp,
 				   enum bpf_attach_type type,
 				   struct bpf_prog_array __rcu **array)
 {
+	enum bpf_cgroup_storage_type stype;
 	struct bpf_prog_array *progs;
 	struct bpf_prog_list *pl;
 	struct cgroup *p = cgrp;
@@ -125,7 +129,9 @@ static int compute_effective_progs(struct cgroup *cgrp,
 				continue;
 
 			progs->items[cnt].prog = pl->prog;
-			progs->items[cnt].cgroup_storage = pl->storage;
+			for_each_cgroup_storage_type(stype)
+				progs->items[cnt].cgroup_storage[stype] =
+					pl->storage[stype];
 			cnt++;
 		}
 	} while ((p = cgroup_parent(p)));
@@ -232,7 +238,9 @@ 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 bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE],
+		*old_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {NULL};
+	enum bpf_cgroup_storage_type stype;
 	struct bpf_prog_list *pl;
 	bool pl_was_allocated;
 	int err;
@@ -254,34 +262,44 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
 	if (prog_list_length(progs) >= BPF_CGROUP_MAX_PROGS)
 		return -E2BIG;
 
-	storage = bpf_cgroup_storage_alloc(prog);
-	if (IS_ERR(storage))
-		return -ENOMEM;
+	for_each_cgroup_storage_type(stype) {
+		storage[stype] = bpf_cgroup_storage_alloc(prog, stype);
+		if (IS_ERR(storage[stype])) {
+			storage[stype] = NULL;
+			for_each_cgroup_storage_type(stype)
+				bpf_cgroup_storage_free(storage[stype]);
+			return -ENOMEM;
+		}
+	}
 
 	if (flags & BPF_F_ALLOW_MULTI) {
 		list_for_each_entry(pl, progs, node) {
 			if (pl->prog == prog) {
 				/* disallow attaching the same prog twice */
-				bpf_cgroup_storage_free(storage);
+				for_each_cgroup_storage_type(stype)
+					bpf_cgroup_storage_free(storage[stype]);
 				return -EINVAL;
 			}
 		}
 
 		pl = kmalloc(sizeof(*pl), GFP_KERNEL);
 		if (!pl) {
-			bpf_cgroup_storage_free(storage);
+			for_each_cgroup_storage_type(stype)
+				bpf_cgroup_storage_free(storage[stype]);
 			return -ENOMEM;
 		}
 
 		pl_was_allocated = true;
 		pl->prog = prog;
-		pl->storage = storage;
+		for_each_cgroup_storage_type(stype)
+			pl->storage[stype] = storage[stype];
 		list_add_tail(&pl->node, progs);
 	} else {
 		if (list_empty(progs)) {
 			pl = kmalloc(sizeof(*pl), GFP_KERNEL);
 			if (!pl) {
-				bpf_cgroup_storage_free(storage);
+				for_each_cgroup_storage_type(stype)
+					bpf_cgroup_storage_free(storage[stype]);
 				return -ENOMEM;
 			}
 			pl_was_allocated = true;
@@ -289,12 +307,15 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
 		} else {
 			pl = list_first_entry(progs, typeof(*pl), node);
 			old_prog = pl->prog;
-			old_storage = pl->storage;
-			bpf_cgroup_storage_unlink(old_storage);
+			for_each_cgroup_storage_type(stype) {
+				old_storage[stype] = pl->storage[stype];
+				bpf_cgroup_storage_unlink(old_storage[stype]);
+			}
 			pl_was_allocated = false;
 		}
 		pl->prog = prog;
-		pl->storage = storage;
+		for_each_cgroup_storage_type(stype)
+			pl->storage[stype] = storage[stype];
 	}
 
 	cgrp->bpf.flags[type] = flags;
@@ -304,21 +325,27 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
 		goto cleanup;
 
 	static_branch_inc(&cgroup_bpf_enabled_key);
-	if (old_storage)
-		bpf_cgroup_storage_free(old_storage);
+	for_each_cgroup_storage_type(stype) {
+		if (!old_storage[stype])
+			continue;
+		bpf_cgroup_storage_free(old_storage[stype]);
+	}
 	if (old_prog) {
 		bpf_prog_put(old_prog);
 		static_branch_dec(&cgroup_bpf_enabled_key);
 	}
-	bpf_cgroup_storage_link(storage, cgrp, type);
+	for_each_cgroup_storage_type(stype)
+		bpf_cgroup_storage_link(storage[stype], cgrp, type);
 	return 0;
 
 cleanup:
 	/* and cleanup the prog list */
 	pl->prog = old_prog;
-	bpf_cgroup_storage_free(pl->storage);
-	pl->storage = old_storage;
-	bpf_cgroup_storage_link(old_storage, cgrp, type);
+	for_each_cgroup_storage_type(stype) {
+		bpf_cgroup_storage_free(pl->storage[stype]);
+		pl->storage[stype] = old_storage[stype];
+		bpf_cgroup_storage_link(old_storage[stype], cgrp, type);
+	}
 	if (pl_was_allocated) {
 		list_del(&pl->node);
 		kfree(pl);
@@ -339,6 +366,7 @@ int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
 			enum bpf_attach_type type, u32 unused_flags)
 {
 	struct list_head *progs = &cgrp->bpf.progs[type];
+	enum bpf_cgroup_storage_type stype;
 	u32 flags = cgrp->bpf.flags[type];
 	struct bpf_prog *old_prog = NULL;
 	struct bpf_prog_list *pl;
@@ -385,8 +413,10 @@ int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
 
 	/* now can actually delete it from this cgroup list */
 	list_del(&pl->node);
-	bpf_cgroup_storage_unlink(pl->storage);
-	bpf_cgroup_storage_free(pl->storage);
+	for_each_cgroup_storage_type(stype) {
+		bpf_cgroup_storage_unlink(pl->storage[stype]);
+		bpf_cgroup_storage_free(pl->storage[stype]);
+	}
 	kfree(pl);
 	if (list_empty(progs))
 		/* last program was detached, reset flags to zero */
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 1991466b8327..9070b2ace6aa 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -194,16 +194,18 @@ const struct bpf_func_proto bpf_get_current_cgroup_id_proto = {
 	.ret_type	= RET_INTEGER,
 };
 
-DECLARE_PER_CPU(void*, bpf_cgroup_storage);
+#ifdef CONFIG_CGROUP_BPF
+DECLARE_PER_CPU(void*, bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]);
 
 BPF_CALL_2(bpf_get_local_storage, struct bpf_map *, map, u64, flags)
 {
-	/* map and flags arguments are not used now,
-	 * but provide an ability to extend the API
-	 * for other types of local storages.
-	 * verifier checks that their values are correct.
+	/* flags argument is not used now,
+	 * but provides an ability to extend the API.
+	 * verifier checks that its value is correct.
 	 */
-	return (unsigned long) this_cpu_read(bpf_cgroup_storage);
+	enum bpf_cgroup_storage_type stype = cgroup_storage_type(map);
+
+	return (unsigned long) this_cpu_read(bpf_cgroup_storage[stype]);
 }
 
 const struct bpf_func_proto bpf_get_local_storage_proto = {
@@ -214,3 +216,4 @@ const struct bpf_func_proto bpf_get_local_storage_proto = {
 	.arg2_type	= ARG_ANYTHING,
 };
 #endif
+#endif
diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
index 22ad967d1e5f..0bd9f19fc557 100644
--- a/kernel/bpf/local_storage.c
+++ b/kernel/bpf/local_storage.c
@@ -7,7 +7,7 @@
 #include <linux/rbtree.h>
 #include <linux/slab.h>
 
-DEFINE_PER_CPU(void*, bpf_cgroup_storage);
+DEFINE_PER_CPU(void*, bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]);
 
 #ifdef CONFIG_CGROUP_BPF
 
@@ -251,6 +251,7 @@ const struct bpf_map_ops cgroup_storage_map_ops = {
 
 int bpf_cgroup_storage_assign(struct bpf_prog *prog, struct bpf_map *_map)
 {
+	enum bpf_cgroup_storage_type stype = cgroup_storage_type(_map);
 	struct bpf_cgroup_storage_map *map = map_to_storage(_map);
 	int ret = -EBUSY;
 
@@ -258,11 +259,12 @@ int bpf_cgroup_storage_assign(struct bpf_prog *prog, struct bpf_map *_map)
 
 	if (map->prog && map->prog != prog)
 		goto unlock;
-	if (prog->aux->cgroup_storage && prog->aux->cgroup_storage != _map)
+	if (prog->aux->cgroup_storage[stype] &&
+	    prog->aux->cgroup_storage[stype] != _map)
 		goto unlock;
 
 	map->prog = prog;
-	prog->aux->cgroup_storage = _map;
+	prog->aux->cgroup_storage[stype] = _map;
 	ret = 0;
 unlock:
 	spin_unlock_bh(&map->lock);
@@ -272,24 +274,26 @@ int bpf_cgroup_storage_assign(struct bpf_prog *prog, struct bpf_map *_map)
 
 void bpf_cgroup_storage_release(struct bpf_prog *prog, struct bpf_map *_map)
 {
+	enum bpf_cgroup_storage_type stype = cgroup_storage_type(_map);
 	struct bpf_cgroup_storage_map *map = map_to_storage(_map);
 
 	spin_lock_bh(&map->lock);
 	if (map->prog == prog) {
-		WARN_ON(prog->aux->cgroup_storage != _map);
+		WARN_ON(prog->aux->cgroup_storage[stype] != _map);
 		map->prog = NULL;
-		prog->aux->cgroup_storage = NULL;
+		prog->aux->cgroup_storage[stype] = NULL;
 	}
 	spin_unlock_bh(&map->lock);
 }
 
-struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(struct bpf_prog *prog)
+struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(struct bpf_prog *prog,
+					enum bpf_cgroup_storage_type stype)
 {
 	struct bpf_cgroup_storage *storage;
 	struct bpf_map *map;
 	u32 pages;
 
-	map = prog->aux->cgroup_storage;
+	map = prog->aux->cgroup_storage[stype];
 	if (!map)
 		return NULL;
 
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index b3c2d09bcf7a..8c91d2b41b1e 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -988,10 +988,15 @@ static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog)
 /* drop refcnt on maps used by eBPF program and free auxilary data */
 static void free_used_maps(struct bpf_prog_aux *aux)
 {
+	enum bpf_cgroup_storage_type stype;
 	int i;
 
-	if (aux->cgroup_storage)
-		bpf_cgroup_storage_release(aux->prog, aux->cgroup_storage);
+	for_each_cgroup_storage_type(stype) {
+		if (!aux->cgroup_storage[stype])
+			continue;
+		bpf_cgroup_storage_release(aux->prog,
+					   aux->cgroup_storage[stype]);
+	}
 
 	for (i = 0; i < aux->used_map_cnt; i++)
 		bpf_map_put(aux->used_maps[i]);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index e986518d7bc3..e90899df585d 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -5171,11 +5171,15 @@ static int replace_map_fd_with_map_ptr(struct bpf_verifier_env *env)
 /* drop refcnt of maps used by the rejected program */
 static void release_maps(struct bpf_verifier_env *env)
 {
+	enum bpf_cgroup_storage_type stype;
 	int i;
 
-	if (env->prog->aux->cgroup_storage)
+	for_each_cgroup_storage_type(stype) {
+		if (!env->prog->aux->cgroup_storage[stype])
+			continue;
 		bpf_cgroup_storage_release(env->prog,
-					   env->prog->aux->cgroup_storage);
+			env->prog->aux->cgroup_storage[stype]);
+	}
 
 	for (i = 0; i < env->used_map_cnt; i++)
 		bpf_map_put(env->used_maps[i]);
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index f4078830ea50..0c423b8cd75c 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -12,7 +12,7 @@
 #include <linux/sched/signal.h>
 
 static __always_inline u32 bpf_test_run_one(struct bpf_prog *prog, void *ctx,
-					    struct bpf_cgroup_storage *storage)
+		struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE])
 {
 	u32 ret;
 
@@ -28,13 +28,20 @@ static __always_inline u32 bpf_test_run_one(struct bpf_prog *prog, void *ctx,
 
 static u32 bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat, u32 *time)
 {
-	struct bpf_cgroup_storage *storage = NULL;
+	struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = { 0 };
+	enum bpf_cgroup_storage_type stype;
 	u64 time_start, time_spent = 0;
 	u32 ret = 0, i;
 
-	storage = bpf_cgroup_storage_alloc(prog);
-	if (IS_ERR(storage))
-		return PTR_ERR(storage);
+	for_each_cgroup_storage_type(stype) {
+		storage[stype] = bpf_cgroup_storage_alloc(prog, stype);
+		if (IS_ERR(storage[stype])) {
+			storage[stype] = NULL;
+			for_each_cgroup_storage_type(stype)
+				bpf_cgroup_storage_free(storage[stype]);
+			return -ENOMEM;
+		}
+	}
 
 	if (!repeat)
 		repeat = 1;
@@ -53,7 +60,8 @@ static u32 bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat, u32 *time)
 	do_div(time_spent, repeat);
 	*time = time_spent > U32_MAX ? U32_MAX : (u32)time_spent;
 
-	bpf_cgroup_storage_free(storage);
+	for_each_cgroup_storage_type(stype)
+		bpf_cgroup_storage_free(storage[stype]);
 
 	return ret;
 }
-- 
2.17.1

^ permalink raw reply related

* [PATCH v4 bpf-next 02/10] bpf: rework cgroup storage pointer passing
From: Roman Gushchin @ 2018-09-28 14:45 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: linux-kernel@vger.kernel.org, Kernel Team, Roman Gushchin,
	Daniel Borkmann, Alexei Starovoitov
In-Reply-To: <20180928144452.5284-1-guro@fb.com>

To simplify the following introduction of per-cpu cgroup storage,
let's rework a bit a mechanism of passing a pointer to a cgroup
storage into the bpf_get_local_storage(). Let's save a pointer
to the corresponding bpf_cgroup_storage structure, instead of
a pointer to the actual buffer.

It will help us to handle per-cpu storage later, which has
a different way of accessing to the actual data.

Signed-off-by: Roman Gushchin <guro@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
---
 include/linux/bpf-cgroup.h | 13 ++++---------
 kernel/bpf/helpers.c       |  8 ++++++--
 kernel/bpf/local_storage.c |  3 ++-
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index e9871b012dac..7e0c9a1d48b7 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -23,7 +23,8 @@ struct bpf_cgroup_storage;
 extern struct static_key_false cgroup_bpf_enabled_key;
 #define cgroup_bpf_enabled static_branch_unlikely(&cgroup_bpf_enabled_key)
 
-DECLARE_PER_CPU(void*, bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]);
+DECLARE_PER_CPU(struct bpf_cgroup_storage*,
+		bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]);
 
 #define for_each_cgroup_storage_type(stype) \
 	for (stype = 0; stype < MAX_BPF_CGROUP_STORAGE_TYPE; stype++)
@@ -115,15 +116,9 @@ static inline void bpf_cgroup_storage_set(struct bpf_cgroup_storage
 					  *storage[MAX_BPF_CGROUP_STORAGE_TYPE])
 {
 	enum bpf_cgroup_storage_type stype;
-	struct bpf_storage_buffer *buf;
-
-	for_each_cgroup_storage_type(stype) {
-		if (!storage[stype])
-			continue;
 
-		buf = READ_ONCE(storage[stype]->buf);
-		this_cpu_write(bpf_cgroup_storage[stype], &buf->data[0]);
-	}
+	for_each_cgroup_storage_type(stype)
+		this_cpu_write(bpf_cgroup_storage[stype], storage[stype]);
 }
 
 struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(struct bpf_prog *prog,
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 9070b2ace6aa..e42f8789b7ea 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -195,7 +195,8 @@ const struct bpf_func_proto bpf_get_current_cgroup_id_proto = {
 };
 
 #ifdef CONFIG_CGROUP_BPF
-DECLARE_PER_CPU(void*, bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]);
+DECLARE_PER_CPU(struct bpf_cgroup_storage*,
+		bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]);
 
 BPF_CALL_2(bpf_get_local_storage, struct bpf_map *, map, u64, flags)
 {
@@ -204,8 +205,11 @@ BPF_CALL_2(bpf_get_local_storage, struct bpf_map *, map, u64, flags)
 	 * verifier checks that its value is correct.
 	 */
 	enum bpf_cgroup_storage_type stype = cgroup_storage_type(map);
+	struct bpf_cgroup_storage *storage;
 
-	return (unsigned long) this_cpu_read(bpf_cgroup_storage[stype]);
+	storage = this_cpu_read(bpf_cgroup_storage[stype]);
+
+	return (unsigned long)&READ_ONCE(storage->buf)->data[0];
 }
 
 const struct bpf_func_proto bpf_get_local_storage_proto = {
diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
index 0bd9f19fc557..6742292fb39e 100644
--- a/kernel/bpf/local_storage.c
+++ b/kernel/bpf/local_storage.c
@@ -7,7 +7,8 @@
 #include <linux/rbtree.h>
 #include <linux/slab.h>
 
-DEFINE_PER_CPU(void*, bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]);
+DEFINE_PER_CPU(struct bpf_cgroup_storage*,
+	       bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]);
 
 #ifdef CONFIG_CGROUP_BPF
 
-- 
2.17.1

^ permalink raw reply related

* [PATCH v4 bpf-next 03/10] bpf: introduce per-cpu cgroup local storage
From: Roman Gushchin @ 2018-09-28 14:45 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: linux-kernel@vger.kernel.org, Kernel Team, Roman Gushchin,
	Daniel Borkmann, Alexei Starovoitov
In-Reply-To: <20180928144452.5284-1-guro@fb.com>

This commit introduced per-cpu cgroup local storage.

Per-cpu cgroup local storage is very similar to simple cgroup storage
(let's call it shared), except all the data is per-cpu.

The main goal of per-cpu variant is to implement super fast
counters (e.g. packet counters), which don't require neither
lookups, neither atomic operations.

>From userspace's point of view, accessing a per-cpu cgroup storage
is similar to other per-cpu map types (e.g. per-cpu hashmaps and
arrays).

Writing to a per-cpu cgroup storage is not atomic, but is performed
by copying longs, so some minimal atomicity is here, exactly
as with other per-cpu maps.

Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
Acked-by: Song Liu <songliubraving@fb.com>
---
 include/linux/bpf-cgroup.h |  20 ++++-
 include/linux/bpf.h        |   1 +
 include/linux/bpf_types.h  |   1 +
 include/uapi/linux/bpf.h   |   1 +
 kernel/bpf/helpers.c       |   8 +-
 kernel/bpf/local_storage.c | 150 ++++++++++++++++++++++++++++++++-----
 kernel/bpf/syscall.c       |  11 ++-
 kernel/bpf/verifier.c      |  15 +++-
 8 files changed, 179 insertions(+), 28 deletions(-)

diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 7e0c9a1d48b7..588dd5f0bd85 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -37,7 +37,10 @@ struct bpf_storage_buffer {
 };
 
 struct bpf_cgroup_storage {
-	struct bpf_storage_buffer *buf;
+	union {
+		struct bpf_storage_buffer *buf;
+		void __percpu *percpu_buf;
+	};
 	struct bpf_cgroup_storage_map *map;
 	struct bpf_cgroup_storage_key key;
 	struct list_head list;
@@ -109,6 +112,9 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
 static inline enum bpf_cgroup_storage_type cgroup_storage_type(
 	struct bpf_map *map)
 {
+	if (map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE)
+		return BPF_CGROUP_STORAGE_PERCPU;
+
 	return BPF_CGROUP_STORAGE_SHARED;
 }
 
@@ -131,6 +137,10 @@ void bpf_cgroup_storage_unlink(struct bpf_cgroup_storage *storage);
 int bpf_cgroup_storage_assign(struct bpf_prog *prog, struct bpf_map *map);
 void bpf_cgroup_storage_release(struct bpf_prog *prog, struct bpf_map *map);
 
+int bpf_percpu_cgroup_storage_copy(struct bpf_map *map, void *key, void *value);
+int bpf_percpu_cgroup_storage_update(struct bpf_map *map, void *key,
+				     void *value, u64 flags);
+
 /* Wrappers for __cgroup_bpf_run_filter_skb() guarded by cgroup_bpf_enabled. */
 #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk, skb)			      \
 ({									      \
@@ -285,6 +295,14 @@ static inline struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(
 	struct bpf_prog *prog, enum bpf_cgroup_storage_type stype) { return 0; }
 static inline void bpf_cgroup_storage_free(
 	struct bpf_cgroup_storage *storage) {}
+static inline int bpf_percpu_cgroup_storage_copy(struct bpf_map *map, void *key,
+						 void *value) {
+	return 0;
+}
+static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,
+					void *key, void *value, u64 flags) {
+	return 0;
+}
 
 #define cgroup_bpf_enabled (0)
 #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (0)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index b457fbe7b70b..018299a595c8 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -274,6 +274,7 @@ struct bpf_prog_offload {
 
 enum bpf_cgroup_storage_type {
 	BPF_CGROUP_STORAGE_SHARED,
+	BPF_CGROUP_STORAGE_PERCPU,
 	__BPF_CGROUP_STORAGE_MAX
 };
 
diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
index c9bd6fb765b0..5432f4c9f50e 100644
--- a/include/linux/bpf_types.h
+++ b/include/linux/bpf_types.h
@@ -43,6 +43,7 @@ BPF_MAP_TYPE(BPF_MAP_TYPE_CGROUP_ARRAY, cgroup_array_map_ops)
 #endif
 #ifdef CONFIG_CGROUP_BPF
 BPF_MAP_TYPE(BPF_MAP_TYPE_CGROUP_STORAGE, cgroup_storage_map_ops)
+BPF_MAP_TYPE(BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE, cgroup_storage_map_ops)
 #endif
 BPF_MAP_TYPE(BPF_MAP_TYPE_HASH, htab_map_ops)
 BPF_MAP_TYPE(BPF_MAP_TYPE_PERCPU_HASH, htab_percpu_map_ops)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index aa5ccd2385ed..e2070d819e04 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -127,6 +127,7 @@ enum bpf_map_type {
 	BPF_MAP_TYPE_SOCKHASH,
 	BPF_MAP_TYPE_CGROUP_STORAGE,
 	BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
+	BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,
 };
 
 enum bpf_prog_type {
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index e42f8789b7ea..6502115e8f55 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -206,10 +206,16 @@ BPF_CALL_2(bpf_get_local_storage, struct bpf_map *, map, u64, flags)
 	 */
 	enum bpf_cgroup_storage_type stype = cgroup_storage_type(map);
 	struct bpf_cgroup_storage *storage;
+	void *ptr;
 
 	storage = this_cpu_read(bpf_cgroup_storage[stype]);
 
-	return (unsigned long)&READ_ONCE(storage->buf)->data[0];
+	if (stype == BPF_CGROUP_STORAGE_SHARED)
+		ptr = &READ_ONCE(storage->buf)->data[0];
+	else
+		ptr = this_cpu_ptr(storage->percpu_buf);
+
+	return (unsigned long)ptr;
 }
 
 const struct bpf_func_proto bpf_get_local_storage_proto = {
diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
index 6742292fb39e..944eb297465f 100644
--- a/kernel/bpf/local_storage.c
+++ b/kernel/bpf/local_storage.c
@@ -152,6 +152,71 @@ static int cgroup_storage_update_elem(struct bpf_map *map, void *_key,
 	return 0;
 }
 
+int bpf_percpu_cgroup_storage_copy(struct bpf_map *_map, void *_key,
+				   void *value)
+{
+	struct bpf_cgroup_storage_map *map = map_to_storage(_map);
+	struct bpf_cgroup_storage_key *key = _key;
+	struct bpf_cgroup_storage *storage;
+	int cpu, off = 0;
+	u32 size;
+
+	rcu_read_lock();
+	storage = cgroup_storage_lookup(map, key, false);
+	if (!storage) {
+		rcu_read_unlock();
+		return -ENOENT;
+	}
+
+	/* per_cpu areas are zero-filled and bpf programs can only
+	 * access 'value_size' of them, so copying rounded areas
+	 * will not leak any kernel data
+	 */
+	size = round_up(_map->value_size, 8);
+	for_each_possible_cpu(cpu) {
+		bpf_long_memcpy(value + off,
+				per_cpu_ptr(storage->percpu_buf, cpu), size);
+		off += size;
+	}
+	rcu_read_unlock();
+	return 0;
+}
+
+int bpf_percpu_cgroup_storage_update(struct bpf_map *_map, void *_key,
+				     void *value, u64 map_flags)
+{
+	struct bpf_cgroup_storage_map *map = map_to_storage(_map);
+	struct bpf_cgroup_storage_key *key = _key;
+	struct bpf_cgroup_storage *storage;
+	int cpu, off = 0;
+	u32 size;
+
+	if (map_flags != BPF_ANY && map_flags != BPF_EXIST)
+		return -EINVAL;
+
+	rcu_read_lock();
+	storage = cgroup_storage_lookup(map, key, false);
+	if (!storage) {
+		rcu_read_unlock();
+		return -ENOENT;
+	}
+
+	/* the user space will provide round_up(value_size, 8) bytes that
+	 * will be copied into per-cpu area. bpf programs can only access
+	 * value_size of it. During lookup the same extra bytes will be
+	 * returned or zeros which were zero-filled by percpu_alloc,
+	 * so no kernel data leaks possible
+	 */
+	size = round_up(_map->value_size, 8);
+	for_each_possible_cpu(cpu) {
+		bpf_long_memcpy(per_cpu_ptr(storage->percpu_buf, cpu),
+				value + off, size);
+		off += size;
+	}
+	rcu_read_unlock();
+	return 0;
+}
+
 static int cgroup_storage_get_next_key(struct bpf_map *_map, void *_key,
 				       void *_next_key)
 {
@@ -287,60 +352,105 @@ void bpf_cgroup_storage_release(struct bpf_prog *prog, struct bpf_map *_map)
 	spin_unlock_bh(&map->lock);
 }
 
+static size_t bpf_cgroup_storage_calculate_size(struct bpf_map *map, u32 *pages)
+{
+	size_t size;
+
+	if (cgroup_storage_type(map) == BPF_CGROUP_STORAGE_SHARED) {
+		size = sizeof(struct bpf_storage_buffer) + map->value_size;
+		*pages = round_up(sizeof(struct bpf_cgroup_storage) + size,
+				  PAGE_SIZE) >> PAGE_SHIFT;
+	} else {
+		size = map->value_size;
+		*pages = round_up(round_up(size, 8) * num_possible_cpus(),
+				  PAGE_SIZE) >> PAGE_SHIFT;
+	}
+
+	return size;
+}
+
 struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(struct bpf_prog *prog,
 					enum bpf_cgroup_storage_type stype)
 {
 	struct bpf_cgroup_storage *storage;
 	struct bpf_map *map;
+	gfp_t flags;
+	size_t size;
 	u32 pages;
 
 	map = prog->aux->cgroup_storage[stype];
 	if (!map)
 		return NULL;
 
-	pages = round_up(sizeof(struct bpf_cgroup_storage) +
-			 sizeof(struct bpf_storage_buffer) +
-			 map->value_size, PAGE_SIZE) >> PAGE_SHIFT;
+	size = bpf_cgroup_storage_calculate_size(map, &pages);
+
 	if (bpf_map_charge_memlock(map, pages))
 		return ERR_PTR(-EPERM);
 
 	storage = kmalloc_node(sizeof(struct bpf_cgroup_storage),
 			       __GFP_ZERO | GFP_USER, map->numa_node);
-	if (!storage) {
-		bpf_map_uncharge_memlock(map, pages);
-		return ERR_PTR(-ENOMEM);
-	}
+	if (!storage)
+		goto enomem;
 
-	storage->buf = kmalloc_node(sizeof(struct bpf_storage_buffer) +
-				    map->value_size, __GFP_ZERO | GFP_USER,
-				    map->numa_node);
-	if (!storage->buf) {
-		bpf_map_uncharge_memlock(map, pages);
-		kfree(storage);
-		return ERR_PTR(-ENOMEM);
+	flags = __GFP_ZERO | GFP_USER;
+
+	if (stype == BPF_CGROUP_STORAGE_SHARED) {
+		storage->buf = kmalloc_node(size, flags, map->numa_node);
+		if (!storage->buf)
+			goto enomem;
+	} else {
+		storage->percpu_buf = __alloc_percpu_gfp(size, 8, flags);
+		if (!storage->percpu_buf)
+			goto enomem;
 	}
 
 	storage->map = (struct bpf_cgroup_storage_map *)map;
 
 	return storage;
+
+enomem:
+	bpf_map_uncharge_memlock(map, pages);
+	kfree(storage);
+	return ERR_PTR(-ENOMEM);
+}
+
+static void free_shared_cgroup_storage_rcu(struct rcu_head *rcu)
+{
+	struct bpf_cgroup_storage *storage =
+		container_of(rcu, struct bpf_cgroup_storage, rcu);
+
+	kfree(storage->buf);
+	kfree(storage);
+}
+
+static void free_percpu_cgroup_storage_rcu(struct rcu_head *rcu)
+{
+	struct bpf_cgroup_storage *storage =
+		container_of(rcu, struct bpf_cgroup_storage, rcu);
+
+	free_percpu(storage->percpu_buf);
+	kfree(storage);
 }
 
 void bpf_cgroup_storage_free(struct bpf_cgroup_storage *storage)
 {
-	u32 pages;
+	enum bpf_cgroup_storage_type stype;
 	struct bpf_map *map;
+	u32 pages;
 
 	if (!storage)
 		return;
 
 	map = &storage->map->map;
-	pages = round_up(sizeof(struct bpf_cgroup_storage) +
-			 sizeof(struct bpf_storage_buffer) +
-			 map->value_size, PAGE_SIZE) >> PAGE_SHIFT;
+
+	bpf_cgroup_storage_calculate_size(map, &pages);
 	bpf_map_uncharge_memlock(map, pages);
 
-	kfree_rcu(storage->buf, rcu);
-	kfree_rcu(storage, rcu);
+	stype = cgroup_storage_type(map);
+	if (stype == BPF_CGROUP_STORAGE_SHARED)
+		call_rcu(&storage->rcu, free_shared_cgroup_storage_rcu);
+	else
+		call_rcu(&storage->rcu, free_percpu_cgroup_storage_rcu);
 }
 
 void bpf_cgroup_storage_link(struct bpf_cgroup_storage *storage,
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 8c91d2b41b1e..5742df21598c 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -686,7 +686,8 @@ static int map_lookup_elem(union bpf_attr *attr)
 
 	if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
 	    map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
-	    map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY)
+	    map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY ||
+	    map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE)
 		value_size = round_up(map->value_size, 8) * num_possible_cpus();
 	else if (IS_FD_MAP(map))
 		value_size = sizeof(u32);
@@ -705,6 +706,8 @@ static int map_lookup_elem(union bpf_attr *attr)
 		err = bpf_percpu_hash_copy(map, key, value);
 	} else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) {
 		err = bpf_percpu_array_copy(map, key, value);
+	} else if (map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE) {
+		err = bpf_percpu_cgroup_storage_copy(map, key, value);
 	} else if (map->map_type == BPF_MAP_TYPE_STACK_TRACE) {
 		err = bpf_stackmap_copy(map, key, value);
 	} else if (IS_FD_ARRAY(map)) {
@@ -774,7 +777,8 @@ static int map_update_elem(union bpf_attr *attr)
 
 	if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
 	    map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
-	    map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY)
+	    map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY ||
+	    map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE)
 		value_size = round_up(map->value_size, 8) * num_possible_cpus();
 	else
 		value_size = map->value_size;
@@ -809,6 +813,9 @@ static int map_update_elem(union bpf_attr *attr)
 		err = bpf_percpu_hash_update(map, key, value, attr->flags);
 	} else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) {
 		err = bpf_percpu_array_update(map, key, value, attr->flags);
+	} else if (map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE) {
+		err = bpf_percpu_cgroup_storage_update(map, key, value,
+						       attr->flags);
 	} else if (IS_FD_ARRAY(map)) {
 		rcu_read_lock();
 		err = bpf_fd_array_map_update_elem(map, f.file, key, value,
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index e90899df585d..a8cc83a970d1 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2074,6 +2074,7 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
 			goto error;
 		break;
 	case BPF_MAP_TYPE_CGROUP_STORAGE:
+	case BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE:
 		if (func_id != BPF_FUNC_get_local_storage)
 			goto error;
 		break;
@@ -2164,7 +2165,8 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
 			goto error;
 		break;
 	case BPF_FUNC_get_local_storage:
-		if (map->map_type != BPF_MAP_TYPE_CGROUP_STORAGE)
+		if (map->map_type != BPF_MAP_TYPE_CGROUP_STORAGE &&
+		    map->map_type != BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE)
 			goto error;
 		break;
 	case BPF_FUNC_sk_select_reuseport:
@@ -5049,6 +5051,12 @@ static int check_map_prog_compatibility(struct bpf_verifier_env *env,
 	return 0;
 }
 
+static bool bpf_map_is_cgroup_storage(struct bpf_map *map)
+{
+	return (map->map_type == BPF_MAP_TYPE_CGROUP_STORAGE ||
+		map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE);
+}
+
 /* look for pseudo eBPF instructions that access map FDs and
  * replace them with actual map pointers
  */
@@ -5139,10 +5147,9 @@ static int replace_map_fd_with_map_ptr(struct bpf_verifier_env *env)
 			}
 			env->used_maps[env->used_map_cnt++] = map;
 
-			if (map->map_type == BPF_MAP_TYPE_CGROUP_STORAGE &&
+			if (bpf_map_is_cgroup_storage(map) &&
 			    bpf_cgroup_storage_assign(env->prog, map)) {
-				verbose(env,
-					"only one cgroup storage is allowed\n");
+				verbose(env, "only one cgroup storage of each type is allowed\n");
 				fdput(f);
 				return -EBUSY;
 			}
-- 
2.17.1

^ permalink raw reply related

* [PATCH v4 bpf-next 04/10] bpf: don't allow create maps of per-cpu cgroup local storages
From: Roman Gushchin @ 2018-09-28 14:45 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: linux-kernel@vger.kernel.org, Kernel Team, Roman Gushchin,
	Daniel Borkmann, Alexei Starovoitov
In-Reply-To: <20180928144452.5284-1-guro@fb.com>

Explicitly forbid creating map of per-cpu cgroup local storages.
This behavior matches the behavior of shared cgroup storages.

Signed-off-by: Roman Gushchin <guro@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
---
 kernel/bpf/map_in_map.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/bpf/map_in_map.c b/kernel/bpf/map_in_map.c
index 3bfbf4464416..99d243e1ad6e 100644
--- a/kernel/bpf/map_in_map.c
+++ b/kernel/bpf/map_in_map.c
@@ -24,7 +24,8 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
 	 * in the verifier is not enough.
 	 */
 	if (inner_map->map_type == BPF_MAP_TYPE_PROG_ARRAY ||
-	    inner_map->map_type == BPF_MAP_TYPE_CGROUP_STORAGE) {
+	    inner_map->map_type == BPF_MAP_TYPE_CGROUP_STORAGE ||
+	    inner_map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE) {
 		fdput(f);
 		return ERR_PTR(-ENOTSUPP);
 	}
-- 
2.17.1

^ permalink raw reply related

* [PATCH v4 bpf-next 05/10] bpf: sync include/uapi/linux/bpf.h to tools/include/uapi/linux/bpf.h
From: Roman Gushchin @ 2018-09-28 14:45 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: linux-kernel@vger.kernel.org, Kernel Team, Roman Gushchin,
	Daniel Borkmann, Alexei Starovoitov
In-Reply-To: <20180928144452.5284-1-guro@fb.com>

The sync is required due to the appearance of a new map type:
BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE, which implements per-cpu
cgroup local storage.

Signed-off-by: Roman Gushchin <guro@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
---
 tools/include/uapi/linux/bpf.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index aa5ccd2385ed..e2070d819e04 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -127,6 +127,7 @@ enum bpf_map_type {
 	BPF_MAP_TYPE_SOCKHASH,
 	BPF_MAP_TYPE_CGROUP_STORAGE,
 	BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
+	BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,
 };
 
 enum bpf_prog_type {
-- 
2.17.1

^ permalink raw reply related

* [PATCH v4 bpf-next 06/10] bpftool: add support for PERCPU_CGROUP_STORAGE maps
From: Roman Gushchin @ 2018-09-28 14:45 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: linux-kernel@vger.kernel.org, Kernel Team, Roman Gushchin,
	Daniel Borkmann, Alexei Starovoitov
In-Reply-To: <20180928144452.5284-1-guro@fb.com>

This commit adds support for BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE
map type.

Signed-off-by: Roman Gushchin <guro@fb.com>
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Acked-by: Song Liu <songliubraving@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
---
 tools/bpf/bpftool/map.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index e22fbe8b975f..6003e9598973 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -72,13 +72,15 @@ static const char * const map_type_name[] = {
 	[BPF_MAP_TYPE_SOCKHASH]		= "sockhash",
 	[BPF_MAP_TYPE_CGROUP_STORAGE]	= "cgroup_storage",
 	[BPF_MAP_TYPE_REUSEPORT_SOCKARRAY] = "reuseport_sockarray",
+	[BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE]	= "percpu_cgroup_storage",
 };
 
 static bool map_is_per_cpu(__u32 type)
 {
 	return type == BPF_MAP_TYPE_PERCPU_HASH ||
 	       type == BPF_MAP_TYPE_PERCPU_ARRAY ||
-	       type == BPF_MAP_TYPE_LRU_PERCPU_HASH;
+	       type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
+	       type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE;
 }
 
 static bool map_is_map_of_maps(__u32 type)
-- 
2.17.1

^ permalink raw reply related

* [PATCH v4 bpf-next 07/10] selftests/bpf: add verifier per-cpu cgroup storage tests
From: Roman Gushchin @ 2018-09-28 14:45 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: linux-kernel@vger.kernel.org, Kernel Team, Roman Gushchin,
	Daniel Borkmann, Alexei Starovoitov
In-Reply-To: <20180928144452.5284-1-guro@fb.com>

This commits adds verifier tests covering per-cpu cgroup storage
functionality. There are 6 new tests, which are exactly the same
as for shared cgroup storage, but do use per-cpu cgroup storage
map.

Expected output:
  $ ./test_verifier
  #0/u add+sub+mul OK
  #0/p add+sub+mul OK
  ...
  #286/p invalid cgroup storage access 6 OK
  #287/p valid per-cpu cgroup storage access OK
  #288/p invalid per-cpu cgroup storage access 1 OK
  #289/p invalid per-cpu cgroup storage access 2 OK
  #290/p invalid per-cpu cgroup storage access 3 OK
  #291/p invalid per-cpu cgroup storage access 4 OK
  #292/p invalid per-cpu cgroup storage access 5 OK
  #293/p invalid per-cpu cgroup storage access 6 OK
  #294/p multiple registers share map_lookup_elem result OK
  ...
  #662/p mov64 src == dst OK
  #663/p mov64 src != dst OK
  Summary: 914 PASSED, 0 SKIPPED, 0 FAILED

Signed-off-by: Roman Gushchin <guro@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
---
 tools/testing/selftests/bpf/test_verifier.c | 139 +++++++++++++++++++-
 1 file changed, 133 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 67c412d19c09..c7d25f23baf9 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -68,6 +68,7 @@ struct bpf_test {
 	int fixup_prog2[MAX_FIXUPS];
 	int fixup_map_in_map[MAX_FIXUPS];
 	int fixup_cgroup_storage[MAX_FIXUPS];
+	int fixup_percpu_cgroup_storage[MAX_FIXUPS];
 	const char *errstr;
 	const char *errstr_unpriv;
 	uint32_t retval;
@@ -4676,7 +4677,7 @@ static struct bpf_test tests[] = {
 		.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
 	},
 	{
-		"invalid per-cgroup storage access 3",
+		"invalid cgroup storage access 3",
 		.insns = {
 			BPF_MOV64_IMM(BPF_REG_2, 0),
 			BPF_LD_MAP_FD(BPF_REG_1, 0),
@@ -4743,6 +4744,121 @@ static struct bpf_test tests[] = {
 		.errstr = "get_local_storage() doesn't support non-zero flags",
 		.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
 	},
+	{
+		"valid per-cpu cgroup storage access",
+		.insns = {
+			BPF_MOV64_IMM(BPF_REG_2, 0),
+			BPF_LD_MAP_FD(BPF_REG_1, 0),
+			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+				     BPF_FUNC_get_local_storage),
+			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
+			BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+			BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
+			BPF_EXIT_INSN(),
+		},
+		.fixup_percpu_cgroup_storage = { 1 },
+		.result = ACCEPT,
+		.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+	},
+	{
+		"invalid per-cpu cgroup storage access 1",
+		.insns = {
+			BPF_MOV64_IMM(BPF_REG_2, 0),
+			BPF_LD_MAP_FD(BPF_REG_1, 0),
+			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+				     BPF_FUNC_get_local_storage),
+			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
+			BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+			BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
+			BPF_EXIT_INSN(),
+		},
+		.fixup_map1 = { 1 },
+		.result = REJECT,
+		.errstr = "cannot pass map_type 1 into func bpf_get_local_storage",
+		.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+	},
+	{
+		"invalid per-cpu cgroup storage access 2",
+		.insns = {
+			BPF_MOV64_IMM(BPF_REG_2, 0),
+			BPF_LD_MAP_FD(BPF_REG_1, 1),
+			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+				     BPF_FUNC_get_local_storage),
+			BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
+			BPF_EXIT_INSN(),
+		},
+		.result = REJECT,
+		.errstr = "fd 1 is not pointing to valid bpf_map",
+		.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+	},
+	{
+		"invalid per-cpu cgroup storage access 3",
+		.insns = {
+			BPF_MOV64_IMM(BPF_REG_2, 0),
+			BPF_LD_MAP_FD(BPF_REG_1, 0),
+			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+				     BPF_FUNC_get_local_storage),
+			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 256),
+			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
+			BPF_MOV64_IMM(BPF_REG_0, 0),
+			BPF_EXIT_INSN(),
+		},
+		.fixup_percpu_cgroup_storage = { 1 },
+		.result = REJECT,
+		.errstr = "invalid access to map value, value_size=64 off=256 size=4",
+		.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+	},
+	{
+		"invalid per-cpu cgroup storage access 4",
+		.insns = {
+			BPF_MOV64_IMM(BPF_REG_2, 0),
+			BPF_LD_MAP_FD(BPF_REG_1, 0),
+			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+				     BPF_FUNC_get_local_storage),
+			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, -2),
+			BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
+			BPF_EXIT_INSN(),
+		},
+		.fixup_cgroup_storage = { 1 },
+		.result = REJECT,
+		.errstr = "invalid access to map value, value_size=64 off=-2 size=4",
+		.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+	},
+	{
+		"invalid per-cpu cgroup storage access 5",
+		.insns = {
+			BPF_MOV64_IMM(BPF_REG_2, 7),
+			BPF_LD_MAP_FD(BPF_REG_1, 0),
+			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+				     BPF_FUNC_get_local_storage),
+			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
+			BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+			BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
+			BPF_EXIT_INSN(),
+		},
+		.fixup_percpu_cgroup_storage = { 1 },
+		.result = REJECT,
+		.errstr = "get_local_storage() doesn't support non-zero flags",
+		.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+	},
+	{
+		"invalid per-cpu cgroup storage access 6",
+		.insns = {
+			BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
+			BPF_LD_MAP_FD(BPF_REG_1, 0),
+			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+				     BPF_FUNC_get_local_storage),
+			BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
+			BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+			BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 1),
+			BPF_EXIT_INSN(),
+		},
+		.fixup_percpu_cgroup_storage = { 1 },
+		.result = REJECT,
+		.errstr = "get_local_storage() doesn't support non-zero flags",
+		.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
+	},
 	{
 		"multiple registers share map_lookup_elem result",
 		.insns = {
@@ -12615,15 +12731,17 @@ static int create_map_in_map(void)
 	return outer_map_fd;
 }
 
-static int create_cgroup_storage(void)
+static int create_cgroup_storage(bool percpu)
 {
+	enum bpf_map_type type = percpu ? BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE :
+		BPF_MAP_TYPE_CGROUP_STORAGE;
 	int fd;
 
-	fd = bpf_create_map(BPF_MAP_TYPE_CGROUP_STORAGE,
-			    sizeof(struct bpf_cgroup_storage_key),
+	fd = bpf_create_map(type, sizeof(struct bpf_cgroup_storage_key),
 			    TEST_DATA_LEN, 0, 0);
 	if (fd < 0)
-		printf("Failed to create array '%s'!\n", strerror(errno));
+		printf("Failed to create cgroup storage '%s'!\n",
+		       strerror(errno));
 
 	return fd;
 }
@@ -12641,6 +12759,7 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
 	int *fixup_prog2 = test->fixup_prog2;
 	int *fixup_map_in_map = test->fixup_map_in_map;
 	int *fixup_cgroup_storage = test->fixup_cgroup_storage;
+	int *fixup_percpu_cgroup_storage = test->fixup_percpu_cgroup_storage;
 
 	if (test->fill_helper)
 		test->fill_helper(test);
@@ -12710,12 +12829,20 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
 	}
 
 	if (*fixup_cgroup_storage) {
-		map_fds[7] = create_cgroup_storage();
+		map_fds[7] = create_cgroup_storage(false);
 		do {
 			prog[*fixup_cgroup_storage].imm = map_fds[7];
 			fixup_cgroup_storage++;
 		} while (*fixup_cgroup_storage);
 	}
+
+	if (*fixup_percpu_cgroup_storage) {
+		map_fds[8] = create_cgroup_storage(true);
+		do {
+			prog[*fixup_percpu_cgroup_storage].imm = map_fds[8];
+			fixup_percpu_cgroup_storage++;
+		} while (*fixup_percpu_cgroup_storage);
+	}
 }
 
 static void do_test_single(struct bpf_test *test, bool unpriv,
-- 
2.17.1

^ permalink raw reply related

* [PATCH v4 bpf-next 08/10] selftests/bpf: extend the storage test to test per-cpu cgroup storage
From: Roman Gushchin @ 2018-09-28 14:45 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: linux-kernel@vger.kernel.org, Kernel Team, Roman Gushchin,
	Daniel Borkmann, Alexei Starovoitov
In-Reply-To: <20180928144452.5284-1-guro@fb.com>

This test extends the cgroup storage test to use per-cpu flavor
of the cgroup storage as well.

The test initializes a per-cpu cgroup storage to some non-zero initial
value (1000), and then simple bumps a per-cpu counter each time
the shared counter is atomically incremented. Then it reads all
per-cpu areas from the userspace side, and checks that the sum
of values adds to the expected sum.

Expected output:
  $ ./test_cgroup_storage
  test_cgroup_storage:PASS

Signed-off-by: Roman Gushchin <guro@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
---
 .../selftests/bpf/test_cgroup_storage.c       | 60 ++++++++++++++++++-
 1 file changed, 57 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/bpf/test_cgroup_storage.c b/tools/testing/selftests/bpf/test_cgroup_storage.c
index 4e196e3bfecf..f44834155f25 100644
--- a/tools/testing/selftests/bpf/test_cgroup_storage.c
+++ b/tools/testing/selftests/bpf/test_cgroup_storage.c
@@ -4,6 +4,7 @@
 #include <linux/filter.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/sysinfo.h>
 
 #include "bpf_rlimit.h"
 #include "cgroup_helpers.h"
@@ -15,6 +16,14 @@ char bpf_log_buf[BPF_LOG_BUF_SIZE];
 int main(int argc, char **argv)
 {
 	struct bpf_insn prog[] = {
+		BPF_LD_MAP_FD(BPF_REG_1, 0), /* percpu map fd */
+		BPF_MOV64_IMM(BPF_REG_2, 0), /* flags, not used */
+		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+			     BPF_FUNC_get_local_storage),
+		BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 0x1),
+		BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
+
 		BPF_LD_MAP_FD(BPF_REG_1, 0), /* map fd */
 		BPF_MOV64_IMM(BPF_REG_2, 0), /* flags, not used */
 		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
@@ -28,9 +37,18 @@ int main(int argc, char **argv)
 	};
 	size_t insns_cnt = sizeof(prog) / sizeof(struct bpf_insn);
 	int error = EXIT_FAILURE;
-	int map_fd, prog_fd, cgroup_fd;
+	int map_fd, percpu_map_fd, prog_fd, cgroup_fd;
 	struct bpf_cgroup_storage_key key;
 	unsigned long long value;
+	unsigned long long *percpu_value;
+	int cpu, nproc;
+
+	nproc = get_nprocs_conf();
+	percpu_value = malloc(sizeof(*percpu_value) * nproc);
+	if (!percpu_value) {
+		printf("Not enough memory for per-cpu area (%d cpus)\n", nproc);
+		goto err;
+	}
 
 	map_fd = bpf_create_map(BPF_MAP_TYPE_CGROUP_STORAGE, sizeof(key),
 				sizeof(value), 0, 0);
@@ -39,7 +57,15 @@ int main(int argc, char **argv)
 		goto out;
 	}
 
-	prog[0].imm = map_fd;
+	percpu_map_fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,
+				       sizeof(key), sizeof(value), 0, 0);
+	if (percpu_map_fd < 0) {
+		printf("Failed to create map: %s\n", strerror(errno));
+		goto out;
+	}
+
+	prog[0].imm = percpu_map_fd;
+	prog[7].imm = map_fd;
 	prog_fd = bpf_load_program(BPF_PROG_TYPE_CGROUP_SKB,
 				   prog, insns_cnt, "GPL", 0,
 				   bpf_log_buf, BPF_LOG_BUF_SIZE);
@@ -77,7 +103,15 @@ int main(int argc, char **argv)
 	}
 
 	if (bpf_map_lookup_elem(map_fd, &key, &value)) {
-		printf("Failed to lookup cgroup storage\n");
+		printf("Failed to lookup cgroup storage 0\n");
+		goto err;
+	}
+
+	for (cpu = 0; cpu < nproc; cpu++)
+		percpu_value[cpu] = 1000;
+
+	if (bpf_map_update_elem(percpu_map_fd, &key, percpu_value, 0)) {
+		printf("Failed to update the data in the cgroup storage\n");
 		goto err;
 	}
 
@@ -120,11 +154,31 @@ int main(int argc, char **argv)
 		goto err;
 	}
 
+	/* Check the final value of the counter in the percpu local storage */
+
+	for (cpu = 0; cpu < nproc; cpu++)
+		percpu_value[cpu] = 0;
+
+	if (bpf_map_lookup_elem(percpu_map_fd, &key, percpu_value)) {
+		printf("Failed to lookup the per-cpu cgroup storage\n");
+		goto err;
+	}
+
+	value = 0;
+	for (cpu = 0; cpu < nproc; cpu++)
+		value += percpu_value[cpu];
+
+	if (value != nproc * 1000 + 6) {
+		printf("Unexpected data in the per-cpu cgroup storage\n");
+		goto err;
+	}
+
 	error = 0;
 	printf("test_cgroup_storage:PASS\n");
 
 err:
 	cleanup_cgroup_environment();
+	free(percpu_value);
 
 out:
 	return error;
-- 
2.17.1

^ permalink raw reply related

* [PATCH v4 bpf-next 09/10] samples/bpf: extend test_cgrp2_attach2 test to use per-cpu cgroup storage
From: Roman Gushchin @ 2018-09-28 14:45 UTC (permalink / raw)
  To: netdev@vger.kernel.org
  Cc: linux-kernel@vger.kernel.org, Kernel Team, Roman Gushchin,
	Daniel Borkmann, Alexei Starovoitov
In-Reply-To: <20180928144452.5284-1-guro@fb.com>

This commit extends the test_cgrp2_attach2 test to cover per-cpu
cgroup storage. Bpf program will use shared and per-cpu cgroup
storages simultaneously, so a better coverage of corresponding
core code will be achieved.

Expected output:
  $ ./test_cgrp2_attach2
  Attached DROP prog. This ping in cgroup /foo should fail...
  ping: sendmsg: Operation not permitted
  Attached DROP prog. This ping in cgroup /foo/bar should fail...
  ping: sendmsg: Operation not permitted
  Attached PASS prog. This ping in cgroup /foo/bar should pass...
  Detached PASS from /foo/bar while DROP is attached to /foo.
  This ping in cgroup /foo/bar should fail...
  ping: sendmsg: Operation not permitted
  Attached PASS from /foo/bar and detached DROP from /foo.
  This ping in cgroup /foo/bar should pass...
  ### override:PASS
  ### multi:PASS

Signed-off-by: Roman Gushchin <guro@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
---
 samples/bpf/test_cgrp2_attach2.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/samples/bpf/test_cgrp2_attach2.c b/samples/bpf/test_cgrp2_attach2.c
index 180f9d813bca..d7b68ef5ba79 100644
--- a/samples/bpf/test_cgrp2_attach2.c
+++ b/samples/bpf/test_cgrp2_attach2.c
@@ -209,7 +209,7 @@ static int map_fd = -1;
 
 static int prog_load_cnt(int verdict, int val)
 {
-	int cgroup_storage_fd;
+	int cgroup_storage_fd, percpu_cgroup_storage_fd;
 
 	if (map_fd < 0)
 		map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, 4, 8, 1, 0);
@@ -225,6 +225,14 @@ static int prog_load_cnt(int verdict, int val)
 		return -1;
 	}
 
+	percpu_cgroup_storage_fd = bpf_create_map(
+		BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,
+		sizeof(struct bpf_cgroup_storage_key), 8, 0, 0);
+	if (percpu_cgroup_storage_fd < 0) {
+		printf("failed to create map '%s'\n", strerror(errno));
+		return -1;
+	}
+
 	struct bpf_insn prog[] = {
 		BPF_MOV32_IMM(BPF_REG_0, 0),
 		BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4), /* *(u32 *)(fp - 4) = r0 */
@@ -235,11 +243,20 @@ static int prog_load_cnt(int verdict, int val)
 		BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
 		BPF_MOV64_IMM(BPF_REG_1, val), /* r1 = 1 */
 		BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_DW, BPF_REG_0, BPF_REG_1, 0, 0), /* xadd r0 += r1 */
+
 		BPF_LD_MAP_FD(BPF_REG_1, cgroup_storage_fd),
 		BPF_MOV64_IMM(BPF_REG_2, 0),
 		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_local_storage),
 		BPF_MOV64_IMM(BPF_REG_1, val),
 		BPF_RAW_INSN(BPF_STX | BPF_XADD | BPF_W, BPF_REG_0, BPF_REG_1, 0, 0),
+
+		BPF_LD_MAP_FD(BPF_REG_1, percpu_cgroup_storage_fd),
+		BPF_MOV64_IMM(BPF_REG_2, 0),
+		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_local_storage),
+		BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 0x1),
+		BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
+
 		BPF_MOV64_IMM(BPF_REG_0, verdict), /* r0 = verdict */
 		BPF_EXIT_INSN(),
 	};
-- 
2.17.1

^ permalink raw reply related

* Re: [PATCH 00/15] octeontx2-af: Add RVU Admin Function driver
From: Arnd Bergmann @ 2018-09-28  8:27 UTC (permalink / raw)
  To: Sunil Kovvuri; +Cc: Networking, David Miller, linux-soc, sgoutham
In-Reply-To: <1538114872-10820-1-git-send-email-sunil.kovvuri@gmail.com>

On Fri, Sep 28, 2018 at 8:08 AM <sunil.kovvuri@gmail.com> wrote:
>
> From: Sunil Goutham <sgoutham@marvell.com>
>
> Resource virtualization unit (RVU) on Marvell's OcteonTX2 SOC maps HW
> resources from the network, crypto and other functional blocks into
> PCI-compatible physical and virtual functions. Each functional block
> again has multiple local functions (LFs) for provisioning to PCI devices.
> RVU supports multiple PCIe SRIOV physical functions (PFs) and virtual
> functions (VFs). PF0 is called the administrative / admin function (AF)
> and has privileges to provision RVU functional block's LFs to each of the
> PF/VF.
>
> RVU managed networking functional blocks
>  - Network pool allocator (NPA)
>  - Network interface controller (NIX)
>  - Network parser CAM (NPC)
>  - Schedule/Synchronize/Order unit (SSO)
>
> RVU managed non-networking functional blocks
>  - Crypto accelerator (CPT)
>  - Scheduled timers unit (TIM)
>  - Schedule/Synchronize/Order unit (SSO)
>    Used for both networking and non networking usecases
>  - Compression (upcoming in future variants of the silicons)
>
> Resource provisioning examples
>  - A PF/VF with NIX-LF & NPA-LF resources works as a pure network device
>  - A PF/VF with CPT-LF resource works as a pure cyrpto offload device.
>
> This admin function driver neither receives any data nor processes it i.e
> no I/O, a configuration only driver.
>
> PF/VFs communicates with AF via a shared memory region (mailbox). Upon
> receiving requests from PF/VF, AF does resource provisioning and other
> HW configuration. AF is always attached to host, but PF/VFs may be used
> by host kernel itself, or attached to VMs or to userspace applications
> like DPDK etc. So AF has to handle provisioning/configuration requests
> sent by any device from any domain.
>
> This patch series adds logic for the following
>  - RVU AF driver with functional blocks provisioning support.
>  - Mailbox infrastructure for communication between AF and PFs.
>  - CGX (MAC controller) driver which communicates with firmware for
>    managing  physical ethernet interfaces. AF collects info from this
>    driver and forwards the same to the PF/VFs uaing these interfaces.
>
> This is the first set of patches out of 80+ patches.

Hi Sunil,

This looks good overall, thanks for moving it to drivers/net
as I suggested. I found two more minor remaining issues here,
it should not be a problem to change the code accordingly.

One thing I was missing here is a revision history for the patch
series, it would have been helpful to get a list of things you have
changed compared to the previous submission, what triggered
those changes, and which issues (if any) are still remaining.
Best add the full revision history in the next (hopefully final)
round for these patches, and use 'git format-patch --reroll-count'
to add the patchset revision number.

I assume that the next set of patches will be more controversial
as you get to the point that adds the user interface. I have
not looked at those patches yet, so it may just be fine, assuming
all the configuration is done using devlink. Please keep me
on Cc for the future series, even if I don't participate in those
reviews as much.

Thanks,

      Arnd

^ permalink raw reply

* Re: [PATCH net-next v6 01/23] asm: simd context helper API
From: Ard Biesheuvel @ 2018-09-28  8:28 UTC (permalink / raw)
  To: Jason A. Donenfeld
  Cc: Linux Kernel Mailing List, <netdev@vger.kernel.org>,
	open list:HARDWARE RANDOM NUMBER GENERATOR CORE, David S. Miller,
	Greg Kroah-Hartman, Samuel Neves, Andy Lutomirski,
	Thomas Gleixner, linux-arch
In-Reply-To: <20180925145622.29959-2-Jason@zx2c4.com>

On 25 September 2018 at 16:56, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> Sometimes it's useful to amortize calls to XSAVE/XRSTOR and the related
> FPU/SIMD functions over a number of calls, because FPU restoration is
> quite expensive. This adds a simple header for carrying out this pattern:
>
>     simd_context_t simd_context;
>
>     simd_get(&simd_context);
>     while ((item = get_item_from_queue()) != NULL) {
>         encrypt_item(item, simd_context);
>         simd_relax(&simd_context);
>     }
>     simd_put(&simd_context);
>
> The relaxation step ensures that we don't trample over preemption, and
> the get/put API should be a familiar paradigm in the kernel.
>
> On the other end, code that actually wants to use SIMD instructions can
> accept this as a parameter and check it via:
>
>    void encrypt_item(struct item *item, simd_context_t *simd_context)
>    {
>        if (item->len > LARGE_FOR_SIMD && simd_use(simd_context))
>            wild_simd_code(item);
>        else
>            boring_scalar_code(item);
>    }
>
> The actual XSAVE happens during simd_use (and only on the first time),
> so that if the context is never actually used, no performance penalty is
> hit.
>
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> Cc: Samuel Neves <sneves@dei.uc.pt>
> Cc: Andy Lutomirski <luto@kernel.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Greg KH <gregkh@linuxfoundation.org>
> Cc: linux-arch@vger.kernel.org
> ---
>  arch/alpha/include/asm/Kbuild      |  5 ++-
>  arch/arc/include/asm/Kbuild        |  1 +
>  arch/arm/include/asm/simd.h        | 63 ++++++++++++++++++++++++++++++
>  arch/arm64/include/asm/simd.h      | 51 +++++++++++++++++++++---
>  arch/c6x/include/asm/Kbuild        |  3 +-
>  arch/h8300/include/asm/Kbuild      |  3 +-
>  arch/hexagon/include/asm/Kbuild    |  1 +
>  arch/ia64/include/asm/Kbuild       |  1 +
>  arch/m68k/include/asm/Kbuild       |  1 +
>  arch/microblaze/include/asm/Kbuild |  1 +
>  arch/mips/include/asm/Kbuild       |  1 +
>  arch/nds32/include/asm/Kbuild      |  7 ++--
>  arch/nios2/include/asm/Kbuild      |  1 +
>  arch/openrisc/include/asm/Kbuild   |  7 ++--
>  arch/parisc/include/asm/Kbuild     |  1 +
>  arch/powerpc/include/asm/Kbuild    |  3 +-
>  arch/riscv/include/asm/Kbuild      |  3 +-
>  arch/s390/include/asm/Kbuild       |  3 +-
>  arch/sh/include/asm/Kbuild         |  1 +
>  arch/sparc/include/asm/Kbuild      |  1 +
>  arch/um/include/asm/Kbuild         |  3 +-
>  arch/unicore32/include/asm/Kbuild  |  1 +
>  arch/x86/include/asm/simd.h        | 44 ++++++++++++++++++++-
>  arch/xtensa/include/asm/Kbuild     |  1 +
>  include/asm-generic/simd.h         | 20 ++++++++++
>  include/linux/simd.h               | 28 +++++++++++++
>  26 files changed, 234 insertions(+), 21 deletions(-)
>  create mode 100644 arch/arm/include/asm/simd.h
>  create mode 100644 include/linux/simd.h
>
> diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild
> index 0580cb8c84b2..07b2c1025d34 100644
> --- a/arch/alpha/include/asm/Kbuild
> +++ b/arch/alpha/include/asm/Kbuild
> @@ -2,14 +2,15 @@
>
>
>  generic-y += compat.h
> +generic-y += current.h
>  generic-y += exec.h
>  generic-y += export.h
>  generic-y += fb.h
>  generic-y += irq_work.h
> +generic-y += kprobes.h
>  generic-y += mcs_spinlock.h
>  generic-y += mm-arch-hooks.h
>  generic-y += preempt.h
>  generic-y += sections.h
> +generic-y += simd.h
>  generic-y += trace_clock.h
> -generic-y += current.h
> -generic-y += kprobes.h

Given that this patch applies to all architectures at once, it is
probably better to drop the unrelated reordering hunks to avoid
conflicts.

> diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild
> index feed50ce89fa..a7f4255f1649 100644
> --- a/arch/arc/include/asm/Kbuild
> +++ b/arch/arc/include/asm/Kbuild
> @@ -22,6 +22,7 @@ generic-y += parport.h
>  generic-y += pci.h
>  generic-y += percpu.h
>  generic-y += preempt.h
> +generic-y += simd.h
>  generic-y += topology.h
>  generic-y += trace_clock.h
>  generic-y += user.h
> diff --git a/arch/arm/include/asm/simd.h b/arch/arm/include/asm/simd.h
> new file mode 100644
> index 000000000000..263950dd69cb
> --- /dev/null
> +++ b/arch/arm/include/asm/simd.h
> @@ -0,0 +1,63 @@
> +/* SPDX-License-Identifier: GPL-2.0
> + *
> + * Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
> + */
> +
> +#include <linux/simd.h>
> +#ifndef _ASM_SIMD_H
> +#define _ASM_SIMD_H
> +
> +#ifdef CONFIG_KERNEL_MODE_NEON
> +#include <asm/neon.h>
> +
> +static __must_check inline bool may_use_simd(void)
> +{
> +       return !in_interrupt();
> +}
> +

Remember this guy?

https://marc.info/?l=linux-arch&m=149631094625176&w=2

That was never merged, so let's get it right this time.

> +static inline void simd_get(simd_context_t *ctx)
> +{
> +       *ctx = may_use_simd() ? HAVE_FULL_SIMD : HAVE_NO_SIMD;
> +}
> +
> +static inline void simd_put(simd_context_t *ctx)
> +{
> +       if (*ctx & HAVE_SIMD_IN_USE)
> +               kernel_neon_end();
> +       *ctx = HAVE_NO_SIMD;
> +}
> +
> +static __must_check inline bool simd_use(simd_context_t *ctx)
> +{
> +       if (!(*ctx & HAVE_FULL_SIMD))
> +               return false;
> +       if (*ctx & HAVE_SIMD_IN_USE)
> +               return true;
> +       kernel_neon_begin();
> +       *ctx |= HAVE_SIMD_IN_USE;
> +       return true;
> +}
> +
> +#else
> +
> +static __must_check inline bool may_use_simd(void)
> +{
> +       return false;
> +}
> +
> +static inline void simd_get(simd_context_t *ctx)
> +{
> +       *ctx = HAVE_NO_SIMD;
> +}
> +
> +static inline void simd_put(simd_context_t *ctx)
> +{
> +}
> +
> +static __must_check inline bool simd_use(simd_context_t *ctx)
> +{
> +       return false;
> +}
> +#endif
> +
> +#endif /* _ASM_SIMD_H */
> diff --git a/arch/arm64/include/asm/simd.h b/arch/arm64/include/asm/simd.h
> index 6495cc51246f..a45ff1600040 100644
> --- a/arch/arm64/include/asm/simd.h
> +++ b/arch/arm64/include/asm/simd.h
> @@ -1,11 +1,10 @@
> -/*
> - * Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org>
> +/* SPDX-License-Identifier: GPL-2.0
>   *
> - * This program is free software; you can redistribute it and/or modify it
> - * under the terms of the GNU General Public License version 2 as published
> - * by the Free Software Foundation.
> + * Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org>
> + * Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
>   */
>
> +#include <linux/simd.h>
>  #ifndef __ASM_SIMD_H
>  #define __ASM_SIMD_H
>
> @@ -16,6 +15,8 @@
>  #include <linux/types.h>
>
>  #ifdef CONFIG_KERNEL_MODE_NEON
> +#include <asm/neon.h>
> +#include <asm/simd.h>
>
>  DECLARE_PER_CPU(bool, kernel_neon_busy);
>
> @@ -40,9 +41,47 @@ static __must_check inline bool may_use_simd(void)
>                 !this_cpu_read(kernel_neon_busy);
>  }
>
> +static inline void simd_get(simd_context_t *ctx)
> +{
> +       *ctx = may_use_simd() ? HAVE_FULL_SIMD : HAVE_NO_SIMD;
> +}
> +
> +static inline void simd_put(simd_context_t *ctx)
> +{
> +       if (*ctx & HAVE_SIMD_IN_USE)
> +               kernel_neon_end();
> +       *ctx = HAVE_NO_SIMD;
> +}
> +
> +static __must_check inline bool simd_use(simd_context_t *ctx)
> +{
> +       if (!(*ctx & HAVE_FULL_SIMD))
> +               return false;
> +       if (*ctx & HAVE_SIMD_IN_USE)
> +               return true;
> +       kernel_neon_begin();
> +       *ctx |= HAVE_SIMD_IN_USE;
> +       return true;
> +}
> +
>  #else /* ! CONFIG_KERNEL_MODE_NEON */
>
> -static __must_check inline bool may_use_simd(void) {
> +static __must_check inline bool may_use_simd(void)
> +{
> +       return false;
> +}
> +
> +static inline void simd_get(simd_context_t *ctx)
> +{
> +       *ctx = HAVE_NO_SIMD;
> +}
> +
> +static inline void simd_put(simd_context_t *ctx)
> +{
> +}
> +
> +static __must_check inline bool simd_use(simd_context_t *ctx)
> +{
>         return false;
>  }
>
> diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
> index 33a2c94fed0d..22f3d8333c74 100644
> --- a/arch/c6x/include/asm/Kbuild
> +++ b/arch/c6x/include/asm/Kbuild
> @@ -5,8 +5,8 @@ generic-y += compat.h
>  generic-y += current.h
>  generic-y += device.h
>  generic-y += div64.h
> -generic-y += dma.h
>  generic-y += dma-mapping.h
> +generic-y += dma.h
>  generic-y += emergency-restart.h
>  generic-y += exec.h
>  generic-y += extable.h
> @@ -30,6 +30,7 @@ generic-y += pgalloc.h
>  generic-y += preempt.h
>  generic-y += segment.h
>  generic-y += serial.h
> +generic-y += simd.h
>  generic-y += tlbflush.h
>  generic-y += topology.h
>  generic-y += trace_clock.h
> diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild
> index a5d0b2991f47..f5c2f12d593e 100644
> --- a/arch/h8300/include/asm/Kbuild
> +++ b/arch/h8300/include/asm/Kbuild
> @@ -8,8 +8,8 @@ generic-y += current.h
>  generic-y += delay.h
>  generic-y += device.h
>  generic-y += div64.h
> -generic-y += dma.h
>  generic-y += dma-mapping.h
> +generic-y += dma.h
>  generic-y += emergency-restart.h
>  generic-y += exec.h
>  generic-y += extable.h
> @@ -39,6 +39,7 @@ generic-y += preempt.h
>  generic-y += scatterlist.h
>  generic-y += sections.h
>  generic-y += serial.h
> +generic-y += simd.h
>  generic-y += sizes.h
>  generic-y += spinlock.h
>  generic-y += timex.h
> diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
> index dd2fd9c0d292..217d4695fd8a 100644
> --- a/arch/hexagon/include/asm/Kbuild
> +++ b/arch/hexagon/include/asm/Kbuild
> @@ -29,6 +29,7 @@ generic-y += rwsem.h
>  generic-y += sections.h
>  generic-y += segment.h
>  generic-y += serial.h
> +generic-y += simd.h
>  generic-y += sizes.h
>  generic-y += topology.h
>  generic-y += trace_clock.h
> diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
> index 557bbc8ba9f5..41c5ebdf79e5 100644
> --- a/arch/ia64/include/asm/Kbuild
> +++ b/arch/ia64/include/asm/Kbuild
> @@ -4,6 +4,7 @@ generic-y += irq_work.h
>  generic-y += mcs_spinlock.h
>  generic-y += mm-arch-hooks.h
>  generic-y += preempt.h
> +generic-y += simd.h
>  generic-y += trace_clock.h
>  generic-y += vtime.h
>  generic-y += word-at-a-time.h
> diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
> index a4b8d3331a9e..73898dd1a4d0 100644
> --- a/arch/m68k/include/asm/Kbuild
> +++ b/arch/m68k/include/asm/Kbuild
> @@ -19,6 +19,7 @@ generic-y += mm-arch-hooks.h
>  generic-y += percpu.h
>  generic-y += preempt.h
>  generic-y += sections.h
> +generic-y += simd.h
>  generic-y += spinlock.h
>  generic-y += topology.h
>  generic-y += trace_clock.h
> diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
> index 569ba9e670c1..7a877eea99d3 100644
> --- a/arch/microblaze/include/asm/Kbuild
> +++ b/arch/microblaze/include/asm/Kbuild
> @@ -25,6 +25,7 @@ generic-y += parport.h
>  generic-y += percpu.h
>  generic-y += preempt.h
>  generic-y += serial.h
> +generic-y += simd.h
>  generic-y += syscalls.h
>  generic-y += topology.h
>  generic-y += trace_clock.h
> diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
> index 58351e48421e..e8868e0fb2c3 100644
> --- a/arch/mips/include/asm/Kbuild
> +++ b/arch/mips/include/asm/Kbuild
> @@ -16,6 +16,7 @@ generic-y += qrwlock.h
>  generic-y += qspinlock.h
>  generic-y += sections.h
>  generic-y += segment.h
> +generic-y += simd.h
>  generic-y += trace_clock.h
>  generic-y += unaligned.h
>  generic-y += user.h
> diff --git a/arch/nds32/include/asm/Kbuild b/arch/nds32/include/asm/Kbuild
> index dbc4e5422550..603c1d020620 100644
> --- a/arch/nds32/include/asm/Kbuild
> +++ b/arch/nds32/include/asm/Kbuild
> @@ -7,14 +7,14 @@ generic-y += bug.h
>  generic-y += bugs.h
>  generic-y += checksum.h
>  generic-y += clkdev.h
> -generic-y += cmpxchg.h
>  generic-y += cmpxchg-local.h
> +generic-y += cmpxchg.h
>  generic-y += compat.h
>  generic-y += cputime.h
>  generic-y += device.h
>  generic-y += div64.h
> -generic-y += dma.h
>  generic-y += dma-mapping.h
> +generic-y += dma.h
>  generic-y += emergency-restart.h
>  generic-y += errno.h
>  generic-y += exec.h
> @@ -46,14 +46,15 @@ generic-y += sections.h
>  generic-y += segment.h
>  generic-y += serial.h
>  generic-y += shmbuf.h
> +generic-y += simd.h
>  generic-y += sizes.h
>  generic-y += stat.h
>  generic-y += switch_to.h
>  generic-y += timex.h
>  generic-y += topology.h
>  generic-y += trace_clock.h
> -generic-y += xor.h
>  generic-y += unaligned.h
>  generic-y += user.h
>  generic-y += vga.h
>  generic-y += word-at-a-time.h
> +generic-y += xor.h
> diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild
> index 8fde4fa2c34f..571a9d9ad107 100644
> --- a/arch/nios2/include/asm/Kbuild
> +++ b/arch/nios2/include/asm/Kbuild
> @@ -33,6 +33,7 @@ generic-y += preempt.h
>  generic-y += sections.h
>  generic-y += segment.h
>  generic-y += serial.h
> +generic-y += simd.h
>  generic-y += spinlock.h
>  generic-y += topology.h
>  generic-y += trace_clock.h
> diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
> index eb87cd8327c8..5e9f2f4c4d39 100644
> --- a/arch/openrisc/include/asm/Kbuild
> +++ b/arch/openrisc/include/asm/Kbuild
> @@ -28,12 +28,13 @@ generic-y += module.h
>  generic-y += pci.h
>  generic-y += percpu.h
>  generic-y += preempt.h
> -generic-y += qspinlock_types.h
> -generic-y += qspinlock.h
> -generic-y += qrwlock_types.h
>  generic-y += qrwlock.h
> +generic-y += qrwlock_types.h
> +generic-y += qspinlock.h
> +generic-y += qspinlock_types.h
>  generic-y += sections.h
>  generic-y += segment.h
> +generic-y += simd.h
>  generic-y += string.h
>  generic-y += switch_to.h
>  generic-y += topology.h
> diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild
> index 2013d639e735..97970b4d05ab 100644
> --- a/arch/parisc/include/asm/Kbuild
> +++ b/arch/parisc/include/asm/Kbuild
> @@ -17,6 +17,7 @@ generic-y += percpu.h
>  generic-y += preempt.h
>  generic-y += seccomp.h
>  generic-y += segment.h
> +generic-y += simd.h
>  generic-y += topology.h
>  generic-y += trace_clock.h
>  generic-y += user.h
> diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
> index 3196d227e351..64290f48e733 100644
> --- a/arch/powerpc/include/asm/Kbuild
> +++ b/arch/powerpc/include/asm/Kbuild
> @@ -4,7 +4,8 @@ generic-y += irq_regs.h
>  generic-y += irq_work.h
>  generic-y += local64.h
>  generic-y += mcs_spinlock.h
> +generic-y += msi.h
>  generic-y += preempt.h
>  generic-y += rwsem.h
> +generic-y += simd.h
>  generic-y += vtime.h
> -generic-y += msi.h
> diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
> index efdbe311e936..6669b7374c0a 100644
> --- a/arch/riscv/include/asm/Kbuild
> +++ b/arch/riscv/include/asm/Kbuild
> @@ -5,9 +5,9 @@ generic-y += compat.h
>  generic-y += cputime.h
>  generic-y += device.h
>  generic-y += div64.h
> -generic-y += dma.h
>  generic-y += dma-contiguous.h
>  generic-y += dma-mapping.h
> +generic-y += dma.h
>  generic-y += emergency-restart.h
>  generic-y += errno.h
>  generic-y += exec.h
> @@ -46,6 +46,7 @@ generic-y += setup.h
>  generic-y += shmbuf.h
>  generic-y += shmparam.h
>  generic-y += signal.h
> +generic-y += simd.h
>  generic-y += socket.h
>  generic-y += sockios.h
>  generic-y += stat.h
> diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild
> index e3239772887a..7a26dc6ce815 100644
> --- a/arch/s390/include/asm/Kbuild
> +++ b/arch/s390/include/asm/Kbuild
> @@ -7,9 +7,9 @@ generated-y += unistd_nr.h
>  generic-y += asm-offsets.h
>  generic-y += cacheflush.h
>  generic-y += device.h
> +generic-y += div64.h
>  generic-y += dma-contiguous.h
>  generic-y += dma-mapping.h
> -generic-y += div64.h
>  generic-y += emergency-restart.h
>  generic-y += export.h
>  generic-y += fb.h
> @@ -22,6 +22,7 @@ generic-y += mcs_spinlock.h
>  generic-y += mm-arch-hooks.h
>  generic-y += preempt.h
>  generic-y += rwsem.h
> +generic-y += simd.h
>  generic-y += trace_clock.h
>  generic-y += unaligned.h
>  generic-y += word-at-a-time.h
> diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
> index 6a5609a55965..8e64ff35a933 100644
> --- a/arch/sh/include/asm/Kbuild
> +++ b/arch/sh/include/asm/Kbuild
> @@ -16,6 +16,7 @@ generic-y += percpu.h
>  generic-y += preempt.h
>  generic-y += rwsem.h
>  generic-y += serial.h
> +generic-y += simd.h
>  generic-y += sizes.h
>  generic-y += trace_clock.h
>  generic-y += xor.h
> diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
> index 410b263ef5c8..72b9e08fb350 100644
> --- a/arch/sparc/include/asm/Kbuild
> +++ b/arch/sparc/include/asm/Kbuild
> @@ -17,5 +17,6 @@ generic-y += msi.h
>  generic-y += preempt.h
>  generic-y += rwsem.h
>  generic-y += serial.h
> +generic-y += simd.h
>  generic-y += trace_clock.h
>  generic-y += word-at-a-time.h
> diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild
> index b10dde6cb793..d37288b08dd2 100644
> --- a/arch/um/include/asm/Kbuild
> +++ b/arch/um/include/asm/Kbuild
> @@ -16,15 +16,16 @@ generic-y += io.h
>  generic-y += irq_regs.h
>  generic-y += irq_work.h
>  generic-y += kdebug.h
> +generic-y += kprobes.h
>  generic-y += mcs_spinlock.h
>  generic-y += mm-arch-hooks.h
>  generic-y += param.h
>  generic-y += pci.h
>  generic-y += percpu.h
>  generic-y += preempt.h
> +generic-y += simd.h
>  generic-y += switch_to.h
>  generic-y += topology.h
>  generic-y += trace_clock.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
> -generic-y += kprobes.h
> diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild
> index bfc7abe77905..98a908720bbd 100644
> --- a/arch/unicore32/include/asm/Kbuild
> +++ b/arch/unicore32/include/asm/Kbuild
> @@ -27,6 +27,7 @@ generic-y += preempt.h
>  generic-y += sections.h
>  generic-y += segment.h
>  generic-y += serial.h
> +generic-y += simd.h
>  generic-y += sizes.h
>  generic-y += syscalls.h
>  generic-y += topology.h
> diff --git a/arch/x86/include/asm/simd.h b/arch/x86/include/asm/simd.h
> index a341c878e977..4aad7f158dcb 100644
> --- a/arch/x86/include/asm/simd.h
> +++ b/arch/x86/include/asm/simd.h
> @@ -1,4 +1,11 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> +/* SPDX-License-Identifier: GPL-2.0
> + *
> + * Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
> + */
> +
> +#include <linux/simd.h>
> +#ifndef _ASM_SIMD_H
> +#define _ASM_SIMD_H
>
>  #include <asm/fpu/api.h>
>
> @@ -10,3 +17,38 @@ static __must_check inline bool may_use_simd(void)
>  {
>         return irq_fpu_usable();
>  }
> +
> +static inline void simd_get(simd_context_t *ctx)
> +{
> +#if !defined(CONFIG_UML)
> +       *ctx = may_use_simd() ? HAVE_FULL_SIMD : HAVE_NO_SIMD;
> +#else
> +       *ctx = HAVE_NO_SIMD;
> +#endif
> +}
> +
> +static inline void simd_put(simd_context_t *ctx)
> +{
> +#if !defined(CONFIG_UML)
> +       if (*ctx & HAVE_SIMD_IN_USE)
> +               kernel_fpu_end();
> +#endif
> +       *ctx = HAVE_NO_SIMD;
> +}
> +
> +static __must_check inline bool simd_use(simd_context_t *ctx)
> +{
> +#if !defined(CONFIG_UML)
> +       if (!(*ctx & HAVE_FULL_SIMD))
> +               return false;
> +       if (*ctx & HAVE_SIMD_IN_USE)
> +               return true;
> +       kernel_fpu_begin();
> +       *ctx |= HAVE_SIMD_IN_USE;
> +       return true;
> +#else
> +       return false;
> +#endif
> +}
> +
> +#endif /* _ASM_SIMD_H */
> diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild
> index 82c756431b49..7950f359649d 100644
> --- a/arch/xtensa/include/asm/Kbuild
> +++ b/arch/xtensa/include/asm/Kbuild
> @@ -24,6 +24,7 @@ generic-y += percpu.h
>  generic-y += preempt.h
>  generic-y += rwsem.h
>  generic-y += sections.h
> +generic-y += simd.h
>  generic-y += topology.h
>  generic-y += trace_clock.h
>  generic-y += word-at-a-time.h
> diff --git a/include/asm-generic/simd.h b/include/asm-generic/simd.h
> index d0343d58a74a..b3dd61ac010e 100644
> --- a/include/asm-generic/simd.h
> +++ b/include/asm-generic/simd.h
> @@ -1,5 +1,9 @@
>  /* SPDX-License-Identifier: GPL-2.0 */
>
> +#include <linux/simd.h>
> +#ifndef _ASM_SIMD_H
> +#define _ASM_SIMD_H
> +
>  #include <linux/hardirq.h>
>
>  /*
> @@ -13,3 +17,19 @@ static __must_check inline bool may_use_simd(void)
>  {
>         return !in_interrupt();
>  }
> +
> +static inline void simd_get(simd_context_t *ctx)
> +{
> +       *ctx = HAVE_NO_SIMD;
> +}
> +
> +static inline void simd_put(simd_context_t *ctx)
> +{
> +}
> +
> +static __must_check inline bool simd_use(simd_context_t *ctx)
> +{
> +       return false;
> +}
> +
> +#endif /* _ASM_SIMD_H */
> diff --git a/include/linux/simd.h b/include/linux/simd.h
> new file mode 100644
> index 000000000000..33bba21012ff
> --- /dev/null
> +++ b/include/linux/simd.h
> @@ -0,0 +1,28 @@
> +/* SPDX-License-Identifier: GPL-2.0
> + *
> + * Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
> + */
> +
> +#ifndef _SIMD_H
> +#define _SIMD_H
> +
> +typedef enum {
> +       HAVE_NO_SIMD = 1 << 0,
> +       HAVE_FULL_SIMD = 1 << 1,
> +       HAVE_SIMD_IN_USE = 1 << 31
> +} simd_context_t;
> +
> +#include <linux/sched.h>
> +#include <asm/simd.h>
> +
> +static inline void simd_relax(simd_context_t *ctx)
> +{
> +#ifdef CONFIG_PREEMPT
> +       if ((*ctx & HAVE_SIMD_IN_USE) && need_resched()) {
> +               simd_put(ctx);
> +               simd_get(ctx);
> +       }
> +#endif

Could we return a bool here indicating whether we rescheduled or not?
In some cases, we could pass that into the asm code as a 'reload'
param, allowing repeated loads of key schedules, round constant tables
or S-boxes to be elided.

> +}
> +
> +#endif /* _SIMD_H */
> --
> 2.19.0
>

^ permalink raw reply

* RE: [PATCH v2 net-next 0/2] Add support for Microchip Technology KSZ9131 10/100/1000 Ethernet PHY
From: Yuiko.Oshino @ 2018-09-28 14:51 UTC (permalink / raw)
  To: f.fainelli, davem, robh+dt, devicetree, andrew
  Cc: linux-kernel, mark.rutland, m.felsch, Markus.Niebel, netdev,
	UNGLinuxDriver
In-Reply-To: <7c84dfed-6864-7b25-38d1-9bed1cfea0bc@gmail.com>

>On 09/27/2018 01:15 PM, Yuiko Oshino wrote:
>> This is the initial driver for Microchip KSZ9131 10/100/1000 Ethernet
>> PHY
>>
>> v2:
>> - Creating a series from two related patches.
>
>When people give you Acked-by or Reviewed-by tags in prior versions, it is usually
>a good  practice to add them to your next version of the patch submission. Also,
>your patches 1 and 2 did not show up as as reply to this cover letter, while they
>should, please fix this if you ever need to submit new patches in the future.
>
>Thank you!

Florian,
Thank you for your reviews. Sorry I forgot to add Acked-by.
Is seems like I am modifying the dt-binding doc, so I will submit v3.
Thank you!

>
>--
>Florian

Yuiko

^ permalink raw reply

* Re: [PATCH] netfilter: check if the socket netns is correct.
From: Pablo Neira Ayuso @ 2018-09-28  8:33 UTC (permalink / raw)
  To: Flavio Leitner
  Cc: Guenter Roeck, Jozsef Kadlecsik, Florian Westphal,
	David S. Miller, Alexey Kuznetsov, Hideaki YOSHIFUJI,
	netfilter-devel, coreteam, netdev, linux-kernel
In-Reply-To: <20180927225824.GT2702@plex.lan>

On Thu, Sep 27, 2018 at 07:58:24PM -0300, Flavio Leitner wrote:
[...]
> From a5f927e7f1368d753f87cb978d630d786d5adb62 Mon Sep 17 00:00:00 2001
> From: Flavio Leitner <fbl@redhat.com>
> Date: Thu, 27 Sep 2018 19:36:28 -0300
> Subject: [PATCH] xt_socket: check sk before checking for netns.
> 
> Only check for the network namespace if the socket is available.

Applied.

Please, Cc netfilter-devel@vger.kernel.org next time for your
netfilter patches.

Thanks.

^ permalink raw reply

* Re: [PATCH net-next v6 23/23] net: WireGuard secure network tunnel
From: Andrew Lunn @ 2018-09-28 15:01 UTC (permalink / raw)
  To: Jason A. Donenfeld
  Cc: LKML, Netdev, Linux Crypto Mailing List, David Miller,
	Greg Kroah-Hartman
In-Reply-To: <CAHmME9q7WRGF3TTRhhy0i_EB4ad2DaSD=tnHM92zfV4Cckyw=A@mail.gmail.com>

On Fri, Sep 28, 2018 at 12:37:03AM +0200, Jason A. Donenfeld wrote:
> Hi Andrew,
> 
> Thanks for following up with this.
> 
> On Thu, Sep 27, 2018 at 3:15 AM Andrew Lunn <andrew@lunn.ch> wrote:
> > I know you have been concentrating on the crypto code, so i'm not
> > expecting too many changes at the moment in the network code.
> 
> I should be addressing things in parallel, actually, so I'm happy to
> work on this.
> 
> > WARNING: Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()
> > #2984: FILE: drivers/net/wireguard/noise.c:293:
> > +       BUG_ON(first_len > BLAKE2S_HASH_SIZE || second_len > BLAKE2S_HASH_SIZE ||
> 
> I was actually going to ask you about this, because it applies
> similarly in another context too that I'm trying to refine. The above
> function you quote has the following properties:

We have the above case, and we have the general case. The general case
is, only use BUG_ON() when you know things have already gone bad and
there is no recovery for the machine. I doubt that ever applies to
wireguard. So i expect all the BUG_ON() to be removed. This is
something which Linus keeps ranting about....

In this case:

You have it inside a #ifdef. Meaning you don't really care, you can
keep going anyway if debugging is turned of. So just turn it into a
WARN_ON() so you get the splat, but the kernel keeps running.

You have some other options. first_len, second_len, third_len are all
parameter coming from #defines. As you suggested, you could do
BUILD_BUG_ON(), but you have to do it at the caller. Which is fine,
this is debug code, not user input validation code...

        BUILD_BUG_ON(NOISE_HASH_LEN > BLAKE2S_HAS_SIZE)
        BUILD_BUG_ON(NOISE_SYMMETRIC_KEY_LEN > BLAKE2S_HAS_SIZE)
        BUILD_BUG_ON(NOISE_PUBLIC_KEY_LEN > BLAKE2S_HAS_SIZE)
        kdf(chaining_key, key, NULL, dh_calculation, NOISE_HASH_LEN,
            NOISE_SYMMETRIC_KEY_LEN, 0, NOISE_PUBLIC_KEY_LEN, chaining_key);

> > WARNING: Macros with flow control statements should be avoided
> > #5471: FILE: drivers/net/wireguard/selftest/allowedips.h:456:
> > +#define init_peer(name) do {                                               \
> > +               name = kzalloc(sizeof(*name), GFP_KERNEL);                 \
> > +               if (unlikely(!name)) {                                     \
> > +                       pr_info("allowedips self-test: out of memory\n");  \
> > +                       goto free;                                         \
> > +               }                                                          \
> > +               kref_init(&name->refcount);                                \
> > +       } while (0)
> 
> This is part of a debugging selftest, where I'm initing a bunch of
> peers one after another, and this macro helps keep the test clear
> while offloading the actual irrelevant coding part to this macro. The
> test itself then just has code like:

Please don't focus on just the examples i give you. Look at the bigger
issue. We cannot see the woods for the trees. checkpatch is giving out
lots of warnings. There are so many, it is hard to see the interesting
ones from the simple ones where you need to add an extra space, or add
missing {}.

If checkpatch was just issues one or two warnings about a goto in a
macro, and nothing else, i probably would let it pass. This is bad,
but it is not terrible. I personally have fallen into a trap caused by
a goto in a macro. I changed the locking, not knowing about the goto,
causing an error path not to unlock the lock. It took a while, but
eventually the error happened, and soon after the machine
deadlocked. At the time static checkers did not expand macros, so they
did not detect the issue.

> On a slightly related note, out of curiosity, any idea what's up with
> the future of LTO in the kernel?

Sorry, i've no idea. Not my corner of the kernel.

> It sounds like that'd be nice to have
> on a module-by-module basis. IOW, I'd love to LTO all of my .c files
> in wireguard together, and then only ever expose mod_init/exit and
> whatever I explicitly EXPORT_SYMBOL

The namespace is more than just about the linker. I see an Opps stack
trace with wg_ symbols, i know i need to talk to Jason. Without any
prefix, i have to go digging into the code to find out who i need to
talk to. This is one reason why often every symbol has the prefix, not
just the global scope ones. Go look at other code in driver/net. You
will find that most drivers use a prefix everywhere, both local and
global.

     Andrew

^ permalink raw reply

* Re: [PATCH net-next v6 23/23] net: WireGuard secure network tunnel
From: Jason A. Donenfeld @ 2018-09-28 15:04 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: LKML, Netdev, Linux Crypto Mailing List, David Miller,
	Greg Kroah-Hartman
In-Reply-To: <20180928150117.GA19396@lunn.ch>

On Fri, Sep 28, 2018 at 5:01 PM Andrew Lunn <andrew@lunn.ch> wrote:
> The namespace is more than just about the linker. I see an Opps stack
> trace with wg_ symbols, i know i need to talk to Jason. Without any
> prefix, i have to go digging into the code to find out who i need to
> talk to. This is one reason why often every symbol has the prefix, not
> just the global scope ones.

Good point. I'll see what the wg_ prefixing looks like for all the
static functions too.

^ permalink raw reply

* INFO: trying to register non-static key in tun_chr_write_iter
From: syzbot @ 2018-09-28 15:05 UTC (permalink / raw)
  To: brouer, davem, edumazet, jasowang, linux-kernel, mst, netdev, sd,
	syzkaller-bugs

Hello,

syzbot found the following crash on:

HEAD commit:    100811936f89 bpf: test_bpf: add init_net to dev for flow_d..
git tree:       bpf-next
console output: https://syzkaller.appspot.com/x/log.txt?x=145378e6400000
kernel config:  https://syzkaller.appspot.com/x/.config?x=443816db871edd66
dashboard link: https://syzkaller.appspot.com/bug?extid=e662df0ac1d753b57e80
compiler:       gcc (GCC) 8.0.1 20180413 (experimental)

Unfortunately, I don't have any reproducer for this crash yet.

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+e662df0ac1d753b57e80@syzkaller.appspotmail.com

device nr0\x01 entered promiscuous mode
INFO: trying to register non-static key.
kobject: 'tx-1' (00000000e8c66ef6): kobject_add_internal: parent: 'queues',  
set: 'queues'
the code is fine but needs lockdep annotation.
turning off the locking correctness validator.
CPU: 0 PID: 11684 Comm: syz-executor3 Not tainted 4.19.0-rc5+ #104
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS  
Google 01/01/2011
Call Trace:
  __dump_stack lib/dump_stack.c:77 [inline]
  dump_stack+0x1c4/0x2b4 lib/dump_stack.c:113
  assign_lock_key kernel/locking/lockdep.c:727 [inline]
  register_lock_class+0x21a7/0x29b0 kernel/locking/lockdep.c:753
  __lock_acquire+0x1c1/0x4ec0 kernel/locking/lockdep.c:3299
  lock_acquire+0x1ed/0x520 kernel/locking/lockdep.c:3900
  __mutex_lock_common kernel/locking/mutex.c:925 [inline]
  __mutex_lock+0x166/0x1700 kernel/locking/mutex.c:1072
  mutex_lock_nested+0x16/0x20 kernel/locking/mutex.c:1087
  tun_get_user+0x1e02/0x42a0 drivers/net/tun.c:1826
  tun_chr_write_iter+0xb9/0x160 drivers/net/tun.c:2001
  call_write_iter include/linux/fs.h:1808 [inline]
  new_sync_write fs/read_write.c:474 [inline]
  __vfs_write+0x6b8/0x9f0 fs/read_write.c:487
  vfs_write+0x1fc/0x560 fs/read_write.c:549
  ksys_write+0x101/0x260 fs/read_write.c:598
  __do_sys_write fs/read_write.c:610 [inline]
  __se_sys_write fs/read_write.c:607 [inline]
  __x64_sys_write+0x73/0xb0 fs/read_write.c:607
  do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290
  entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x457579
Code: 1d b4 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7  
48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff  
ff 0f 83 eb b3 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007f681315ec78 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000457579
RDX: 0000000000000012 RSI: 0000000020000000 RDI: 000000000000000b
RBP: 000000000072c180 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007f681315f6d4
R13: 00000000004c5574 R14: 00000000004d8e98 R15: 00000000ffffffff
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'tx-1' (00000000e8c66ef6): kobject_uevent_env
kobject: 'tx-1' (00000000e8c66ef6): fill_kobj_path: path  
= '/devices/virtual/net/nr0\x01/queues/tx-1'
kobject: 'rx-1' (00000000b39a08f5): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop4' (00000000a9f26271): fill_kobj_path: path  
= '/devices/virtual/block/loop4'
kobject: 'rx-1' (00000000b39a08f5): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'rx-1' (00000000b39a08f5): fill_kobj_path: path  
= '/devices/virtual/net/nr0\x01/queues/rx-1'
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'tx-1' (00000000e8c66ef6): kobject_cleanup, parent 000000007699ee79
kobject: 'tx-1' (00000000e8c66ef6): auto cleanup 'remove' event
kobject: 'tx-1' (00000000e8c66ef6): kobject_uevent_env
kobject: 'tx-1' (00000000e8c66ef6): fill_kobj_path: path  
= '/devices/virtual/net/nr0\x01/queues/tx-1'
kobject: 'tx-1' (00000000e8c66ef6): auto cleanup kobject_del
kobject: 'tx-1' (00000000e8c66ef6): calling ktype release
kobject: 'tx-1': free name
kobject: 'rx-1' (00000000b39a08f5): kobject_cleanup, parent 000000007699ee79
kobject: 'rx-1' (00000000b39a08f5): auto cleanup 'remove' event
kobject: 'rx-1' (00000000b39a08f5): kobject_uevent_env
kobject: 'rx-1' (00000000b39a08f5): fill_kobj_path: path  
= '/devices/virtual/net/nr0\x01/queues/rx-1'
kobject: 'rx-1' (00000000b39a08f5): auto cleanup kobject_del
kobject: 'rx-1' (00000000b39a08f5): calling ktype release
kobject: 'rx-1': free name
kobject: 'rx-0' (000000003e93d61e): kobject_cleanup, parent 000000007699ee79
kobject: 'rx-0' (000000003e93d61e): auto cleanup 'remove' event
kobject: 'rx-0' (000000003e93d61e): kobject_uevent_env
kobject: 'rx-0' (000000003e93d61e): fill_kobj_path: path  
= '/devices/virtual/net/nr0\x01/queues/rx-0'
kobject: 'rx-0' (000000003e93d61e): auto cleanup kobject_del
kobject: 'rx-0' (000000003e93d61e): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (000000003e264bf3): kobject_cleanup, parent 000000007699ee79
kobject: 'tx-0' (000000003e264bf3): auto cleanup 'remove' event
kobject: 'tx-0' (000000003e264bf3): kobject_uevent_env
kobject: 'tx-0' (000000003e264bf3): fill_kobj_path: path  
= '/devices/virtual/net/nr0\x01/queues/tx-0'
kobject: 'tx-0' (000000003e264bf3): auto cleanup kobject_del
kobject: 'tx-0' (000000003e264bf3): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (000000007699ee79): kobject_cleanup, parent            
(null)
kobject: 'queues' (000000007699ee79): calling ktype release
kobject: 'queues' (000000007699ee79): kset_release
kobject: 'queues': free name
kobject: 'nr0\x01' (00000000ee24d4b5): kobject_uevent_env
kobject: 'nr0\x01' (00000000ee24d4b5): fill_kobj_path: path  
= '/devices/virtual/net/nr0\x01'
kobject: 'nr0\x01' (00000000ee24d4b5): kobject_cleanup, parent           (null)
kobject: 'nr0\x01' (00000000ee24d4b5): calling ktype release
kobject: 'nr0\x01': free name
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'i' (00000000c801699c): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'i' (00000000c801699c): kobject_uevent_env
kobject: 'i' (00000000c801699c): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'queues' (0000000043f5dc52): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'queues' (0000000043f5dc52): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'queues' (0000000043f5dc52): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'rx-0' (00000000600dcf17): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'rx-0' (00000000600dcf17): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'rx-0' (00000000600dcf17): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'tx-0' (0000000047ae8cc6): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'tx-0' (0000000047ae8cc6): kobject_uevent_env
kobject: 'tx-0' (0000000047ae8cc6): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'rx-0' (00000000600dcf17): kobject_cleanup, parent 0000000043f5dc52
kobject: 'rx-0' (00000000600dcf17): auto cleanup 'remove' event
kobject: 'rx-0' (00000000600dcf17): kobject_uevent_env
kobject: 'rx-0' (00000000600dcf17): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (00000000600dcf17): auto cleanup kobject_del
kobject: 'rx-0' (00000000600dcf17): calling ktype release
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'rx-0': free name
kobject: 'tx-0' (0000000047ae8cc6): kobject_cleanup, parent 0000000043f5dc52
kobject: 'tx-0' (0000000047ae8cc6): auto cleanup 'remove' event
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'tx-0' (0000000047ae8cc6): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'tx-0' (0000000047ae8cc6): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'tx-0' (0000000047ae8cc6): auto cleanup kobject_del
kobject: 'tx-0' (0000000047ae8cc6): calling ktype release
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'tx-0': free name
kobject: 'queues' (0000000043f5dc52): kobject_cleanup, parent            
(null)
kobject: 'queues' (0000000043f5dc52): calling ktype release
kobject: 'queues' (0000000043f5dc52): kset_release
kobject: 'queues': free name
kobject: 'i' (00000000c801699c): kobject_uevent_env
kobject: 'i' (00000000c801699c): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'i' (00000000c801699c): kobject_cleanup, parent           (null)
kobject: 'i' (00000000c801699c): calling ktype release
kobject: 'i': free name
kobject: 'i' (00000000a7641c59): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'i' (00000000a7641c59): kobject_uevent_env
kobject: 'i' (00000000a7641c59): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'queues' (0000000095fbc889): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'queues' (0000000095fbc889): kobject_uevent_env
kobject: 'queues' (0000000095fbc889): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'rx-0' (00000000eef86eb6): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'rx-0' (00000000eef86eb6): kobject_uevent_env
kobject: 'rx-0' (00000000eef86eb6): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (0000000077222671): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'tx-0' (0000000077222671): kobject_uevent_env
kobject: 'tx-0' (0000000077222671): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'rx-0' (00000000eef86eb6): kobject_cleanup, parent 0000000095fbc889
kobject: 'rx-0' (00000000eef86eb6): auto cleanup 'remove' event
kobject: 'rx-0' (00000000eef86eb6): kobject_uevent_env
kobject: 'rx-0' (00000000eef86eb6): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (00000000eef86eb6): auto cleanup kobject_del
kobject: 'rx-0' (00000000eef86eb6): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (0000000077222671): kobject_cleanup, parent 0000000095fbc889
kobject: 'tx-0' (0000000077222671): auto cleanup 'remove' event
kobject: 'tx-0' (0000000077222671): kobject_uevent_env
kobject: 'tx-0' (0000000077222671): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (0000000077222671): auto cleanup kobject_del
kobject: 'tx-0' (0000000077222671): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (0000000095fbc889): kobject_cleanup, parent            
(null)
kobject: 'queues' (0000000095fbc889): calling ktype release
kobject: 'queues' (0000000095fbc889): kset_release
kobject: 'queues': free name
kobject: 'i' (00000000a7641c59): kobject_uevent_env
kobject: 'i' (00000000a7641c59): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'i' (00000000a7641c59): kobject_cleanup, parent           (null)
kobject: 'i' (00000000a7641c59): calling ktype release
kobject: 'i': free name
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'loop4' (00000000a9f26271): fill_kobj_path: path  
= '/devices/virtual/block/loop4'
kobject: 'i' (000000000d9ae1e5): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'i' (000000000d9ae1e5): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'i' (000000000d9ae1e5): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'queues' (00000000e089a529): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'queues' (00000000e089a529): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'queues' (00000000e089a529): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'rx-0' (0000000095823a56): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'rx-0' (0000000095823a56): kobject_uevent_env
kobject: 'rx-0' (0000000095823a56): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (000000002f7588ed): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'tx-0' (000000002f7588ed): kobject_uevent_env
kobject: 'tx-0' (000000002f7588ed): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'rx-0' (0000000095823a56): kobject_cleanup, parent 00000000e089a529
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'rx-0' (0000000095823a56): auto cleanup 'remove' event
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'rx-0' (0000000095823a56): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'rx-0' (0000000095823a56): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'rx-0' (0000000095823a56): auto cleanup kobject_del
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'rx-0' (0000000095823a56): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (000000002f7588ed): kobject_cleanup, parent 00000000e089a529
kobject: 'tx-0' (000000002f7588ed): auto cleanup 'remove' event
kobject: 'tx-0' (000000002f7588ed): kobject_uevent_env
kobject: 'tx-0' (000000002f7588ed): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (000000002f7588ed): auto cleanup kobject_del
kobject: 'tx-0' (000000002f7588ed): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (00000000e089a529): kobject_cleanup, parent            
(null)
kobject: 'queues' (00000000e089a529): calling ktype release
kobject: 'queues' (00000000e089a529): kset_release
kobject: 'queues': free name
kobject: 'i' (000000000d9ae1e5): kobject_uevent_env
kobject: 'i' (000000000d9ae1e5): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'i' (000000000d9ae1e5): kobject_cleanup, parent           (null)
kobject: 'i' (000000000d9ae1e5): calling ktype release
kobject: 'i': free name
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'loop4' (00000000a9f26271): fill_kobj_path: path  
= '/devices/virtual/block/loop4'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'i' (000000003db311aa): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'i' (000000003db311aa): kobject_uevent_env
kobject: 'i' (000000003db311aa): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'queues' (0000000006c3516d): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'queues' (0000000006c3516d): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'queues' (0000000006c3516d): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'rx-0' (00000000ca97a144): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'rx-0' (00000000ca97a144): kobject_uevent_env
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'rx-0' (00000000ca97a144): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'tx-0' (00000000a18be29e): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'tx-0' (00000000a18be29e): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'tx-0' (00000000a18be29e): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'rx-0' (00000000ca97a144): kobject_cleanup, parent 0000000006c3516d
kobject: 'rx-0' (00000000ca97a144): auto cleanup 'remove' event
kobject: 'rx-0' (00000000ca97a144): kobject_uevent_env
kobject: 'rx-0' (00000000ca97a144): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (00000000ca97a144): auto cleanup kobject_del
kobject: 'rx-0' (00000000ca97a144): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (00000000a18be29e): kobject_cleanup, parent 0000000006c3516d
kobject: 'tx-0' (00000000a18be29e): auto cleanup 'remove' event
kobject: 'tx-0' (00000000a18be29e): kobject_uevent_env
kobject: 'tx-0' (00000000a18be29e): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (00000000a18be29e): auto cleanup kobject_del
kobject: 'tx-0' (00000000a18be29e): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (0000000006c3516d): kobject_cleanup, parent            
(null)
kobject: 'queues' (0000000006c3516d): calling ktype release
kobject: 'queues' (0000000006c3516d): kset_release
kobject: 'queues': free name
kobject: 'i' (000000003db311aa): kobject_uevent_env
kobject: 'i' (000000003db311aa): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'i' (000000003db311aa): kobject_cleanup, parent           (null)
kobject: 'i' (000000003db311aa): calling ktype release
kobject: 'i': free name
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'i' (00000000d8b5fb5b): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'i' (00000000d8b5fb5b): kobject_uevent_env
kobject: 'i' (00000000d8b5fb5b): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'queues' (0000000029da0284): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'queues' (0000000029da0284): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'queues' (0000000029da0284): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'rx-0' (000000009326241e): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop4' (00000000a9f26271): fill_kobj_path: path  
= '/devices/virtual/block/loop4'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'rx-0' (000000009326241e): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'rx-0' (000000009326241e): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (00000000c0e108a6): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'tx-0' (00000000c0e108a6): kobject_uevent_env
kobject: 'tx-0' (00000000c0e108a6): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'i' (00000000983a79d1): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'i' (00000000983a79d1): kobject_uevent_env
kobject: 'i' (00000000983a79d1): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'queues' (0000000067601488): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'queues' (0000000067601488): kobject_uevent_env
kobject: 'queues' (0000000067601488): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'rx-0' (0000000081097f67): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'rx-0' (0000000081097f67): kobject_uevent_env
kobject: 'rx-0' (0000000081097f67): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (000000005f03e7ce): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'tx-0' (000000005f03e7ce): kobject_uevent_env
kobject: 'tx-0' (000000005f03e7ce): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'rx-0' (0000000081097f67): kobject_cleanup, parent 0000000067601488
kobject: 'rx-0' (0000000081097f67): auto cleanup 'remove' event
kobject: 'rx-0' (0000000081097f67): kobject_uevent_env
kobject: 'rx-0' (0000000081097f67): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (0000000081097f67): auto cleanup kobject_del
kobject: 'rx-0' (0000000081097f67): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (000000005f03e7ce): kobject_cleanup, parent 0000000067601488
kobject: 'tx-0' (000000005f03e7ce): auto cleanup 'remove' event
kobject: 'tx-0' (000000005f03e7ce): kobject_uevent_env
kobject: 'tx-0' (000000005f03e7ce): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (000000005f03e7ce): auto cleanup kobject_del
kobject: 'tx-0' (000000005f03e7ce): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (0000000067601488): kobject_cleanup, parent            
(null)
kobject: 'queues' (0000000067601488): calling ktype release
kobject: 'queues' (0000000067601488): kset_release
kobject: 'queues': free name
kobject: 'i' (00000000983a79d1): kobject_uevent_env
kobject: 'i' (00000000983a79d1): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'rx-0' (000000009326241e): kobject_cleanup, parent 0000000029da0284
kobject: 'rx-0' (000000009326241e): auto cleanup 'remove' event
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'rx-0' (000000009326241e): kobject_uevent_env
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'rx-0' (000000009326241e): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (000000009326241e): auto cleanup kobject_del
kobject: 'rx-0' (000000009326241e): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (00000000c0e108a6): kobject_cleanup, parent 0000000029da0284
kobject: 'tx-0' (00000000c0e108a6): auto cleanup 'remove' event
kobject: 'tx-0' (00000000c0e108a6): kobject_uevent_env
kobject: 'tx-0' (00000000c0e108a6): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (00000000c0e108a6): auto cleanup kobject_del
kobject: 'tx-0' (00000000c0e108a6): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (0000000029da0284): kobject_cleanup, parent            
(null)
kobject: 'queues' (0000000029da0284): calling ktype release
kobject: 'queues' (0000000029da0284): kset_release
kobject: 'queues': free name
kobject: 'i' (00000000d8b5fb5b): kobject_uevent_env
kobject: 'i' (00000000d8b5fb5b): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'i' (00000000983a79d1): kobject_cleanup, parent           (null)
kobject: 'i' (00000000983a79d1): calling ktype release
kobject: 'i': free name
kobject: 'i' (00000000d8b5fb5b): kobject_cleanup, parent           (null)
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'i' (00000000d8b5fb5b): calling ktype release
kobject: 'loop4' (00000000a9f26271): fill_kobj_path: path  
= '/devices/virtual/block/loop4'
kobject: 'i': free name
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'i' (00000000127717e2): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'i' (00000000127717e2): kobject_uevent_env
kobject: 'i' (00000000127717e2): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'queues' (00000000d6787087): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'queues' (00000000d6787087): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'queues' (00000000d6787087): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'rx-0' (0000000066d53395): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'rx-0' (0000000066d53395): kobject_uevent_env
kobject: 'rx-0' (0000000066d53395): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (00000000cd4658a4): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'tx-0' (00000000cd4658a4): kobject_uevent_env
kobject: 'tx-0' (00000000cd4658a4): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'i' (000000008ace66eb): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'i' (000000008ace66eb): kobject_uevent_env
kobject: 'i' (000000008ace66eb): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'queues' (00000000261c8543): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'queues' (00000000261c8543): kobject_uevent_env
kobject: 'queues' (00000000261c8543): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'rx-0' (000000004a180861): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'rx-0' (000000004a180861): kobject_uevent_env
kobject: 'rx-0' (000000004a180861): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (00000000063907b4): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'tx-0' (00000000063907b4): kobject_uevent_env
kobject: 'tx-0' (00000000063907b4): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'rx-0' (000000004a180861): kobject_cleanup, parent 00000000261c8543
kobject: 'rx-0' (000000004a180861): auto cleanup 'remove' event
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'rx-0' (000000004a180861): kobject_uevent_env
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'rx-0' (000000004a180861): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (000000004a180861): auto cleanup kobject_del
kobject: 'rx-0' (000000004a180861): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (00000000063907b4): kobject_cleanup, parent 00000000261c8543
kobject: 'tx-0' (00000000063907b4): auto cleanup 'remove' event
kobject: 'tx-0' (00000000063907b4): kobject_uevent_env
kobject: 'tx-0' (00000000063907b4): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (00000000063907b4): auto cleanup kobject_del
kobject: 'tx-0' (00000000063907b4): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (00000000261c8543): kobject_cleanup, parent            
(null)
kobject: 'queues' (00000000261c8543): calling ktype release
kobject: 'queues' (00000000261c8543): kset_release
kobject: 'queues': free name
kobject: 'i' (000000008ace66eb): kobject_uevent_env
kobject: 'i' (000000008ace66eb): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'rx-0' (0000000066d53395): kobject_cleanup, parent 00000000d6787087
kobject: 'rx-0' (0000000066d53395): auto cleanup 'remove' event
kobject: 'rx-0' (0000000066d53395): kobject_uevent_env
kobject: 'rx-0' (0000000066d53395): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (0000000066d53395): auto cleanup kobject_del
kobject: 'rx-0' (0000000066d53395): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (00000000cd4658a4): kobject_cleanup, parent 00000000d6787087
kobject: 'tx-0' (00000000cd4658a4): auto cleanup 'remove' event
kobject: 'tx-0' (00000000cd4658a4): kobject_uevent_env
kobject: 'tx-0' (00000000cd4658a4): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (00000000cd4658a4): auto cleanup kobject_del
kobject: 'tx-0' (00000000cd4658a4): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (00000000d6787087): kobject_cleanup, parent            
(null)
kobject: 'queues' (00000000d6787087): calling ktype release
kobject: 'queues' (00000000d6787087): kset_release
kobject: 'queues': free name
kobject: 'i' (00000000127717e2): kobject_uevent_env
kobject: 'i' (00000000127717e2): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'i' (000000008ace66eb): kobject_cleanup, parent           (null)
kobject: 'i' (000000008ace66eb): calling ktype release
kobject: 'i': free name
kobject: 'i' (00000000127717e2): kobject_cleanup, parent           (null)
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'i' (00000000127717e2): calling ktype release
kobject: 'loop4' (00000000a9f26271): fill_kobj_path: path  
= '/devices/virtual/block/loop4'
kobject: 'i': free name
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'i' (000000002a5ba534): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'i' (000000002a5ba534): kobject_uevent_env
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'i' (000000002a5ba534): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'queues' (000000002bd3c0c9): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'queues' (000000002bd3c0c9): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'queues' (000000002bd3c0c9): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'rx-0' (000000001a0ac9ca): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'rx-0' (000000001a0ac9ca): kobject_uevent_env
kobject: 'rx-0' (000000001a0ac9ca): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (000000004afdf9ed): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'tx-0' (000000004afdf9ed): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'tx-0' (000000004afdf9ed): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'i' (0000000089867b8d): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'i' (0000000089867b8d): kobject_uevent_env
kobject: 'i' (0000000089867b8d): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'queues' (00000000f9cebe04): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'queues' (00000000f9cebe04): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'queues' (00000000f9cebe04): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'rx-0' (00000000eb735641): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'rx-0' (00000000eb735641): kobject_uevent_env
kobject: 'rx-0' (00000000eb735641): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (00000000d8b46f99): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'tx-0' (00000000d8b46f99): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'tx-0' (00000000d8b46f99): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'rx-0' (00000000eb735641): kobject_cleanup, parent 00000000f9cebe04
kobject: 'rx-0' (00000000eb735641): auto cleanup 'remove' event
kobject: 'rx-0' (00000000eb735641): kobject_uevent_env
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'rx-0' (00000000eb735641): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'rx-0' (00000000eb735641): auto cleanup kobject_del
kobject: 'rx-0' (00000000eb735641): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (00000000d8b46f99): kobject_cleanup, parent 00000000f9cebe04
kobject: 'tx-0' (00000000d8b46f99): auto cleanup 'remove' event
kobject: 'tx-0' (00000000d8b46f99): kobject_uevent_env
kobject: 'tx-0' (00000000d8b46f99): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (00000000d8b46f99): auto cleanup kobject_del
kobject: 'tx-0' (00000000d8b46f99): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (00000000f9cebe04): kobject_cleanup, parent            
(null)
kobject: 'queues' (00000000f9cebe04): calling ktype release
kobject: 'queues' (00000000f9cebe04): kset_release
kobject: 'queues': free name
kobject: 'i' (0000000089867b8d): kobject_uevent_env
kobject: 'i' (0000000089867b8d): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'rx-0' (000000001a0ac9ca): kobject_cleanup, parent 000000002bd3c0c9
kobject: 'rx-0' (000000001a0ac9ca): auto cleanup 'remove' event
kobject: 'rx-0' (000000001a0ac9ca): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'rx-0' (000000001a0ac9ca): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'rx-0' (000000001a0ac9ca): auto cleanup kobject_del
kobject: 'rx-0' (000000001a0ac9ca): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (000000004afdf9ed): kobject_cleanup, parent 000000002bd3c0c9
kobject: 'tx-0' (000000004afdf9ed): auto cleanup 'remove' event
kobject: 'tx-0' (000000004afdf9ed): kobject_uevent_env
kobject: 'tx-0' (000000004afdf9ed): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (000000004afdf9ed): auto cleanup kobject_del
kobject: 'tx-0' (000000004afdf9ed): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (000000002bd3c0c9): kobject_cleanup, parent            
(null)
kobject: 'queues' (000000002bd3c0c9): calling ktype release
kobject: 'queues' (000000002bd3c0c9): kset_release
kobject: 'queues': free name
kobject: 'i' (000000002a5ba534): kobject_uevent_env
kobject: 'i' (000000002a5ba534): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'i' (00000000bdbce1b0): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'i' (00000000bdbce1b0): kobject_uevent_env
kobject: 'i' (00000000bdbce1b0): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'queues' (0000000086c1dba6): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'queues' (0000000086c1dba6): kobject_uevent_env
kobject: 'queues' (0000000086c1dba6): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'rx-0' (0000000004c94468): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'rx-0' (0000000004c94468): kobject_uevent_env
kobject: 'rx-0' (0000000004c94468): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (0000000004076f2f): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'tx-0' (0000000004076f2f): kobject_uevent_env
kobject: 'tx-0' (0000000004076f2f): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'rx-0' (0000000004c94468): kobject_cleanup, parent 0000000086c1dba6
kobject: 'rx-0' (0000000004c94468): auto cleanup 'remove' event
kobject: 'rx-0' (0000000004c94468): kobject_uevent_env
kobject: 'rx-0' (0000000004c94468): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (0000000004c94468): auto cleanup kobject_del
kobject: 'rx-0' (0000000004c94468): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (0000000004076f2f): kobject_cleanup, parent 0000000086c1dba6
kobject: 'tx-0' (0000000004076f2f): auto cleanup 'remove' event
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'tx-0' (0000000004076f2f): kobject_uevent_env
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'tx-0' (0000000004076f2f): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (0000000004076f2f): auto cleanup kobject_del
kobject: 'tx-0' (0000000004076f2f): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (0000000086c1dba6): kobject_cleanup, parent            
(null)
kobject: 'queues' (0000000086c1dba6): calling ktype release
kobject: 'queues' (0000000086c1dba6): kset_release
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'queues': free name
kobject: 'i' (00000000bdbce1b0): kobject_uevent_env
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'i' (00000000bdbce1b0): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'i' (0000000089867b8d): kobject_cleanup, parent           (null)
kobject: 'i' (0000000089867b8d): calling ktype release
kobject: 'i' (000000002a5ba534): kobject_cleanup, parent           (null)
kobject: 'i': free name
kobject: 'i' (000000002a5ba534): calling ktype release
kobject: 'i': free name
kobject: 'i' (00000000bdbce1b0): kobject_cleanup, parent           (null)
kobject: 'i' (00000000bdbce1b0): calling ktype release
kobject: 'i': free name
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'i' (000000006d24ca63): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'loop4' (00000000a9f26271): fill_kobj_path: path  
= '/devices/virtual/block/loop4'
kobject: 'i' (000000006d24ca63): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'i' (000000006d24ca63): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'queues' (0000000007a511a1): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'queues' (0000000007a511a1): kobject_uevent_env
kobject: 'queues' (0000000007a511a1): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'rx-0' (000000001946dc59): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'rx-0' (000000001946dc59): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'rx-0' (000000001946dc59): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (00000000ef0cc92d): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'tx-0' (00000000ef0cc92d): kobject_uevent_env
kobject: 'tx-0' (00000000ef0cc92d): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'i' (00000000917865da): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'i' (00000000917865da): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'i' (00000000917865da): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'queues' (0000000088d9fc56): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'queues' (0000000088d9fc56): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'queues' (0000000088d9fc56): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'rx-0' (0000000098e9720c): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'rx-0' (0000000098e9720c): kobject_uevent_env
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'rx-0' (0000000098e9720c): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'tx-0' (000000003a747871): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'tx-0' (000000003a747871): kobject_uevent_env
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'tx-0' (000000003a747871): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'i' (00000000d2824c3a): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'i' (00000000d2824c3a): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'i' (00000000d2824c3a): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'queues' (00000000f8d9b04d): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'queues' (00000000f8d9b04d): kobject_uevent_env
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'queues' (00000000f8d9b04d): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'rx-0' (0000000076725752): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'rx-0' (0000000076725752): kobject_uevent_env
kobject: 'rx-0' (0000000076725752): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (00000000dfa5fc07): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'tx-0' (00000000dfa5fc07): kobject_uevent_env
kobject: 'tx-0' (00000000dfa5fc07): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'rx-0' (000000001946dc59): kobject_cleanup, parent 0000000007a511a1
kobject: 'rx-0' (000000001946dc59): auto cleanup 'remove' event
kobject: 'rx-0' (000000001946dc59): kobject_uevent_env
kobject: 'rx-0' (000000001946dc59): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (000000001946dc59): auto cleanup kobject_del
kobject: 'rx-0' (000000001946dc59): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (00000000ef0cc92d): kobject_cleanup, parent 0000000007a511a1
kobject: 'tx-0' (00000000ef0cc92d): auto cleanup 'remove' event
kobject: 'tx-0' (00000000ef0cc92d): kobject_uevent_env
kobject: 'tx-0' (00000000ef0cc92d): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (00000000ef0cc92d): auto cleanup kobject_del
kobject: 'tx-0' (00000000ef0cc92d): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (0000000007a511a1): kobject_cleanup, parent            
(null)
kobject: 'queues' (0000000007a511a1): calling ktype release
kobject: 'queues' (0000000007a511a1): kset_release
kobject: 'queues': free name
kobject: 'i' (000000006d24ca63): kobject_uevent_env
kobject: 'i' (000000006d24ca63): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'rx-0' (0000000098e9720c): kobject_cleanup, parent 0000000088d9fc56
kobject: 'rx-0' (0000000098e9720c): auto cleanup 'remove' event
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'rx-0' (0000000098e9720c): kobject_uevent_env
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'rx-0' (0000000098e9720c): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (0000000098e9720c): auto cleanup kobject_del
kobject: 'rx-0' (0000000098e9720c): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (000000003a747871): kobject_cleanup, parent 0000000088d9fc56
kobject: 'tx-0' (000000003a747871): auto cleanup 'remove' event
kobject: 'tx-0' (000000003a747871): kobject_uevent_env
kobject: 'tx-0' (000000003a747871): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (000000003a747871): auto cleanup kobject_del
kobject: 'tx-0' (000000003a747871): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (0000000088d9fc56): kobject_cleanup, parent            
(null)
kobject: 'queues' (0000000088d9fc56): calling ktype release
kobject: 'queues' (0000000088d9fc56): kset_release
kobject: 'queues': free name
kobject: 'i' (00000000917865da): kobject_uevent_env
kobject: 'i' (00000000917865da): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'rx-0' (0000000076725752): kobject_cleanup, parent 00000000f8d9b04d
kobject: 'rx-0' (0000000076725752): auto cleanup 'remove' event
kobject: 'rx-0' (0000000076725752): kobject_uevent_env
kobject: 'rx-0' (0000000076725752): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (0000000076725752): auto cleanup kobject_del
kobject: 'rx-0' (0000000076725752): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (00000000dfa5fc07): kobject_cleanup, parent 00000000f8d9b04d
kobject: 'tx-0' (00000000dfa5fc07): auto cleanup 'remove' event
kobject: 'tx-0' (00000000dfa5fc07): kobject_uevent_env
kobject: 'tx-0' (00000000dfa5fc07): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (00000000dfa5fc07): auto cleanup kobject_del
kobject: 'tx-0' (00000000dfa5fc07): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (00000000f8d9b04d): kobject_cleanup, parent            
(null)
kobject: 'queues' (00000000f8d9b04d): calling ktype release
kobject: 'queues' (00000000f8d9b04d): kset_release
kobject: 'queues': free name
kobject: 'i' (00000000d2824c3a): kobject_uevent_env
kobject: 'i' (00000000d2824c3a): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'i' (000000006d24ca63): kobject_cleanup, parent           (null)
kobject: 'i' (00000000917865da): kobject_cleanup, parent           (null)
kobject: 'i' (000000006d24ca63): calling ktype release
kobject: 'i' (00000000917865da): calling ktype release
kobject: 'i': free name
kobject: 'i': free name
kobject: 'i' (00000000d2824c3a): kobject_cleanup, parent           (null)
kobject: 'i' (00000000d2824c3a): calling ktype release
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'i': free name
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'i' (000000009af5bdee): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'loop4' (00000000a9f26271): fill_kobj_path: path  
= '/devices/virtual/block/loop4'
kobject: 'i' (000000009af5bdee): kobject_uevent_env
kobject: 'i' (000000009af5bdee): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'queues' (000000004c6d032d): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'queues' (000000004c6d032d): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'queues' (000000004c6d032d): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'rx-0' (00000000e5074add): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'rx-0' (00000000e5074add): kobject_uevent_env
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'rx-0' (00000000e5074add): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (00000000b544d9b3): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'tx-0' (00000000b544d9b3): kobject_uevent_env
kobject: 'tx-0' (00000000b544d9b3): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'i' (000000009fd50b90): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'i' (000000009fd50b90): kobject_uevent_env
kobject: 'i' (000000009fd50b90): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'queues' (0000000054942d99): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'loop4' (00000000a9f26271): fill_kobj_path: path  
= '/devices/virtual/block/loop4'
kobject: 'queues' (0000000054942d99): kobject_uevent_env
kobject: 'queues' (0000000054942d99): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'rx-0' (0000000035ecd1ba): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'rx-0' (0000000035ecd1ba): kobject_uevent_env
kobject: 'rx-0' (0000000035ecd1ba): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (0000000055425850): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'tx-0' (0000000055425850): kobject_uevent_env
kobject: 'tx-0' (0000000055425850): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'rx-0' (0000000035ecd1ba): kobject_cleanup, parent 0000000054942d99
kobject: 'rx-0' (0000000035ecd1ba): auto cleanup 'remove' event
kobject: 'rx-0' (0000000035ecd1ba): kobject_uevent_env
kobject: 'rx-0' (0000000035ecd1ba): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (0000000035ecd1ba): auto cleanup kobject_del
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'rx-0' (0000000035ecd1ba): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (0000000055425850): kobject_cleanup, parent 0000000054942d99
kobject: 'tx-0' (0000000055425850): auto cleanup 'remove' event
kobject: 'tx-0' (0000000055425850): kobject_uevent_env
kobject: 'tx-0' (0000000055425850): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'tx-0' (0000000055425850): auto cleanup kobject_del
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'tx-0' (0000000055425850): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (0000000054942d99): kobject_cleanup, parent            
(null)
kobject: 'queues' (0000000054942d99): calling ktype release
kobject: 'queues' (0000000054942d99): kset_release
kobject: 'queues': free name
kobject: 'i' (000000009fd50b90): kobject_uevent_env
kobject: 'i' (000000009fd50b90): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'rx-0' (00000000e5074add): kobject_cleanup, parent 000000004c6d032d
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'rx-0' (00000000e5074add): auto cleanup 'remove' event
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'rx-0' (00000000e5074add): kobject_uevent_env
kobject: 'rx-0' (00000000e5074add): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (00000000e5074add): auto cleanup kobject_del
kobject: 'rx-0' (00000000e5074add): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (00000000b544d9b3): kobject_cleanup, parent 000000004c6d032d
kobject: 'tx-0' (00000000b544d9b3): auto cleanup 'remove' event
kobject: 'tx-0' (00000000b544d9b3): kobject_uevent_env
kobject: 'tx-0' (00000000b544d9b3): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (00000000b544d9b3): auto cleanup kobject_del
kobject: 'tx-0' (00000000b544d9b3): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (000000004c6d032d): kobject_cleanup, parent            
(null)
kobject: 'queues' (000000004c6d032d): calling ktype release
kobject: 'queues' (000000004c6d032d): kset_release
kobject: 'queues': free name
kobject: 'i' (000000009af5bdee): kobject_uevent_env
kobject: 'i' (000000009af5bdee): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'i' (000000009fd50b90): kobject_cleanup, parent           (null)
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'i' (000000009fd50b90): calling ktype release
kobject: 'loop4' (00000000a9f26271): fill_kobj_path: path  
= '/devices/virtual/block/loop4'
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'i' (000000009af5bdee): kobject_cleanup, parent           (null)
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'i': free name
kobject: 'i' (000000009af5bdee): calling ktype release
kobject: 'i': free name
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'i' (0000000070ce36e1): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'i' (0000000070ce36e1): kobject_uevent_env
kobject: 'i' (0000000070ce36e1): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'queues' (000000005c80c146): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'queues' (000000005c80c146): kobject_uevent_env
kobject: 'queues' (000000005c80c146): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'rx-0' (000000002363462e): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'rx-0' (000000002363462e): kobject_uevent_env
kobject: 'rx-0' (000000002363462e): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (000000000c8c9968): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'tx-0' (000000000c8c9968): kobject_uevent_env
kobject: 'tx-0' (000000000c8c9968): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'i' (0000000040059e2c): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'i' (0000000040059e2c): kobject_uevent_env
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'i' (0000000040059e2c): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'queues' (00000000f51a7dec): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'queues' (00000000f51a7dec): kobject_uevent_env
kobject: 'queues' (00000000f51a7dec): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'rx-0' (0000000087391310): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'rx-0' (0000000087391310): kobject_uevent_env
kobject: 'rx-0' (0000000087391310): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'tx-0' (00000000fdc0981c): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'tx-0' (00000000fdc0981c): kobject_uevent_env
kobject: 'tx-0' (00000000fdc0981c): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'rx-0' (000000002363462e): kobject_cleanup, parent 000000005c80c146
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'rx-0' (000000002363462e): auto cleanup 'remove' event
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'rx-0' (000000002363462e): kobject_uevent_env
kobject: 'rx-0' (000000002363462e): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (000000002363462e): auto cleanup kobject_del
kobject: 'rx-0' (000000002363462e): calling ktype release
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'rx-0': free name
kobject: 'tx-0' (000000000c8c9968): kobject_cleanup, parent 000000005c80c146
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'tx-0' (000000000c8c9968): auto cleanup 'remove' event
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'tx-0' (000000000c8c9968): kobject_uevent_env
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'tx-0' (000000000c8c9968): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'tx-0' (000000000c8c9968): auto cleanup kobject_del
kobject: 'loop4' (00000000a9f26271): fill_kobj_path: path  
= '/devices/virtual/block/loop4'
kobject: 'tx-0' (000000000c8c9968): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (000000005c80c146): kobject_cleanup, parent            
(null)
kobject: 'queues' (000000005c80c146): calling ktype release
kobject: 'queues' (000000005c80c146): kset_release
kobject: 'queues': free name
kobject: 'i' (0000000070ce36e1): kobject_uevent_env
kobject: 'i' (0000000070ce36e1): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'rx-0' (0000000087391310): kobject_cleanup, parent 00000000f51a7dec
kobject: 'rx-0' (0000000087391310): auto cleanup 'remove' event
kobject: 'rx-0' (0000000087391310): kobject_uevent_env
kobject: 'rx-0' (0000000087391310): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'rx-0' (0000000087391310): auto cleanup kobject_del
kobject: 'rx-0' (0000000087391310): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (00000000fdc0981c): kobject_cleanup, parent 00000000f51a7dec
kobject: 'tx-0' (00000000fdc0981c): auto cleanup 'remove' event
kobject: 'tx-0' (00000000fdc0981c): kobject_uevent_env
kobject: 'tx-0' (00000000fdc0981c): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (00000000fdc0981c): auto cleanup kobject_del
kobject: 'tx-0' (00000000fdc0981c): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (00000000f51a7dec): kobject_cleanup, parent            
(null)
kobject: 'queues' (00000000f51a7dec): calling ktype release
kobject: 'queues' (00000000f51a7dec): kset_release
kobject: 'queues': free name
kobject: 'i' (0000000040059e2c): kobject_uevent_env
kobject: 'i' (0000000040059e2c): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'i' (0000000070ce36e1): kobject_cleanup, parent           (null)
kobject: 'i' (0000000070ce36e1): calling ktype release
kobject: 'i': free name
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'i' (0000000040059e2c): kobject_cleanup, parent           (null)
kobject: 'i' (0000000040059e2c): calling ktype release
kobject: 'i': free name
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'i' (00000000141c63e1): kobject_add_internal: parent: 'net',  
set: 'devices'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'i' (00000000141c63e1): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'i' (00000000141c63e1): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'queues' (000000008e34733f): kobject_add_internal: parent: 'i',  
set: '<NULL>'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'queues' (000000008e34733f): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'queues' (000000008e34733f): kobject_uevent_env: filter function  
caused the event to drop!
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'rx-0' (00000000753bdf04): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'rx-0' (00000000753bdf04): kobject_uevent_env
kobject: 'rx-0' (00000000753bdf04): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'tx-0' (000000004bbe743b): kobject_add_internal: parent: 'queues',  
set: 'queues'
kobject: 'tx-0' (000000004bbe743b): kobject_uevent_env
kobject: 'tx-0' (000000004bbe743b): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'loop0' (000000009f832ae0): kobject_uevent_env
kobject: 'loop0' (000000009f832ae0): fill_kobj_path: path  
= '/devices/virtual/block/loop0'
kobject: 'rx-0' (00000000753bdf04): kobject_cleanup, parent 000000008e34733f
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'rx-0' (00000000753bdf04): auto cleanup 'remove' event
kobject: 'loop4' (00000000a9f26271): fill_kobj_path: path  
= '/devices/virtual/block/loop4'
kobject: 'rx-0' (00000000753bdf04): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'rx-0' (00000000753bdf04): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/rx-0'
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'rx-0' (00000000753bdf04): auto cleanup kobject_del
kobject: 'rx-0' (00000000753bdf04): calling ktype release
kobject: 'rx-0': free name
kobject: 'tx-0' (000000004bbe743b): kobject_cleanup, parent 000000008e34733f
kobject: 'tx-0' (000000004bbe743b): auto cleanup 'remove' event
kobject: 'tx-0' (000000004bbe743b): kobject_uevent_env
kobject: 'tx-0' (000000004bbe743b): fill_kobj_path: path  
= '/devices/virtual/net/i/queues/tx-0'
kobject: 'tx-0' (000000004bbe743b): auto cleanup kobject_del
kobject: 'tx-0' (000000004bbe743b): calling ktype release
kobject: 'tx-0': free name
kobject: 'queues' (000000008e34733f): kobject_cleanup, parent            
(null)
kobject: 'queues' (000000008e34733f): calling ktype release
kobject: 'queues' (000000008e34733f): kset_release
kobject: 'queues': free name
kobject: 'i' (00000000141c63e1): kobject_uevent_env
kobject: 'i' (00000000141c63e1): fill_kobj_path: path  
= '/devices/virtual/net/i'
kobject: 'i' (00000000141c63e1): kobject_cleanup, parent           (null)
kobject: 'i' (00000000141c63e1): calling ktype release
kobject: 'i': free name
kobject: 'loop3' (00000000b2c7bab5): kobject_uevent_env
kobject: 'loop3' (00000000b2c7bab5): fill_kobj_path: path  
= '/devices/virtual/block/loop3'
kobject: 'loop2' (00000000b2d1fc99): kobject_uevent_env
kobject: 'loop2' (00000000b2d1fc99): fill_kobj_path: path  
= '/devices/virtual/block/loop2'
kobject: 'loop5' (000000005737c1db): kobject_uevent_env
kobject: 'loop5' (000000005737c1db): fill_kobj_path: path  
= '/devices/virtual/block/loop5'
kobject: 'loop1' (0000000028db64e1): kobject_uevent_env
kobject: 'loop1' (0000000028db64e1): fill_kobj_path: path  
= '/devices/virtual/block/loop1'
kobject: 'loop4' (00000000a9f26271): kobject_uevent_env
kobject: 'loop4' (00000000a9f26271): fill_kobj_p

---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#bug-status-tracking for how to communicate with  
syzbot.

^ permalink raw reply

* Re: [PATCH 1/2] net: dpaa2: move DPAA2 PTP driver out of staging/
From: Andrew Lunn @ 2018-09-28 15:17 UTC (permalink / raw)
  To: Y.b. Lu
  Cc: linux-kernel@vger.kernel.org, devel@driverdev.osuosl.org,
	netdev@vger.kernel.org, Richard Cochran, David S . Miller,
	Ioana Ciocoi Radulescu, Greg Kroah-Hartman
In-Reply-To: <VI1PR0401MB223737CACE4E4064AE8325A4F8EC0@VI1PR0401MB2237.eurprd04.prod.outlook.com>

> > struct dprtc_cmd_get_irq - Putting pad at the beginning of a struct seems very
> > odd. And it is not the only example.
> 
> [Y.b. Lu] This should depended on MC firmware and APIs I think. Once the MC improves this, the APIs could be updated to fix this.

That is going to be hard to do. Ideally the driver should work with
any firmware version. You don't really want to force the user to
upgrade the driver/kernel and the firmware at the same time. So you
cannot for example remove this pad. What you might be able to do in
newer versions is actually use the space. But you have to be sure the
current code is correctly ignoring it and setting it to zero.

	Andrew

^ permalink raw reply

* Re: [PATCH v3 2/2] netfilter: nf_tables: add requirements for connsecmark support
From: Pablo Neira Ayuso @ 2018-09-28  9:01 UTC (permalink / raw)
  To: Christian Göttsche
  Cc: kadlec, fw, davem, netfilter-devel, coreteam, netdev,
	linux-kernel, paul, sds, eparis, jmorris, serge, selinux,
	linux-security-module
In-Reply-To: <20180923182616.11398-2-cgzones@googlemail.com>

On Sun, Sep 23, 2018 at 08:26:16PM +0200, Christian Göttsche wrote:
> Add ability to set the connection tracking secmark value.
> 
> Add ability to set the meta secmark value.

Also applied, thanks.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox