diff options
Diffstat (limited to 'lib')
| -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/swiotlb.c | 4 | ||||
| -rw-r--r-- | lib/vsprintf.c | 26 |
5 files changed, 37 insertions, 34 deletions
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); | |||
| 111 | * errseq_sample() - Grab current errseq_t value. | 111 | * errseq_sample() - Grab current errseq_t value. |
| 112 | * @eseq: Pointer to errseq_t to be sampled. | 112 | * @eseq: Pointer to errseq_t to be sampled. |
| 113 | * | 113 | * |
| 114 | * This function allows callers to sample an errseq_t value, marking it as | 114 | * This function allows callers to initialise their errseq_t variable. |
| 115 | * "seen" if required. | 115 | * If the error has been "seen", new callers will not see an old error. |
| 116 | * If there is an unseen error in @eseq, the caller of this function will | ||
| 117 | * see it the next time it checks for an error. | ||
| 116 | * | 118 | * |
| 119 | * Context: Any context. | ||
| 117 | * Return: The current errseq value. | 120 | * Return: The current errseq value. |
| 118 | */ | 121 | */ |
| 119 | errseq_t errseq_sample(errseq_t *eseq) | 122 | errseq_t errseq_sample(errseq_t *eseq) |
| 120 | { | 123 | { |
| 121 | errseq_t old = READ_ONCE(*eseq); | 124 | errseq_t old = READ_ONCE(*eseq); |
| 122 | errseq_t new = old; | ||
| 123 | 125 | ||
| 124 | /* | 126 | /* If nobody has seen this error yet, then we can be the first. */ |
| 125 | * For the common case of no errors ever having been set, we can skip | 127 | if (!(old & ERRSEQ_SEEN)) |
| 126 | * marking the SEEN bit. Once an error has been set, the value will | 128 | old = 0; |
| 127 | * never go back to zero. | 129 | return old; |
| 128 | */ | ||
| 129 | if (old != 0) { | ||
| 130 | new |= ERRSEQ_SEEN; | ||
| 131 | if (old != new) | ||
| 132 | cmpxchg(eseq, old, new); | ||
| 133 | } | ||
| 134 | return new; | ||
| 135 | } | 130 | } |
| 136 | EXPORT_SYMBOL(errseq_sample); | 131 | EXPORT_SYMBOL(errseq_sample); |
| 137 | 132 | ||
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) | |||
| 132 | test_find_next_bit(bitmap, BITMAP_LEN); | 132 | test_find_next_bit(bitmap, BITMAP_LEN); |
| 133 | test_find_next_zero_bit(bitmap, BITMAP_LEN); | 133 | test_find_next_zero_bit(bitmap, BITMAP_LEN); |
| 134 | test_find_last_bit(bitmap, BITMAP_LEN); | 134 | test_find_last_bit(bitmap, BITMAP_LEN); |
| 135 | test_find_first_bit(bitmap, BITMAP_LEN); | 135 | |
| 136 | /* | ||
| 137 | * test_find_first_bit() may take some time, so | ||
| 138 | * traverse only part of bitmap to avoid soft lockup. | ||
| 139 | */ | ||
| 140 | test_find_first_bit(bitmap, BITMAP_LEN / 10); | ||
| 136 | test_find_next_and_bit(bitmap, bitmap2, BITMAP_LEN); | 141 | test_find_next_and_bit(bitmap, bitmap2, BITMAP_LEN); |
| 137 | 142 | ||
| 138 | pr_err("\nStart testing find_bit() with sparse bitmap\n"); | 143 | 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) | |||
| 233 | 233 | ||
| 234 | /* be noisy on error issues */ | 234 | /* be noisy on error issues */ |
| 235 | if (error == -EEXIST) | 235 | if (error == -EEXIST) |
| 236 | WARN(1, | 236 | pr_err("%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n", |
| 237 | "%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n", | 237 | __func__, kobject_name(kobj)); |
| 238 | __func__, kobject_name(kobj)); | ||
| 239 | else | 238 | else |
| 240 | WARN(1, "%s failed for %s (error: %d parent: %s)\n", | 239 | pr_err("%s failed for %s (error: %d parent: %s)\n", |
| 241 | __func__, kobject_name(kobj), error, | 240 | __func__, kobject_name(kobj), error, |
| 242 | parent ? kobject_name(parent) : "'none'"); | 241 | parent ? kobject_name(parent) : "'none'"); |
| 243 | } else | 242 | } else |
| 244 | kobj->state_in_sysfs = 1; | 243 | kobj->state_in_sysfs = 1; |
| 245 | 244 | ||
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, | |||
| 714 | 714 | ||
| 715 | phys_addr = swiotlb_tbl_map_single(dev, | 715 | phys_addr = swiotlb_tbl_map_single(dev, |
| 716 | __phys_to_dma(dev, io_tlb_start), | 716 | __phys_to_dma(dev, io_tlb_start), |
| 717 | 0, size, DMA_FROM_DEVICE, 0); | 717 | 0, size, DMA_FROM_DEVICE, attrs); |
| 718 | if (phys_addr == SWIOTLB_MAP_ERROR) | 718 | if (phys_addr == SWIOTLB_MAP_ERROR) |
| 719 | goto out_warn; | 719 | goto out_warn; |
| 720 | 720 | ||
| @@ -737,7 +737,7 @@ out_unmap: | |||
| 737 | swiotlb_tbl_unmap_single(dev, phys_addr, size, DMA_TO_DEVICE, | 737 | swiotlb_tbl_unmap_single(dev, phys_addr, size, DMA_TO_DEVICE, |
| 738 | DMA_ATTR_SKIP_CPU_SYNC); | 738 | DMA_ATTR_SKIP_CPU_SYNC); |
| 739 | out_warn: | 739 | out_warn: |
| 740 | if ((attrs & DMA_ATTR_NO_WARN) && printk_ratelimit()) { | 740 | if (!(attrs & DMA_ATTR_NO_WARN) && printk_ratelimit()) { |
| 741 | dev_warn(dev, | 741 | dev_warn(dev, |
| 742 | "swiotlb: coherent allocation failed, size=%zu\n", | 742 | "swiotlb: coherent allocation failed, size=%zu\n", |
| 743 | size); | 743 | size); |
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, | |||
| 1669 | return number(buf, end, (unsigned long int)ptr, spec); | 1669 | return number(buf, end, (unsigned long int)ptr, spec); |
| 1670 | } | 1670 | } |
| 1671 | 1671 | ||
| 1672 | static bool have_filled_random_ptr_key __read_mostly; | 1672 | static DEFINE_STATIC_KEY_TRUE(not_filled_random_ptr_key); |
| 1673 | static siphash_key_t ptr_key __read_mostly; | 1673 | static siphash_key_t ptr_key __read_mostly; |
| 1674 | 1674 | ||
| 1675 | static void fill_random_ptr_key(struct random_ready_callback *unused) | 1675 | static void enable_ptr_key_workfn(struct work_struct *work) |
| 1676 | { | 1676 | { |
| 1677 | get_random_bytes(&ptr_key, sizeof(ptr_key)); | 1677 | get_random_bytes(&ptr_key, sizeof(ptr_key)); |
| 1678 | /* | 1678 | /* Needs to run from preemptible context */ |
| 1679 | * have_filled_random_ptr_key==true is dependent on get_random_bytes(). | 1679 | static_branch_disable(¬_filled_random_ptr_key); |
| 1680 | * ptr_to_id() needs to see have_filled_random_ptr_key==true | 1680 | } |
| 1681 | * after get_random_bytes() returns. | 1681 | |
| 1682 | */ | 1682 | static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn); |
| 1683 | smp_mb(); | 1683 | |
| 1684 | WRITE_ONCE(have_filled_random_ptr_key, true); | 1684 | static void fill_random_ptr_key(struct random_ready_callback *unused) |
| 1685 | { | ||
| 1686 | /* This may be in an interrupt handler. */ | ||
| 1687 | queue_work(system_unbound_wq, &enable_ptr_key_work); | ||
| 1685 | } | 1688 | } |
| 1686 | 1689 | ||
| 1687 | static struct random_ready_callback random_ready = { | 1690 | static struct random_ready_callback random_ready = { |
| @@ -1695,7 +1698,8 @@ static int __init initialize_ptr_random(void) | |||
| 1695 | if (!ret) { | 1698 | if (!ret) { |
| 1696 | return 0; | 1699 | return 0; |
| 1697 | } else if (ret == -EALREADY) { | 1700 | } else if (ret == -EALREADY) { |
| 1698 | fill_random_ptr_key(&random_ready); | 1701 | /* This is in preemptible context */ |
| 1702 | enable_ptr_key_workfn(&enable_ptr_key_work); | ||
| 1699 | return 0; | 1703 | return 0; |
| 1700 | } | 1704 | } |
| 1701 | 1705 | ||
| @@ -1709,7 +1713,7 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) | |||
| 1709 | unsigned long hashval; | 1713 | unsigned long hashval; |
| 1710 | const int default_width = 2 * sizeof(ptr); | 1714 | const int default_width = 2 * sizeof(ptr); |
| 1711 | 1715 | ||
| 1712 | if (unlikely(!have_filled_random_ptr_key)) { | 1716 | if (static_branch_unlikely(¬_filled_random_ptr_key)) { |
| 1713 | spec.field_width = default_width; | 1717 | spec.field_width = default_width; |
| 1714 | /* string length must be less than default_width */ | 1718 | /* string length must be less than default_width */ |
| 1715 | return string(buf, end, "(ptrval)", spec); | 1719 | return string(buf, end, "(ptrval)", spec); |
