diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/dma-direct.c | 3 | ||||
| -rw-r--r-- | lib/errseq.c | 23 | ||||
| -rw-r--r-- | lib/find_bit_benchmark.c | 7 | ||||
| -rw-r--r-- | lib/kobject.c | 11 | ||||
| -rw-r--r-- | lib/radix-tree.c | 6 | ||||
| -rw-r--r-- | lib/swiotlb.c | 4 | ||||
| -rw-r--r-- | lib/test_bitmap.c | 21 | ||||
| -rw-r--r-- | lib/textsearch.c | 40 | ||||
| -rw-r--r-- | lib/vsprintf.c | 26 | 
9 files changed, 79 insertions, 62 deletions
diff --git a/lib/dma-direct.c b/lib/dma-direct.c index c0bba30fef0a..bbfb229aa067 100644 --- a/lib/dma-direct.c +++ b/lib/dma-direct.c @@ -84,7 +84,8 @@ again:  		__free_pages(page, page_order);  		page = NULL; -		if (dev->coherent_dma_mask < DMA_BIT_MASK(32) && +		if (IS_ENABLED(CONFIG_ZONE_DMA) && +		    dev->coherent_dma_mask < DMA_BIT_MASK(32) &&  		    !(gfp & GFP_DMA)) {  			gfp = (gfp & ~GFP_DMA32) | GFP_DMA;  			goto again; diff --git a/lib/errseq.c b/lib/errseq.c index df782418b333..81f9e33aa7e7 100644 --- a/lib/errseq.c +++ b/lib/errseq.c @@ -111,27 +111,22 @@ EXPORT_SYMBOL(errseq_set);   * errseq_sample() - Grab current errseq_t value.   * @eseq: Pointer to errseq_t to be sampled.   * - * This function allows callers to sample an errseq_t value, marking it as - * "seen" if required. + * This function allows callers to initialise their errseq_t variable. + * If the error has been "seen", new callers will not see an old error. + * If there is an unseen error in @eseq, the caller of this function will + * see it the next time it checks for an error.   * + * Context: Any context.   * Return: The current errseq value.   */  errseq_t errseq_sample(errseq_t *eseq)  {  	errseq_t old = READ_ONCE(*eseq); -	errseq_t new = old; -	/* -	 * For the common case of no errors ever having been set, we can skip -	 * marking the SEEN bit. Once an error has been set, the value will -	 * never go back to zero. -	 */ -	if (old != 0) { -		new |= ERRSEQ_SEEN; -		if (old != new) -			cmpxchg(eseq, old, new); -	} -	return new; +	/* If nobody has seen this error yet, then we can be the first. */ +	if (!(old & ERRSEQ_SEEN)) +		old = 0; +	return old;  }  EXPORT_SYMBOL(errseq_sample); diff --git a/lib/find_bit_benchmark.c b/lib/find_bit_benchmark.c index 5985a25e6cbc..5367ffa5c18f 100644 --- a/lib/find_bit_benchmark.c +++ b/lib/find_bit_benchmark.c @@ -132,7 +132,12 @@ static int __init find_bit_test(void)  	test_find_next_bit(bitmap, BITMAP_LEN);  	test_find_next_zero_bit(bitmap, BITMAP_LEN);  	test_find_last_bit(bitmap, BITMAP_LEN); -	test_find_first_bit(bitmap, BITMAP_LEN); + +	/* +	 * test_find_first_bit() may take some time, so +	 * traverse only part of bitmap to avoid soft lockup. +	 */ +	test_find_first_bit(bitmap, BITMAP_LEN / 10);  	test_find_next_and_bit(bitmap, bitmap2, BITMAP_LEN);  	pr_err("\nStart testing find_bit() with sparse bitmap\n"); diff --git a/lib/kobject.c b/lib/kobject.c index e1d1f290bf35..18989b5b3b56 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -233,13 +233,12 @@ static int kobject_add_internal(struct kobject *kobj)  		/* be noisy on error issues */  		if (error == -EEXIST) -			WARN(1, -			     "%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n", -			     __func__, kobject_name(kobj)); +			pr_err("%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n", +			       __func__, kobject_name(kobj));  		else -			WARN(1, "%s failed for %s (error: %d parent: %s)\n", -			     __func__, kobject_name(kobj), error, -			     parent ? kobject_name(parent) : "'none'"); +			pr_err("%s failed for %s (error: %d parent: %s)\n", +			       __func__, kobject_name(kobj), error, +			       parent ? kobject_name(parent) : "'none'");  	} else  		kobj->state_in_sysfs = 1; diff --git a/lib/radix-tree.c b/lib/radix-tree.c index da9e10c827df..43e0cbedc3a0 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -1612,11 +1612,9 @@ static void set_iter_tags(struct radix_tree_iter *iter,  static void __rcu **skip_siblings(struct radix_tree_node **nodep,  			void __rcu **slot, struct radix_tree_iter *iter)  { -	void *sib = node_to_entry(slot - 1); -  	while (iter->index < iter->next_index) {  		*nodep = rcu_dereference_raw(*slot); -		if (*nodep && *nodep != sib) +		if (*nodep && !is_sibling_entry(iter->node, *nodep))  			return slot;  		slot++;  		iter->index = __radix_tree_iter_add(iter, 1); @@ -1631,7 +1629,7 @@ void __rcu **__radix_tree_next_slot(void __rcu **slot,  				struct radix_tree_iter *iter, unsigned flags)  {  	unsigned tag = flags & RADIX_TREE_ITER_TAG_MASK; -	struct radix_tree_node *node = rcu_dereference_raw(*slot); +	struct radix_tree_node *node;  	slot = skip_siblings(&node, slot, iter); diff --git a/lib/swiotlb.c b/lib/swiotlb.c index fece57566d45..cc640588f145 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -714,7 +714,7 @@ swiotlb_alloc_buffer(struct device *dev, size_t size, dma_addr_t *dma_handle,  	phys_addr = swiotlb_tbl_map_single(dev,  			__phys_to_dma(dev, io_tlb_start), -			0, size, DMA_FROM_DEVICE, 0); +			0, size, DMA_FROM_DEVICE, attrs);  	if (phys_addr == SWIOTLB_MAP_ERROR)  		goto out_warn; @@ -737,7 +737,7 @@ out_unmap:  	swiotlb_tbl_unmap_single(dev, phys_addr, size, DMA_TO_DEVICE,  			DMA_ATTR_SKIP_CPU_SYNC);  out_warn: -	if ((attrs & DMA_ATTR_NO_WARN) && printk_ratelimit()) { +	if (!(attrs & DMA_ATTR_NO_WARN) && printk_ratelimit()) {  		dev_warn(dev,  			"swiotlb: coherent allocation failed, size=%zu\n",  			size); diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c index de16f7869fb1..6cd7d0740005 100644 --- a/lib/test_bitmap.c +++ b/lib/test_bitmap.c @@ -331,23 +331,32 @@ static void noinline __init test_mem_optimisations(void)  	unsigned int start, nbits;  	for (start = 0; start < 1024; start += 8) { -		memset(bmap1, 0x5a, sizeof(bmap1)); -		memset(bmap2, 0x5a, sizeof(bmap2));  		for (nbits = 0; nbits < 1024 - start; nbits += 8) { +			memset(bmap1, 0x5a, sizeof(bmap1)); +			memset(bmap2, 0x5a, sizeof(bmap2)); +  			bitmap_set(bmap1, start, nbits);  			__bitmap_set(bmap2, start, nbits); -			if (!bitmap_equal(bmap1, bmap2, 1024)) +			if (!bitmap_equal(bmap1, bmap2, 1024)) {  				printk("set not equal %d %d\n", start, nbits); -			if (!__bitmap_equal(bmap1, bmap2, 1024)) +				failed_tests++; +			} +			if (!__bitmap_equal(bmap1, bmap2, 1024)) {  				printk("set not __equal %d %d\n", start, nbits); +				failed_tests++; +			}  			bitmap_clear(bmap1, start, nbits);  			__bitmap_clear(bmap2, start, nbits); -			if (!bitmap_equal(bmap1, bmap2, 1024)) +			if (!bitmap_equal(bmap1, bmap2, 1024)) {  				printk("clear not equal %d %d\n", start, nbits); -			if (!__bitmap_equal(bmap1, bmap2, 1024)) +				failed_tests++; +			} +			if (!__bitmap_equal(bmap1, bmap2, 1024)) {  				printk("clear not __equal %d %d\n", start,  									nbits); +				failed_tests++; +			}  		}  	}  } diff --git a/lib/textsearch.c b/lib/textsearch.c index 0b79908dfe89..5939549c0e7b 100644 --- a/lib/textsearch.c +++ b/lib/textsearch.c @@ -10,7 +10,10 @@   * 		Pablo Neira Ayuso <pablo@netfilter.org>   *   * ========================================================================== - * + */ + +/** + * DOC: ts_intro   * INTRODUCTION   *   *   The textsearch infrastructure provides text searching facilities for @@ -19,7 +22,9 @@   *   * ARCHITECTURE   * - *      User + * .. code-block:: none + * + *     User   *     +----------------+   *     |        finish()|<--------------(6)-----------------+   *     |get_next_block()|<--------------(5)---------------+ | @@ -33,21 +38,21 @@   *     |             (3)|----->| find()/next() |-----------+          |   *     |             (7)|----->| destroy()     |----------------------+   *     +----------------+      +---------------+ - *   - *   (1) User configures a search by calling _prepare() specifying the - *       search parameters such as the pattern and algorithm name. + * + *   (1) User configures a search by calling textsearch_prepare() specifying + *       the search parameters such as the pattern and algorithm name.   *   (2) Core requests the algorithm to allocate and initialize a search   *       configuration according to the specified parameters. - *   (3) User starts the search(es) by calling _find() or _next() to - *       fetch subsequent occurrences. A state variable is provided - *       to the algorithm to store persistent variables. + *   (3) User starts the search(es) by calling textsearch_find() or + *       textsearch_next() to fetch subsequent occurrences. A state variable + *       is provided to the algorithm to store persistent variables.   *   (4) Core eventually resets the search offset and forwards the find()   *       request to the algorithm.   *   (5) Algorithm calls get_next_block() provided by the user continuously   *       to fetch the data to be searched in block by block.   *   (6) Algorithm invokes finish() after the last call to get_next_block   *       to clean up any leftovers from get_next_block. (Optional) - *   (7) User destroys the configuration by calling _destroy(). + *   (7) User destroys the configuration by calling textsearch_destroy().   *   (8) Core notifies the algorithm to destroy algorithm specific   *       allocations. (Optional)   * @@ -62,9 +67,10 @@   *   amount of times and even in parallel as long as a separate struct   *   ts_state variable is provided to every instance.   * - *   The actual search is performed by either calling textsearch_find_- - *   continuous() for linear data or by providing an own get_next_block() - *   implementation and calling textsearch_find(). Both functions return + *   The actual search is performed by either calling + *   textsearch_find_continuous() for linear data or by providing + *   an own get_next_block() implementation and + *   calling textsearch_find(). Both functions return   *   the position of the first occurrence of the pattern or UINT_MAX if   *   no match was found. Subsequent occurrences can be found by calling   *   textsearch_next() regardless of the linearity of the data. @@ -72,7 +78,7 @@   *   Once you're done using a configuration it must be given back via   *   textsearch_destroy.   * - * EXAMPLE + * EXAMPLE::   *   *   int pos;   *   struct ts_config *conf; @@ -87,13 +93,13 @@   *       goto errout;   *   }   * - *   pos = textsearch_find_continuous(conf, &state, example, strlen(example)); + *   pos = textsearch_find_continuous(conf, \&state, example, strlen(example));   *   if (pos != UINT_MAX) - *       panic("Oh my god, dancing chickens at %d\n", pos); + *       panic("Oh my god, dancing chickens at \%d\n", pos);   *   *   textsearch_destroy(conf); - * ==========================================================================   */ +/* ========================================================================== */  #include <linux/module.h>  #include <linux/types.h> @@ -225,7 +231,7 @@ static unsigned int get_linear_data(unsigned int consumed, const u8 **dst,   *   * Returns the position of first occurrence of the pattern or   * %UINT_MAX if no occurrence was found. - */  + */  unsigned int textsearch_find_continuous(struct ts_config *conf,  					struct ts_state *state,  					const void *data, unsigned int len) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 30c0cb8cc9bc..23920c5ff728 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1669,19 +1669,22 @@ char *pointer_string(char *buf, char *end, const void *ptr,  	return number(buf, end, (unsigned long int)ptr, spec);  } -static bool have_filled_random_ptr_key __read_mostly; +static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key);  static siphash_key_t ptr_key __read_mostly; -static void fill_random_ptr_key(struct random_ready_callback *unused) +static void enable_ptr_key_workfn(struct work_struct *work)  {  	get_random_bytes(&ptr_key, sizeof(ptr_key)); -	/* -	 * have_filled_random_ptr_key==true is dependent on get_random_bytes(). -	 * ptr_to_id() needs to see have_filled_random_ptr_key==true -	 * after get_random_bytes() returns. -	 */ -	smp_mb(); -	WRITE_ONCE(have_filled_random_ptr_key, true); +	/* Needs to run from preemptible context */ +	static_branch_disable(¬_filled_random_ptr_key); +} + +static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); + +static void fill_random_ptr_key(struct random_ready_callback *unused) +{ +	/* This may be in an interrupt handler. */ +	queue_work(system_unbound_wq, &enable_ptr_key_work);  }  static struct random_ready_callback random_ready = { @@ -1695,7 +1698,8 @@ static int __init initialize_ptr_random(void)  	if (!ret) {  		return 0;  	} else if (ret == -EALREADY) { -		fill_random_ptr_key(&random_ready); +		/* This is in preemptible context */ +		enable_ptr_key_workfn(&enable_ptr_key_work);  		return 0;  	} @@ -1709,7 +1713,7 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)  	unsigned long hashval;  	const int default_width = 2 * sizeof(ptr); -	if (unlikely(!have_filled_random_ptr_key)) { +	if (static_branch_unlikely(¬_filled_random_ptr_key)) {  		spec.field_width = default_width;  		/* string length must be less than default_width */  		return string(buf, end, "(ptrval)", spec);  | 
