aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 17:27:06 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 17:27:06 -0500
commit70e71ca0af244f48a5dcf56dc435243792e3a495 (patch)
treef7d9c4c4d9a857a00043e9bf6aa2d6f533a34778 /lib
parentbae41e45b7400496b9bf0c70c6004419d9987819 (diff)
parent00c83b01d58068dfeb2e1351cca6fccf2a83fa8f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) New offloading infrastructure and example 'rocker' driver for offloading of switching and routing to hardware. This work was done by a large group of dedicated individuals, not limited to: Scott Feldman, Jiri Pirko, Thomas Graf, John Fastabend, Jamal Hadi Salim, Andy Gospodarek, Florian Fainelli, Roopa Prabhu 2) Start making the networking operate on IOV iterators instead of modifying iov objects in-situ during transfers. Thanks to Al Viro and Herbert Xu. 3) A set of new netlink interfaces for the TIPC stack, from Richard Alpe. 4) Remove unnecessary looping during ipv6 routing lookups, from Martin KaFai Lau. 5) Add PAUSE frame generation support to gianfar driver, from Matei Pavaluca. 6) Allow for larger reordering levels in TCP, which are easily achievable in the real world right now, from Eric Dumazet. 7) Add a variable of napi_schedule that doesn't need to disable cpu interrupts, from Eric Dumazet. 8) Use a doubly linked list to optimize neigh_parms_release(), from Nicolas Dichtel. 9) Various enhancements to the kernel BPF verifier, and allow eBPF programs to actually be attached to sockets. From Alexei Starovoitov. 10) Support TSO/LSO in sunvnet driver, from David L Stevens. 11) Allow controlling ECN usage via routing metrics, from Florian Westphal. 12) Remote checksum offload, from Tom Herbert. 13) Add split-header receive, BQL, and xmit_more support to amd-xgbe driver, from Thomas Lendacky. 14) Add MPLS support to openvswitch, from Simon Horman. 15) Support wildcard tunnel endpoints in ipv6 tunnels, from Steffen Klassert. 16) Do gro flushes on a per-device basis using a timer, from Eric Dumazet. This tries to resolve the conflicting goals between the desired handling of bulk vs. RPC-like traffic. 17) Allow userspace to ask for the CPU upon what a packet was received/steered, via SO_INCOMING_CPU. From Eric Dumazet. 18) Limit GSO packets to half the current congestion window, from Eric Dumazet. 19) Add a generic helper so that all drivers set their RSS keys in a consistent way, from Eric Dumazet. 20) Add xmit_more support to enic driver, from Govindarajulu Varadarajan. 21) Add VLAN packet scheduler action, from Jiri Pirko. 22) Support configurable RSS hash functions via ethtool, from Eyal Perry. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1820 commits) Fix race condition between vxlan_sock_add and vxlan_sock_release net/macb: fix compilation warning for print_hex_dump() called with skb->mac_header net/mlx4: Add support for A0 steering net/mlx4: Refactor QUERY_PORT net/mlx4_core: Add explicit error message when rule doesn't meet configuration net/mlx4: Add A0 hybrid steering net/mlx4: Add mlx4_bitmap zone allocator net/mlx4: Add a check if there are too many reserved QPs net/mlx4: Change QP allocation scheme net/mlx4_core: Use tasklet for user-space CQ completion events net/mlx4_core: Mask out host side virtualization features for guests net/mlx4_en: Set csum level for encapsulated packets be2net: Export tunnel offloads only when a VxLAN tunnel is created gianfar: Fix dma check map error when DMA_API_DEBUG is enabled cxgb4/csiostor: Don't use MASTER_MUST for fw_hello call net: fec: only enable mdio interrupt before phy device link up net: fec: clear all interrupt events to support i.MX6SX net: fec: reset fep link status in suspend function net: sock: fix access via invalid file descriptor net: introduce helper macro for_each_cmsghdr ...
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile2
-rw-r--r--lib/hash.c39
-rw-r--r--lib/iovec.c25
-rw-r--r--lib/rhashtable.c88
-rw-r--r--lib/test_bpf.c53
5 files changed, 103 insertions, 104 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 923a191eaf71..3c3b30b9e020 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -26,7 +26,7 @@ obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
26 bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ 26 bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
27 gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \ 27 gcd.o lcm.o list_sort.o uuid.o flex_array.o iovec.o clz_ctz.o \
28 bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \ 28 bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \
29 percpu-refcount.o percpu_ida.o hash.o rhashtable.o reciprocal_div.o 29 percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o
30obj-y += string_helpers.o 30obj-y += string_helpers.o
31obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o 31obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
32obj-y += kstrtox.o 32obj-y += kstrtox.o
diff --git a/lib/hash.c b/lib/hash.c
deleted file mode 100644
index fea973f4bd57..000000000000
--- a/lib/hash.c
+++ /dev/null
@@ -1,39 +0,0 @@
1/* General purpose hashing library
2 *
3 * That's a start of a kernel hashing library, which can be extended
4 * with further algorithms in future. arch_fast_hash{2,}() will
5 * eventually resolve to an architecture optimized implementation.
6 *
7 * Copyright 2013 Francesco Fusco <ffusco@redhat.com>
8 * Copyright 2013 Daniel Borkmann <dborkman@redhat.com>
9 * Copyright 2013 Thomas Graf <tgraf@redhat.com>
10 * Licensed under the GNU General Public License, version 2.0 (GPLv2)
11 */
12
13#include <linux/jhash.h>
14#include <linux/hash.h>
15#include <linux/cache.h>
16
17static struct fast_hash_ops arch_hash_ops __read_mostly = {
18 .hash = jhash,
19 .hash2 = jhash2,
20};
21
22u32 arch_fast_hash(const void *data, u32 len, u32 seed)
23{
24 return arch_hash_ops.hash(data, len, seed);
25}
26EXPORT_SYMBOL_GPL(arch_fast_hash);
27
28u32 arch_fast_hash2(const u32 *data, u32 len, u32 seed)
29{
30 return arch_hash_ops.hash2(data, len, seed);
31}
32EXPORT_SYMBOL_GPL(arch_fast_hash2);
33
34static int __init hashlib_init(void)
35{
36 setup_arch_fast_hash(&arch_hash_ops);
37 return 0;
38}
39early_initcall(hashlib_init);
diff --git a/lib/iovec.c b/lib/iovec.c
index df3abd1eaa4a..2d99cb4a5006 100644
--- a/lib/iovec.c
+++ b/lib/iovec.c
@@ -29,31 +29,6 @@ EXPORT_SYMBOL(memcpy_fromiovec);
29 29
30/* 30/*
31 * Copy kernel to iovec. Returns -EFAULT on error. 31 * Copy kernel to iovec. Returns -EFAULT on error.
32 *
33 * Note: this modifies the original iovec.
34 */
35
36int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
37{
38 while (len > 0) {
39 if (iov->iov_len) {
40 int copy = min_t(unsigned int, iov->iov_len, len);
41 if (copy_to_user(iov->iov_base, kdata, copy))
42 return -EFAULT;
43 kdata += copy;
44 len -= copy;
45 iov->iov_len -= copy;
46 iov->iov_base += copy;
47 }
48 iov++;
49 }
50
51 return 0;
52}
53EXPORT_SYMBOL(memcpy_toiovec);
54
55/*
56 * Copy kernel to iovec. Returns -EFAULT on error.
57 */ 32 */
58 33
59int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata, 34int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata,
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 624a0b7c05ef..6c3c723e902b 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -20,7 +20,7 @@
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
22#include <linux/mm.h> 22#include <linux/mm.h>
23#include <linux/hash.h> 23#include <linux/jhash.h>
24#include <linux/random.h> 24#include <linux/random.h>
25#include <linux/rhashtable.h> 25#include <linux/rhashtable.h>
26 26
@@ -32,7 +32,7 @@
32#ifdef CONFIG_PROVE_LOCKING 32#ifdef CONFIG_PROVE_LOCKING
33int lockdep_rht_mutex_is_held(const struct rhashtable *ht) 33int lockdep_rht_mutex_is_held(const struct rhashtable *ht)
34{ 34{
35 return ht->p.mutex_is_held(); 35 return ht->p.mutex_is_held(ht->p.parent);
36} 36}
37EXPORT_SYMBOL_GPL(lockdep_rht_mutex_is_held); 37EXPORT_SYMBOL_GPL(lockdep_rht_mutex_is_held);
38#endif 38#endif
@@ -107,13 +107,13 @@ static u32 head_hashfn(const struct rhashtable *ht,
107 return obj_hashfn(ht, rht_obj(ht, he), hsize); 107 return obj_hashfn(ht, rht_obj(ht, he), hsize);
108} 108}
109 109
110static struct bucket_table *bucket_table_alloc(size_t nbuckets, gfp_t flags) 110static struct bucket_table *bucket_table_alloc(size_t nbuckets)
111{ 111{
112 struct bucket_table *tbl; 112 struct bucket_table *tbl;
113 size_t size; 113 size_t size;
114 114
115 size = sizeof(*tbl) + nbuckets * sizeof(tbl->buckets[0]); 115 size = sizeof(*tbl) + nbuckets * sizeof(tbl->buckets[0]);
116 tbl = kzalloc(size, flags); 116 tbl = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
117 if (tbl == NULL) 117 if (tbl == NULL)
118 tbl = vzalloc(size); 118 tbl = vzalloc(size);
119 119
@@ -200,7 +200,6 @@ static void hashtable_chain_unzip(const struct rhashtable *ht,
200/** 200/**
201 * rhashtable_expand - Expand hash table while allowing concurrent lookups 201 * rhashtable_expand - Expand hash table while allowing concurrent lookups
202 * @ht: the hash table to expand 202 * @ht: the hash table to expand
203 * @flags: allocation flags
204 * 203 *
205 * A secondary bucket array is allocated and the hash entries are migrated 204 * A secondary bucket array is allocated and the hash entries are migrated
206 * while keeping them on both lists until the end of the RCU grace period. 205 * while keeping them on both lists until the end of the RCU grace period.
@@ -211,7 +210,7 @@ static void hashtable_chain_unzip(const struct rhashtable *ht,
211 * The caller must ensure that no concurrent table mutations take place. 210 * The caller must ensure that no concurrent table mutations take place.
212 * It is however valid to have concurrent lookups if they are RCU protected. 211 * It is however valid to have concurrent lookups if they are RCU protected.
213 */ 212 */
214int rhashtable_expand(struct rhashtable *ht, gfp_t flags) 213int rhashtable_expand(struct rhashtable *ht)
215{ 214{
216 struct bucket_table *new_tbl, *old_tbl = rht_dereference(ht->tbl, ht); 215 struct bucket_table *new_tbl, *old_tbl = rht_dereference(ht->tbl, ht);
217 struct rhash_head *he; 216 struct rhash_head *he;
@@ -223,7 +222,7 @@ int rhashtable_expand(struct rhashtable *ht, gfp_t flags)
223 if (ht->p.max_shift && ht->shift >= ht->p.max_shift) 222 if (ht->p.max_shift && ht->shift >= ht->p.max_shift)
224 return 0; 223 return 0;
225 224
226 new_tbl = bucket_table_alloc(old_tbl->size * 2, flags); 225 new_tbl = bucket_table_alloc(old_tbl->size * 2);
227 if (new_tbl == NULL) 226 if (new_tbl == NULL)
228 return -ENOMEM; 227 return -ENOMEM;
229 228
@@ -281,7 +280,6 @@ EXPORT_SYMBOL_GPL(rhashtable_expand);
281/** 280/**
282 * rhashtable_shrink - Shrink hash table while allowing concurrent lookups 281 * rhashtable_shrink - Shrink hash table while allowing concurrent lookups
283 * @ht: the hash table to shrink 282 * @ht: the hash table to shrink
284 * @flags: allocation flags
285 * 283 *
286 * This function may only be called in a context where it is safe to call 284 * This function may only be called in a context where it is safe to call
287 * synchronize_rcu(), e.g. not within a rcu_read_lock() section. 285 * synchronize_rcu(), e.g. not within a rcu_read_lock() section.
@@ -289,7 +287,7 @@ EXPORT_SYMBOL_GPL(rhashtable_expand);
289 * The caller must ensure that no concurrent table mutations take place. 287 * The caller must ensure that no concurrent table mutations take place.
290 * It is however valid to have concurrent lookups if they are RCU protected. 288 * It is however valid to have concurrent lookups if they are RCU protected.
291 */ 289 */
292int rhashtable_shrink(struct rhashtable *ht, gfp_t flags) 290int rhashtable_shrink(struct rhashtable *ht)
293{ 291{
294 struct bucket_table *ntbl, *tbl = rht_dereference(ht->tbl, ht); 292 struct bucket_table *ntbl, *tbl = rht_dereference(ht->tbl, ht);
295 struct rhash_head __rcu **pprev; 293 struct rhash_head __rcu **pprev;
@@ -300,7 +298,7 @@ int rhashtable_shrink(struct rhashtable *ht, gfp_t flags)
300 if (ht->shift <= ht->p.min_shift) 298 if (ht->shift <= ht->p.min_shift)
301 return 0; 299 return 0;
302 300
303 ntbl = bucket_table_alloc(tbl->size / 2, flags); 301 ntbl = bucket_table_alloc(tbl->size / 2);
304 if (ntbl == NULL) 302 if (ntbl == NULL)
305 return -ENOMEM; 303 return -ENOMEM;
306 304
@@ -341,7 +339,6 @@ EXPORT_SYMBOL_GPL(rhashtable_shrink);
341 * rhashtable_insert - insert object into hash hash table 339 * rhashtable_insert - insert object into hash hash table
342 * @ht: hash table 340 * @ht: hash table
343 * @obj: pointer to hash head inside object 341 * @obj: pointer to hash head inside object
344 * @flags: allocation flags (table expansion)
345 * 342 *
346 * Will automatically grow the table via rhashtable_expand() if the the 343 * Will automatically grow the table via rhashtable_expand() if the the
347 * grow_decision function specified at rhashtable_init() returns true. 344 * grow_decision function specified at rhashtable_init() returns true.
@@ -349,8 +346,7 @@ EXPORT_SYMBOL_GPL(rhashtable_shrink);
349 * The caller must ensure that no concurrent table mutations occur. It is 346 * The caller must ensure that no concurrent table mutations occur. It is
350 * however valid to have concurrent lookups if they are RCU protected. 347 * however valid to have concurrent lookups if they are RCU protected.
351 */ 348 */
352void rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj, 349void rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj)
353 gfp_t flags)
354{ 350{
355 struct bucket_table *tbl = rht_dereference(ht->tbl, ht); 351 struct bucket_table *tbl = rht_dereference(ht->tbl, ht);
356 u32 hash; 352 u32 hash;
@@ -363,7 +359,7 @@ void rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj,
363 ht->nelems++; 359 ht->nelems++;
364 360
365 if (ht->p.grow_decision && ht->p.grow_decision(ht, tbl->size)) 361 if (ht->p.grow_decision && ht->p.grow_decision(ht, tbl->size))
366 rhashtable_expand(ht, flags); 362 rhashtable_expand(ht);
367} 363}
368EXPORT_SYMBOL_GPL(rhashtable_insert); 364EXPORT_SYMBOL_GPL(rhashtable_insert);
369 365
@@ -372,14 +368,13 @@ EXPORT_SYMBOL_GPL(rhashtable_insert);
372 * @ht: hash table 368 * @ht: hash table
373 * @obj: pointer to hash head inside object 369 * @obj: pointer to hash head inside object
374 * @pprev: pointer to previous element 370 * @pprev: pointer to previous element
375 * @flags: allocation flags (table expansion)
376 * 371 *
377 * Identical to rhashtable_remove() but caller is alreayd aware of the element 372 * Identical to rhashtable_remove() but caller is alreayd aware of the element
378 * in front of the element to be deleted. This is in particular useful for 373 * in front of the element to be deleted. This is in particular useful for
379 * deletion when combined with walking or lookup. 374 * deletion when combined with walking or lookup.
380 */ 375 */
381void rhashtable_remove_pprev(struct rhashtable *ht, struct rhash_head *obj, 376void rhashtable_remove_pprev(struct rhashtable *ht, struct rhash_head *obj,
382 struct rhash_head __rcu **pprev, gfp_t flags) 377 struct rhash_head __rcu **pprev)
383{ 378{
384 struct bucket_table *tbl = rht_dereference(ht->tbl, ht); 379 struct bucket_table *tbl = rht_dereference(ht->tbl, ht);
385 380
@@ -390,7 +385,7 @@ void rhashtable_remove_pprev(struct rhashtable *ht, struct rhash_head *obj,
390 385
391 if (ht->p.shrink_decision && 386 if (ht->p.shrink_decision &&
392 ht->p.shrink_decision(ht, tbl->size)) 387 ht->p.shrink_decision(ht, tbl->size))
393 rhashtable_shrink(ht, flags); 388 rhashtable_shrink(ht);
394} 389}
395EXPORT_SYMBOL_GPL(rhashtable_remove_pprev); 390EXPORT_SYMBOL_GPL(rhashtable_remove_pprev);
396 391
@@ -398,7 +393,6 @@ EXPORT_SYMBOL_GPL(rhashtable_remove_pprev);
398 * rhashtable_remove - remove object from hash table 393 * rhashtable_remove - remove object from hash table
399 * @ht: hash table 394 * @ht: hash table
400 * @obj: pointer to hash head inside object 395 * @obj: pointer to hash head inside object
401 * @flags: allocation flags (table expansion)
402 * 396 *
403 * Since the hash chain is single linked, the removal operation needs to 397 * Since the hash chain is single linked, the removal operation needs to
404 * walk the bucket chain upon removal. The removal operation is thus 398 * walk the bucket chain upon removal. The removal operation is thus
@@ -410,8 +404,7 @@ EXPORT_SYMBOL_GPL(rhashtable_remove_pprev);
410 * The caller must ensure that no concurrent table mutations occur. It is 404 * The caller must ensure that no concurrent table mutations occur. It is
411 * however valid to have concurrent lookups if they are RCU protected. 405 * however valid to have concurrent lookups if they are RCU protected.
412 */ 406 */
413bool rhashtable_remove(struct rhashtable *ht, struct rhash_head *obj, 407bool rhashtable_remove(struct rhashtable *ht, struct rhash_head *obj)
414 gfp_t flags)
415{ 408{
416 struct bucket_table *tbl = rht_dereference(ht->tbl, ht); 409 struct bucket_table *tbl = rht_dereference(ht->tbl, ht);
417 struct rhash_head __rcu **pprev; 410 struct rhash_head __rcu **pprev;
@@ -429,7 +422,7 @@ bool rhashtable_remove(struct rhashtable *ht, struct rhash_head *obj,
429 continue; 422 continue;
430 } 423 }
431 424
432 rhashtable_remove_pprev(ht, he, pprev, flags); 425 rhashtable_remove_pprev(ht, he, pprev);
433 return true; 426 return true;
434 } 427 }
435 428
@@ -531,8 +524,10 @@ static size_t rounded_hashtable_size(struct rhashtable_params *params)
531 * .head_offset = offsetof(struct test_obj, node), 524 * .head_offset = offsetof(struct test_obj, node),
532 * .key_offset = offsetof(struct test_obj, key), 525 * .key_offset = offsetof(struct test_obj, key),
533 * .key_len = sizeof(int), 526 * .key_len = sizeof(int),
534 * .hashfn = arch_fast_hash, 527 * .hashfn = jhash,
528 * #ifdef CONFIG_PROVE_LOCKING
535 * .mutex_is_held = &my_mutex_is_held, 529 * .mutex_is_held = &my_mutex_is_held,
530 * #endif
536 * }; 531 * };
537 * 532 *
538 * Configuration Example 2: Variable length keys 533 * Configuration Example 2: Variable length keys
@@ -550,9 +545,11 @@ static size_t rounded_hashtable_size(struct rhashtable_params *params)
550 * 545 *
551 * struct rhashtable_params params = { 546 * struct rhashtable_params params = {
552 * .head_offset = offsetof(struct test_obj, node), 547 * .head_offset = offsetof(struct test_obj, node),
553 * .hashfn = arch_fast_hash, 548 * .hashfn = jhash,
554 * .obj_hashfn = my_hash_fn, 549 * .obj_hashfn = my_hash_fn,
550 * #ifdef CONFIG_PROVE_LOCKING
555 * .mutex_is_held = &my_mutex_is_held, 551 * .mutex_is_held = &my_mutex_is_held,
552 * #endif
556 * }; 553 * };
557 */ 554 */
558int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params) 555int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params)
@@ -572,7 +569,7 @@ int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params)
572 if (params->nelem_hint) 569 if (params->nelem_hint)
573 size = rounded_hashtable_size(params); 570 size = rounded_hashtable_size(params);
574 571
575 tbl = bucket_table_alloc(size, GFP_KERNEL); 572 tbl = bucket_table_alloc(size);
576 if (tbl == NULL) 573 if (tbl == NULL)
577 return -ENOMEM; 574 return -ENOMEM;
578 575
@@ -613,10 +610,12 @@ EXPORT_SYMBOL_GPL(rhashtable_destroy);
613#define TEST_PTR ((void *) 0xdeadbeef) 610#define TEST_PTR ((void *) 0xdeadbeef)
614#define TEST_NEXPANDS 4 611#define TEST_NEXPANDS 4
615 612
616static int test_mutex_is_held(void) 613#ifdef CONFIG_PROVE_LOCKING
614static int test_mutex_is_held(void *parent)
617{ 615{
618 return 1; 616 return 1;
619} 617}
618#endif
620 619
621struct test_obj { 620struct test_obj {
622 void *ptr; 621 void *ptr;
@@ -654,15 +653,15 @@ static int __init test_rht_lookup(struct rhashtable *ht)
654 return 0; 653 return 0;
655} 654}
656 655
657static void test_bucket_stats(struct rhashtable *ht, 656static void test_bucket_stats(struct rhashtable *ht, bool quiet)
658 struct bucket_table *tbl,
659 bool quiet)
660{ 657{
661 unsigned int cnt, i, total = 0; 658 unsigned int cnt, rcu_cnt, i, total = 0;
662 struct test_obj *obj; 659 struct test_obj *obj;
660 struct bucket_table *tbl;
663 661
662 tbl = rht_dereference_rcu(ht->tbl, ht);
664 for (i = 0; i < tbl->size; i++) { 663 for (i = 0; i < tbl->size; i++) {
665 cnt = 0; 664 rcu_cnt = cnt = 0;
666 665
667 if (!quiet) 666 if (!quiet)
668 pr_info(" [%#4x/%zu]", i, tbl->size); 667 pr_info(" [%#4x/%zu]", i, tbl->size);
@@ -674,6 +673,13 @@ static void test_bucket_stats(struct rhashtable *ht,
674 pr_cont(" [%p],", obj); 673 pr_cont(" [%p],", obj);
675 } 674 }
676 675
676 rht_for_each_entry_rcu(obj, tbl->buckets[i], node)
677 rcu_cnt++;
678
679 if (rcu_cnt != cnt)
680 pr_warn("Test failed: Chain count mismach %d != %d",
681 cnt, rcu_cnt);
682
677 if (!quiet) 683 if (!quiet)
678 pr_cont("\n [%#x] first element: %p, chain length: %u\n", 684 pr_cont("\n [%#x] first element: %p, chain length: %u\n",
679 i, tbl->buckets[i], cnt); 685 i, tbl->buckets[i], cnt);
@@ -681,6 +687,9 @@ static void test_bucket_stats(struct rhashtable *ht,
681 687
682 pr_info(" Traversal complete: counted=%u, nelems=%zu, entries=%d\n", 688 pr_info(" Traversal complete: counted=%u, nelems=%zu, entries=%d\n",
683 total, ht->nelems, TEST_ENTRIES); 689 total, ht->nelems, TEST_ENTRIES);
690
691 if (total != ht->nelems || total != TEST_ENTRIES)
692 pr_warn("Test failed: Total count mismatch ^^^");
684} 693}
685 694
686static int __init test_rhashtable(struct rhashtable *ht) 695static int __init test_rhashtable(struct rhashtable *ht)
@@ -707,18 +716,17 @@ static int __init test_rhashtable(struct rhashtable *ht)
707 obj->ptr = TEST_PTR; 716 obj->ptr = TEST_PTR;
708 obj->value = i * 2; 717 obj->value = i * 2;
709 718
710 rhashtable_insert(ht, &obj->node, GFP_KERNEL); 719 rhashtable_insert(ht, &obj->node);
711 } 720 }
712 721
713 rcu_read_lock(); 722 rcu_read_lock();
714 tbl = rht_dereference_rcu(ht->tbl, ht); 723 test_bucket_stats(ht, true);
715 test_bucket_stats(ht, tbl, true);
716 test_rht_lookup(ht); 724 test_rht_lookup(ht);
717 rcu_read_unlock(); 725 rcu_read_unlock();
718 726
719 for (i = 0; i < TEST_NEXPANDS; i++) { 727 for (i = 0; i < TEST_NEXPANDS; i++) {
720 pr_info(" Table expansion iteration %u...\n", i); 728 pr_info(" Table expansion iteration %u...\n", i);
721 rhashtable_expand(ht, GFP_KERNEL); 729 rhashtable_expand(ht);
722 730
723 rcu_read_lock(); 731 rcu_read_lock();
724 pr_info(" Verifying lookups...\n"); 732 pr_info(" Verifying lookups...\n");
@@ -728,7 +736,7 @@ static int __init test_rhashtable(struct rhashtable *ht)
728 736
729 for (i = 0; i < TEST_NEXPANDS; i++) { 737 for (i = 0; i < TEST_NEXPANDS; i++) {
730 pr_info(" Table shrinkage iteration %u...\n", i); 738 pr_info(" Table shrinkage iteration %u...\n", i);
731 rhashtable_shrink(ht, GFP_KERNEL); 739 rhashtable_shrink(ht);
732 740
733 rcu_read_lock(); 741 rcu_read_lock();
734 pr_info(" Verifying lookups...\n"); 742 pr_info(" Verifying lookups...\n");
@@ -736,6 +744,10 @@ static int __init test_rhashtable(struct rhashtable *ht)
736 rcu_read_unlock(); 744 rcu_read_unlock();
737 } 745 }
738 746
747 rcu_read_lock();
748 test_bucket_stats(ht, true);
749 rcu_read_unlock();
750
739 pr_info(" Deleting %d keys\n", TEST_ENTRIES); 751 pr_info(" Deleting %d keys\n", TEST_ENTRIES);
740 for (i = 0; i < TEST_ENTRIES; i++) { 752 for (i = 0; i < TEST_ENTRIES; i++) {
741 u32 key = i * 2; 753 u32 key = i * 2;
@@ -743,7 +755,7 @@ static int __init test_rhashtable(struct rhashtable *ht)
743 obj = rhashtable_lookup(ht, &key); 755 obj = rhashtable_lookup(ht, &key);
744 BUG_ON(!obj); 756 BUG_ON(!obj);
745 757
746 rhashtable_remove(ht, &obj->node, GFP_KERNEL); 758 rhashtable_remove(ht, &obj->node);
747 kfree(obj); 759 kfree(obj);
748 } 760 }
749 761
@@ -766,8 +778,10 @@ static int __init test_rht_init(void)
766 .head_offset = offsetof(struct test_obj, node), 778 .head_offset = offsetof(struct test_obj, node),
767 .key_offset = offsetof(struct test_obj, value), 779 .key_offset = offsetof(struct test_obj, value),
768 .key_len = sizeof(int), 780 .key_len = sizeof(int),
769 .hashfn = arch_fast_hash, 781 .hashfn = jhash,
782#ifdef CONFIG_PROVE_LOCKING
770 .mutex_is_held = &test_mutex_is_held, 783 .mutex_is_held = &test_mutex_is_held,
784#endif
771 .grow_decision = rht_grow_above_75, 785 .grow_decision = rht_grow_above_75,
772 .shrink_decision = rht_shrink_below_30, 786 .shrink_decision = rht_shrink_below_30,
773 }; 787 };
diff --git a/lib/test_bpf.c b/lib/test_bpf.c
index 23e070bcf72d..80d78c51f65f 100644
--- a/lib/test_bpf.c
+++ b/lib/test_bpf.c
@@ -124,7 +124,7 @@ static struct bpf_test tests[] = {
124 { { 0, 0xfffffffd } } 124 { { 0, 0xfffffffd } }
125 }, 125 },
126 { 126 {
127 "DIV_KX", 127 "DIV_MOD_KX",
128 .u.insns = { 128 .u.insns = {
129 BPF_STMT(BPF_LD | BPF_IMM, 8), 129 BPF_STMT(BPF_LD | BPF_IMM, 8),
130 BPF_STMT(BPF_ALU | BPF_DIV | BPF_K, 2), 130 BPF_STMT(BPF_ALU | BPF_DIV | BPF_K, 2),
@@ -134,12 +134,18 @@ static struct bpf_test tests[] = {
134 BPF_STMT(BPF_MISC | BPF_TAX, 0), 134 BPF_STMT(BPF_MISC | BPF_TAX, 0),
135 BPF_STMT(BPF_LD | BPF_IMM, 0xffffffff), 135 BPF_STMT(BPF_LD | BPF_IMM, 0xffffffff),
136 BPF_STMT(BPF_ALU | BPF_DIV | BPF_K, 0x70000000), 136 BPF_STMT(BPF_ALU | BPF_DIV | BPF_K, 0x70000000),
137 BPF_STMT(BPF_MISC | BPF_TAX, 0),
138 BPF_STMT(BPF_LD | BPF_IMM, 0xffffffff),
139 BPF_STMT(BPF_ALU | BPF_MOD | BPF_X, 0),
140 BPF_STMT(BPF_MISC | BPF_TAX, 0),
141 BPF_STMT(BPF_LD | BPF_IMM, 0xffffffff),
142 BPF_STMT(BPF_ALU | BPF_MOD | BPF_K, 0x70000000),
137 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0), 143 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
138 BPF_STMT(BPF_RET | BPF_A, 0) 144 BPF_STMT(BPF_RET | BPF_A, 0)
139 }, 145 },
140 CLASSIC | FLAG_NO_DATA, 146 CLASSIC | FLAG_NO_DATA,
141 { }, 147 { },
142 { { 0, 0x40000001 } } 148 { { 0, 0x20000000 } }
143 }, 149 },
144 { 150 {
145 "AND_OR_LSH_K", 151 "AND_OR_LSH_K",
@@ -1756,6 +1762,49 @@ static struct bpf_test tests[] = {
1756 { }, 1762 { },
1757 { { 0, 1 } } 1763 { { 0, 1 } }
1758 }, 1764 },
1765 {
1766 "nmap reduced",
1767 .u.insns_int = {
1768 BPF_MOV64_REG(R6, R1),
1769 BPF_LD_ABS(BPF_H, 12),
1770 BPF_JMP_IMM(BPF_JNE, R0, 0x806, 28),
1771 BPF_LD_ABS(BPF_H, 12),
1772 BPF_JMP_IMM(BPF_JNE, R0, 0x806, 26),
1773 BPF_MOV32_IMM(R0, 18),
1774 BPF_STX_MEM(BPF_W, R10, R0, -64),
1775 BPF_LDX_MEM(BPF_W, R7, R10, -64),
1776 BPF_LD_IND(BPF_W, R7, 14),
1777 BPF_STX_MEM(BPF_W, R10, R0, -60),
1778 BPF_MOV32_IMM(R0, 280971478),
1779 BPF_STX_MEM(BPF_W, R10, R0, -56),
1780 BPF_LDX_MEM(BPF_W, R7, R10, -56),
1781 BPF_LDX_MEM(BPF_W, R0, R10, -60),
1782 BPF_ALU32_REG(BPF_SUB, R0, R7),
1783 BPF_JMP_IMM(BPF_JNE, R0, 0, 15),
1784 BPF_LD_ABS(BPF_H, 12),
1785 BPF_JMP_IMM(BPF_JNE, R0, 0x806, 13),
1786 BPF_MOV32_IMM(R0, 22),
1787 BPF_STX_MEM(BPF_W, R10, R0, -56),
1788 BPF_LDX_MEM(BPF_W, R7, R10, -56),
1789 BPF_LD_IND(BPF_H, R7, 14),
1790 BPF_STX_MEM(BPF_W, R10, R0, -52),
1791 BPF_MOV32_IMM(R0, 17366),
1792 BPF_STX_MEM(BPF_W, R10, R0, -48),
1793 BPF_LDX_MEM(BPF_W, R7, R10, -48),
1794 BPF_LDX_MEM(BPF_W, R0, R10, -52),
1795 BPF_ALU32_REG(BPF_SUB, R0, R7),
1796 BPF_JMP_IMM(BPF_JNE, R0, 0, 2),
1797 BPF_MOV32_IMM(R0, 256),
1798 BPF_EXIT_INSN(),
1799 BPF_MOV32_IMM(R0, 0),
1800 BPF_EXIT_INSN(),
1801 },
1802 INTERNAL,
1803 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x08, 0x06, 0, 0,
1804 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1805 0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6},
1806 { { 38, 256 } }
1807 },
1759}; 1808};
1760 1809
1761static struct net_device dev; 1810static struct net_device dev;