aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2018-06-26 03:02:41 -0400
committerIngo Molnar <mingo@kernel.org>2018-06-26 03:02:41 -0400
commitf446474889c06883a3879faa0896e2359e812a6b (patch)
tree95634685d56dd532d1e9b73fbd07ca389296911b /lib
parent01bdee64f9cf8e15f998bf52789ed9d0ebdfa621 (diff)
parent6f0d349d922ba44e4348a17a78ea51b7135965b1 (diff)
Merge branch 'linus' into perf/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile6
-rw-r--r--lib/dec_and_lock.c16
-rw-r--r--lib/refcount.c28
3 files changed, 45 insertions, 5 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 8153fdab287f..90dc5520b784 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -23,7 +23,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
23 sha1.o chacha20.o irq_regs.o argv_split.o \ 23 sha1.o chacha20.o irq_regs.o argv_split.o \
24 flex_proportions.o ratelimit.o show_mem.o \ 24 flex_proportions.o ratelimit.o show_mem.o \
25 is_single_threaded.o plist.o decompress.o kobject_uevent.o \ 25 is_single_threaded.o plist.o decompress.o kobject_uevent.o \
26 earlycpio.o seq_buf.o siphash.o \ 26 earlycpio.o seq_buf.o siphash.o dec_and_lock.o \
27 nmi_backtrace.o nodemask.o win_minmax.o 27 nmi_backtrace.o nodemask.o win_minmax.o
28 28
29lib-$(CONFIG_PRINTK) += dump_stack.o 29lib-$(CONFIG_PRINTK) += dump_stack.o
@@ -95,10 +95,6 @@ obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
95obj-$(CONFIG_DEBUG_LIST) += list_debug.o 95obj-$(CONFIG_DEBUG_LIST) += list_debug.o
96obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o 96obj-$(CONFIG_DEBUG_OBJECTS) += debugobjects.o
97 97
98ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
99 lib-y += dec_and_lock.o
100endif
101
102obj-$(CONFIG_BITREVERSE) += bitrev.o 98obj-$(CONFIG_BITREVERSE) += bitrev.o
103obj-$(CONFIG_RATIONAL) += rational.o 99obj-$(CONFIG_RATIONAL) += rational.o
104obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o 100obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o
diff --git a/lib/dec_and_lock.c b/lib/dec_and_lock.c
index 347fa7ac2e8a..9555b68bb774 100644
--- a/lib/dec_and_lock.c
+++ b/lib/dec_and_lock.c
@@ -33,3 +33,19 @@ int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
33} 33}
34 34
35EXPORT_SYMBOL(_atomic_dec_and_lock); 35EXPORT_SYMBOL(_atomic_dec_and_lock);
36
37int _atomic_dec_and_lock_irqsave(atomic_t *atomic, spinlock_t *lock,
38 unsigned long *flags)
39{
40 /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */
41 if (atomic_add_unless(atomic, -1, 1))
42 return 0;
43
44 /* Otherwise do it the slow way */
45 spin_lock_irqsave(lock, *flags);
46 if (atomic_dec_and_test(atomic))
47 return 1;
48 spin_unlock_irqrestore(lock, *flags);
49 return 0;
50}
51EXPORT_SYMBOL(_atomic_dec_and_lock_irqsave);
diff --git a/lib/refcount.c b/lib/refcount.c
index 0eb48353abe3..d3b81cefce91 100644
--- a/lib/refcount.c
+++ b/lib/refcount.c
@@ -350,3 +350,31 @@ bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock)
350} 350}
351EXPORT_SYMBOL(refcount_dec_and_lock); 351EXPORT_SYMBOL(refcount_dec_and_lock);
352 352
353/**
354 * refcount_dec_and_lock_irqsave - return holding spinlock with disabled
355 * interrupts if able to decrement refcount to 0
356 * @r: the refcount
357 * @lock: the spinlock to be locked
358 * @flags: saved IRQ-flags if the is acquired
359 *
360 * Same as refcount_dec_and_lock() above except that the spinlock is acquired
361 * with disabled interupts.
362 *
363 * Return: true and hold spinlock if able to decrement refcount to 0, false
364 * otherwise
365 */
366bool refcount_dec_and_lock_irqsave(refcount_t *r, spinlock_t *lock,
367 unsigned long *flags)
368{
369 if (refcount_dec_not_one(r))
370 return false;
371
372 spin_lock_irqsave(lock, *flags);
373 if (!refcount_dec_and_test(r)) {
374 spin_unlock_irqrestore(lock, *flags);
375 return false;
376 }
377
378 return true;
379}
380EXPORT_SYMBOL(refcount_dec_and_lock_irqsave);