* [PATCH 0/7] Assorted rhashtables cleanups.
From: NeilBrown @ 2018-06-18 2:52 UTC (permalink / raw)
To: Thomas Graf, Herbert Xu, David Miller; +Cc: netdev, linux-kernel
Following 7 patches are selections from a recent RFC series I posted
that have all received suitable Acks.
The most visible changes are that rhashtable-types.h is now preferred
for inclusion in include/linux/*.h rather than rhashtable.h, and
that the full hash is used - no bits a reserved for a NULLS pointer.
Thanks,
NeilBrown
---
NeilBrown (7):
rhashtable: silence RCU warning in rhashtable_test.
rhashtable: split rhashtable.h
rhashtable: remove nulls_base and related code.
rhashtable: simplify INIT_RHT_NULLS_HEAD()
rhashtable: simplify nested_table_alloc() and rht_bucket_nested_insert()
rhashtable: use cmpxchg() to protect ->future_tbl.
rhashtable: clean up dereference of ->future_tbl.
MAINTAINERS | 2
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1
include/linux/ipc.h | 2
include/linux/ipc_namespace.h | 2
include/linux/mroute_base.h | 2
include/linux/rhashtable-types.h | 137 +++++++++++++++++++++++
include/linux/rhashtable.h | 164 +---------------------------
include/net/inet_frag.h | 2
include/net/netfilter/nf_flow_table.h | 2
include/net/sctp/structs.h | 2
include/net/seg6.h | 2
include/net/seg6_hmac.h | 2
ipc/msg.c | 1
ipc/sem.c | 1
ipc/shm.c | 1
ipc/util.c | 1
lib/rhashtable.c | 58 +++-------
lib/test_rhashtable.c | 8 +
net/core/xdp.c | 4 -
net/ipv4/inet_fragment.c | 1
net/ipv4/ipmr.c | 1
net/ipv4/ipmr_base.c | 1
net/ipv6/ip6mr.c | 1
net/ipv6/seg6.c | 1
net/ipv6/seg6_hmac.c | 1
net/netfilter/nf_tables_api.c | 1
net/sctp/input.c | 1
net/sctp/socket.c | 1
28 files changed, 191 insertions(+), 212 deletions(-)
create mode 100644 include/linux/rhashtable-types.h
--
Signature
^ permalink raw reply
* [PATCH 1/7] rhashtable: silence RCU warning in rhashtable_test.
From: NeilBrown @ 2018-06-18 2:52 UTC (permalink / raw)
To: Thomas Graf, Herbert Xu, David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <152929034948.23173.8671757672560065344.stgit@noble>
print_ht in rhashtable_test calls rht_dereference() with neither
RCU protection or the mutex. This triggers an RCU warning.
So take the mutex to silence the warning.
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: NeilBrown <neilb@suse.com>
---
lib/test_rhashtable.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c
index fb6968109113..6ca59ffcacbe 100644
--- a/lib/test_rhashtable.c
+++ b/lib/test_rhashtable.c
@@ -501,6 +501,8 @@ static unsigned int __init print_ht(struct rhltable *rhlt)
unsigned int i, cnt = 0;
ht = &rhlt->ht;
+ /* Take the mutex to avoid RCU warning */
+ mutex_lock(&ht->mutex);
tbl = rht_dereference(ht->tbl, ht);
for (i = 0; i < tbl->size; i++) {
struct rhash_head *pos, *next;
@@ -534,6 +536,7 @@ static unsigned int __init print_ht(struct rhltable *rhlt)
}
}
printk(KERN_ERR "\n---- ht: ----%s\n-------------\n", buff);
+ mutex_unlock(&ht->mutex);
return cnt;
}
^ permalink raw reply related
* [PATCH 3/7] rhashtable: remove nulls_base and related code.
From: NeilBrown @ 2018-06-18 2:52 UTC (permalink / raw)
To: Thomas Graf, Herbert Xu, David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <152929034948.23173.8671757672560065344.stgit@noble>
This "feature" is unused, undocumented, and untested and so doesn't
really belong. A patch is under development to properly implement
support for detecting when a search gets diverted down a different
chain, which the common purpose of nulls markers.
This patch actually fixes a bug too. The table resizing allows a
table to grow to 2^31 buckets, but the hash is truncated to 27 bits -
any growth beyond 2^27 is wasteful an ineffective.
This patch results in NULLS_MARKER(0) being used for all chains,
and leaves the use of rht_is_a_null() to test for it.
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: NeilBrown <neilb@suse.com>
---
include/linux/rhashtable-types.h | 2 --
include/linux/rhashtable.h | 33 +++------------------------------
lib/rhashtable.c | 8 --------
lib/test_rhashtable.c | 5 +----
net/core/xdp.c | 4 ++--
5 files changed, 6 insertions(+), 46 deletions(-)
diff --git a/include/linux/rhashtable-types.h b/include/linux/rhashtable-types.h
index 9740063ff13b..763d613ce2c2 100644
--- a/include/linux/rhashtable-types.h
+++ b/include/linux/rhashtable-types.h
@@ -50,7 +50,6 @@ typedef int (*rht_obj_cmpfn_t)(struct rhashtable_compare_arg *arg,
* @min_size: Minimum size while shrinking
* @locks_mul: Number of bucket locks to allocate per cpu (default: 32)
* @automatic_shrinking: Enable automatic shrinking of tables
- * @nulls_base: Base value to generate nulls marker
* @hashfn: Hash function (default: jhash2 if !(key_len % 4), or jhash)
* @obj_hashfn: Function to hash object
* @obj_cmpfn: Function to compare key with object
@@ -64,7 +63,6 @@ struct rhashtable_params {
u16 min_size;
bool automatic_shrinking;
u8 locks_mul;
- u32 nulls_base;
rht_hashfn_t hashfn;
rht_obj_hashfn_t obj_hashfn;
rht_obj_cmpfn_t obj_cmpfn;
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 48754ab07cdf..d9f719af7936 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -28,25 +28,8 @@
#include <linux/rhashtable-types.h>
/*
* The end of the chain is marked with a special nulls marks which has
- * the following format:
- *
- * +-------+-----------------------------------------------------+-+
- * | Base | Hash |1|
- * +-------+-----------------------------------------------------+-+
- *
- * Base (4 bits) : Reserved to distinguish between multiple tables.
- * Specified via &struct rhashtable_params.nulls_base.
- * Hash (27 bits): Full hash (unmasked) of first element added to bucket
- * 1 (1 bit) : Nulls marker (always set)
- *
- * The remaining bits of the next pointer remain unused for now.
+ * the least significant bit set.
*/
-#define RHT_BASE_BITS 4
-#define RHT_HASH_BITS 27
-#define RHT_BASE_SHIFT RHT_HASH_BITS
-
-/* Base bits plus 1 bit for nulls marker */
-#define RHT_HASH_RESERVED_SPACE (RHT_BASE_BITS + 1)
/* Maximum chain length before rehash
*
@@ -92,24 +75,14 @@ struct bucket_table {
struct rhash_head __rcu *buckets[] ____cacheline_aligned_in_smp;
};
-static inline unsigned long rht_marker(const struct rhashtable *ht, u32 hash)
-{
- return NULLS_MARKER(ht->p.nulls_base + hash);
-}
-
#define INIT_RHT_NULLS_HEAD(ptr, ht, hash) \
- ((ptr) = (typeof(ptr)) rht_marker(ht, hash))
+ ((ptr) = (typeof(ptr)) NULLS_MARKER(0))
static inline bool rht_is_a_nulls(const struct rhash_head *ptr)
{
return ((unsigned long) ptr & 1);
}
-static inline unsigned long rht_get_nulls_value(const struct rhash_head *ptr)
-{
- return ((unsigned long) ptr) >> 1;
-}
-
static inline void *rht_obj(const struct rhashtable *ht,
const struct rhash_head *he)
{
@@ -119,7 +92,7 @@ static inline void *rht_obj(const struct rhashtable *ht,
static inline unsigned int rht_bucket_index(const struct bucket_table *tbl,
unsigned int hash)
{
- return (hash >> RHT_HASH_RESERVED_SPACE) & (tbl->size - 1);
+ return hash & (tbl->size - 1);
}
static inline unsigned int rht_key_get_hash(struct rhashtable *ht,
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index c9fafea7dc6e..688693c919be 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -995,7 +995,6 @@ static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed)
* .key_offset = offsetof(struct test_obj, key),
* .key_len = sizeof(int),
* .hashfn = jhash,
- * .nulls_base = (1U << RHT_BASE_SHIFT),
* };
*
* Configuration Example 2: Variable length keys
@@ -1029,9 +1028,6 @@ int rhashtable_init(struct rhashtable *ht,
(params->obj_hashfn && !params->obj_cmpfn))
return -EINVAL;
- if (params->nulls_base && params->nulls_base < (1U << RHT_BASE_SHIFT))
- return -EINVAL;
-
memset(ht, 0, sizeof(*ht));
mutex_init(&ht->mutex);
spin_lock_init(&ht->lock);
@@ -1096,10 +1092,6 @@ int rhltable_init(struct rhltable *hlt, const struct rhashtable_params *params)
{
int err;
- /* No rhlist NULLs marking for now. */
- if (params->nulls_base)
- return -EINVAL;
-
err = rhashtable_init(&hlt->ht, params);
hlt->ht.rhlist = true;
return err;
diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c
index 6ca59ffcacbe..82ac39ce5310 100644
--- a/lib/test_rhashtable.c
+++ b/lib/test_rhashtable.c
@@ -83,7 +83,7 @@ static u32 my_hashfn(const void *data, u32 len, u32 seed)
{
const struct test_obj_rhl *obj = data;
- return (obj->value.id % 10) << RHT_HASH_RESERVED_SPACE;
+ return (obj->value.id % 10);
}
static int my_cmpfn(struct rhashtable_compare_arg *arg, const void *obj)
@@ -99,7 +99,6 @@ static struct rhashtable_params test_rht_params = {
.key_offset = offsetof(struct test_obj, value),
.key_len = sizeof(struct test_obj_val),
.hashfn = jhash,
- .nulls_base = (3U << RHT_BASE_SHIFT),
};
static struct rhashtable_params test_rht_params_dup = {
@@ -296,8 +295,6 @@ static int __init test_rhltable(unsigned int entries)
if (!obj_in_table)
goto out_free;
- /* nulls_base not supported in rhlist interface */
- test_rht_params.nulls_base = 0;
err = rhltable_init(&rhlt, &test_rht_params);
if (WARN_ON(err))
goto out_free;
diff --git a/net/core/xdp.c b/net/core/xdp.c
index 9d1f22072d5d..31c58719b5a9 100644
--- a/net/core/xdp.c
+++ b/net/core/xdp.c
@@ -45,8 +45,8 @@ static u32 xdp_mem_id_hashfn(const void *data, u32 len, u32 seed)
BUILD_BUG_ON(FIELD_SIZEOF(struct xdp_mem_allocator, mem.id)
!= sizeof(u32));
- /* Use cyclic increasing ID as direct hash key, see rht_bucket_index */
- return key << RHT_HASH_RESERVED_SPACE;
+ /* Use cyclic increasing ID as direct hash key */
+ return key;
}
static int xdp_mem_id_cmp(struct rhashtable_compare_arg *arg,
^ permalink raw reply related
* [PATCH 2/7] rhashtable: split rhashtable.h
From: NeilBrown @ 2018-06-18 2:52 UTC (permalink / raw)
To: Thomas Graf, Herbert Xu, David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <152929034948.23173.8671757672560065344.stgit@noble>
Due to the use of rhashtables in net namespaces,
rhashtable.h is included in lots of the kernel,
so a small changes can required a large recompilation.
This makes development painful.
This patch splits out rhashtable-types.h which just includes
the major type declarations, and does not include (non-trivial)
inline code. rhashtable.h is no longer included by anything
in the include/ directory.
Common include files only include rhashtable-types.h so a large
recompilation is only triggered when that changes.
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: NeilBrown <neilb@suse.com>
---
MAINTAINERS | 2
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1
include/linux/ipc.h | 2
include/linux/ipc_namespace.h | 2
include/linux/mroute_base.h | 2
include/linux/rhashtable-types.h | 139 ++++++++++++++++++++++++++++
include/linux/rhashtable.h | 127 --------------------------
include/net/inet_frag.h | 2
include/net/netfilter/nf_flow_table.h | 2
include/net/sctp/structs.h | 2
include/net/seg6.h | 2
include/net/seg6_hmac.h | 2
ipc/msg.c | 1
ipc/sem.c | 1
ipc/shm.c | 1
ipc/util.c | 1
lib/rhashtable.c | 1
net/ipv4/inet_fragment.c | 1
net/ipv4/ipmr.c | 1
net/ipv4/ipmr_base.c | 1
net/ipv6/ip6mr.c | 1
net/ipv6/seg6.c | 1
net/ipv6/seg6_hmac.c | 1
net/netfilter/nf_tables_api.c | 1
net/sctp/input.c | 1
net/sctp/socket.c | 1
26 files changed, 166 insertions(+), 133 deletions(-)
create mode 100644 include/linux/rhashtable-types.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 9d5eeff51b5f..5b57d9078d79 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12162,7 +12162,9 @@ M: Herbert Xu <herbert@gondor.apana.org.au>
L: netdev@vger.kernel.org
S: Maintained
F: lib/rhashtable.c
+F: lib/test_rhashtable.c
F: include/linux/rhashtable.h
+F: include/linux/rhashtable-types.h
RICOH R5C592 MEMORYSTICK DRIVER
M: Maxim Levitsky <maximlevitsky@gmail.com>
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 0dbe2d9e22d6..1adb968b8354 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -46,6 +46,7 @@
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/vmalloc.h>
+#include <linux/rhashtable.h>
#include <linux/etherdevice.h>
#include <linux/net_tstamp.h>
#include <linux/ptp_clock_kernel.h>
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index 6cc2df7f7ac9..e1c9eea6015b 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -4,7 +4,7 @@
#include <linux/spinlock.h>
#include <linux/uidgid.h>
-#include <linux/rhashtable.h>
+#include <linux/rhashtable-types.h>
#include <uapi/linux/ipc.h>
#include <linux/refcount.h>
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
index b5630c8eb2f3..6cea726612b7 100644
--- a/include/linux/ipc_namespace.h
+++ b/include/linux/ipc_namespace.h
@@ -9,7 +9,7 @@
#include <linux/nsproxy.h>
#include <linux/ns_common.h>
#include <linux/refcount.h>
-#include <linux/rhashtable.h>
+#include <linux/rhashtable-types.h>
struct user_namespace;
diff --git a/include/linux/mroute_base.h b/include/linux/mroute_base.h
index d633f737b3c6..fd436cdd4725 100644
--- a/include/linux/mroute_base.h
+++ b/include/linux/mroute_base.h
@@ -2,7 +2,7 @@
#define __LINUX_MROUTE_BASE_H
#include <linux/netdevice.h>
-#include <linux/rhashtable.h>
+#include <linux/rhashtable-types.h>
#include <linux/spinlock.h>
#include <net/net_namespace.h>
#include <net/sock.h>
diff --git a/include/linux/rhashtable-types.h b/include/linux/rhashtable-types.h
new file mode 100644
index 000000000000..9740063ff13b
--- /dev/null
+++ b/include/linux/rhashtable-types.h
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Resizable, Scalable, Concurrent Hash Table
+ *
+ * Simple structures that might be needed in include
+ * files.
+ */
+
+#ifndef _LINUX_RHASHTABLE_TYPES_H
+#define _LINUX_RHASHTABLE_TYPES_H
+
+#include <linux/atomic.h>
+#include <linux/compiler.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+
+struct rhash_head {
+ struct rhash_head __rcu *next;
+};
+
+struct rhlist_head {
+ struct rhash_head rhead;
+ struct rhlist_head __rcu *next;
+};
+
+struct bucket_table;
+
+/**
+ * struct rhashtable_compare_arg - Key for the function rhashtable_compare
+ * @ht: Hash table
+ * @key: Key to compare against
+ */
+struct rhashtable_compare_arg {
+ struct rhashtable *ht;
+ const void *key;
+};
+
+typedef u32 (*rht_hashfn_t)(const void *data, u32 len, u32 seed);
+typedef u32 (*rht_obj_hashfn_t)(const void *data, u32 len, u32 seed);
+typedef int (*rht_obj_cmpfn_t)(struct rhashtable_compare_arg *arg,
+ const void *obj);
+
+/**
+ * struct rhashtable_params - Hash table construction parameters
+ * @nelem_hint: Hint on number of elements, should be 75% of desired size
+ * @key_len: Length of key
+ * @key_offset: Offset of key in struct to be hashed
+ * @head_offset: Offset of rhash_head in struct to be hashed
+ * @max_size: Maximum size while expanding
+ * @min_size: Minimum size while shrinking
+ * @locks_mul: Number of bucket locks to allocate per cpu (default: 32)
+ * @automatic_shrinking: Enable automatic shrinking of tables
+ * @nulls_base: Base value to generate nulls marker
+ * @hashfn: Hash function (default: jhash2 if !(key_len % 4), or jhash)
+ * @obj_hashfn: Function to hash object
+ * @obj_cmpfn: Function to compare key with object
+ */
+struct rhashtable_params {
+ u16 nelem_hint;
+ u16 key_len;
+ u16 key_offset;
+ u16 head_offset;
+ unsigned int max_size;
+ u16 min_size;
+ bool automatic_shrinking;
+ u8 locks_mul;
+ u32 nulls_base;
+ rht_hashfn_t hashfn;
+ rht_obj_hashfn_t obj_hashfn;
+ rht_obj_cmpfn_t obj_cmpfn;
+};
+
+/**
+ * struct rhashtable - Hash table handle
+ * @tbl: Bucket table
+ * @key_len: Key length for hashfn
+ * @max_elems: Maximum number of elements in table
+ * @p: Configuration parameters
+ * @rhlist: True if this is an rhltable
+ * @run_work: Deferred worker to expand/shrink asynchronously
+ * @mutex: Mutex to protect current/future table swapping
+ * @lock: Spin lock to protect walker list
+ * @nelems: Number of elements in table
+ */
+struct rhashtable {
+ struct bucket_table __rcu *tbl;
+ unsigned int key_len;
+ unsigned int max_elems;
+ struct rhashtable_params p;
+ bool rhlist;
+ struct work_struct run_work;
+ struct mutex mutex;
+ spinlock_t lock;
+ atomic_t nelems;
+};
+
+/**
+ * struct rhltable - Hash table with duplicate objects in a list
+ * @ht: Underlying rhtable
+ */
+struct rhltable {
+ struct rhashtable ht;
+};
+
+/**
+ * struct rhashtable_walker - Hash table walker
+ * @list: List entry on list of walkers
+ * @tbl: The table that we were walking over
+ */
+struct rhashtable_walker {
+ struct list_head list;
+ struct bucket_table *tbl;
+};
+
+/**
+ * struct rhashtable_iter - Hash table iterator
+ * @ht: Table to iterate through
+ * @p: Current pointer
+ * @list: Current hash list pointer
+ * @walker: Associated rhashtable walker
+ * @slot: Current slot
+ * @skip: Number of entries to skip in slot
+ */
+struct rhashtable_iter {
+ struct rhashtable *ht;
+ struct rhash_head *p;
+ struct rhlist_head *list;
+ struct rhashtable_walker walker;
+ unsigned int slot;
+ unsigned int skip;
+ bool end_of_table;
+};
+
+int rhashtable_init(struct rhashtable *ht,
+ const struct rhashtable_params *params);
+int rhltable_init(struct rhltable *hlt,
+ const struct rhashtable_params *params);
+
+#endif /* _LINUX_RHASHTABLE_TYPES_H */
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 4e1f535c2034..48754ab07cdf 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Resizable, Scalable, Concurrent Hash Table
*
@@ -17,16 +18,14 @@
#ifndef _LINUX_RHASHTABLE_H
#define _LINUX_RHASHTABLE_H
-#include <linux/atomic.h>
-#include <linux/compiler.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/jhash.h>
#include <linux/list_nulls.h>
#include <linux/workqueue.h>
-#include <linux/mutex.h>
#include <linux/rculist.h>
+#include <linux/rhashtable-types.h>
/*
* The end of the chain is marked with a special nulls marks which has
* the following format:
@@ -64,15 +63,6 @@
*/
#define RHT_ELASTICITY 16u
-struct rhash_head {
- struct rhash_head __rcu *next;
-};
-
-struct rhlist_head {
- struct rhash_head rhead;
- struct rhlist_head __rcu *next;
-};
-
/**
* struct bucket_table - Table of hash buckets
* @size: Number of hash buckets
@@ -102,114 +92,6 @@ struct bucket_table {
struct rhash_head __rcu *buckets[] ____cacheline_aligned_in_smp;
};
-/**
- * struct rhashtable_compare_arg - Key for the function rhashtable_compare
- * @ht: Hash table
- * @key: Key to compare against
- */
-struct rhashtable_compare_arg {
- struct rhashtable *ht;
- const void *key;
-};
-
-typedef u32 (*rht_hashfn_t)(const void *data, u32 len, u32 seed);
-typedef u32 (*rht_obj_hashfn_t)(const void *data, u32 len, u32 seed);
-typedef int (*rht_obj_cmpfn_t)(struct rhashtable_compare_arg *arg,
- const void *obj);
-
-struct rhashtable;
-
-/**
- * struct rhashtable_params - Hash table construction parameters
- * @nelem_hint: Hint on number of elements, should be 75% of desired size
- * @key_len: Length of key
- * @key_offset: Offset of key in struct to be hashed
- * @head_offset: Offset of rhash_head in struct to be hashed
- * @max_size: Maximum size while expanding
- * @min_size: Minimum size while shrinking
- * @locks_mul: Number of bucket locks to allocate per cpu (default: 32)
- * @automatic_shrinking: Enable automatic shrinking of tables
- * @nulls_base: Base value to generate nulls marker
- * @hashfn: Hash function (default: jhash2 if !(key_len % 4), or jhash)
- * @obj_hashfn: Function to hash object
- * @obj_cmpfn: Function to compare key with object
- */
-struct rhashtable_params {
- u16 nelem_hint;
- u16 key_len;
- u16 key_offset;
- u16 head_offset;
- unsigned int max_size;
- u16 min_size;
- bool automatic_shrinking;
- u8 locks_mul;
- u32 nulls_base;
- rht_hashfn_t hashfn;
- rht_obj_hashfn_t obj_hashfn;
- rht_obj_cmpfn_t obj_cmpfn;
-};
-
-/**
- * struct rhashtable - Hash table handle
- * @tbl: Bucket table
- * @key_len: Key length for hashfn
- * @max_elems: Maximum number of elements in table
- * @p: Configuration parameters
- * @rhlist: True if this is an rhltable
- * @run_work: Deferred worker to expand/shrink asynchronously
- * @mutex: Mutex to protect current/future table swapping
- * @lock: Spin lock to protect walker list
- * @nelems: Number of elements in table
- */
-struct rhashtable {
- struct bucket_table __rcu *tbl;
- unsigned int key_len;
- unsigned int max_elems;
- struct rhashtable_params p;
- bool rhlist;
- struct work_struct run_work;
- struct mutex mutex;
- spinlock_t lock;
- atomic_t nelems;
-};
-
-/**
- * struct rhltable - Hash table with duplicate objects in a list
- * @ht: Underlying rhtable
- */
-struct rhltable {
- struct rhashtable ht;
-};
-
-/**
- * struct rhashtable_walker - Hash table walker
- * @list: List entry on list of walkers
- * @tbl: The table that we were walking over
- */
-struct rhashtable_walker {
- struct list_head list;
- struct bucket_table *tbl;
-};
-
-/**
- * struct rhashtable_iter - Hash table iterator
- * @ht: Table to iterate through
- * @p: Current pointer
- * @list: Current hash list pointer
- * @walker: Associated rhashtable walker
- * @slot: Current slot
- * @skip: Number of entries to skip in slot
- */
-struct rhashtable_iter {
- struct rhashtable *ht;
- struct rhash_head *p;
- struct rhlist_head *list;
- struct rhashtable_walker walker;
- unsigned int slot;
- unsigned int skip;
- bool end_of_table;
-};
-
static inline unsigned long rht_marker(const struct rhashtable *ht, u32 hash)
{
return NULLS_MARKER(ht->p.nulls_base + hash);
@@ -376,11 +258,6 @@ static inline int lockdep_rht_bucket_is_held(const struct bucket_table *tbl,
}
#endif /* CONFIG_PROVE_LOCKING */
-int rhashtable_init(struct rhashtable *ht,
- const struct rhashtable_params *params);
-int rhltable_init(struct rhltable *hlt,
- const struct rhashtable_params *params);
-
void *rhashtable_insert_slow(struct rhashtable *ht, const void *key,
struct rhash_head *obj);
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index ed07e3786d98..f4272a29dc44 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -2,7 +2,7 @@
#ifndef __NET_FRAG_H__
#define __NET_FRAG_H__
-#include <linux/rhashtable.h>
+#include <linux/rhashtable-types.h>
struct netns_frags {
/* sysctls */
diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
index ba9fa4592f2b..0e355f4a3d76 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
@@ -4,7 +4,7 @@
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/netdevice.h>
-#include <linux/rhashtable.h>
+#include <linux/rhashtable-types.h>
#include <linux/rcupdate.h>
#include <linux/netfilter/nf_conntrack_tuple_common.h>
#include <net/dst.h>
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index dbe1b911a24d..e0f962d27386 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -48,7 +48,7 @@
#define __sctp_structs_h__
#include <linux/ktime.h>
-#include <linux/rhashtable.h>
+#include <linux/rhashtable-types.h>
#include <linux/socket.h> /* linux/in.h needs this!! */
#include <linux/in.h> /* We get struct sockaddr_in. */
#include <linux/in6.h> /* We get struct in6_addr */
diff --git a/include/net/seg6.h b/include/net/seg6.h
index e029e301faa5..2567941a2f32 100644
--- a/include/net/seg6.h
+++ b/include/net/seg6.h
@@ -18,7 +18,7 @@
#include <linux/ipv6.h>
#include <net/lwtunnel.h>
#include <linux/seg6.h>
-#include <linux/rhashtable.h>
+#include <linux/rhashtable-types.h>
static inline void update_csum_diff4(struct sk_buff *skb, __be32 from,
__be32 to)
diff --git a/include/net/seg6_hmac.h b/include/net/seg6_hmac.h
index 69c3a106056b..7fda469e2758 100644
--- a/include/net/seg6_hmac.h
+++ b/include/net/seg6_hmac.h
@@ -22,7 +22,7 @@
#include <linux/route.h>
#include <net/seg6.h>
#include <linux/seg6_hmac.h>
-#include <linux/rhashtable.h>
+#include <linux/rhashtable-types.h>
#define SEG6_HMAC_MAX_DIGESTSIZE 160
#define SEG6_HMAC_RING_SIZE 256
diff --git a/ipc/msg.c b/ipc/msg.c
index 3b6545302598..203281198079 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -38,6 +38,7 @@
#include <linux/rwsem.h>
#include <linux/nsproxy.h>
#include <linux/ipc_namespace.h>
+#include <linux/rhashtable.h>
#include <asm/current.h>
#include <linux/uaccess.h>
diff --git a/ipc/sem.c b/ipc/sem.c
index 5af1943ad782..29c0347ef11d 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -86,6 +86,7 @@
#include <linux/ipc_namespace.h>
#include <linux/sched/wake_q.h>
#include <linux/nospec.h>
+#include <linux/rhashtable.h>
#include <linux/uaccess.h>
#include "util.h"
diff --git a/ipc/shm.c b/ipc/shm.c
index 051a3e1fb8df..d4daf78df6da 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -43,6 +43,7 @@
#include <linux/nsproxy.h>
#include <linux/mount.h>
#include <linux/ipc_namespace.h>
+#include <linux/rhashtable.h>
#include <linux/uaccess.h>
diff --git a/ipc/util.c b/ipc/util.c
index 4e81182fa0ac..fdffff41f65b 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -63,6 +63,7 @@
#include <linux/rwsem.h>
#include <linux/memory.h>
#include <linux/ipc_namespace.h>
+#include <linux/rhashtable.h>
#include <asm/unistd.h>
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 9427b5766134..c9fafea7dc6e 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -28,6 +28,7 @@
#include <linux/rhashtable.h>
#include <linux/err.h>
#include <linux/export.h>
+#include <linux/rhashtable.h>
#define HASH_DEFAULT_SIZE 64UL
#define HASH_MIN_SIZE 4U
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index c9e35b81d093..316518f87294 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -20,6 +20,7 @@
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/slab.h>
+#include <linux/rhashtable.h>
#include <net/sock.h>
#include <net/inet_frag.h>
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 9f79b9803a16..82f914122f1b 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -60,6 +60,7 @@
#include <linux/netfilter_ipv4.h>
#include <linux/compat.h>
#include <linux/export.h>
+#include <linux/rhashtable.h>
#include <net/ip_tunnels.h>
#include <net/checksum.h>
#include <net/netlink.h>
diff --git a/net/ipv4/ipmr_base.c b/net/ipv4/ipmr_base.c
index cafb0506c8c9..1ad9aa62a97b 100644
--- a/net/ipv4/ipmr_base.c
+++ b/net/ipv4/ipmr_base.c
@@ -2,6 +2,7 @@
* Common logic shared by IPv4 [ipmr] and IPv6 [ip6mr] implementation
*/
+#include <linux/rhashtable.h>
#include <linux/mroute_base.h>
/* Sets everything common except 'dev', since that is done under locking */
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 0d0f0053bb11..d0b7e0249c13 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -32,6 +32,7 @@
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/compat.h>
+#include <linux/rhashtable.h>
#include <net/protocol.h>
#include <linux/skbuff.h>
#include <net/raw.h>
diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c
index 0fdf2a55e746..8d0ba757a46c 100644
--- a/net/ipv6/seg6.c
+++ b/net/ipv6/seg6.c
@@ -17,6 +17,7 @@
#include <linux/net.h>
#include <linux/in6.h>
#include <linux/slab.h>
+#include <linux/rhashtable.h>
#include <net/ipv6.h>
#include <net/protocol.h>
diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
index 33fb35cbfac1..b1791129a875 100644
--- a/net/ipv6/seg6_hmac.c
+++ b/net/ipv6/seg6_hmac.c
@@ -22,6 +22,7 @@
#include <linux/icmpv6.h>
#include <linux/mroute6.h>
#include <linux/slab.h>
+#include <linux/rhashtable.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 896d4a36081d..3f211e1025c1 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -14,6 +14,7 @@
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/vmalloc.h>
+#include <linux/rhashtable.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
diff --git a/net/sctp/input.c b/net/sctp/input.c
index ba8a6e6c36fa..9bbc5f92c941 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -56,6 +56,7 @@
#include <net/sctp/sm.h>
#include <net/sctp/checksum.h>
#include <net/net_namespace.h>
+#include <linux/rhashtable.h>
/* Forward declarations for internal helpers. */
static int sctp_rcv_ootb(struct sk_buff *);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index d20f7addee19..0e91e83eea5a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -66,6 +66,7 @@
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/compat.h>
+#include <linux/rhashtable.h>
#include <net/ip.h>
#include <net/icmp.h>
^ permalink raw reply related
* [PATCH 4/7] rhashtable: simplify INIT_RHT_NULLS_HEAD()
From: NeilBrown @ 2018-06-18 2:52 UTC (permalink / raw)
To: Thomas Graf, Herbert Xu, David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <152929034948.23173.8671757672560065344.stgit@noble>
The 'ht' and 'hash' arguments to INIT_RHT_NULLS_HEAD() are
no longer used - so drop them. This allows us to also
remove the nhash argument from nested_table_alloc().
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: NeilBrown <neilb@suse.com>
---
include/linux/rhashtable.h | 2 +-
lib/rhashtable.c | 15 ++++++---------
2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index d9f719af7936..3f3a182bd0b4 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -75,7 +75,7 @@ struct bucket_table {
struct rhash_head __rcu *buckets[] ____cacheline_aligned_in_smp;
};
-#define INIT_RHT_NULLS_HEAD(ptr, ht, hash) \
+#define INIT_RHT_NULLS_HEAD(ptr) \
((ptr) = (typeof(ptr)) NULLS_MARKER(0))
static inline bool rht_is_a_nulls(const struct rhash_head *ptr)
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 688693c919be..a81cd27d518c 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -116,8 +116,7 @@ static void bucket_table_free_rcu(struct rcu_head *head)
static union nested_table *nested_table_alloc(struct rhashtable *ht,
union nested_table __rcu **prev,
- unsigned int shifted,
- unsigned int nhash)
+ unsigned int shifted)
{
union nested_table *ntbl;
int i;
@@ -130,8 +129,7 @@ static union nested_table *nested_table_alloc(struct rhashtable *ht,
if (ntbl && shifted) {
for (i = 0; i < PAGE_SIZE / sizeof(ntbl[0].bucket); i++)
- INIT_RHT_NULLS_HEAD(ntbl[i].bucket, ht,
- (i << shifted) | nhash);
+ INIT_RHT_NULLS_HEAD(ntbl[i].bucket);
}
rcu_assign_pointer(*prev, ntbl);
@@ -157,7 +155,7 @@ static struct bucket_table *nested_bucket_table_alloc(struct rhashtable *ht,
return NULL;
if (!nested_table_alloc(ht, (union nested_table __rcu **)tbl->buckets,
- 0, 0)) {
+ 0)) {
kfree(tbl);
return NULL;
}
@@ -207,7 +205,7 @@ static struct bucket_table *bucket_table_alloc(struct rhashtable *ht,
tbl->hash_rnd = get_random_u32();
for (i = 0; i < nbuckets; i++)
- INIT_RHT_NULLS_HEAD(tbl->buckets[i], ht, i);
+ INIT_RHT_NULLS_HEAD(tbl->buckets[i]);
return tbl;
}
@@ -1217,7 +1215,7 @@ struct rhash_head __rcu **rht_bucket_nested_insert(struct rhashtable *ht,
nhash = index;
shifted = tbl->nest;
ntbl = nested_table_alloc(ht, &ntbl[index].table,
- size <= (1 << shift) ? shifted : 0, nhash);
+ size <= (1 << shift) ? shifted : 0);
while (ntbl && size > (1 << shift)) {
index = hash & ((1 << shift) - 1);
@@ -1226,8 +1224,7 @@ struct rhash_head __rcu **rht_bucket_nested_insert(struct rhashtable *ht,
nhash |= index << shifted;
shifted += shift;
ntbl = nested_table_alloc(ht, &ntbl[index].table,
- size <= (1 << shift) ? shifted : 0,
- nhash);
+ size <= (1 << shift) ? shifted : 0);
}
if (!ntbl)
^ permalink raw reply related
* [PATCH 5/7] rhashtable: simplify nested_table_alloc() and rht_bucket_nested_insert()
From: NeilBrown @ 2018-06-18 2:52 UTC (permalink / raw)
To: Thomas Graf, Herbert Xu, David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <152929034948.23173.8671757672560065344.stgit@noble>
Now that we don't use the hash value or shift in nested_table_alloc()
there is room for simplification.
We only need to pass a "is this a leaf" flag to nested_table_alloc(),
and don't need to track as much information in
rht_bucket_nested_insert().
Note there is another minor cleanup in nested_table_alloc() here.
The number of elements in a page of "union nested_tables" is most naturally
PAGE_SIZE / sizeof(ntbl[0])
The previous code had
PAGE_SIZE / sizeof(ntbl[0].bucket)
which happens to be the correct value only because the bucket uses all
the space in the union.
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: NeilBrown <neilb@suse.com>
---
lib/rhashtable.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index a81cd27d518c..2aa41c15df17 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -116,7 +116,7 @@ static void bucket_table_free_rcu(struct rcu_head *head)
static union nested_table *nested_table_alloc(struct rhashtable *ht,
union nested_table __rcu **prev,
- unsigned int shifted)
+ bool leaf)
{
union nested_table *ntbl;
int i;
@@ -127,8 +127,8 @@ static union nested_table *nested_table_alloc(struct rhashtable *ht,
ntbl = kzalloc(PAGE_SIZE, GFP_ATOMIC);
- if (ntbl && shifted) {
- for (i = 0; i < PAGE_SIZE / sizeof(ntbl[0].bucket); i++)
+ if (ntbl && leaf) {
+ for (i = 0; i < PAGE_SIZE / sizeof(ntbl[0]); i++)
INIT_RHT_NULLS_HEAD(ntbl[i].bucket);
}
@@ -155,7 +155,7 @@ static struct bucket_table *nested_bucket_table_alloc(struct rhashtable *ht,
return NULL;
if (!nested_table_alloc(ht, (union nested_table __rcu **)tbl->buckets,
- 0)) {
+ false)) {
kfree(tbl);
return NULL;
}
@@ -1207,24 +1207,18 @@ struct rhash_head __rcu **rht_bucket_nested_insert(struct rhashtable *ht,
unsigned int index = hash & ((1 << tbl->nest) - 1);
unsigned int size = tbl->size >> tbl->nest;
union nested_table *ntbl;
- unsigned int shifted;
- unsigned int nhash;
ntbl = (union nested_table *)rcu_dereference_raw(tbl->buckets[0]);
hash >>= tbl->nest;
- nhash = index;
- shifted = tbl->nest;
ntbl = nested_table_alloc(ht, &ntbl[index].table,
- size <= (1 << shift) ? shifted : 0);
+ size <= (1 << shift));
while (ntbl && size > (1 << shift)) {
index = hash & ((1 << shift) - 1);
size >>= shift;
hash >>= shift;
- nhash |= index << shifted;
- shifted += shift;
ntbl = nested_table_alloc(ht, &ntbl[index].table,
- size <= (1 << shift) ? shifted : 0);
+ size <= (1 << shift));
}
if (!ntbl)
^ permalink raw reply related
* [PATCH 6/7] rhashtable: use cmpxchg() to protect ->future_tbl.
From: NeilBrown @ 2018-06-18 2:52 UTC (permalink / raw)
To: Thomas Graf, Herbert Xu, David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <152929034948.23173.8671757672560065344.stgit@noble>
Rather than borrowing one of the bucket locks to
protect ->future_tbl updates, use cmpxchg().
This gives more freedom to change how bucket locking
is implemented.
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: NeilBrown <neilb@suse.com>
---
lib/rhashtable.c | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 2aa41c15df17..52ec83212856 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -297,21 +297,14 @@ static int rhashtable_rehash_attach(struct rhashtable *ht,
struct bucket_table *old_tbl,
struct bucket_table *new_tbl)
{
- /* Protect future_tbl using the first bucket lock. */
- spin_lock_bh(old_tbl->locks);
-
- /* Did somebody beat us to it? */
- if (rcu_access_pointer(old_tbl->future_tbl)) {
- spin_unlock_bh(old_tbl->locks);
- return -EEXIST;
- }
-
/* Make insertions go into the new, empty table right away. Deletions
* and lookups will be attempted in both tables until we synchronize.
+ * As cmpxchg() provides strong barriers, we do not need
+ * rcu_assign_pointer().
*/
- rcu_assign_pointer(old_tbl->future_tbl, new_tbl);
- spin_unlock_bh(old_tbl->locks);
+ if (cmpxchg(&old_tbl->future_tbl, NULL, new_tbl) != NULL)
+ return -EEXIST;
return 0;
}
^ permalink raw reply related
* [PATCH 7/7] rhashtable: clean up dereference of ->future_tbl.
From: NeilBrown @ 2018-06-18 2:52 UTC (permalink / raw)
To: Thomas Graf, Herbert Xu, David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <152929034948.23173.8671757672560065344.stgit@noble>
Using rht_dereference_bucket() to dereference
->future_tbl looks like a type error, and could be confusing.
Using rht_dereference_rcu() to test a pointer for NULL
adds an unnecessary barrier - rcu_access_pointer() is preferred
for NULL tests when no lock is held.
This uses 3 different ways to access ->future_tbl.
- if we know the mutex is held, use rht_dereference()
- if we don't hold the mutex, and are only testing for NULL,
use rcu_access_pointer()
- otherwise (using RCU protection for true dereference),
use rht_dereference_rcu().
Note that this includes a simplification of the call to
rhashtable_last_table() - we don't do an extra dereference
before the call any more.
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: NeilBrown <neilb@suse.com>
---
include/linux/rhashtable.h | 2 +-
lib/rhashtable.c | 9 ++++-----
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 3f3a182bd0b4..eb7111039247 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -595,7 +595,7 @@ static inline void *__rhashtable_insert_fast(
lock = rht_bucket_lock(tbl, hash);
spin_lock_bh(lock);
- if (unlikely(rht_dereference_bucket(tbl->future_tbl, tbl, hash))) {
+ if (unlikely(rcu_access_pointer(tbl->future_tbl))) {
slow_path:
spin_unlock_bh(lock);
rcu_read_unlock();
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 52ec83212856..0e04947b7e0c 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -226,8 +226,7 @@ static struct bucket_table *rhashtable_last_table(struct rhashtable *ht,
static int rhashtable_rehash_one(struct rhashtable *ht, unsigned int old_hash)
{
struct bucket_table *old_tbl = rht_dereference(ht->tbl, ht);
- struct bucket_table *new_tbl = rhashtable_last_table(ht,
- rht_dereference_rcu(old_tbl->future_tbl, ht));
+ struct bucket_table *new_tbl = rhashtable_last_table(ht, old_tbl);
struct rhash_head __rcu **pprev = rht_bucket_var(old_tbl, old_hash);
int err = -EAGAIN;
struct rhash_head *head, *next, *entry;
@@ -467,7 +466,7 @@ static int rhashtable_insert_rehash(struct rhashtable *ht,
fail:
/* Do not fail the insert if someone else did a rehash. */
- if (likely(rcu_dereference_raw(tbl->future_tbl)))
+ if (likely(rcu_access_pointer(tbl->future_tbl)))
return 0;
/* Schedule async rehash to retry allocation in process context. */
@@ -540,7 +539,7 @@ static struct bucket_table *rhashtable_insert_one(struct rhashtable *ht,
if (PTR_ERR(data) != -EAGAIN && PTR_ERR(data) != -ENOENT)
return ERR_CAST(data);
- new_tbl = rcu_dereference(tbl->future_tbl);
+ new_tbl = rht_dereference_rcu(tbl->future_tbl, ht);
if (new_tbl)
return new_tbl;
@@ -599,7 +598,7 @@ static void *rhashtable_try_insert(struct rhashtable *ht, const void *key,
break;
spin_unlock_bh(lock);
- tbl = rcu_dereference(tbl->future_tbl);
+ tbl = rht_dereference_rcu(tbl->future_tbl, ht);
}
data = rhashtable_lookup_one(ht, tbl, hash, key, obj);
^ permalink raw reply related
* [PATCH 1/2] eth phy: add mdio bus char device interface
From: Wei Li @ 2018-06-18 3:32 UTC (permalink / raw)
To: andrew, f.fainelli; +Cc: netdev
Add the char device interface of mdio bus, like what i2c-dev or spidev do.
They make it possible for user-space programs to access the bus directly.
Signed-off-by: Wei Li <liwei1412@163.com>
---
drivers/net/phy/Kconfig | 10 ++
drivers/net/phy/Makefile | 1 +
drivers/net/phy/mdio-dev.c | 376 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/mdio-dev.h | 28 ++++
4 files changed, 415 insertions(+)
create mode 100644 drivers/net/phy/mdio-dev.c
create mode 100644 include/linux/mdio-dev.h
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index bdfbabb..cd688c5 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -158,6 +158,16 @@ config MDIO_XGENE
This module provides a driver for the MDIO busses found in the
APM X-Gene SoC's.
+config MDIO_CHARDEV
+ tristate "MDIO device interface"
+ help
+ Say Y here to use mdio-* device files, usually found in the /dev
+ directory on your system. They make it possible to have user-space
+ programs use the MDIO bus.
+
+ This support is also available as a module. If so, the module
+ will be called mdio-dev.
+
endif
config PHYLINK
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 01acbcb..a0566f8 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o
obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o
+obj-$(CONFIG_MDIO_CHARDEV) += mdio-dev.o
obj-$(CONFIG_SFP) += sfp.o
sfp-obj-$(CONFIG_SFP) += sfp-bus.o
diff --git a/drivers/net/phy/mdio-dev.c b/drivers/net/phy/mdio-dev.c
new file mode 100644
index 0000000..61487d2
--- /dev/null
+++ b/drivers/net/phy/mdio-dev.c
@@ -0,0 +1,376 @@
+/*
+ * mdio-dev.c - mdio-bus driver, char device interface
+ *
+ * Copyright (C) 2018 Wei Li <liwei1412@163.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/mdio-dev.h>
+#include <linux/mdio.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/slab.h>
+#include <linux/phy.h>
+
+/*
+ * An mdio_dev represents a mii_bus. It's coupled
+ * with a character special file which is accessed by user mode drivers.
+ *
+ * The list of mdio_dev structures is parallel to the mii_bus lists
+ * maintained by the driver model, and is updated using bus notifications.
+ */
+struct mdio_dev {
+ struct list_head list;
+ struct mii_bus *bus;
+ int nr;
+ struct device *dev;
+ struct cdev cdev;
+};
+
+static DEFINE_MUTEX(mdio_dev_lock);
+static DEFINE_IDR(mdio_dev_idr);
+static LIST_HEAD(mdio_dev_list);
+static DEFINE_SPINLOCK(mdio_dev_list_lock);
+
+static struct mdio_dev *mdio_dev_get_by_bus(struct mii_bus *bus)
+{
+ struct mdio_dev *mdio_dev;
+
+ if (!bus)
+ return NULL;
+
+ spin_lock(&mdio_dev_list_lock);
+ list_for_each_entry(mdio_dev, &mdio_dev_list, list) {
+ if (mdio_dev->bus == bus)
+ goto found;
+ }
+ mdio_dev = NULL;
+found:
+ spin_unlock(&mdio_dev_list_lock);
+ return mdio_dev;
+}
+
+static int alloc_mdio_dev_id(struct mdio_dev *mdio_dev)
+{
+ int id;
+
+ mutex_lock(&mdio_dev_lock);
+ id = idr_alloc(&mdio_dev_idr, mdio_dev, 0, MDIO_MINORS, GFP_KERNEL);
+ mutex_unlock(&mdio_dev_lock);
+ if (WARN(id < 0, "couldn't get idr"))
+ return id == -ENOSPC ? -EBUSY : id;
+
+ mdio_dev->nr = id;
+ return 0;
+}
+
+static void free_mdio_dev_id(struct mdio_dev *mdio_dev)
+{
+ mutex_lock(&mdio_dev_lock);
+ idr_remove(&mdio_dev_idr, mdio_dev->nr);
+ mutex_unlock(&mdio_dev_lock);
+ mdio_dev->nr = -1;
+}
+
+static struct mii_bus *mdiodev_get_bus(int nr)
+{
+ struct mdio_dev *found;
+
+ mutex_lock(&mdio_dev_lock);
+ found = idr_find(&mdio_dev_idr, nr);
+ if (!found)
+ goto exit;
+
+ if (try_module_get(found->bus->owner))
+ get_device(&found->bus->dev);
+ else
+ found = NULL;
+
+exit:
+ mutex_unlock(&mdio_dev_lock);
+ return found ? found->bus : NULL;
+}
+
+static void mdiodev_put_bus(struct mii_bus *bus)
+{
+ if (!bus)
+ return;
+
+ put_device(&bus->dev);
+ module_put(bus->owner);
+}
+
+static struct mdio_dev *get_free_mdio_dev(struct mii_bus *bus)
+{
+ struct mdio_dev *mdio_dev;
+
+ mdio_dev = kzalloc(sizeof(*mdio_dev), GFP_KERNEL);
+ if (!mdio_dev)
+ return ERR_PTR(-ENOMEM);
+ mdio_dev->bus = bus;
+
+ if (alloc_mdio_dev_id(mdio_dev)) {
+ printk(KERN_ERR "mdio-dev: Out of device minors\n");
+ kfree(mdio_dev);
+ return ERR_PTR(-ENODEV);
+ }
+
+ spin_lock(&mdio_dev_list_lock);
+ list_add_tail(&mdio_dev->list, &mdio_dev_list);
+ spin_unlock(&mdio_dev_list_lock);
+ return mdio_dev;
+}
+
+static void put_mdio_dev(struct mdio_dev *mdio_dev)
+{
+ spin_lock(&mdio_dev_list_lock);
+ list_del(&mdio_dev->list);
+ spin_unlock(&mdio_dev_list_lock);
+ free_mdio_dev_id(mdio_dev);
+ kfree(mdio_dev);
+}
+
+static ssize_t name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mii_bus *bus = mdiodev_get_bus(MINOR(dev->devt));
+
+ if (!bus)
+ return -ENODEV;
+ return sprintf(buf, "%s\n", bus->name);
+}
+static DEVICE_ATTR_RO(name);
+
+static struct attribute *mdio_attrs[] = {
+ &dev_attr_name.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(mdio);
+
+/*-------------------------------------------------------------------------*/
+
+static long mdiodev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct mii_bus *bus = file->private_data;
+ struct mii_ioctl_data data;
+ int res;
+
+ dev_dbg(&bus->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n", cmd, arg);
+
+ switch (cmd) {
+ case SIOCSMIIREG:
+ if (copy_from_user(&data,
+ (struct mii_ioctl_data __user *)arg, sizeof(data)))
+ return -EFAULT;
+
+ res = mdiobus_write(bus, data.phy_id, data.reg_num, data.val_in);
+ if (res < 0)
+ return -EIO;
+ return 0;
+
+ case SIOCGMIIREG:
+ if (copy_from_user(&data,
+ (struct mii_ioctl_data __user *)arg, sizeof(data)))
+ return -EFAULT;
+
+ res = mdiobus_read(bus, data.phy_id, data.reg_num);
+ if (res < 0)
+ return -EIO;
+
+ data.val_out = res;
+ if (copy_to_user((struct mii_ioctl_data __user *)arg,
+ &data, sizeof(data)))
+ return -EFAULT;
+ return 0;
+
+ default:
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+static int mdiodev_open(struct inode *inode, struct file *file)
+{
+ unsigned int minor = iminor(inode);
+ struct mii_bus *bus;
+
+ bus = mdiodev_get_bus(minor);
+ if (!bus)
+ return -ENODEV;
+
+ file->private_data = bus;
+
+ return 0;
+}
+
+static int mdiodev_release(struct inode *inode, struct file *file)
+{
+ struct mii_bus *bus = file->private_data;
+
+ mdiodev_put_bus(bus);
+ file->private_data = NULL;
+
+ return 0;
+}
+
+static const struct file_operations mdiodev_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .unlocked_ioctl = mdiodev_ioctl,
+ .open = mdiodev_open,
+ .release = mdiodev_release,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int mdio_major;
+static struct class *mdio_dev_class;
+
+static int mdiodev_attach_bus(struct device *dev, void *dummy)
+{
+ struct mii_bus *bus;
+ struct mdio_dev *mdio_dev;
+ int res;
+
+ if (dev->class != &mdio_bus_class)
+ return 0;
+ bus = to_mii_bus(dev);
+
+ mdio_dev = get_free_mdio_dev(bus);
+ if (IS_ERR(mdio_dev))
+ return PTR_ERR(mdio_dev);
+
+ cdev_init(&mdio_dev->cdev, &mdiodev_fops);
+ mdio_dev->cdev.owner = THIS_MODULE;
+ res = cdev_add(&mdio_dev->cdev, MKDEV(mdio_major, mdio_dev->nr), 1);
+ if (res)
+ goto error_cdev;
+
+ /* register this mdio device with the driver core */
+ mdio_dev->dev = device_create(mdio_dev_class, &bus->dev,
+ MKDEV(mdio_major, mdio_dev->nr), NULL,
+ "mdio-%d", mdio_dev->nr);
+ if (IS_ERR(mdio_dev->dev)) {
+ res = PTR_ERR(mdio_dev->dev);
+ goto error;
+ }
+
+ pr_debug("mdio-dev: bus [%s] registered as minor %d\n",
+ bus->name, mdio_dev->nr);
+ return 0;
+error:
+ cdev_del(&mdio_dev->cdev);
+error_cdev:
+ put_mdio_dev(mdio_dev);
+ return res;
+}
+
+static int mdiodev_detach_bus(struct device *dev, void *dummy)
+{
+ struct mii_bus *bus;
+ struct mdio_dev *mdio_dev;
+
+ if (dev->class != &mdio_bus_class)
+ return 0;
+ bus = to_mii_bus(dev);
+
+ mdio_dev = mdio_dev_get_by_bus(bus);
+ if (!mdio_dev) /* attach_bus must have failed */
+ return 0;
+
+ cdev_del(&mdio_dev->cdev);
+ device_destroy(mdio_dev_class, MKDEV(mdio_major, mdio_dev->nr));
+ put_mdio_dev(mdio_dev);
+
+ pr_debug("mdio-dev: bus [%s] unregistered\n", bus->name);
+ return 0;
+}
+
+static int mdiodev_notifier_call(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct device *dev = data;
+
+ switch (action) {
+ case BUS_NOTIFY_ADD_DEVICE:
+ return mdiodev_attach_bus(dev, NULL);
+ case BUS_NOTIFY_DEL_DEVICE:
+ return mdiodev_detach_bus(dev, NULL);
+ }
+
+ return 0;
+}
+
+static struct notifier_block mdiodev_notifier = {
+ .notifier_call = mdiodev_notifier_call,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int __init mdio_dev_init(void)
+{
+ int res;
+ dev_t devid;
+
+ printk(KERN_INFO "mdio /dev entries driver\n");
+
+ res = alloc_chrdev_region(&devid, 0, MDIO_MINORS, "mdio");
+ if (res)
+ goto out;
+
+ mdio_major = MAJOR(devid);
+ mdio_dev_class = class_create(THIS_MODULE, "mdio-dev");
+ if (IS_ERR(mdio_dev_class)) {
+ res = PTR_ERR(mdio_dev_class);
+ goto out_unreg_chrdev;
+ }
+ mdio_dev_class->dev_groups = mdio_groups;
+
+ /* Keep track of buses which will be added or removed later */
+ res = mdiobus_register_notifier(&mdiodev_notifier);
+ if (res)
+ goto out_unreg_class;
+
+ /* Bind to already existing buses right away */
+ class_for_each_device(&mdio_bus_class, NULL, NULL, mdiodev_attach_bus);
+
+ return 0;
+
+out_unreg_class:
+ class_destroy(mdio_dev_class);
+out_unreg_chrdev:
+ unregister_chrdev_region(MKDEV(mdio_major, 0), MDIO_MINORS);
+out:
+ printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);
+ return res;
+}
+
+static void __exit mdio_dev_exit(void)
+{
+ mdiobus_unregister_notifier(&mdiodev_notifier);
+ class_for_each_device(&mdio_bus_class, NULL, NULL, mdiodev_detach_bus);
+ class_destroy(mdio_dev_class);
+ unregister_chrdev_region(MKDEV(mdio_major, 0), MDIO_MINORS);
+}
+
+MODULE_AUTHOR("Wei Li <liwei1412@163.com>");
+MODULE_DESCRIPTION("MDIO /dev entries driver");
+MODULE_LICENSE("GPL");
+
+module_init(mdio_dev_init);
+module_exit(mdio_dev_exit);
diff --git a/include/linux/mdio-dev.h b/include/linux/mdio-dev.h
new file mode 100644
index 0000000..cc4ed36
--- /dev/null
+++ b/include/linux/mdio-dev.h
@@ -0,0 +1,28 @@
+/*
+ * mdio-dev.h - mdio-bus driver, char device interface
+ *
+ * Copyright (C) 2018 Wei Li <liwei1412@163.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+#ifndef _LINUX_MDIO_DEV_H
+#define _LINUX_MDIO_DEV_H
+
+#include <uapi/linux/mii.h>
+
+#define MDIO_MINORS MINORMASK
+
+#endif /* _LINUX_MDIO_DEV_H */
--
2.1.4
^ permalink raw reply related
* [PATCH 2/2] eth phy: add mdio bus char device interface
From: Wei Li @ 2018-06-18 3:32 UTC (permalink / raw)
To: andrew, f.fainelli; +Cc: netdev
In-Reply-To: <1529292733-13243-1-git-send-email-liwei1412@163.com>
Add the notifier for the change of mdio bus, since i wanna that a char device
represents a mii_bus not a mdio_device.
Signed-off-by: Wei Li <liwei1412@163.com>
---
drivers/net/phy/mdio_bus.c | 21 ++++++++++++++++++++-
include/linux/mdio.h | 1 +
include/linux/phy.h | 2 ++
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 24b5511..3821dc8 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -240,10 +240,25 @@ static void mdiobus_release(struct device *d)
kfree(bus);
}
-static struct class mdio_bus_class = {
+struct class mdio_bus_class = {
.name = "mdio_bus",
.dev_release = mdiobus_release,
};
+EXPORT_SYMBOL_GPL(mdio_bus_class);
+
+static BLOCKING_NOTIFIER_HEAD(mdio_bus_notifier_list);
+
+int mdiobus_register_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(
+ &mdio_bus_notifier_list, nb);
+}
+
+int mdiobus_unregister_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(
+ &mdio_bus_notifier_list, nb);
+}
#if IS_ENABLED(CONFIG_OF_MDIO)
/* Helper function for of_mdio_find_bus */
@@ -418,6 +433,8 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
mdiobus_setup_mdiodev_from_board_info(bus, mdiobus_create_device);
bus->state = MDIOBUS_REGISTERED;
+ blocking_notifier_call_chain(&mdio_bus_notifier_list,
+ BUS_NOTIFY_ADD_DEVICE, &bus->dev);
pr_info("%s: probed\n", bus->name);
return 0;
@@ -446,6 +463,8 @@ void mdiobus_unregister(struct mii_bus *bus)
int i;
BUG_ON(bus->state != MDIOBUS_REGISTERED);
+ blocking_notifier_call_chain(&mdio_bus_notifier_list,
+ BUS_NOTIFY_DEL_DEVICE, &bus->dev);
bus->state = MDIOBUS_UNREGISTERED;
for (i = 0; i < PHY_MAX_ADDR; i++) {
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index 2cfffe5..29ab455 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -79,6 +79,7 @@ void mdio_device_reset(struct mdio_device *mdiodev, int value);
int mdio_driver_register(struct mdio_driver *drv);
void mdio_driver_unregister(struct mdio_driver *drv);
int mdio_device_bus_match(struct device *dev, struct device_driver *drv);
+extern struct class mdio_bus_class;
static inline bool mdio_phy_id_is_c45(int phy_id)
{
diff --git a/include/linux/phy.h b/include/linux/phy.h
index f0b5870..39f2609 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -246,6 +246,8 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner);
#define mdiobus_register(bus) __mdiobus_register(bus, THIS_MODULE)
void mdiobus_unregister(struct mii_bus *bus);
void mdiobus_free(struct mii_bus *bus);
+int mdiobus_register_notifier(struct notifier_block *nb);
+int mdiobus_unregister_notifier(struct notifier_block *nb);
struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv);
static inline struct mii_bus *devm_mdiobus_alloc(struct device *dev)
{
--
2.1.4
^ permalink raw reply related
* Re: linux-next: build failure in Linus' tree
From: Stephen Rothwell @ 2018-06-18 3:50 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann
Cc: Linux-Next Mailing List, Linux Kernel Mailing List, David Miller,
Networking, Michael Ellerman, Benjamin Herrenschmidt, PowerPC
In-Reply-To: <20180612122640.534118ed@canb.auug.org.au>
[-- Attachment #1: Type: text/plain, Size: 659 bytes --]
Hi all,
On Tue, 12 Jun 2018 12:26:40 +1000 Stephen Rothwell <sfr@canb.auug.org.au> wrote:
>
> Building Linus' tree, today's linux-next build (powerpc allyesconfig)
> failed like this:
>
> ld: net/bpfilter/bpfilter_umh.o: compiled for a little endian system and target is big endian
> ld: failed to merge target specific data of file net/bpfilter/bpfilter_umh.o
>
> This has come to light since I started using a native compiler (i.e. one
> that can build executables, not just the kernel) for my PowerPC builds
> on a powerpcle host.
>
> I have switched back to my limited compiler.
Any progress on this?
--
Cheers,
Stephen Rothwell
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* DEAR FRIEND
From: Payton Rupali @ 2018-06-18 4:18 UTC (permalink / raw)
In-Reply-To: <1718819165.1036367.1529295496452.ref@mail.yahoo.com>
Dear friend,
My name is Mr.Payton Rupali. I am working with one of the prime banks in Burkina Faso. Here in this bank existed a dormant account for many years, which belong to one of our late foreign customer. The amount in this account stands at $13,300,000.00 (Thirteen Million Three Hundred Thousand USA Dollars).
I want a foreign account where the bank will transfer this fund. I know you would be surprised to read this message, especially from someone relatively unknown to you. But, do not worry yourself so much. This is a genuine, risk free and legal business transaction. All details shall be sent to you once I hear from you.
I was very fortunate to come across the deceased customer's security file during documentation of old and abandoned customer’s files for an official redocumentation and audit of the year 2018.
If you are really sure of your sincerity, trustworthiness,accountability and confidentiality over this transaction, reply back to me urgently.
Best regards,
Mr.Payton Rupali
Email:paytonrupali10@gmail.com
^ permalink raw reply
* Re: [PATCH 1/2] eth phy: add mdio bus char device interface
From: kbuild test robot @ 2018-06-18 5:22 UTC (permalink / raw)
To: Wei Li; +Cc: kbuild-all, andrew, f.fainelli, netdev
In-Reply-To: <1529292733-13243-1-git-send-email-liwei1412@163.com>
[-- Attachment #1: Type: text/plain, Size: 7227 bytes --]
Hi Wei,
I love your patch! Yet something to improve:
[auto build test ERROR on net-next/master]
[also build test ERROR on v4.18-rc1 next-20180615]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Wei-Li/eth-phy-add-mdio-bus-char-device-interface/20180618-115206
config: xtensa-allmodconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=8.1.0 make.cross ARCH=xtensa
Note: the linux-review/Wei-Li/eth-phy-add-mdio-bus-char-device-interface/20180618-115206 HEAD 611497ceadd8527fc1e4aa0eb8936171906118dd builds fine.
It only hurts bisectibility.
All errors (new ones prefixed by >>):
drivers/net/phy/mdio-dev.c: In function 'mdiodev_attach_bus':
>> drivers/net/phy/mdio-dev.c:250:21: error: 'mdio_bus_class' undeclared (first use in this function); did you mean 'mdio_dev_class'?
if (dev->class != &mdio_bus_class)
^~~~~~~~~~~~~~
mdio_dev_class
drivers/net/phy/mdio-dev.c:250:21: note: each undeclared identifier is reported only once for each function it appears in
drivers/net/phy/mdio-dev.c: In function 'mdiodev_detach_bus':
drivers/net/phy/mdio-dev.c:288:21: error: 'mdio_bus_class' undeclared (first use in this function); did you mean 'mdio_dev_class'?
if (dev->class != &mdio_bus_class)
^~~~~~~~~~~~~~
mdio_dev_class
drivers/net/phy/mdio-dev.c: In function 'mdio_dev_init':
>> drivers/net/phy/mdio-dev.c:345:8: error: implicit declaration of function 'mdiobus_register_notifier'; did you mean 'bus_register_notifier'? [-Werror=implicit-function-declaration]
res = mdiobus_register_notifier(&mdiodev_notifier);
^~~~~~~~~~~~~~~~~~~~~~~~~
bus_register_notifier
drivers/net/phy/mdio-dev.c:350:25: error: 'mdio_bus_class' undeclared (first use in this function); did you mean 'mdio_dev_class'?
class_for_each_device(&mdio_bus_class, NULL, NULL, mdiodev_attach_bus);
^~~~~~~~~~~~~~
mdio_dev_class
drivers/net/phy/mdio-dev.c: In function 'mdio_dev_exit':
>> drivers/net/phy/mdio-dev.c:365:2: error: implicit declaration of function 'mdiobus_unregister_notifier'; did you mean 'bus_unregister_notifier'? [-Werror=implicit-function-declaration]
mdiobus_unregister_notifier(&mdiodev_notifier);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
bus_unregister_notifier
drivers/net/phy/mdio-dev.c:366:25: error: 'mdio_bus_class' undeclared (first use in this function); did you mean 'mdio_dev_class'?
class_for_each_device(&mdio_bus_class, NULL, NULL, mdiodev_detach_bus);
^~~~~~~~~~~~~~
mdio_dev_class
cc1: some warnings being treated as errors
vim +250 drivers/net/phy/mdio-dev.c
243
244 static int mdiodev_attach_bus(struct device *dev, void *dummy)
245 {
246 struct mii_bus *bus;
247 struct mdio_dev *mdio_dev;
248 int res;
249
> 250 if (dev->class != &mdio_bus_class)
251 return 0;
252 bus = to_mii_bus(dev);
253
254 mdio_dev = get_free_mdio_dev(bus);
255 if (IS_ERR(mdio_dev))
256 return PTR_ERR(mdio_dev);
257
258 cdev_init(&mdio_dev->cdev, &mdiodev_fops);
259 mdio_dev->cdev.owner = THIS_MODULE;
260 res = cdev_add(&mdio_dev->cdev, MKDEV(mdio_major, mdio_dev->nr), 1);
261 if (res)
262 goto error_cdev;
263
264 /* register this mdio device with the driver core */
265 mdio_dev->dev = device_create(mdio_dev_class, &bus->dev,
266 MKDEV(mdio_major, mdio_dev->nr), NULL,
267 "mdio-%d", mdio_dev->nr);
268 if (IS_ERR(mdio_dev->dev)) {
269 res = PTR_ERR(mdio_dev->dev);
270 goto error;
271 }
272
273 pr_debug("mdio-dev: bus [%s] registered as minor %d\n",
274 bus->name, mdio_dev->nr);
275 return 0;
276 error:
277 cdev_del(&mdio_dev->cdev);
278 error_cdev:
279 put_mdio_dev(mdio_dev);
280 return res;
281 }
282
283 static int mdiodev_detach_bus(struct device *dev, void *dummy)
284 {
285 struct mii_bus *bus;
286 struct mdio_dev *mdio_dev;
287
288 if (dev->class != &mdio_bus_class)
289 return 0;
290 bus = to_mii_bus(dev);
291
292 mdio_dev = mdio_dev_get_by_bus(bus);
293 if (!mdio_dev) /* attach_bus must have failed */
294 return 0;
295
296 cdev_del(&mdio_dev->cdev);
297 device_destroy(mdio_dev_class, MKDEV(mdio_major, mdio_dev->nr));
298 put_mdio_dev(mdio_dev);
299
300 pr_debug("mdio-dev: bus [%s] unregistered\n", bus->name);
301 return 0;
302 }
303
304 static int mdiodev_notifier_call(struct notifier_block *nb, unsigned long action,
305 void *data)
306 {
307 struct device *dev = data;
308
309 switch (action) {
310 case BUS_NOTIFY_ADD_DEVICE:
311 return mdiodev_attach_bus(dev, NULL);
312 case BUS_NOTIFY_DEL_DEVICE:
313 return mdiodev_detach_bus(dev, NULL);
314 }
315
316 return 0;
317 }
318
319 static struct notifier_block mdiodev_notifier = {
320 .notifier_call = mdiodev_notifier_call,
321 };
322
323 /*-------------------------------------------------------------------------*/
324
325 static int __init mdio_dev_init(void)
326 {
327 int res;
328 dev_t devid;
329
330 printk(KERN_INFO "mdio /dev entries driver\n");
331
332 res = alloc_chrdev_region(&devid, 0, MDIO_MINORS, "mdio");
333 if (res)
334 goto out;
335
336 mdio_major = MAJOR(devid);
337 mdio_dev_class = class_create(THIS_MODULE, "mdio-dev");
338 if (IS_ERR(mdio_dev_class)) {
339 res = PTR_ERR(mdio_dev_class);
340 goto out_unreg_chrdev;
341 }
342 mdio_dev_class->dev_groups = mdio_groups;
343
344 /* Keep track of buses which will be added or removed later */
> 345 res = mdiobus_register_notifier(&mdiodev_notifier);
346 if (res)
347 goto out_unreg_class;
348
349 /* Bind to already existing buses right away */
350 class_for_each_device(&mdio_bus_class, NULL, NULL, mdiodev_attach_bus);
351
352 return 0;
353
354 out_unreg_class:
355 class_destroy(mdio_dev_class);
356 out_unreg_chrdev:
357 unregister_chrdev_region(MKDEV(mdio_major, 0), MDIO_MINORS);
358 out:
359 printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);
360 return res;
361 }
362
363 static void __exit mdio_dev_exit(void)
364 {
> 365 mdiobus_unregister_notifier(&mdiodev_notifier);
366 class_for_each_device(&mdio_bus_class, NULL, NULL, mdiodev_detach_bus);
367 class_destroy(mdio_dev_class);
368 unregister_chrdev_region(MKDEV(mdio_major, 0), MDIO_MINORS);
369 }
370
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 53907 bytes --]
^ permalink raw reply
* KASAN: use-after-free Read in fib6_table_lookup
From: syzbot @ 2018-06-18 6:06 UTC (permalink / raw)
To: davem, kuznet, linux-kernel, netdev, syzkaller-bugs, yoshfuji
Hello,
syzbot found the following crash on:
HEAD commit: f0dc7f9c6dd9 Merge git://git.kernel.org/pub/scm/linux/kern..
git tree: bpf-next
console output: https://syzkaller.appspot.com/x/log.txt?x=16725130400000
kernel config: https://syzkaller.appspot.com/x/.config?x=fa9c20c48788d1c1
dashboard link: https://syzkaller.appspot.com/bug?extid=9e6d75e3edef427ee888
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+9e6d75e3edef427ee888@syzkaller.appspotmail.com
==================================================================
BUG: KASAN: use-after-free in __read_once_size include/linux/compiler.h:188
[inline]
BUG: KASAN: use-after-free in find_rr_leaf net/ipv6/route.c:705 [inline]
BUG: KASAN: use-after-free in rt6_select net/ipv6/route.c:761 [inline]
BUG: KASAN: use-after-free in fib6_table_lookup+0x12b7/0x14d0
net/ipv6/route.c:1823
Read of size 8 at addr ffff8801b5df2588 by task udevd/1407
overlayfs: unrecognized mount
option "Sl�tI��p�5�Wӌ���c��\x14&�\x1ee"\x03�M��q�W����u�r'�v�-br\x10E1n��U(��K�g�==;GZ��
\x18�\x1d\x1e��<��2
N���\x13�������\x19\x05l�\x0f8_��'�%]�]X�7���aNvD�cA��_�\x12(\x0f�"��w��Q��++Q%5�����/��>*4Ϻ��k�{�)<��^\x01r\aΎ�B��b\x1ĕ��(�ӷ�ӌ���l\aå�
�b��\v������b�@\x04iO^[�A�s��\aN� � �91�¢^[��m�Gc�\x10��\x10�j��\�2G-k\x03��\x16'��UI\x18\x05�\8\x16��\b}0�\x11�.�Gh�P�\x0ew�����U�^9�\���\x17\x05Sݐ�ʊ��n��a]��T�E�����gaj=Zڒ�_kP��l!�Þ\x02���r��s\x0e��.\x12�9��\�D]��b�y$���\x11mQ�\x17����ڨҙM�q��~vX'��6�ň$5��a+^[�.}�\x14U\x11uc9݇o.׃�.S܉I��7\x13�5�e�D8��k��E�M#������m�����Vy����7=jV����\x16:�k[(>M
#�b���Z秺]k/^�\x19�\x03���৴�\x1e�;�v\x04����^[`G6�m>�\x16��'e0�^[�q
�s|�wJ�'\x16r\x04A����M�$�^[��r\x170\x14�
u�U\x0fU~\x03|��}>P{1\x1eflt��i�1+A� �%۪(7˧Ȯ�?ܟ�\x12����)_�\a����[�w������9W\a�
�،��\x0e�&B�M�m�\x1a\x122�\x10b֊ɹ�S@�q�
��4\x01j�h�%��\fT�'$'�\x05!�ٌt�4C3�g�nypBŔ���o�B�\x19q\v�o�'�}��!�Tp9d\x06˨^[���c��U`}_EҨ��\\x0e\a\x06�I�X��q\x18^�7-[\x10��v[�-�_G�\x0eg)�?#~��h
CPU: 0 PID: 1407 Comm: udevd Not tainted 4.17.0+ #39
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
<IRQ>
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x1b9/0x294 lib/dump_stack.c:113
print_address_description+0x6c/0x20b mm/kasan/report.c:256
kasan_report_error mm/kasan/report.c:354 [inline]
kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412
__asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:433
__read_once_size include/linux/compiler.h:188 [inline]
find_rr_leaf net/ipv6/route.c:705 [inline]
rt6_select net/ipv6/route.c:761 [inline]
fib6_table_lookup+0x12b7/0x14d0 net/ipv6/route.c:1823
ip6_pol_route+0x1c2/0x1020 net/ipv6/route.c:1856
ip6_pol_route_output+0x54/0x70 net/ipv6/route.c:2082
fib6_rule_lookup+0x211/0x6d0 net/ipv6/fib6_rules.c:122
ip6_route_output_flags+0x2c5/0x350 net/ipv6/route.c:2110
ip6_route_output include/net/ip6_route.h:82 [inline]
icmpv6_xrlim_allow net/ipv6/icmp.c:211 [inline]
icmp6_send+0x147c/0x2da0 net/ipv6/icmp.c:535
icmpv6_send+0x17a/0x300 net/ipv6/ip6_icmp.c:43
ip6_link_failure+0xa5/0x790 net/ipv6/route.c:2244
dst_link_failure include/net/dst.h:427 [inline]
ndisc_error_report+0xd1/0x1c0 net/ipv6/ndisc.c:695
neigh_invalidate+0x246/0x550 net/core/neighbour.c:892
neigh_timer_handler+0xaf9/0xde0 net/core/neighbour.c:978
call_timer_fn+0x230/0x940 kernel/time/timer.c:1326
expire_timers kernel/time/timer.c:1363 [inline]
__run_timers+0x79e/0xc50 kernel/time/timer.c:1666
run_timer_softirq+0x4c/0x70 kernel/time/timer.c:1692
__do_softirq+0x2e0/0xaf5 kernel/softirq.c:284
invoke_softirq kernel/softirq.c:364 [inline]
irq_exit+0x1d1/0x200 kernel/softirq.c:404
exiting_irq arch/x86/include/asm/apic.h:527 [inline]
smp_apic_timer_interrupt+0x17e/0x710 arch/x86/kernel/apic/apic.c:1052
apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:863
</IRQ>
RIP: 0010:strlen+0x5e/0xa0 lib/string.c:482
Code: 24 00 74 3b 48 bb 00 00 00 00 00 fc ff df 4c 89 e0 48 83 c0 01 48 89
c2 48 89 c1 48 c1 ea 03 83 e1 07 0f b6 14 1a 38 ca 7f 04 <84> d2 75 23 80
38 00 75 de 48 83 c4 08 4c 29 e0 5b 41 5c 5d c3 48
RSP: 0018:ffff8801af117850 EFLAGS: 00000246 ORIG_RAX: ffffffffffffff13
RAX: ffff880197f53bd0 RBX: dffffc0000000000 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffffffff81c5b06c RDI: ffff880197f53bc0
RBP: ffff8801af117868 R08: ffff88019a976540 R09: 0000000000000000
R10: ffff88019a976540 R11: 0000000000000000 R12: ffff880197f53bc0
R13: ffff880197f53bc0 R14: ffffffff899e4e90 R15: ffff8801d91c6a00
strlen include/linux/string.h:267 [inline]
getname_kernel+0x24/0x370 fs/namei.c:218
open_exec+0x17/0x70 fs/exec.c:882
load_elf_binary+0x968/0x5610 fs/binfmt_elf.c:780
search_binary_handler+0x17d/0x570 fs/exec.c:1653
exec_binprm fs/exec.c:1695 [inline]
__do_execve_file.isra.35+0x16fe/0x2710 fs/exec.c:1819
do_execveat_common fs/exec.c:1866 [inline]
do_execve fs/exec.c:1883 [inline]
__do_sys_execve fs/exec.c:1964 [inline]
__se_sys_execve fs/exec.c:1959 [inline]
__x64_sys_execve+0x8f/0xc0 fs/exec.c:1959
do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x7f1576a46207
Code: 77 19 f4 48 89 d7 44 89 c0 0f 05 48 3d 00 f0 ff ff 76 e0 f7 d8 64 41
89 01 eb d8 f7 d8 64 41 89 01 eb df b8 3b 00 00 00 0f 05 <48> 3d 00 f0 ff
ff 77 02 f3 c3 48 8b 15 00 8c 2d 00 f7 d8 64 89 02
RSP: 002b:00007ffff2784568 EFLAGS: 00000202 ORIG_RAX: 000000000000003b
RAX: ffffffffffffffda RBX: 00000000ffffffff RCX: 00007f1576a46207
RDX: 0000000001215b10 RSI: 00007ffff2784660 RDI: 00007ffff2785670
RBP: 0000000000625500 R08: 000000000000589c R09: 000000000000589c
R10: 0000000000000000 R11: 0000000000000202 R12: 0000000001215b10
R13: 0000000000000007 R14: 0000000001204250 R15: 0000000000000005
Allocated by task 12188:
save_stack+0x43/0xd0 mm/kasan/kasan.c:448
set_track mm/kasan/kasan.c:460 [inline]
kasan_kmalloc+0xc4/0xe0 mm/kasan/kasan.c:553
kmem_cache_alloc_trace+0x152/0x780 mm/slab.c:3620
kmalloc include/linux/slab.h:513 [inline]
kzalloc include/linux/slab.h:706 [inline]
fib6_info_alloc+0xbb/0x280 net/ipv6/ip6_fib.c:152
ip6_route_info_create+0x782/0x2b50 net/ipv6/route.c:3013
ip6_route_add+0x23/0xb0 net/ipv6/route.c:3154
ipv6_route_ioctl+0x5a5/0x760 net/ipv6/route.c:3660
inet6_ioctl+0x100/0x1f0 net/ipv6/af_inet6.c:546
sock_do_ioctl+0xe4/0x3e0 net/socket.c:973
sock_ioctl+0x30d/0x680 net/socket.c:1097
vfs_ioctl fs/ioctl.c:46 [inline]
file_ioctl fs/ioctl.c:500 [inline]
do_vfs_ioctl+0x1cf/0x16f0 fs/ioctl.c:684
ksys_ioctl+0xa9/0xd0 fs/ioctl.c:701
__do_sys_ioctl fs/ioctl.c:708 [inline]
__se_sys_ioctl fs/ioctl.c:706 [inline]
__x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:706
do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
Freed by task 1402:
save_stack+0x43/0xd0 mm/kasan/kasan.c:448
set_track mm/kasan/kasan.c:460 [inline]
__kasan_slab_free+0x11a/0x170 mm/kasan/kasan.c:521
kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528
__cache_free mm/slab.c:3498 [inline]
kfree+0xd9/0x260 mm/slab.c:3813
fib6_info_destroy+0x29b/0x350 net/ipv6/ip6_fib.c:207
fib6_info_release include/net/ip6_fib.h:286 [inline]
__ip6_del_rt_siblings net/ipv6/route.c:3235 [inline]
ip6_route_del+0x11c4/0x13b0 net/ipv6/route.c:3316
ipv6_route_ioctl+0x616/0x760 net/ipv6/route.c:3663
inet6_ioctl+0x100/0x1f0 net/ipv6/af_inet6.c:546
sock_do_ioctl+0xe4/0x3e0 net/socket.c:973
sock_ioctl+0x30d/0x680 net/socket.c:1097
vfs_ioctl fs/ioctl.c:46 [inline]
file_ioctl fs/ioctl.c:500 [inline]
do_vfs_ioctl+0x1cf/0x16f0 fs/ioctl.c:684
ksys_ioctl+0xa9/0xd0 fs/ioctl.c:701
__do_sys_ioctl fs/ioctl.c:708 [inline]
__se_sys_ioctl fs/ioctl.c:706 [inline]
__x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:706
do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
The buggy address belongs to the object at ffff8801b5df2580
which belongs to the cache kmalloc-256 of size 256
The buggy address is located 8 bytes inside of
256-byte region [ffff8801b5df2580, ffff8801b5df2680)
The buggy address belongs to the page:
page:ffffea0006d77c80 count:1 mapcount:0 mapping:ffff8801da8007c0
index:0xffff8801b5df2e40
flags: 0x2fffc0000000100(slab)
raw: 02fffc0000000100 ffffea0006c5cc48 ffffea0007363308 ffff8801da8007c0
raw: ffff8801b5df2e40 ffff8801b5df2080 0000000100000006 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8801b5df2480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8801b5df2500: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
> ffff8801b5df2580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8801b5df2600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8801b5df2680: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
==================================================================
---
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 2/2] eth phy: add mdio bus char device interface
From: kbuild test robot @ 2018-06-18 6:52 UTC (permalink / raw)
To: Wei Li; +Cc: kbuild-all, andrew, f.fainelli, netdev
In-Reply-To: <1529292733-13243-2-git-send-email-liwei1412@163.com>
[-- Attachment #1: Type: text/plain, Size: 1237 bytes --]
Hi Wei,
I love your patch! Yet something to improve:
[auto build test ERROR on net-next/master]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Wei-Li/eth-phy-add-mdio-bus-char-device-interface/20180618-115206
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 8.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=8.1.0 make.cross ARCH=ia64
All errors (new ones prefixed by >>):
ERROR: "ia64_delay_loop" [drivers/spi/spi-thunderx.ko] undefined!
ERROR: "__sw_hweight8" [drivers/net/wireless/mediatek/mt76/mt76.ko] undefined!
>> ERROR: "mdiobus_unregister_notifier" [drivers/net/phy/mdio-dev.ko] undefined!
>> ERROR: "mdiobus_register_notifier" [drivers/net/phy/mdio-dev.ko] undefined!
ERROR: "ia64_delay_loop" [drivers/net/phy/mdio-cavium.ko] undefined!
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 50794 bytes --]
^ permalink raw reply
* Re: [PATCH] dt-bindings: Fix unbalanced quotation marks
From: Krzysztof Kozlowski @ 2018-06-18 7:06 UTC (permalink / raw)
To: Jonathan Neuschäfer
Cc: devicetree, Kukjin Kim, Rob Herring, Mark Rutland, Linus Walleij,
Dmitry Torokhov, Thomas Gleixner, Jason Cooper, Marc Zyngier,
Thierry Reding, Jonathan Hunter, Maxime Coquelin,
Alexandre Torgue, Hauke Mehrtens, Rafał Miłecki,
Ralf Baechle, Paul Burton, James Hogan, Madalin Bucur
In-Reply-To: <20180617143127.11421-1-j.neuschaefer@gmx.net>
On Sun, Jun 17, 2018 at 4:31 PM, Jonathan Neuschäfer
<j.neuschaefer@gmx.net> wrote:
> Multiple binding documents have various forms of unbalanced quotation
> marks. Fix them.
>
> Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
> ---
>
> Should I split this patch so that different parts can go through different trees?
> ---
> .../devicetree/bindings/arm/samsung/samsung-boards.txt | 2 +-
> .../devicetree/bindings/gpio/nintendo,hollywood-gpio.txt | 2 +-
> Documentation/devicetree/bindings/input/touchscreen/hideep.txt | 2 +-
> .../bindings/interrupt-controller/nvidia,tegra20-ictlr.txt | 2 +-
> .../devicetree/bindings/interrupt-controller/st,stm32-exti.txt | 2 +-
> Documentation/devicetree/bindings/mips/brcm/soc.txt | 2 +-
> Documentation/devicetree/bindings/net/fsl-fman.txt | 2 +-
> Documentation/devicetree/bindings/power/power_domain.txt | 2 +-
> Documentation/devicetree/bindings/regulator/tps65090.txt | 2 +-
> Documentation/devicetree/bindings/reset/st,sti-softreset.txt | 2 +-
> Documentation/devicetree/bindings/sound/qcom,apq8016-sbc.txt | 2 +-
> Documentation/devicetree/bindings/sound/qcom,apq8096.txt | 2 +-
> 12 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
> index bdadc3da9556..6970f30a3770 100644
> --- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
> +++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
> @@ -66,7 +66,7 @@ Required root node properties:
> - "insignal,arndale-octa" - for Exynos5420-based Insignal Arndale
> Octa board.
> - "insignal,origen" - for Exynos4210-based Insignal Origen board.
> - - "insignal,origen4412 - for Exynos4412-based Insignal Origen board.
> + - "insignal,origen4412" - for Exynos4412-based Insignal Origen board.
>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH 0/4] Slience NCSI logging
From: Joel Stanley @ 2018-06-18 7:19 UTC (permalink / raw)
To: Samuel Mendoza-Jonas, David S . Miller; +Cc: netdev
Here are three changes to silence unnecessary warnings in the ncsi code.
The final patch adds Sam as the maintainer for NCSI.
Joel Stanley (4):
net/ncsi: Silence debug messages
net/ncsi: Drop no more channels message
net/ncsi: Use netdev_dbg for debug messages
MAINTAINERS: Add Sam as the maintainer for NCSI
MAINTAINERS | 5 +++
drivers/net/ethernet/faraday/ftgmac100.c | 2 +-
net/ncsi/ncsi-aen.c | 10 ++---
net/ncsi/ncsi-manage.c | 49 +++++++++++-------------
4 files changed, 33 insertions(+), 33 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH 1/4] net/ncsi: Silence debug messages
From: Joel Stanley @ 2018-06-18 7:19 UTC (permalink / raw)
To: Samuel Mendoza-Jonas, David S . Miller; +Cc: netdev
In-Reply-To: <20180618071916.6765-1-joel@jms.id.au>
In normal operation we see this series of messages as the host drives
the network device:
ftgmac100 1e660000.ethernet eth0: NCSI: LSC AEN - channel 0 state down
ftgmac100 1e660000.ethernet eth0: NCSI: suspending channel 0
ftgmac100 1e660000.ethernet eth0: NCSI: configuring channel 0
ftgmac100 1e660000.ethernet eth0: NCSI: channel 0 link down after config
ftgmac100 1e660000.ethernet eth0: NCSI interface down
ftgmac100 1e660000.ethernet eth0: NCSI: LSC AEN - channel 0 state up
ftgmac100 1e660000.ethernet eth0: NCSI: configuring channel 0
ftgmac100 1e660000.ethernet eth0: NCSI interface up
ftgmac100 1e660000.ethernet eth0: NCSI: LSC AEN - channel 0 state down
ftgmac100 1e660000.ethernet eth0: NCSI: suspending channel 0
ftgmac100 1e660000.ethernet eth0: NCSI: configuring channel 0
ftgmac100 1e660000.ethernet eth0: NCSI: channel 0 link down after config
ftgmac100 1e660000.ethernet eth0: NCSI interface down
ftgmac100 1e660000.ethernet eth0: NCSI: LSC AEN - channel 0 state up
ftgmac100 1e660000.ethernet eth0: NCSI: configuring channel 0
ftgmac100 1e660000.ethernet eth0: NCSI interface up
This makes all of these messages netdev_dbg. They are still useful to
debug eg. misbehaving network device firmware, but we do not need them
filling up the kernel logs in normal operation.
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
drivers/net/ethernet/faraday/ftgmac100.c | 2 +-
net/ncsi/ncsi-aen.c | 4 ++--
net/ncsi/ncsi-manage.c | 14 +++++++-------
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index 78db8e62a83f..a78413d5bfde 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -1735,7 +1735,7 @@ static void ftgmac100_ncsi_handler(struct ncsi_dev *nd)
if (unlikely(nd->state != ncsi_dev_state_functional))
return;
- netdev_info(nd->dev, "NCSI interface %s\n",
+ netdev_dbg(nd->dev, "NCSI interface %s\n",
nd->link_up ? "up" : "down");
}
diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c
index e7b05de1e6d1..f899ed61bb57 100644
--- a/net/ncsi/ncsi-aen.c
+++ b/net/ncsi/ncsi-aen.c
@@ -73,8 +73,8 @@ static int ncsi_aen_handler_lsc(struct ncsi_dev_priv *ndp,
ncm->data[2] = data;
ncm->data[4] = ntohl(lsc->oem_status);
- netdev_info(ndp->ndev.dev, "NCSI: LSC AEN - channel %u state %s\n",
- nc->id, data & 0x1 ? "up" : "down");
+ netdev_dbg(ndp->ndev.dev, "NCSI: LSC AEN - channel %u state %s\n",
+ nc->id, data & 0x1 ? "up" : "down");
chained = !list_empty(&nc->link);
state = nc->state;
diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
index 5561e221b71f..616441c2b54f 100644
--- a/net/ncsi/ncsi-manage.c
+++ b/net/ncsi/ncsi-manage.c
@@ -816,9 +816,9 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
} else {
hot_nc = NULL;
nc->state = NCSI_CHANNEL_INACTIVE;
- netdev_warn(ndp->ndev.dev,
- "NCSI: channel %u link down after config\n",
- nc->id);
+ netdev_dbg(ndp->ndev.dev,
+ "NCSI: channel %u link down after config\n",
+ nc->id);
}
spin_unlock_irqrestore(&nc->lock, flags);
@@ -1199,14 +1199,14 @@ int ncsi_process_next_channel(struct ncsi_dev_priv *ndp)
switch (old_state) {
case NCSI_CHANNEL_INACTIVE:
ndp->ndev.state = ncsi_dev_state_config;
- netdev_info(ndp->ndev.dev, "NCSI: configuring channel %u\n",
- nc->id);
+ netdev_dbg(ndp->ndev.dev, "NCSI: configuring channel %u\n",
+ nc->id);
ncsi_configure_channel(ndp);
break;
case NCSI_CHANNEL_ACTIVE:
ndp->ndev.state = ncsi_dev_state_suspend;
- netdev_info(ndp->ndev.dev, "NCSI: suspending channel %u\n",
- nc->id);
+ netdev_dbg(ndp->ndev.dev, "NCSI: suspending channel %u\n",
+ nc->id);
ncsi_suspend_channel(ndp);
break;
default:
--
2.17.1
^ permalink raw reply related
* [PATCH 2/4] net/ncsi: Drop no more channels message
From: Joel Stanley @ 2018-06-18 7:19 UTC (permalink / raw)
To: Samuel Mendoza-Jonas, David S . Miller; +Cc: netdev
In-Reply-To: <20180618071916.6765-1-joel@jms.id.au>
This does not provide useful information. As the ncsi maintainer said:
> either we get a channel or broadcom has gone out to lunch
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
net/ncsi/ncsi-manage.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
index 616441c2b54f..716493a61ba6 100644
--- a/net/ncsi/ncsi-manage.c
+++ b/net/ncsi/ncsi-manage.c
@@ -1226,8 +1226,6 @@ int ncsi_process_next_channel(struct ncsi_dev_priv *ndp)
return ncsi_choose_active_channel(ndp);
}
- netdev_printk(KERN_DEBUG, ndp->ndev.dev,
- "NCSI: No more channels to process\n");
ncsi_report_link(ndp, false);
return -ENODEV;
}
--
2.17.1
^ permalink raw reply related
* [PATCH 3/4] net/ncsi: Use netdev_dbg for debug messages
From: Joel Stanley @ 2018-06-18 7:19 UTC (permalink / raw)
To: Samuel Mendoza-Jonas, David S . Miller; +Cc: netdev
In-Reply-To: <20180618071916.6765-1-joel@jms.id.au>
This moves all of the netdev_printk(KERN_DEBUG, ...) messages over to
netdev_dbg. There is no change in behaviour.
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
net/ncsi/ncsi-aen.c | 6 +++---
net/ncsi/ncsi-manage.c | 33 +++++++++++++++------------------
2 files changed, 18 insertions(+), 21 deletions(-)
diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c
index f899ed61bb57..25e483e8278b 100644
--- a/net/ncsi/ncsi-aen.c
+++ b/net/ncsi/ncsi-aen.c
@@ -148,9 +148,9 @@ static int ncsi_aen_handler_hncdsc(struct ncsi_dev_priv *ndp,
hncdsc = (struct ncsi_aen_hncdsc_pkt *)h;
ncm->data[3] = ntohl(hncdsc->status);
spin_unlock_irqrestore(&nc->lock, flags);
- netdev_printk(KERN_DEBUG, ndp->ndev.dev,
- "NCSI: host driver %srunning on channel %u\n",
- ncm->data[3] & 0x1 ? "" : "not ", nc->id);
+ netdev_dbg(ndp->ndev.dev,
+ "NCSI: host driver %srunning on channel %u\n",
+ ncm->data[3] & 0x1 ? "" : "not ", nc->id);
return 0;
}
diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
index 716493a61ba6..091284760d21 100644
--- a/net/ncsi/ncsi-manage.c
+++ b/net/ncsi/ncsi-manage.c
@@ -788,8 +788,8 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
}
break;
case ncsi_dev_state_config_done:
- netdev_printk(KERN_DEBUG, ndp->ndev.dev,
- "NCSI: channel %u config done\n", nc->id);
+ netdev_dbg(ndp->ndev.dev, "NCSI: channel %u config done\n",
+ nc->id);
spin_lock_irqsave(&nc->lock, flags);
if (nc->reconfigure_needed) {
/* This channel's configuration has been updated
@@ -804,8 +804,7 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
list_add_tail_rcu(&nc->link, &ndp->channel_queue);
spin_unlock_irqrestore(&ndp->lock, flags);
- netdev_printk(KERN_DEBUG, dev,
- "Dirty NCSI channel state reset\n");
+ netdev_dbg(dev, "Dirty NCSI channel state reset\n");
ncsi_process_next_channel(ndp);
break;
}
@@ -908,9 +907,9 @@ static int ncsi_choose_active_channel(struct ncsi_dev_priv *ndp)
}
ncm = &found->modes[NCSI_MODE_LINK];
- netdev_printk(KERN_DEBUG, ndp->ndev.dev,
- "NCSI: Channel %u added to queue (link %s)\n",
- found->id, ncm->data[2] & 0x1 ? "up" : "down");
+ netdev_dbg(ndp->ndev.dev,
+ "NCSI: Channel %u added to queue (link %s)\n",
+ found->id, ncm->data[2] & 0x1 ? "up" : "down");
out:
spin_lock_irqsave(&ndp->lock, flags);
@@ -1316,9 +1315,9 @@ static int ncsi_kick_channels(struct ncsi_dev_priv *ndp)
if ((ndp->ndev.state & 0xff00) ==
ncsi_dev_state_config ||
!list_empty(&nc->link)) {
- netdev_printk(KERN_DEBUG, nd->dev,
- "NCSI: channel %p marked dirty\n",
- nc);
+ netdev_dbg(nd->dev,
+ "NCSI: channel %p marked dirty\n",
+ nc);
nc->reconfigure_needed = true;
}
spin_unlock_irqrestore(&nc->lock, flags);
@@ -1336,8 +1335,7 @@ static int ncsi_kick_channels(struct ncsi_dev_priv *ndp)
list_add_tail_rcu(&nc->link, &ndp->channel_queue);
spin_unlock_irqrestore(&ndp->lock, flags);
- netdev_printk(KERN_DEBUG, nd->dev,
- "NCSI: kicked channel %p\n", nc);
+ netdev_dbg(nd->dev, "NCSI: kicked channel %p\n", nc);
n++;
}
}
@@ -1368,8 +1366,8 @@ int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) {
n_vids++;
if (vlan->vid == vid) {
- netdev_printk(KERN_DEBUG, dev,
- "NCSI: vid %u already registered\n", vid);
+ netdev_dbg(dev, "NCSI: vid %u already registered\n",
+ vid);
return 0;
}
}
@@ -1388,7 +1386,7 @@ int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
vlan->vid = vid;
list_add_rcu(&vlan->list, &ndp->vlan_vids);
- netdev_printk(KERN_DEBUG, dev, "NCSI: Added new vid %u\n", vid);
+ netdev_dbg(dev, "NCSI: Added new vid %u\n", vid);
found = ncsi_kick_channels(ndp) != 0;
@@ -1417,8 +1415,7 @@ int ncsi_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
/* Remove the VLAN id from our internal list */
list_for_each_entry_safe(vlan, tmp, &ndp->vlan_vids, list)
if (vlan->vid == vid) {
- netdev_printk(KERN_DEBUG, dev,
- "NCSI: vid %u found, removing\n", vid);
+ netdev_dbg(dev, "NCSI: vid %u found, removing\n", vid);
list_del_rcu(&vlan->list);
found = true;
kfree(vlan);
@@ -1545,7 +1542,7 @@ void ncsi_stop_dev(struct ncsi_dev *nd)
}
}
- netdev_printk(KERN_DEBUG, ndp->ndev.dev, "NCSI: Stopping device\n");
+ netdev_dbg(ndp->ndev.dev, "NCSI: Stopping device\n");
ncsi_report_link(ndp, true);
}
EXPORT_SYMBOL_GPL(ncsi_stop_dev);
--
2.17.1
^ permalink raw reply related
* [PATCH 4/4] MAINTAINERS: Add Sam as the maintainer for NCSI
From: Joel Stanley @ 2018-06-18 7:19 UTC (permalink / raw)
To: Samuel Mendoza-Jonas, David S . Miller; +Cc: netdev
In-Reply-To: <20180618071916.6765-1-joel@jms.id.au>
Sam has been handing the maintenance of NCSI for a number release cycles
now.
Signed-off-by: Joel Stanley <joel@jms.id.au>
---
MAINTAINERS | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 9d5eeff51b5f..44851f7c46fc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9756,6 +9756,11 @@ L: linux-scsi@vger.kernel.org
S: Maintained
F: drivers/scsi/NCR_D700.*
+NCSI LIBRARY:
+M: Samuel Mendoza-Jonas <sam@mendozajonas.com>
+S: Maintained
+F: net/ncsi/
+
NCT6775 HARDWARE MONITOR DRIVER
M: Guenter Roeck <linux@roeck-us.net>
L: linux-hwmon@vger.kernel.org
--
2.17.1
^ permalink raw reply related
* Re: WARNING in xfrm_state_fini (2)
From: Dmitry Vyukov @ 2018-06-18 7:25 UTC (permalink / raw)
To: Jason Litzinger, David Miller, Herbert Xu, LKML, netdev,
Steffen Klassert
Cc: syzkaller-bugs
In-Reply-To: <cf1a05d1-0cb2-4fac-84b0-0efd3e0b12ca@googlegroups.com>
On Mon, Jun 18, 2018 at 6:14 AM, Jason Litzinger
<jlitzingerdev@gmail.com> wrote:
> I've simplified the reproducer provided by syzbot to the included
> version. The warning is reproduced 100% using the qemu image in the
> syzkaller docs running the latest upstream and net.
>
> As noted on the dashboard, this is similar to [1], in that an entry
> remains in the xfrm_state_walk list, but different because the
> protocol is not 0, it is 43, IPPROTO_ROUTING (and is valid by the fix
> for [1], see 6a53b7593233).
>
> Unfortunately, when a namespace exits, xfrm_state_fini only flushes
> IPSEC protocols. I don't have enough experience with the xfrm
> subsystem to know whether this is correct, however, dc00a525603650a14
> explicitly allows non ipsec protocols, as well as 0 for "all".
>
> Would it be more appropriate for flush to also flush the non ipsec
> protocols allowed in xfrm_user.c:validate_tmpl (explicitly or with 0)?
>
> If someone with more experience with the subsystem believes that to be
> the case I'm happy to send a patch (against net or ipsec?), otherwise
> I'm going to keep digging to see if a better option presents itself.
>
> Regardless I hope the simplified reproducer might be useful.
>
> -Jason
>
> [1]
> https://syzkaller.appspot.com/bug?id=c922592229951800c197ce48a5eaab8877c33723
>
> * I wasn't subscribed to the list for the original message, so I'm
> using the GUI to reply...apologies if anything is mangled.
+kernel developers back to CC
Jason did some debugging of this bug and have some questions as to
what's the best way to proceed. Please read the above.
^ permalink raw reply
* Re: [PATCH 1/2] eth phy: add mdio bus char device interface
From: Andrew Lunn @ 2018-06-18 7:25 UTC (permalink / raw)
To: Wei Li; +Cc: f.fainelli, netdev
In-Reply-To: <1529292733-13243-1-git-send-email-liwei1412@163.com>
1;5202;0cOn Mon, Jun 18, 2018 at 11:32:12AM +0800, Wei Li wrote:
> Add the char device interface of mdio bus, like what i2c-dev or spidev do.
> They make it possible for user-space programs to access the bus directly.
>
Hi Wei
What is your real use case here?
What we don't want to do is add an easy to use API to allow vendors to
write user space binary blob propriatary Ethernet switch or PHY
drivers.
Also, it has been agreed that all new API's to the network stack need
to use netlink sockets, not IOCTLs.
The IOCTL interface you provide is very similar to what the stack
already has. Why cannot use you use that?
Andrew
^ permalink raw reply
* Re: [PATCH] net: fix e100.rst Documentation build errors
From: Jani Nikula @ 2018-06-18 8:04 UTC (permalink / raw)
To: Randy Dunlap, linux-doc@vger.kernel.org, netdev@vger.kernel.org,
Jeff Kirsher, David Miller
Cc: LKML, Aaron Brown
In-Reply-To: <72f13386-c484-3eed-c363-a5b667aea2e6@infradead.org>
On Sat, 16 Jun 2018, Randy Dunlap <rdunlap@infradead.org> wrote:
> From: Randy Dunlap <rdunlap@infradead.org>
>
> Fix Documentation build errors in e100.rst. Several section titles
> and the corresponding underlines should not be indented.
Really the content blocks below the titles should not be indented
either. It's not an error, but the end result is probably not what you
want.
BR,
Jani.
>
> Documentation/networking/e100.rst:90: (SEVERE/4) Unexpected section title.
> Documentation/networking/e100.rst:109: (SEVERE/4) Unexpected section title.
>
> Fixes: 85d63445f411 ("Documentation: e100: Update the Intel 10/100 driver doc")
>
> Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
> Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Cc: Aaron Brown <aaron.f.brown@intel.com>
> ---
> Is there a Sphinx version problem here? Tested-by: should indicate
> that there was no error like I am seeing.
>
> Documentation/networking/e100.rst | 24 ++++++++++++------------
> 1 file changed, 12 insertions(+), 12 deletions(-)
>
> --- lnx-418-rc1.orig/Documentation/networking/e100.rst
> +++ lnx-418-rc1/Documentation/networking/e100.rst
> @@ -86,8 +86,8 @@ Event Log Message Level: The driver use
> Additional Configurations
> =========================
>
> - Configuring the Driver on Different Distributions
> - -------------------------------------------------
> +Configuring the Driver on Different Distributions
> +-------------------------------------------------
>
> Configuring a network driver to load properly when the system is started is
> distribution dependent. Typically, the configuration process involves adding
> @@ -105,8 +105,8 @@ Additional Configurations
> alias eth0 e100
> alias eth1 e100
>
> - Viewing Link Messages
> - ---------------------
> +Viewing Link Messages
> +---------------------
> In order to see link messages and other Intel driver information on your
> console, you must set the dmesg level up to six. This can be done by
> entering the following on the command line before loading the e100 driver::
> @@ -119,8 +119,8 @@ Additional Configurations
> NOTE: This setting is not saved across reboots.
>
>
> - ethtool
> - -------
> +ethtool
> +-------
>
> The driver utilizes the ethtool interface for driver configuration and
> diagnostics, as well as displaying statistical information. The ethtool
> @@ -129,8 +129,8 @@ Additional Configurations
> The latest release of ethtool can be found from
> https://www.kernel.org/pub/software/network/ethtool/
>
> - Enabling Wake on LAN* (WoL)
> - ---------------------------
> +Enabling Wake on LAN* (WoL)
> +---------------------------
> WoL is provided through the ethtool* utility. For instructions on enabling
> WoL with ethtool, refer to the ethtool man page.
>
> @@ -138,16 +138,16 @@ Additional Configurations
> this driver version, in order to enable WoL, the e100 driver must be
> loaded when shutting down or rebooting the system.
>
> - NAPI
> - ----
> +NAPI
> +----
>
> NAPI (Rx polling mode) is supported in the e100 driver.
>
> See https://wiki.linuxfoundation.org/networking/napi for more information
> on NAPI.
>
> - Multiple Interfaces on Same Ethernet Broadcast Network
> - ------------------------------------------------------
> +Multiple Interfaces on Same Ethernet Broadcast Network
> +------------------------------------------------------
>
> Due to the default ARP behavior on Linux, it is not possible to have
> one system on two IP networks in the same Ethernet broadcast domain
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-doc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Jani Nikula, Intel Open Source Graphics Center
^ permalink raw reply
* [PATCH 4.16 179/279] bpf: fix possible spectre-v1 in find_and_alloc_map()
From: Greg Kroah-Hartman @ 2018-06-18 8:12 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, stable, Mark Rutland, Alexei Starovoitov,
Dan Carpenter, Daniel Borkmann, Peter Zijlstra, netdev,
David S. Miller, Sasha Levin
In-Reply-To: <20180618080608.851973560@linuxfoundation.org>
4.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <mark.rutland@arm.com>
[ Upstream commit 9ef09e35e521bf0df5325cc9cffa726a8f5f3c1b ]
It's possible for userspace to control attr->map_type. Sanitize it when
using it as an array index to prevent an out-of-bounds value being used
under speculation.
Found by smatch.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: netdev@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/bpf/syscall.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -26,6 +26,7 @@
#include <linux/cred.h>
#include <linux/timekeeping.h>
#include <linux/ctype.h>
+#include <linux/nospec.h>
#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \
(map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
@@ -102,12 +103,14 @@ const struct bpf_map_ops bpf_map_offload
static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
{
const struct bpf_map_ops *ops;
+ u32 type = attr->map_type;
struct bpf_map *map;
int err;
- if (attr->map_type >= ARRAY_SIZE(bpf_map_types))
+ if (type >= ARRAY_SIZE(bpf_map_types))
return ERR_PTR(-EINVAL);
- ops = bpf_map_types[attr->map_type];
+ type = array_index_nospec(type, ARRAY_SIZE(bpf_map_types));
+ ops = bpf_map_types[type];
if (!ops)
return ERR_PTR(-EINVAL);
@@ -122,7 +125,7 @@ static struct bpf_map *find_and_alloc_ma
if (IS_ERR(map))
return map;
map->ops = ops;
- map->map_type = attr->map_type;
+ map->map_type = type;
return map;
}
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox