Commit 079dff39 authored by Linus Torvalds's avatar Linus Torvalds

- pre4:

   - Andrea Arcangeli: SMP scheduler memory barrier fixup
   - Richard Henderson: fix alpha semaphores and spinlock bugs.
   - Richard Henderson: clean up the file from hell: "xor.c"
parent 7f6760c7
......@@ -63,7 +63,6 @@ unset CONFIG_ALPHA_T2 CONFIG_ALPHA_PYXIS CONFIG_ALPHA_POLARIS
unset CONFIG_ALPHA_TSUNAMI CONFIG_ALPHA_MCPCIA
unset CONFIG_ALPHA_IRONGATE
unset CONFIG_ALPHA_BROKEN_IRQ_MASK
unset CONFIG_ALPHA_LARGE_VMALLOC
# Most of these machines have ISA slots; not exactly sure which don't,
# and this doesn't activate hordes of code, so do it always.
......@@ -215,6 +214,8 @@ if [ "$CONFIG_ALPHA_GENERIC" = "y" -o "$CONFIG_ALPHA_DP264" = "y" \
-o "$CONFIG_ALPHA_WILDFIRE" = "y" -o "$CONFIG_ALPHA_TITAN" = "y" ]
then
bool 'Large VMALLOC support' CONFIG_ALPHA_LARGE_VMALLOC
else
define_bool CONFIG_ALPHA_LARGE_VMALLOC n
fi
source drivers/pci/Config.in
......
......@@ -160,15 +160,20 @@ EXPORT_SYMBOL_NOVERS(__do_clear_user);
EXPORT_SYMBOL(__strncpy_from_user);
EXPORT_SYMBOL(__strnlen_user);
/*
* The following are specially called from the semaphore assembly stubs.
*/
EXPORT_SYMBOL_NOVERS(__down_failed);
EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
EXPORT_SYMBOL_NOVERS(__up_wakeup);
EXPORT_SYMBOL_NOVERS(__down_read_failed);
EXPORT_SYMBOL_NOVERS(__down_write_failed);
EXPORT_SYMBOL_NOVERS(__rwsem_wake);
/* Semaphore helper functions. */
EXPORT_SYMBOL(__down_failed);
EXPORT_SYMBOL(__down_failed_interruptible);
EXPORT_SYMBOL(__up_wakeup);
EXPORT_SYMBOL(down);
EXPORT_SYMBOL(down_interruptible);
EXPORT_SYMBOL(up);
EXPORT_SYMBOL(__down_read_failed);
EXPORT_SYMBOL(__down_write_failed);
EXPORT_SYMBOL(__rwsem_wake);
EXPORT_SYMBOL(down_read);
EXPORT_SYMBOL(down_write);
EXPORT_SYMBOL(up_read);
EXPORT_SYMBOL(up_write);
/*
* SMP-specific symbols.
......
This diff is collapsed.
......@@ -378,6 +378,9 @@ do_settimeofday(struct timeval *tv)
* BUG: This routine does not handle hour overflow properly; it just
* sets the minutes. Usually you won't notice until after reboot!
*/
extern int abs(int);
static int
set_rtc_mmss(unsigned long nowtime)
{
......
......@@ -12,7 +12,7 @@ OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \
strcat.o strcpy.o strncat.o strncpy.o stxcpy.o stxncpy.o \
strchr.o strrchr.o memchr.o \
copy_user.o clear_user.o strncpy_from_user.o strlen_user.o \
csum_ipv6_magic.o strcasecmp.o semaphore.o fpreg.o \
csum_ipv6_magic.o strcasecmp.o fpreg.o \
callback_srm.o srm_puts.o srm_printk.o
lib.a: $(OBJS)
......
/*
* linux/arch/alpha/lib/semaphore.S
*
* Copyright (C) 1999, 2000 Richard Henderson
*/
/*
* The semaphore operations have a special calling sequence that
* allow us to do a simpler in-line version of them. These routines
* need to convert that sequence back into the C sequence when
* there is contention on the semaphore.
*/
.set noat
.set noreorder
.align 4
/* __down_failed takes the semaphore in $24, clobbers $24 and $28. */
.globl __down_failed
.ent __down_failed
__down_failed:
ldgp $29,0($27)
lda $30, -20*8($30)
stq $28, 0*8($30)
stq $0, 1*8($30)
stq $1, 2*8($30)
stq $2, 3*8($30)
stq $3, 4*8($30)
stq $4, 5*8($30)
stq $5, 6*8($30)
stq $6, 7*8($30)
stq $7, 8*8($30)
stq $16, 9*8($30)
stq $17, 10*8($30)
stq $18, 11*8($30)
stq $19, 12*8($30)
stq $20, 13*8($30)
stq $21, 14*8($30)
stq $22, 15*8($30)
stq $23, 16*8($30)
stq $25, 17*8($30)
stq $26, 18*8($30)
.frame $30, 20*8, $28
.prologue 1
mov $24, $16
jsr __down
ldq $28, 0*8($30)
ldq $0, 1*8($30)
ldq $1, 2*8($30)
ldq $2, 3*8($30)
ldq $3, 4*8($30)
ldq $4, 5*8($30)
ldq $5, 6*8($30)
ldq $6, 7*8($30)
ldq $7, 8*8($30)
ldq $16, 9*8($30)
ldq $17, 10*8($30)
ldq $18, 11*8($30)
ldq $19, 12*8($30)
ldq $20, 13*8($30)
ldq $21, 14*8($30)
ldq $22, 15*8($30)
ldq $23, 16*8($30)
ldq $25, 17*8($30)
ldq $26, 18*8($30)
lda $30, 20*8($30)
ret $31, ($28), 0
.end __down_failed
/* __down_failed_interruptible takes the semaphore in $24,
clobbers $28, returns success in $24. */
.globl __down_failed_interruptible
.ent __down_failed_interruptible
__down_failed_interruptible:
ldgp $29,0($27)
lda $30, -20*8($30)
stq $28, 0*8($30)
stq $0, 1*8($30)
stq $1, 2*8($30)
stq $2, 3*8($30)
stq $3, 4*8($30)
stq $4, 5*8($30)
stq $5, 6*8($30)
stq $6, 7*8($30)
stq $7, 8*8($30)
stq $16, 9*8($30)
stq $17, 10*8($30)
stq $18, 11*8($30)
stq $19, 12*8($30)
stq $20, 13*8($30)
stq $21, 14*8($30)
stq $22, 15*8($30)
stq $23, 16*8($30)
stq $25, 17*8($30)
stq $26, 18*8($30)
.frame $30, 20*8, $28
.prologue 1
mov $24, $16
jsr __down_interruptible
mov $0, $24
ldq $28, 0*8($30)
ldq $0, 1*8($30)
ldq $1, 2*8($30)
ldq $2, 3*8($30)
ldq $3, 4*8($30)
ldq $4, 5*8($30)
ldq $5, 6*8($30)
ldq $6, 7*8($30)
ldq $7, 8*8($30)
ldq $16, 9*8($30)
ldq $17, 10*8($30)
ldq $18, 11*8($30)
ldq $19, 12*8($30)
ldq $20, 13*8($30)
ldq $21, 14*8($30)
ldq $22, 15*8($30)
ldq $23, 16*8($30)
ldq $25, 17*8($30)
ldq $26, 18*8($30)
lda $30, 20*8($30)
ret $31, ($28), 0
.end __down_failed_interruptible
/* __up_wakeup takes the semaphore in $24, clobbers $24 and $28. */
.globl __up_wakeup
.ent __up_wakeup
__up_wakeup:
ldgp $29,0($27)
lda $30, -20*8($30)
stq $28, 0*8($30)
stq $0, 1*8($30)
stq $1, 2*8($30)
stq $2, 3*8($30)
stq $3, 4*8($30)
stq $4, 5*8($30)
stq $5, 6*8($30)
stq $6, 7*8($30)
stq $7, 8*8($30)
stq $16, 9*8($30)
stq $17, 10*8($30)
stq $18, 11*8($30)
stq $19, 12*8($30)
stq $20, 13*8($30)
stq $21, 14*8($30)
stq $22, 15*8($30)
stq $23, 16*8($30)
stq $25, 17*8($30)
stq $26, 18*8($30)
.frame $30, 20*8, $28
.prologue 1
mov $24, $16
jsr __up
ldq $28, 0*8($30)
ldq $0, 1*8($30)
ldq $1, 2*8($30)
ldq $2, 3*8($30)
ldq $3, 4*8($30)
ldq $4, 5*8($30)
ldq $5, 6*8($30)
ldq $6, 7*8($30)
ldq $7, 8*8($30)
ldq $16, 9*8($30)
ldq $17, 10*8($30)
ldq $18, 11*8($30)
ldq $19, 12*8($30)
ldq $20, 13*8($30)
ldq $21, 14*8($30)
ldq $22, 15*8($30)
ldq $23, 16*8($30)
ldq $25, 17*8($30)
ldq $26, 18*8($30)
lda $30, 20*8($30)
ret $31, ($28), 0
.end __up_wakeup
/* __down_read_failed takes the semaphore in $24, count in $25;
clobbers $24, $25 and $28. */
.globl __down_read_failed
.ent __down_read_failed
__down_read_failed:
ldgp $29,0($27)
lda $30, -18*8($30)
stq $28, 0*8($30)
stq $0, 1*8($30)
stq $1, 2*8($30)
stq $2, 3*8($30)
stq $3, 4*8($30)
stq $4, 5*8($30)
stq $5, 6*8($30)
stq $6, 7*8($30)
stq $7, 8*8($30)
stq $16, 9*8($30)
stq $17, 10*8($30)
stq $18, 11*8($30)
stq $19, 12*8($30)
stq $20, 13*8($30)
stq $21, 14*8($30)
stq $22, 15*8($30)
stq $23, 16*8($30)
stq $26, 17*8($30)
.frame $30, 18*8, $28
.prologue 1
mov $24, $16
mov $25, $17
jsr __down_read
ldq $28, 0*8($30)
ldq $0, 1*8($30)
ldq $1, 2*8($30)
ldq $2, 3*8($30)
ldq $3, 4*8($30)
ldq $4, 5*8($30)
ldq $5, 6*8($30)
ldq $6, 7*8($30)
ldq $7, 8*8($30)
ldq $16, 9*8($30)
ldq $17, 10*8($30)
ldq $18, 11*8($30)
ldq $19, 12*8($30)
ldq $20, 13*8($30)
ldq $21, 14*8($30)
ldq $22, 15*8($30)
ldq $23, 16*8($30)
ldq $26, 17*8($30)
lda $30, 18*8($30)
ret $31, ($28), 0
.end __down_read_failed
/* __down_write_failed takes the semaphore in $24, count in $25;
clobbers $24, $25 and $28. */
.globl __down_write_failed
.ent __down_write_failed
__down_write_failed:
ldgp $29,0($27)
lda $30, -20*8($30)
stq $28, 0*8($30)
stq $0, 1*8($30)
stq $1, 2*8($30)
stq $2, 3*8($30)
stq $3, 4*8($30)
stq $4, 5*8($30)
stq $5, 6*8($30)
stq $6, 7*8($30)
stq $7, 8*8($30)
stq $16, 9*8($30)
stq $17, 10*8($30)
stq $18, 11*8($30)
stq $19, 12*8($30)
stq $20, 13*8($30)
stq $21, 14*8($30)
stq $22, 15*8($30)
stq $23, 16*8($30)
stq $26, 17*8($30)
.frame $30, 18*8, $28
.prologue 1
mov $24, $16
mov $25, $17
jsr __down_write
ldq $28, 0*8($30)
ldq $0, 1*8($30)
ldq $1, 2*8($30)
ldq $2, 3*8($30)
ldq $3, 4*8($30)
ldq $4, 5*8($30)
ldq $5, 6*8($30)
ldq $6, 7*8($30)
ldq $7, 8*8($30)
ldq $16, 9*8($30)
ldq $17, 10*8($30)
ldq $18, 11*8($30)
ldq $19, 12*8($30)
ldq $20, 13*8($30)
ldq $21, 14*8($30)
ldq $22, 15*8($30)
ldq $23, 16*8($30)
ldq $26, 17*8($30)
lda $30, 18*8($30)
ret $31, ($28), 0
.end __down_write_failed
/* __rwsem_wake takes the semaphore in $24, readers in $25;
clobbers $24, $25, and $28. */
.globl __rwsem_wake
.ent __rwsem_wake
__rwsem_wake:
ldgp $29,0($27)
lda $30, -18*8($30)
stq $28, 0*8($30)
stq $0, 1*8($30)
stq $1, 2*8($30)
stq $2, 3*8($30)
stq $3, 4*8($30)
stq $4, 5*8($30)
stq $5, 6*8($30)
stq $6, 7*8($30)
stq $7, 8*8($30)
stq $16, 9*8($30)
stq $17, 10*8($30)
stq $18, 11*8($30)
stq $19, 12*8($30)
stq $20, 13*8($30)
stq $21, 14*8($30)
stq $22, 15*8($30)
stq $23, 16*8($30)
stq $26, 17*8($30)
.frame $30, 18*8, $28
.prologue 1
mov $24, $16
mov $25, $17
jsr __do_rwsem_wake
ldq $28, 0*8($30)
ldq $0, 1*8($30)
ldq $1, 2*8($30)
ldq $2, 3*8($30)
ldq $3, 4*8($30)
ldq $4, 5*8($30)
ldq $5, 6*8($30)
ldq $6, 7*8($30)
ldq $7, 8*8($30)
ldq $16, 9*8($30)
ldq $17, 10*8($30)
ldq $18, 11*8($30)
ldq $19, 12*8($30)
ldq $20, 13*8($30)
ldq $21, 14*8($30)
ldq $22, 15*8($30)
ldq $23, 16*8($30)
ldq $26, 17*8($30)
lda $30, 18*8($30)
ret $31, ($28), 0
.end __rwsem_wake
......@@ -2344,18 +2344,7 @@ static mdk_personality_t raid5_personality=
int raid5_init (void)
{
int err;
err = register_md_personality (RAID5, &raid5_personality);
if (err)
return err;
/*
* pick a XOR routine, runtime.
*/
calibrate_xor_block();
return 0;
return register_md_personality (RAID5, &raid5_personality);
}
#ifdef MODULE
......
This diff is collapsed.
......@@ -1129,7 +1129,7 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
if ((speed = irda_get_speed(skb)) != self->io.speed) {
/* Check for empty frame */
if (!skb->len) {
nsc_ircc_change_speed_complete(self, speed);
nsc_ircc_change_speed(self, speed);
return 0;
} else
self->new_speed = speed;
......
......@@ -207,8 +207,10 @@ int __init a2091_detect(Scsi_Host_Template *tpnt)
continue;
instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata));
if(instance == NULL)
continue;
if (instance == NULL) {
release_mem_region(address, 256);
continue;
}
instance->base = ZTWO_VADDR(address);
instance->irq = IRQ_AMIGA_PORTS;
instance->unique_id = z->slotaddr;
......
......@@ -66,8 +66,8 @@ static __inline__ long atomic_add_return(int i, atomic_t * v)
long temp, result;
__asm__ __volatile__(
"1: ldl_l %0,%1\n"
" addl %0,%3,%2\n"
" addl %0,%3,%0\n"
" mov %0,%2\n"
" stl_c %0,%1\n"
" beq %0,2f\n"
" mb\n"
......@@ -84,8 +84,8 @@ static __inline__ long atomic_sub_return(int i, atomic_t * v)
long temp, result;
__asm__ __volatile__(
"1: ldl_l %0,%1\n"
" subl %0,%3,%2\n"
" subl %0,%3,%0\n"
" mov %0,%2\n"
" stl_c %0,%1\n"
" beq %0,2f\n"
" mb\n"
......
......@@ -72,4 +72,13 @@
__asm__("stw %1,%0" : "=m"(mem) : "r"(val))
#endif
/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
a mechanism by which the user can annotate likely branch directions and
expect the blocks to be reordered appropriately. Define __builtin_expect
to nothing for earlier compilers. */
#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
#define __builtin_expect(x, expected_value) (x)
#endif
#endif /* __ALPHA_COMPILER_H */
#ifndef _ALPHA_SEMAPHORE_HELPER_H
#define _ALPHA_SEMAPHORE_HELPER_H
/*
* SMP- and interrupt-safe semaphores helper functions.
*
* (C) Copyright 1996 Linus Torvalds
* (C) Copyright 1999 Richard Henderson
*/
/*
* These two _must_ execute atomically wrt each other.
*
* This is trivially done with load_locked/store_cond,
* which we have. Let the rest of the losers suck eggs.
*/
static inline void
wake_one_more(struct semaphore * sem)
{
atomic_inc(&sem->waking);
}
static inline int
waking_non_zero(struct semaphore *sem)
{
long ret, tmp;
/* An atomic conditional decrement. */
__asm__ __volatile__(
"1: ldl_l %1,%2\n"
" blt %1,2f\n"
" subl %1,1,%0\n"
" stl_c %0,%2\n"
" beq %0,3f\n"
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=r"(ret), "=r"(tmp), "=m"(sem->waking.counter)
: "0"(0));
return ret > 0;
}
/*
* waking_non_zero_interruptible:
* 1 got the lock
* 0 go to sleep
* -EINTR interrupted
*
* We must undo the sem->count down_interruptible decrement
* simultaneously and atomicly with the sem->waking adjustment,
* otherwise we can race with wake_one_more.
*
* This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words.
*/
static inline int
waking_non_zero_interruptible(struct semaphore *sem, struct task_struct *tsk)
{
long ret, tmp, tmp2, tmp3;
/* "Equivalent" C. Note that we have to do this all without
(taken) branches in order to be a valid ll/sc sequence.
do {
tmp = ldq_l;
ret = 0;
if (tmp >= 0) {
tmp += 0xffffffff00000000;
ret = 1;
}
else if (pending) {
// Since -1 + 1 carries into the high word, we have
// to be more careful adding 1 here.
tmp = (tmp & 0xffffffff00000000)
| ((tmp + 1) & 0x00000000ffffffff;
ret = -EINTR;
}
else {
break; // ideally. we don't actually break
// since this is a predicate we don't
// have, and is more trouble to build
// than to elide the noop stq_c.
}
tmp = stq_c = tmp;
} while (tmp == 0);
*/
__asm__ __volatile__(
"1: ldq_l %1,%4\n"
" lda %0,0\n"
" cmovne %5,%6,%0\n"
" addq %1,1,%2\n"
" and %1,%7,%3\n"
" andnot %2,%7,%2\n"
" cmovge %1,1,%0\n"
" or %3,%2,%2\n"
" addq %1,%7,%3\n"
" cmovne %5,%2,%1\n"
" cmovge %2,%3,%1\n"
" stq_c %1,%4\n"
" beq %1,3f\n"
"2:\n"
".subsection 2\n"
"3: br 1b\n"
".previous"
: "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(tmp3), "=m"(*sem)
: "r"(signal_pending(tsk)), "r"(-EINTR),
"r"(0xffffffff00000000));
return ret;
}
/*
* waking_non_zero_trylock is unused. we do everything in
* down_trylock and let non-ll/sc hosts bounce around.
*/
static inline int
waking_non_zero_trylock(struct semaphore *sem)
{
return 0;
}
#endif
This diff is collapsed.
......@@ -80,7 +80,7 @@ static inline void spin_lock(spinlock_t * lock)
" blbs %0,2b\n"
" br 1b\n"
".previous"
: "=r" (tmp), "=m" (lock->lock)
: "=&r" (tmp), "=m" (lock->lock)
: "m"(lock->lock) : "memory");
}
......
This diff is collapsed.
#include <asm-generic/xor.h>
/*
* include/asm-generic/xor.h
*
* Generic optimized RAID-5 checksumming functions.
*
* 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, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* (for example /usr/src/linux/COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
static void
xor_8regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
{
long lines = bytes / (sizeof (long)) / 8;
do {
p1[0] ^= p2[0];
p1[1] ^= p2[1];
p1[2] ^= p2[2];
p1[3] ^= p2[3];
p1[4] ^= p2[4];
p1[5] ^= p2[5];
p1[6] ^= p2[6];
p1[7] ^= p2[7];
p1 += 8;
p2 += 8;
} while (--lines > 0);
}
static void
xor_8regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3)
{
long lines = bytes / (sizeof (long)) / 8;
do {
p1[0] ^= p2[0] ^ p3[0];
p1[1] ^= p2[1] ^ p3[1];
p1[2] ^= p2[2] ^ p3[2];
p1[3] ^= p2[3] ^ p3[3];
p1[4] ^= p2[4] ^ p3[4];
p1[5] ^= p2[5] ^ p3[5];
p1[6] ^= p2[6] ^ p3[6];
p1[7] ^= p2[7] ^ p3[7];
p1 += 8;
p2 += 8;
p3 += 8;
} while (--lines > 0);
}
static void
xor_8regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3, unsigned long *p4)
{
long lines = bytes / (sizeof (long)) / 8;
do {
p1[0] ^= p2[0] ^ p3[0] ^ p4[0];
p1[1] ^= p2[1] ^ p3[1] ^ p4[1];
p1[2] ^= p2[2] ^ p3[2] ^ p4[2];
p1[3] ^= p2[3] ^ p3[3] ^ p4[3];
p1[4] ^= p2[4] ^ p3[4] ^ p4[4];
p1[5] ^= p2[5] ^ p3[5] ^ p4[5];
p1[6] ^= p2[6] ^ p3[6] ^ p4[6];
p1[7] ^= p2[7] ^ p3[7] ^ p4[7];
p1 += 8;
p2 += 8;
p3 += 8;
p4 += 8;
} while (--lines > 0);
}
static void
xor_8regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3, unsigned long *p4, unsigned long *p5)
{
long lines = bytes / (sizeof (long)) / 8;
do {
p1[0] ^= p2[0] ^ p3[0] ^ p4[0] ^ p5[0];
p1[1] ^= p2[1] ^ p3[1] ^ p4[1] ^ p5[1];
p1[2] ^= p2[2] ^ p3[2] ^ p4[2] ^ p5[2];
p1[3] ^= p2[3] ^ p3[3] ^ p4[3] ^ p5[3];
p1[4] ^= p2[4] ^ p3[4] ^ p4[4] ^ p5[4];
p1[5] ^= p2[5] ^ p3[5] ^ p4[5] ^ p5[5];
p1[6] ^= p2[6] ^ p3[6] ^ p4[6] ^ p5[6];
p1[7] ^= p2[7] ^ p3[7] ^ p4[7] ^ p5[7];
p1 += 8;
p2 += 8;
p3 += 8;
p4 += 8;
p5 += 8;
} while (--lines > 0);
}
static void
xor_32regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
{
long lines = bytes / (sizeof (long)) / 8;
do {
register long d0, d1, d2, d3, d4, d5, d6, d7;
d0 = p1[0]; /* Pull the stuff into registers */
d1 = p1[1]; /* ... in bursts, if possible. */
d2 = p1[2];
d3 = p1[3];
d4 = p1[4];
d5 = p1[5];
d6 = p1[6];
d7 = p1[7];
d0 ^= p2[0];
d1 ^= p2[1];
d2 ^= p2[2];
d3 ^= p2[3];
d4 ^= p2[4];
d5 ^= p2[5];
d6 ^= p2[6];
d7 ^= p2[7];
p1[0] = d0; /* Store the result (in burts) */
p1[1] = d1;
p1[2] = d2;
p1[3] = d3;
p1[4] = d4;
p1[5] = d5;
p1[6] = d6;
p1[7] = d7;
p1 += 8;
p2 += 8;
} while (--lines > 0);
}
static void
xor_32regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3)
{
long lines = bytes / (sizeof (long)) / 8;
do {
register long d0, d1, d2, d3, d4, d5, d6, d7;
d0 = p1[0]; /* Pull the stuff into registers */
d1 = p1[1]; /* ... in bursts, if possible. */
d2 = p1[2];
d3 = p1[3];
d4 = p1[4];
d5 = p1[5];
d6 = p1[6];
d7 = p1[7];
d0 ^= p2[0];
d1 ^= p2[1];
d2 ^= p2[2];
d3 ^= p2[3];
d4 ^= p2[4];
d5 ^= p2[5];
d6 ^= p2[6];
d7 ^= p2[7];
d0 ^= p3[0];
d1 ^= p3[1];
d2 ^= p3[2];
d3 ^= p3[3];
d4 ^= p3[4];
d5 ^= p3[5];
d6 ^= p3[6];
d7 ^= p3[7];
p1[0] = d0; /* Store the result (in burts) */
p1[1] = d1;
p1[2] = d2;
p1[3] = d3;
p1[4] = d4;
p1[5] = d5;
p1[6] = d6;
p1[7] = d7;
p1 += 8;
p2 += 8;
p3 += 8;
} while (--lines > 0);
}
static void
xor_32regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3, unsigned long *p4)
{
long lines = bytes / (sizeof (long)) / 8;
do {
register long d0, d1, d2, d3, d4, d5, d6, d7;
d0 = p1[0]; /* Pull the stuff into registers */
d1 = p1[1]; /* ... in bursts, if possible. */
d2 = p1[2];
d3 = p1[3];
d4 = p1[4];
d5 = p1[5];
d6 = p1[6];
d7 = p1[7];
d0 ^= p2[0];
d1 ^= p2[1];
d2 ^= p2[2];
d3 ^= p2[3];
d4 ^= p2[4];
d5 ^= p2[5];
d6 ^= p2[6];
d7 ^= p2[7];
d0 ^= p3[0];
d1 ^= p3[1];
d2 ^= p3[2];
d3 ^= p3[3];
d4 ^= p3[4];
d5 ^= p3[5];
d6 ^= p3[6];
d7 ^= p3[7];
d0 ^= p4[0];
d1 ^= p4[1];
d2 ^= p4[2];
d3 ^= p4[3];
d4 ^= p4[4];
d5 ^= p4[5];
d6 ^= p4[6];
d7 ^= p4[7];
p1[0] = d0; /* Store the result (in burts) */
p1[1] = d1;
p1[2] = d2;
p1[3] = d3;
p1[4] = d4;
p1[5] = d5;
p1[6] = d6;
p1[7] = d7;
p1 += 8;
p2 += 8;
p3 += 8;
p4 += 8;
} while (--lines > 0);
}
static void
xor_32regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
unsigned long *p3, unsigned long *p4, unsigned long *p5)
{
long lines = bytes / (sizeof (long)) / 8;
do {
register long d0, d1, d2, d3, d4, d5, d6, d7;
d0 = p1[0]; /* Pull the stuff into registers */
d1 = p1[1]; /* ... in bursts, if possible. */
d2 = p1[2];
d3 = p1[3];
d4 = p1[4];
d5 = p1[5];
d6 = p1[6];
d7 = p1[7];
d0 ^= p2[0];
d1 ^= p2[1];
d2 ^= p2[2];
d3 ^= p2[3];
d4 ^= p2[4];
d5 ^= p2[5];
d6 ^= p2[6];
d7 ^= p2[7];
d0 ^= p3[0];
d1 ^= p3[1];
d2 ^= p3[2];
d3 ^= p3[3];
d4 ^= p3[4];
d5 ^= p3[5];
d6 ^= p3[6];
d7 ^= p3[7];
d0 ^= p4[0];
d1 ^= p4[1];
d2 ^= p4[2];
d3 ^= p4[3];
d4 ^= p4[4];
d5 ^= p4[5];
d6 ^= p4[6];
d7 ^= p4[7];
d0 ^= p5[0];
d1 ^= p5[1];
d2 ^= p5[2];
d3 ^= p5[3];
d4 ^= p5[4];
d5 ^= p5[5];
d6 ^= p5[6];
d7 ^= p5[7];
p1[0] = d0; /* Store the result (in burts) */
p1[1] = d1;
p1[2] = d2;
p1[3] = d3;
p1[4] = d4;
p1[5] = d5;
p1[6] = d6;
p1[7] = d7;
p1 += 8;
p2 += 8;
p3 += 8;
p4 += 8;
p5 += 8;
} while (--lines > 0);
}
static struct xor_block_template xor_block_8regs = {
name: "8regs",
do_2: xor_8regs_2,
do_3: xor_8regs_3,
do_4: xor_8regs_4,
do_5: xor_8regs_5,
};
static struct xor_block_template xor_block_32regs = {
name: "32regs",
do_2: xor_32regs_2,
do_3: xor_32regs_3,
do_4: xor_32regs_4,
do_5: xor_32regs_5,
};
#define XOR_TRY_TEMPLATES \
do { \
xor_speed(&xor_block_8regs); \
xor_speed(&xor_block_32regs); \
} while (0)
This diff is collapsed.
This diff is collapsed.
#include <asm-generic/xor.h>
#include <asm-generic/xor.h>
#include <asm-generic/xor.h>
#include <asm-generic/xor.h>
#include <asm-generic/xor.h>
#include <asm-generic/xor.h>
This diff is collapsed.
This diff is collapsed.
......@@ -73,7 +73,7 @@ extern struct kernel_param __setup_start, __setup_end;
* Mark functions and data as being only used at initialization
* or exit time.
*/
#define __init __attribute__ ((__section__ (".text.init")))
#define __init /* __attribute__ ((__section__ (".text.init"))) */
#define __exit __attribute__ ((unused, __section__(".text.exit")))
#define __initdata __attribute__ ((__section__ (".data.init")))
#define __exitdata __attribute__ ((unused, __section__ (".data.exit")))
......
......@@ -3,10 +3,21 @@
#include <linux/raid/md.h>
#define MAX_XOR_BLOCKS 4
#define MAX_XOR_BLOCKS 5
extern void calibrate_xor_block(void);
extern void (*xor_block)(unsigned int count,
struct buffer_head **bh_ptr);
extern void xor_block(unsigned int count, struct buffer_head **bh_ptr);
struct xor_block_template {
struct xor_block_template *next;
const char *name;
int speed;
void (*do_2)(unsigned long, unsigned long *, unsigned long *);
void (*do_3)(unsigned long, unsigned long *, unsigned long *,
unsigned long *);
void (*do_4)(unsigned long, unsigned long *, unsigned long *,
unsigned long *, unsigned long *);
void (*do_5)(unsigned long, unsigned long *, unsigned long *,
unsigned long *, unsigned long *, unsigned long *);
};
#endif
......@@ -486,10 +486,6 @@ EXPORT_SYMBOL(remove_inode_hash);
EXPORT_SYMBOL(make_bad_inode);
EXPORT_SYMBOL(is_bad_inode);
EXPORT_SYMBOL(event);
EXPORT_SYMBOL(__down);
EXPORT_SYMBOL(__down_interruptible);
EXPORT_SYMBOL(__down_trylock);
EXPORT_SYMBOL(__up);
EXPORT_SYMBOL(brw_page);
#ifdef CONFIG_UID16
......
......@@ -432,16 +432,28 @@ static inline void __schedule_tail(struct task_struct *prev)
#ifdef CONFIG_SMP
int policy;
/*
* prev->policy can be written from here only before `prev'
* can be scheduled (before setting prev->has_cpu to zero).
* Of course it must also be read before allowing prev
* to be rescheduled, but since the write depends on the read
* to complete, wmb() is enough. (the spin_lock() acquired
* before setting has_cpu is not enough because the spin_lock()
* common code semantics allows code outside the critical section
* to enter inside the critical section)
*/
policy = prev->policy;
prev->policy = policy & ~SCHED_YIELD;
wmb();
/*
* fast path falls through. We have to clear has_cpu before
* checking prev->state to avoid a wakeup race - thus we
* also have to protect against the task exiting early.
*/
task_lock(prev);
policy = prev->policy;
prev->policy = policy & ~SCHED_YIELD;
prev->has_cpu = 0;
wmb();
mb();
if (prev->state == TASK_RUNNING)
goto needs_resched;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment