Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 8982
b: refs/heads/master
c: fea2efe
h: refs/heads/master
v: v3
  • Loading branch information
Russell King authored and Russell King committed Sep 15, 2005
1 parent 56bc44e commit 5cd2502
Show file tree
Hide file tree
Showing 60 changed files with 614 additions and 344 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bc9a5154a24d16d41cc79dbf1442de34454bc7db
refs/heads/master: fea2efe3bba15f0aa8f840fbe052699808187cb6
5 changes: 5 additions & 0 deletions trunk/arch/i386/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,11 @@ config IRQBALANCE
The default yes will allow the kernel to do irq load balancing.
Saying no will keep the kernel from doing irq load balancing.

config HAVE_DEC_LOCK
bool
depends on (SMP || PREEMPT) && X86_CMPXCHG
default y

# turning this on wastes a bunch of space.
# Summit needs it only when NUMA is on
config BOOT_IOREMAP
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/i386/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \
bitops.o

lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
42 changes: 42 additions & 0 deletions trunk/arch/i386/lib/dec_and_lock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* x86 version of "atomic_dec_and_lock()" using
* the atomic "cmpxchg" instruction.
*
* (For CPU's lacking cmpxchg, we use the slow
* generic version, and this one never even gets
* compiled).
*/

#include <linux/spinlock.h>
#include <linux/module.h>
#include <asm/atomic.h>

int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
{
int counter;
int newcount;

repeat:
counter = atomic_read(atomic);
newcount = counter-1;

if (!newcount)
goto slow_path;

asm volatile("lock; cmpxchgl %1,%2"
:"=a" (newcount)
:"r" (newcount), "m" (atomic->counter), "0" (counter));

/* If the above failed, "eax" will have changed */
if (newcount != counter)
goto repeat;
return 0;

slow_path:
spin_lock(lock);
if (atomic_dec_and_test(atomic))
return 1;
spin_unlock(lock);
return 0;
}
EXPORT_SYMBOL(_atomic_dec_and_lock);
5 changes: 5 additions & 0 deletions trunk/arch/ia64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,11 @@ config PREEMPT

source "mm/Kconfig"

config HAVE_DEC_LOCK
bool
depends on (SMP || PREEMPT)
default y

config IA32_SUPPORT
bool "Support for Linux/x86 binaries"
help
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/ia64/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o
lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o
lib-$(CONFIG_PERFMON) += carta_random.o
lib-$(CONFIG_MD_RAID5) += xor.o
lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o

AFLAGS___divdi3.o =
AFLAGS___udivdi3.o = -DUNSIGNED
Expand Down
42 changes: 42 additions & 0 deletions trunk/arch/ia64/lib/dec_and_lock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (C) 2003 Jerome Marchand, Bull S.A.
* Cleaned up by David Mosberger-Tang <davidm@hpl.hp.com>
*
* This file is released under the GPLv2, or at your option any later version.
*
* ia64 version of "atomic_dec_and_lock()" using the atomic "cmpxchg" instruction. This
* code is an adaptation of the x86 version of "atomic_dec_and_lock()".
*/

#include <linux/compiler.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>

/*
* Decrement REFCOUNT and if the count reaches zero, acquire the spinlock. Both of these
* operations have to be done atomically, so that the count doesn't drop to zero without
* acquiring the spinlock first.
*/
int
_atomic_dec_and_lock (atomic_t *refcount, spinlock_t *lock)
{
int old, new;

do {
old = atomic_read(refcount);
new = old - 1;

if (unlikely (old == 1)) {
/* oops, we may be decrementing to zero, do it the slow way... */
spin_lock(lock);
if (atomic_dec_and_test(refcount))
return 1;
spin_unlock(lock);
return 0;
}
} while (cmpxchg(&refcount->counter, old, new) != old);
return 0;
}

EXPORT_SYMBOL(_atomic_dec_and_lock);
5 changes: 5 additions & 0 deletions trunk/arch/m32r/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ config PREEMPT
Say Y here if you are building a kernel for a desktop, embedded
or real-time system. Say N if you are unsure.

config HAVE_DEC_LOCK
bool
depends on (SMP || PREEMPT)
default n

config SMP
bool "Symmetric multi-processing support"
---help---
Expand Down
4 changes: 4 additions & 0 deletions trunk/arch/mips/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,10 @@ config GENERIC_CALIBRATE_DELAY
bool
default y

config HAVE_DEC_LOCK
bool
default y

#
# Select some configuration options automatically based on user selections.
#
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/mips/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Makefile for MIPS-specific library files..
#

lib-y += csum_partial_copy.o memcpy.o promlib.o \
lib-y += csum_partial_copy.o dec_and_lock.o memcpy.o promlib.o \
strlen_user.o strncpy_user.o strnlen_user.o

obj-y += iomap.o
Expand Down
47 changes: 47 additions & 0 deletions trunk/arch/mips/lib/dec_and_lock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* MIPS version of atomic_dec_and_lock() using cmpxchg
*
* 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.
*/

#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>
#include <asm/system.h>

/*
* This is an implementation of the notion of "decrement a
* reference count, and return locked if it decremented to zero".
*
* This implementation can be used on any architecture that
* has a cmpxchg, and where atomic->value is an int holding
* the value of the atomic (i.e. the high bits aren't used
* for a lock or anything like that).
*/
int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
{
int counter;
int newcount;

for (;;) {
counter = atomic_read(atomic);
newcount = counter - 1;
if (!newcount)
break; /* do it the slow way */

newcount = cmpxchg(&atomic->counter, counter, newcount);
if (newcount == counter)
return 0;
}

spin_lock(lock);
if (atomic_dec_and_test(atomic))
return 1;
spin_unlock(lock);
return 0;
}

EXPORT_SYMBOL(_atomic_dec_and_lock);
4 changes: 4 additions & 0 deletions trunk/arch/ppc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ config GENERIC_CALIBRATE_DELAY
bool
default y

config HAVE_DEC_LOCK
bool
default y

config PPC
bool
default y
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/ppc/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Makefile for ppc-specific library files..
#

obj-y := checksum.o string.o strcase.o div64.o
obj-y := checksum.o string.o strcase.o dec_and_lock.o div64.o

obj-$(CONFIG_8xx) += rheap.o
obj-$(CONFIG_CPM2) += rheap.o
38 changes: 38 additions & 0 deletions trunk/arch/ppc/lib/dec_and_lock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>
#include <asm/system.h>

/*
* This is an implementation of the notion of "decrement a
* reference count, and return locked if it decremented to zero".
*
* This implementation can be used on any architecture that
* has a cmpxchg, and where atomic->value is an int holding
* the value of the atomic (i.e. the high bits aren't used
* for a lock or anything like that).
*/
int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
{
int counter;
int newcount;

for (;;) {
counter = atomic_read(atomic);
newcount = counter - 1;
if (!newcount)
break; /* do it the slow way */

newcount = cmpxchg(&atomic->counter, counter, newcount);
if (newcount == counter)
return 0;
}

spin_lock(lock);
if (atomic_dec_and_test(atomic))
return 1;
spin_unlock(lock);
return 0;
}

EXPORT_SYMBOL(_atomic_dec_and_lock);
4 changes: 4 additions & 0 deletions trunk/arch/ppc64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ config GENERIC_ISA_DMA
bool
default y

config HAVE_DEC_LOCK
bool
default y

config EARLY_PRINTK
bool
default y
Expand Down
6 changes: 3 additions & 3 deletions trunk/arch/ppc64/kernel/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -1649,7 +1649,7 @@ _GLOBAL(__secondary_start)
ld r3,0(r3)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
beq 98f /* branch if result is 0 */
bne 98f
mfspr r3,PVR
srwi r3,r3,16
cmpwi r3,0x37 /* SStar */
Expand Down Expand Up @@ -1813,7 +1813,7 @@ _STATIC(start_here_multiplatform)
ld r3,0(r3)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
beq 98f /* branch if result is 0 */
bne 98f
mfspr r3,PVR
srwi r3,r3,16
cmpwi r3,0x37 /* SStar */
Expand All @@ -1834,7 +1834,7 @@ _STATIC(start_here_multiplatform)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
/* Test if bit 0 is set (LPAR bit) */
andi. r3,r3,PLATFORM_LPAR
bne 98f /* branch if result is !0 */
bne 98f
LOADADDR(r6,_SDR1) /* Only if NOT LPAR */
sub r6,r6,r26
ld r6,0(r6) /* get the value of _SDR1 */
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/ppc64/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Makefile for ppc64-specific library files..
#

lib-y := checksum.o string.o strcase.o
lib-y := checksum.o dec_and_lock.o string.o strcase.o
lib-y += copypage.o memcpy.o copyuser.o usercopy.o

# Lock primitives are defined as no-ops in include/linux/spinlock.h
Expand Down
47 changes: 47 additions & 0 deletions trunk/arch/ppc64/lib/dec_and_lock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* ppc64 version of atomic_dec_and_lock() using cmpxchg
*
* 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.
*/

#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>
#include <asm/system.h>

/*
* This is an implementation of the notion of "decrement a
* reference count, and return locked if it decremented to zero".
*
* This implementation can be used on any architecture that
* has a cmpxchg, and where atomic->value is an int holding
* the value of the atomic (i.e. the high bits aren't used
* for a lock or anything like that).
*/
int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
{
int counter;
int newcount;

for (;;) {
counter = atomic_read(atomic);
newcount = counter - 1;
if (!newcount)
break; /* do it the slow way */

newcount = cmpxchg(&atomic->counter, counter, newcount);
if (newcount == counter)
return 0;
}

spin_lock(lock);
if (atomic_dec_and_test(atomic))
return 1;
spin_unlock(lock);
return 0;
}

EXPORT_SYMBOL(_atomic_dec_and_lock);
8 changes: 8 additions & 0 deletions trunk/arch/sparc64/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ config DEBUG_BOOTMEM
depends on DEBUG_KERNEL
bool "Debug BOOTMEM initialization"

# We have a custom atomic_dec_and_lock() implementation but it's not
# compatible with spinlock debugging so we need to fall back on
# the generic version in that case.
config HAVE_DEC_LOCK
bool
depends on SMP && !DEBUG_SPINLOCK
default y

config MCOUNT
bool
depends on STACK_DEBUG
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/sparc64/kernel/sparc64_ksyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ EXPORT_SYMBOL(atomic64_add);
EXPORT_SYMBOL(atomic64_add_ret);
EXPORT_SYMBOL(atomic64_sub);
EXPORT_SYMBOL(atomic64_sub_ret);
#ifdef CONFIG_SMP
EXPORT_SYMBOL(_atomic_dec_and_lock);
#endif

/* Atomic bit operations. */
EXPORT_SYMBOL(test_and_set_bit);
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/sparc64/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ lib-y := PeeCeeI.o copy_page.o clear_page.o strlen.o strncmp.o \
copy_in_user.o user_fixup.o memmove.o \
mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o

lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o

obj-y += iomap.o
Loading

0 comments on commit 5cd2502

Please sign in to comment.