Commit 52c785da authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.6-rmk

into ppc970.osdl.org:/home/torvalds/v2.5/linux
parents 2cc49b50 e3439af1
...@@ -288,39 +288,6 @@ config FORCE_MAX_ZONEORDER ...@@ -288,39 +288,6 @@ config FORCE_MAX_ZONEORDER
int int
default "18" default "18"
choice
prompt "Huge TLB page size"
depends on HUGETLB_PAGE
default HUGETLB_PAGE_SIZE_16MB
config HUGETLB_PAGE_SIZE_4GB
depends on MCKINLEY
bool "4GB"
config HUGETLB_PAGE_SIZE_1GB
depends on MCKINLEY
bool "1GB"
config HUGETLB_PAGE_SIZE_256MB
bool "256MB"
config HUGETLB_PAGE_SIZE_64MB
bool "64MB"
config HUGETLB_PAGE_SIZE_16MB
bool "16MB"
config HUGETLB_PAGE_SIZE_4MB
bool "4MB"
config HUGETLB_PAGE_SIZE_1MB
bool "1MB"
config HUGETLB_PAGE_SIZE_256KB
bool "256KB"
endchoice
config IA64_PAL_IDLE config IA64_PAL_IDLE
bool "Use PAL_HALT_LIGHT in idle loop" bool "Use PAL_HALT_LIGHT in idle loop"
help help
......
...@@ -816,6 +816,19 @@ GLOBAL_ENTRY(ia64_delay_loop) ...@@ -816,6 +816,19 @@ GLOBAL_ENTRY(ia64_delay_loop)
br.ret.sptk.many rp br.ret.sptk.many rp
END(ia64_delay_loop) END(ia64_delay_loop)
GLOBAL_ENTRY(ia64_invoke_kernel_thread_helper)
.prologue
.save rp, r0 // this is the end of the call-chain
.body
alloc r2 = ar.pfs, 0, 0, 2, 0
mov out0 = r9
mov out1 = r11;;
br.call.sptk.many rp = kernel_thread_helper;;
mov out0 = r8
br.call.sptk.many rp = sys_exit;;
1: br.sptk.few 1b // not reached
END(ia64_invoke_kernel_thread_helper)
#ifdef CONFIG_IA64_BRL_EMU #ifdef CONFIG_IA64_BRL_EMU
/* /*
......
...@@ -103,6 +103,7 @@ static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED; ...@@ -103,6 +103,7 @@ static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
static struct iosapic_intr_info { static struct iosapic_intr_info {
char *addr; /* base address of IOSAPIC */ char *addr; /* base address of IOSAPIC */
u32 low32; /* current value of low word of Redirection table entry */
unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */
char rte_index; /* IOSAPIC RTE index (-1 => not an IOSAPIC interrupt) */ char rte_index; /* IOSAPIC RTE index (-1 => not an IOSAPIC interrupt) */
unsigned char dmode : 3; /* delivery mode (see iosapic.h) */ unsigned char dmode : 3; /* delivery mode (see iosapic.h) */
...@@ -213,6 +214,7 @@ set_rte (unsigned int vector, unsigned int dest) ...@@ -213,6 +214,7 @@ set_rte (unsigned int vector, unsigned int dest)
writel(high32, addr + IOSAPIC_WINDOW); writel(high32, addr + IOSAPIC_WINDOW);
writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
writel(low32, addr + IOSAPIC_WINDOW); writel(low32, addr + IOSAPIC_WINDOW);
iosapic_intr_info[vector].low32 = low32;
} }
static void static void
...@@ -239,9 +241,10 @@ mask_irq (unsigned int irq) ...@@ -239,9 +241,10 @@ mask_irq (unsigned int irq)
spin_lock_irqsave(&iosapic_lock, flags); spin_lock_irqsave(&iosapic_lock, flags);
{ {
writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
low32 = readl(addr + IOSAPIC_WINDOW);
low32 |= (1 << IOSAPIC_MASK_SHIFT); /* set only the mask bit */ /* set only the mask bit */
low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK;
writel(low32, addr + IOSAPIC_WINDOW); writel(low32, addr + IOSAPIC_WINDOW);
} }
spin_unlock_irqrestore(&iosapic_lock, flags); spin_unlock_irqrestore(&iosapic_lock, flags);
...@@ -264,9 +267,7 @@ unmask_irq (unsigned int irq) ...@@ -264,9 +267,7 @@ unmask_irq (unsigned int irq)
spin_lock_irqsave(&iosapic_lock, flags); spin_lock_irqsave(&iosapic_lock, flags);
{ {
writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
low32 = readl(addr + IOSAPIC_WINDOW); low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK;
low32 &= ~(1 << IOSAPIC_MASK_SHIFT); /* clear only the mask bit */
writel(low32, addr + IOSAPIC_WINDOW); writel(low32, addr + IOSAPIC_WINDOW);
} }
spin_unlock_irqrestore(&iosapic_lock, flags); spin_unlock_irqrestore(&iosapic_lock, flags);
...@@ -307,9 +308,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask) ...@@ -307,9 +308,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
{ {
/* get current delivery mode by reading the low32 */ /* get current delivery mode by reading the low32 */
writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
low32 = readl(addr + IOSAPIC_WINDOW); low32 = iosapic_intr_info[vec].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT);
low32 &= ~(7 << IOSAPIC_DELIVERY_SHIFT);
if (redir) if (redir)
/* change delivery mode to lowest priority */ /* change delivery mode to lowest priority */
low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT); low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT);
...@@ -317,6 +316,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask) ...@@ -317,6 +316,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
/* change delivery mode to fixed */ /* change delivery mode to fixed */
low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
iosapic_intr_info[vec].low32 = low32;
writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT); writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
writel(high32, addr + IOSAPIC_WINDOW); writel(high32, addr + IOSAPIC_WINDOW);
writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT); writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
......
...@@ -455,7 +455,6 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs) ...@@ -455,7 +455,6 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
unsigned int status; unsigned int status;
int cpu; int cpu;
irq_enter();
cpu = smp_processor_id(); /* for CONFIG_PREEMPT, this must come after irq_enter()! */ cpu = smp_processor_id(); /* for CONFIG_PREEMPT, this must come after irq_enter()! */
kstat_cpu(cpu).irqs[irq]++; kstat_cpu(cpu).irqs[irq]++;
...@@ -525,7 +524,6 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs) ...@@ -525,7 +524,6 @@ unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs)
desc->handler->end(irq); desc->handler->end(irq);
spin_unlock(&desc->lock); spin_unlock(&desc->lock);
} }
irq_exit();
return 1; return 1;
} }
......
...@@ -120,6 +120,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) ...@@ -120,6 +120,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
* 16 (without this, it would be ~240, which could easily lead * 16 (without this, it would be ~240, which could easily lead
* to kernel stack overflows). * to kernel stack overflows).
*/ */
irq_enter();
saved_tpr = ia64_getreg(_IA64_REG_CR_TPR); saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
ia64_srlz_d(); ia64_srlz_d();
while (vector != IA64_SPURIOUS_INT_VECTOR) { while (vector != IA64_SPURIOUS_INT_VECTOR) {
...@@ -143,8 +144,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) ...@@ -143,8 +144,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
* handler needs to be able to wait for further keyboard interrupts, which can't * handler needs to be able to wait for further keyboard interrupts, which can't
* come through until ia64_eoi() has been done. * come through until ia64_eoi() has been done.
*/ */
if (local_softirq_pending()) irq_exit();
do_softirq();
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
......
...@@ -118,10 +118,11 @@ ENTRY(vhpt_miss) ...@@ -118,10 +118,11 @@ ENTRY(vhpt_miss)
#ifdef CONFIG_HUGETLB_PAGE #ifdef CONFIG_HUGETLB_PAGE
extr.u r26=r25,2,6 extr.u r26=r25,2,6
;; ;;
cmp.eq p8,p0=HPAGE_SHIFT,r26 cmp.ne p8,p0=r18,r26
sub r27=r26,r18
;; ;;
(p8) dep r25=r18,r25,2,6 (p8) dep r25=r18,r25,2,6
(p8) shr r22=r22,HPAGE_SHIFT-PAGE_SHIFT (p8) shr r22=r22,r27
#endif #endif
;; ;;
cmp.eq p6,p7=5,r17 // is IFA pointing into to region 5? cmp.eq p6,p7=5,r17 // is IFA pointing into to region 5?
......
This diff is collapsed.
...@@ -178,6 +178,7 @@ default_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct ...@@ -178,6 +178,7 @@ default_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct
ent->tstamp = stamp; ent->tstamp = stamp;
ent->cpu = smp_processor_id(); ent->cpu = smp_processor_id();
ent->set = arg->active_set; ent->set = arg->active_set;
ent->tgid = current->tgid;
/* /*
* selectively store PMDs in increasing index number * selectively store PMDs in increasing index number
......
...@@ -259,10 +259,12 @@ ia64_load_extra (struct task_struct *task) ...@@ -259,10 +259,12 @@ ia64_load_extra (struct task_struct *task)
* *
* We get here through the following call chain: * We get here through the following call chain:
* *
* <clone syscall> * from user-level: from kernel:
* sys_clone *
* do_fork * <clone syscall> <some kernel call frames>
* copy_thread * sys_clone :
* do_fork do_fork
* copy_thread copy_thread
* *
* This means that the stack layout is as follows: * This means that the stack layout is as follows:
* *
...@@ -276,9 +278,6 @@ ia64_load_extra (struct task_struct *task) ...@@ -276,9 +278,6 @@ ia64_load_extra (struct task_struct *task)
* | | <-- sp (lowest addr) * | | <-- sp (lowest addr)
* +---------------------+ * +---------------------+
* *
* Note: if we get called through kernel_thread() then the memory above "(highest addr)"
* is valid kernel stack memory that needs to be copied as well.
*
* Observe that we copy the unat values that are in pt_regs and switch_stack. Spilling an * Observe that we copy the unat values that are in pt_regs and switch_stack. Spilling an
* integer to address X causes bit N in ar.unat to be set to the NaT bit of the register, * integer to address X causes bit N in ar.unat to be set to the NaT bit of the register,
* with N=(X & 0x1ff)/8. Thus, copying the unat value preserves the NaT bits ONLY if the * with N=(X & 0x1ff)/8. Thus, copying the unat value preserves the NaT bits ONLY if the
...@@ -291,9 +290,9 @@ copy_thread (int nr, unsigned long clone_flags, ...@@ -291,9 +290,9 @@ copy_thread (int nr, unsigned long clone_flags,
unsigned long user_stack_base, unsigned long user_stack_size, unsigned long user_stack_base, unsigned long user_stack_size,
struct task_struct *p, struct pt_regs *regs) struct task_struct *p, struct pt_regs *regs)
{ {
unsigned long rbs, child_rbs, rbs_size, stack_offset, stack_top, stack_used;
struct switch_stack *child_stack, *stack;
extern char ia64_ret_from_clone, ia32_ret_from_clone; extern char ia64_ret_from_clone, ia32_ret_from_clone;
struct switch_stack *child_stack, *stack;
unsigned long rbs, child_rbs, rbs_size;
struct pt_regs *child_ptregs; struct pt_regs *child_ptregs;
int retval = 0; int retval = 0;
...@@ -306,16 +305,13 @@ copy_thread (int nr, unsigned long clone_flags, ...@@ -306,16 +305,13 @@ copy_thread (int nr, unsigned long clone_flags,
return 0; return 0;
#endif #endif
stack_top = (unsigned long) current + IA64_STK_OFFSET;
stack = ((struct switch_stack *) regs) - 1; stack = ((struct switch_stack *) regs) - 1;
stack_used = stack_top - (unsigned long) stack;
stack_offset = IA64_STK_OFFSET - stack_used;
child_stack = (struct switch_stack *) ((unsigned long) p + stack_offset); child_ptregs = (struct pt_regs *) ((unsigned long) p + IA64_STK_OFFSET) - 1;
child_ptregs = (struct pt_regs *) (child_stack + 1); child_stack = (struct switch_stack *) child_ptregs - 1;
/* copy parent's switch_stack & pt_regs to child: */ /* copy parent's switch_stack & pt_regs to child: */
memcpy(child_stack, stack, stack_used); memcpy(child_stack, stack, sizeof(*child_ptregs) + sizeof(*child_stack));
rbs = (unsigned long) current + IA64_RBS_OFFSET; rbs = (unsigned long) current + IA64_RBS_OFFSET;
child_rbs = (unsigned long) p + IA64_RBS_OFFSET; child_rbs = (unsigned long) p + IA64_RBS_OFFSET;
...@@ -324,7 +320,7 @@ copy_thread (int nr, unsigned long clone_flags, ...@@ -324,7 +320,7 @@ copy_thread (int nr, unsigned long clone_flags,
/* copy the parent's register backing store to the child: */ /* copy the parent's register backing store to the child: */
memcpy((void *) child_rbs, (void *) rbs, rbs_size); memcpy((void *) child_rbs, (void *) rbs, rbs_size);
if (user_mode(child_ptregs)) { if (likely(user_mode(child_ptregs))) {
if ((clone_flags & CLONE_SETTLS) && !IS_IA32_PROCESS(regs)) if ((clone_flags & CLONE_SETTLS) && !IS_IA32_PROCESS(regs))
child_ptregs->r13 = regs->r16; /* see sys_clone2() in entry.S */ child_ptregs->r13 = regs->r16; /* see sys_clone2() in entry.S */
if (user_stack_base) { if (user_stack_base) {
...@@ -341,14 +337,14 @@ copy_thread (int nr, unsigned long clone_flags, ...@@ -341,14 +337,14 @@ copy_thread (int nr, unsigned long clone_flags,
* been taken care of by the caller of sys_clone() * been taken care of by the caller of sys_clone()
* already. * already.
*/ */
child_ptregs->r12 = (unsigned long) (child_ptregs + 1); /* kernel sp */ child_ptregs->r12 = (unsigned long) child_ptregs - 16; /* kernel sp */
child_ptregs->r13 = (unsigned long) p; /* set `current' pointer */ child_ptregs->r13 = (unsigned long) p; /* set `current' pointer */
} }
child_stack->ar_bspstore = child_rbs + rbs_size;
if (IS_IA32_PROCESS(regs)) if (IS_IA32_PROCESS(regs))
child_stack->b0 = (unsigned long) &ia32_ret_from_clone; child_stack->b0 = (unsigned long) &ia32_ret_from_clone;
else else
child_stack->b0 = (unsigned long) &ia64_ret_from_clone; child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
child_stack->ar_bspstore = child_rbs + rbs_size;
/* copy parts of thread_struct: */ /* copy parts of thread_struct: */
p->thread.ksp = (unsigned long) child_stack - 16; p->thread.ksp = (unsigned long) child_stack - 16;
...@@ -358,8 +354,8 @@ copy_thread (int nr, unsigned long clone_flags, ...@@ -358,8 +354,8 @@ copy_thread (int nr, unsigned long clone_flags,
* therefore we must specify them explicitly here and not include them in * therefore we must specify them explicitly here and not include them in
* IA64_PSR_BITS_TO_CLEAR. * IA64_PSR_BITS_TO_CLEAR.
*/ */
child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET) child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
& ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP)); & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP));
/* /*
* NOTE: The calling convention considers all floating point * NOTE: The calling convention considers all floating point
...@@ -578,27 +574,43 @@ ia64_set_personality (struct elf64_hdr *elf_ex, int ibcs2_interpreter) ...@@ -578,27 +574,43 @@ ia64_set_personality (struct elf64_hdr *elf_ex, int ibcs2_interpreter)
pid_t pid_t
kernel_thread (int (*fn)(void *), void *arg, unsigned long flags) kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
{ {
struct task_struct *parent = current; extern void ia64_invoke_kernel_thread_helper (void);
int result; unsigned long *helper_fptr = (unsigned long *) &ia64_invoke_kernel_thread_helper;
pid_t tid; struct {
struct switch_stack sw;
struct pt_regs pt;
} regs;
memset(&regs, 0, sizeof(regs));
regs.pt.cr_iip = helper_fptr[0]; /* set entry point (IP) */
regs.pt.r1 = helper_fptr[1]; /* set GP */
regs.pt.r9 = (unsigned long) fn; /* 1st argument */
regs.pt.r11 = (unsigned long) arg; /* 2nd argument */
/* Preserve PSR bits, except for bits 32-34 and 37-45, which we can't read. */
regs.pt.cr_ipsr = ia64_getreg(_IA64_REG_PSR) | IA64_PSR_BN;
regs.pt.cr_ifs = 1UL << 63; /* mark as valid, empty frame */
regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR);
regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET;
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs.pt, 0, NULL, NULL);
}
EXPORT_SYMBOL(kernel_thread);
tid = clone(flags | CLONE_VM | CLONE_UNTRACED, 0); /* This gets called from kernel_thread() via ia64_invoke_thread_helper(). */
if (parent != current) { int
kernel_thread_helper (int (*fn)(void *), void *arg)
{
#ifdef CONFIG_IA32_SUPPORT #ifdef CONFIG_IA32_SUPPORT
if (IS_IA32_PROCESS(ia64_task_regs(current))) { if (IS_IA32_PROCESS(ia64_task_regs(current))) {
/* A kernel thread is always a 64-bit process. */ /* A kernel thread is always a 64-bit process. */
current->thread.map_base = DEFAULT_MAP_BASE; current->thread.map_base = DEFAULT_MAP_BASE;
current->thread.task_size = DEFAULT_TASK_SIZE; current->thread.task_size = DEFAULT_TASK_SIZE;
ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob); ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1); ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);
}
#endif
result = (*fn)(arg);
_exit(result);
} }
return tid; #endif
return (*fn)(arg);
} }
EXPORT_SYMBOL(kernel_thread);
/* /*
* Flush thread state. This is called when a thread does an execve(). * Flush thread state. This is called when a thread does an execve().
......
/* /*
* IA-64 Huge TLB Page Support for Kernel. * IA-64 Huge TLB Page Support for Kernel.
* *
* Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com> * Copyright (C) 2002-2004 Rohit Seth <rohit.seth@intel.com>
* Copyright (C) 2003-2004 Ken Chen <kenneth.w.chen@intel.com>
*
* Sep, 2003: add numa support
* Feb, 2004: dynamic hugetlb page size via boot parameter
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -18,11 +22,10 @@ ...@@ -18,11 +22,10 @@
#include <asm/tlb.h> #include <asm/tlb.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#define TASK_HPAGE_BASE (REGION_HPAGE << REGION_SHIFT)
static long htlbpagemem; static long htlbpagemem;
int htlbpage_max; int htlbpage_max;
static long htlbzone_pages; static long htlbzone_pages;
unsigned int hpage_shift=HPAGE_SHIFT_DEFAULT;
static struct list_head hugepage_freelists[MAX_NUMNODES]; static struct list_head hugepage_freelists[MAX_NUMNODES];
static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED; static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED;
...@@ -407,7 +410,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, u ...@@ -407,7 +410,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, u
return -EINVAL; return -EINVAL;
/* This code assumes that REGION_HPAGE != 0. */ /* This code assumes that REGION_HPAGE != 0. */
if ((REGION_NUMBER(addr) != REGION_HPAGE) || (addr & (HPAGE_SIZE - 1))) if ((REGION_NUMBER(addr) != REGION_HPAGE) || (addr & (HPAGE_SIZE - 1)))
addr = TASK_HPAGE_BASE; addr = HPAGE_REGION_BASE;
else else
addr = ALIGN(addr, HPAGE_SIZE); addr = ALIGN(addr, HPAGE_SIZE);
for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
...@@ -520,6 +523,35 @@ static int __init hugetlb_setup(char *s) ...@@ -520,6 +523,35 @@ static int __init hugetlb_setup(char *s)
} }
__setup("hugepages=", hugetlb_setup); __setup("hugepages=", hugetlb_setup);
static int __init hugetlb_setup_sz(char *str)
{
u64 tr_pages;
unsigned long long size;
if (ia64_pal_vm_page_size(&tr_pages, NULL) != 0)
/*
* shouldn't happen, but just in case.
*/
tr_pages = 0x15557000UL;
size = memparse(str, &str);
if (*str || (size & (size-1)) || !(tr_pages & size) ||
size <= PAGE_SIZE ||
size >= (1UL << PAGE_SHIFT << MAX_ORDER)) {
printk(KERN_WARNING "Invalid huge page size specified\n");
return 1;
}
hpage_shift = __ffs(size);
/*
* boot cpu already executed ia64_mmu_init, and has HPAGE_SHIFT_DEFAULT
* override here with new page shift.
*/
ia64_set_rr(HPAGE_REGION_BASE, hpage_shift << 2);
return 1;
}
__setup("hugepagesz=", hugetlb_setup_sz);
static int __init hugetlb_init(void) static int __init hugetlb_init(void)
{ {
int i; int i;
...@@ -540,7 +572,7 @@ static int __init hugetlb_init(void) ...@@ -540,7 +572,7 @@ static int __init hugetlb_init(void)
printk("Total HugeTLB memory allocated, %ld\n", htlbpagemem); printk("Total HugeTLB memory allocated, %ld\n", htlbpagemem);
return 0; return 0;
} }
module_init(hugetlb_init); __initcall(hugetlb_init);
int hugetlb_report_meminfo(char *buf) int hugetlb_report_meminfo(char *buf)
{ {
......
...@@ -342,6 +342,10 @@ ia64_mmu_init (void *my_cpu_data) ...@@ -342,6 +342,10 @@ ia64_mmu_init (void *my_cpu_data)
ia64_tlb_init(); ia64_tlb_init();
#ifdef CONFIG_HUGETLB_PAGE
ia64_set_rr(HPAGE_REGION_BASE, HPAGE_SHIFT << 2);
#endif
#ifdef CONFIG_IA64_MCA #ifdef CONFIG_IA64_MCA
cpu = smp_processor_id(); cpu = smp_processor_id();
......
...@@ -546,7 +546,7 @@ prom_initialize_lmb(unsigned long mem) ...@@ -546,7 +546,7 @@ prom_initialize_lmb(unsigned long mem)
opt++; opt++;
if (!strncmp(opt, RELOC("off"), 3)) if (!strncmp(opt, RELOC("off"), 3))
nodart = 1; nodart = 1;
else if (!strncmp(opt, RELOC("on"), 2)) else if (!strncmp(opt, RELOC("force"), 5))
RELOC(dart_force_on) = 1; RELOC(dart_force_on) = 1;
} }
#else #else
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#define DBGENTER() pr_debug("%s entered\n", __FUNCTION__) #define DBGENTER() pr_debug("%s entered\n", __FUNCTION__)
extern struct subsystem devices_subsys; /* needed for vio_find_name() */
struct iommu_table *vio_build_iommu_table(struct vio_dev *dev); struct iommu_table *vio_build_iommu_table(struct vio_dev *dev);
static int vio_num_address_cells; static int vio_num_address_cells;
...@@ -157,8 +159,7 @@ static int __init vio_bus_init(void) ...@@ -157,8 +159,7 @@ static int __init vio_bus_init(void)
node_vroot = find_devices("vdevice"); node_vroot = find_devices("vdevice");
if ((node_vroot == NULL) || (node_vroot->child == NULL)) { if ((node_vroot == NULL) || (node_vroot->child == NULL)) {
printk(KERN_INFO "VIO: missing or empty /vdevice node; no virtual IO" /* this machine doesn't do virtual IO, and that's ok */
" devices present.\n");
return 0; return 0;
} }
...@@ -260,7 +261,7 @@ struct vio_dev * __devinit vio_register_device(struct device_node *of_node) ...@@ -260,7 +261,7 @@ struct vio_dev * __devinit vio_register_device(struct device_node *of_node)
/* init generic 'struct device' fields: */ /* init generic 'struct device' fields: */
viodev->dev.parent = &vio_bus_device->dev; viodev->dev.parent = &vio_bus_device->dev;
viodev->dev.bus = &vio_bus_type; viodev->dev.bus = &vio_bus_type;
snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%lx", viodev->unit_address); snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", viodev->unit_address);
viodev->dev.release = vio_dev_release; viodev->dev.release = vio_dev_release;
/* register with generic device framework */ /* register with generic device framework */
...@@ -299,6 +300,42 @@ const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length) ...@@ -299,6 +300,42 @@ const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length)
} }
EXPORT_SYMBOL(vio_get_attribute); EXPORT_SYMBOL(vio_get_attribute);
/* vio_find_name() - internal because only vio.c knows how we formatted the
* kobject name
* XXX once vio_bus_type.devices is actually used as a kset in
* drivers/base/bus.c, this function should be removed in favor of
* "device_find(kobj_name, &vio_bus_type)"
*/
static struct vio_dev *vio_find_name(const char *kobj_name)
{
struct kobject *found;
found = kset_find_obj(&devices_subsys.kset, kobj_name);
if (!found)
return NULL;
return to_vio_dev(container_of(found, struct device, kobj));
}
/**
* vio_find_node - find an already-registered vio_dev
* @vnode: device_node of the virtual device we're looking for
*/
struct vio_dev *vio_find_node(struct device_node *vnode)
{
uint32_t *unit_address;
char kobj_name[BUS_ID_SIZE];
/* construct the kobject name from the device node */
unit_address = (uint32_t *)get_property(vnode, "reg", NULL);
if (!unit_address)
return NULL;
snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
return vio_find_name(kobj_name);
}
EXPORT_SYMBOL(vio_find_node);
/** /**
* vio_build_iommu_table: - gets the dma information from OF and builds the TCE tree. * vio_build_iommu_table: - gets the dma information from OF and builds the TCE tree.
* @dev: the virtual device. * @dev: the virtual device.
......
...@@ -196,6 +196,7 @@ EXPORT_SYMBOL(die_chain); ...@@ -196,6 +196,7 @@ EXPORT_SYMBOL(die_chain);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
EXPORT_SYMBOL(cpu_sibling_map); EXPORT_SYMBOL(cpu_sibling_map);
EXPORT_SYMBOL(smp_num_siblings);
#endif #endif
extern void do_softirq_thunk(void); extern void do_softirq_thunk(void);
......
...@@ -66,16 +66,16 @@ ...@@ -66,16 +66,16 @@
printk(KERN_INFO "%s: " fmt, __FILE__, ## args) printk(KERN_INFO "%s: " fmt, __FILE__, ## args)
#define ibmveth_error_printk(fmt, args...) \ #define ibmveth_error_printk(fmt, args...) \
printk(KERN_ERR "(%s:%3.3d ua:%lx) ERROR: " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args) printk(KERN_ERR "(%s:%3.3d ua:%x) ERROR: " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args)
#ifdef DEBUG #ifdef DEBUG
#define ibmveth_debug_printk_no_adapter(fmt, args...) \ #define ibmveth_debug_printk_no_adapter(fmt, args...) \
printk(KERN_DEBUG "(%s:%3.3d): " fmt, __FILE__, __LINE__ , ## args) printk(KERN_DEBUG "(%s:%3.3d): " fmt, __FILE__, __LINE__ , ## args)
#define ibmveth_debug_printk(fmt, args...) \ #define ibmveth_debug_printk(fmt, args...) \
printk(KERN_DEBUG "(%s:%3.3d ua:%lx): " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args) printk(KERN_DEBUG "(%s:%3.3d ua:%x): " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args)
#define ibmveth_assert(expr) \ #define ibmveth_assert(expr) \
if(!(expr)) { \ if(!(expr)) { \
printk(KERN_DEBUG "assertion failed (%s:%3.3d ua:%lx): %s\n", __FILE__, __LINE__, adapter->vdev->unit_address, #expr); \ printk(KERN_DEBUG "assertion failed (%s:%3.3d ua:%x): %s\n", __FILE__, __LINE__, adapter->vdev->unit_address, #expr); \
BUG(); \ BUG(); \
} }
#else #else
...@@ -869,7 +869,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ ...@@ -869,7 +869,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
unsigned int *mcastFilterSize_p; unsigned int *mcastFilterSize_p;
ibmveth_debug_printk_no_adapter("entering ibmveth_probe for UA 0x%lx\n", ibmveth_debug_printk_no_adapter("entering ibmveth_probe for UA 0x%x\n",
dev->unit_address); dev->unit_address);
mac_addr_p = (unsigned int *) vio_get_attribute(dev, VETH_MAC_ADDR, 0); mac_addr_p = (unsigned int *) vio_get_attribute(dev, VETH_MAC_ADDR, 0);
...@@ -1014,7 +1014,7 @@ static int ibmveth_seq_show(struct seq_file *seq, void *v) ...@@ -1014,7 +1014,7 @@ static int ibmveth_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version); seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version);
seq_printf(seq, "Unit Address: 0x%lx\n", adapter->vdev->unit_address); seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address);
seq_printf(seq, "LIOBN: 0x%lx\n", adapter->liobn); seq_printf(seq, "LIOBN: 0x%lx\n", adapter->liobn);
seq_printf(seq, "Current MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", seq_printf(seq, "Current MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
current_mac[0], current_mac[1], current_mac[2], current_mac[0], current_mac[1], current_mac[2],
......
...@@ -603,7 +603,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t ...@@ -603,7 +603,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
{ {
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
struct usblp *usblp = file->private_data; struct usblp *usblp = file->private_data;
int timeout, err = 0, transfer_length; int timeout, err = 0, transfer_length = 0;
size_t writecount = 0; size_t writecount = 0;
while (writecount < count) { while (writecount < count) {
...@@ -654,6 +654,16 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t ...@@ -654,6 +654,16 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
continue; continue;
} }
/* We must increment writecount here, and not at the
* end of the loop. Otherwise, the final loop iteration may
* be skipped, leading to incomplete printer output.
*/
writecount += transfer_length;
if (writecount == count) {
up(&usblp->sem);
break;
}
transfer_length=(count - writecount); transfer_length=(count - writecount);
if (transfer_length > USBLP_BUF_SIZE) if (transfer_length > USBLP_BUF_SIZE)
transfer_length = USBLP_BUF_SIZE; transfer_length = USBLP_BUF_SIZE;
...@@ -677,8 +687,6 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t ...@@ -677,8 +687,6 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t
break; break;
} }
up (&usblp->sem); up (&usblp->sem);
writecount += transfer_length;
} }
return count; return count;
......
...@@ -1458,6 +1458,7 @@ static int cdrom_do_generic_command(unsigned int fd, unsigned int cmd, unsigned ...@@ -1458,6 +1458,7 @@ static int cdrom_do_generic_command(unsigned int fd, unsigned int cmd, unsigned
struct cdrom_generic_command *cgc; struct cdrom_generic_command *cgc;
struct cdrom_generic_command32 *cgc32; struct cdrom_generic_command32 *cgc32;
unsigned char dir; unsigned char dir;
int itmp;
cgc = compat_alloc_user_space(sizeof(*cgc)); cgc = compat_alloc_user_space(sizeof(*cgc));
cgc32 = compat_ptr(arg); cgc32 = compat_ptr(arg);
...@@ -1469,12 +1470,16 @@ static int cdrom_do_generic_command(unsigned int fd, unsigned int cmd, unsigned ...@@ -1469,12 +1470,16 @@ static int cdrom_do_generic_command(unsigned int fd, unsigned int cmd, unsigned
__cgc_do_ptr((void **) &cgc->sense, &cgc32->sense)) __cgc_do_ptr((void **) &cgc->sense, &cgc32->sense))
return -EFAULT; return -EFAULT;
if (get_user(dir, &cgc->data_direction) || if (get_user(dir, &cgc32->data_direction) ||
put_user(dir, &cgc32->data_direction)) put_user(dir, &cgc->data_direction))
return -EFAULT; return -EFAULT;
if (copy_in_user(&cgc->quiet, &cgc32->quiet, if (get_user(itmp, &cgc32->quiet) ||
2 * sizeof(int))) put_user(itmp, &cgc->quiet))
return -EFAULT;
if (get_user(itmp, &cgc32->timeout) ||
put_user(itmp, &cgc->timeout))
return -EFAULT; return -EFAULT;
if (__cgc_do_ptr(&cgc->reserved[0], &cgc32->reserved[0])) if (__cgc_do_ptr(&cgc->reserved[0], &cgc32->reserved[0]))
......
...@@ -62,56 +62,28 @@ void hpfs_unlock_inode(struct inode *i) ...@@ -62,56 +62,28 @@ void hpfs_unlock_inode(struct inode *i)
void hpfs_lock_2inodes(struct inode *i1, struct inode *i2) void hpfs_lock_2inodes(struct inode *i1, struct inode *i2)
{ {
struct hpfs_inode_info *hpfs_i1 = NULL, *hpfs_i2 = NULL; if (!i2 || i1 == i2) {
hpfs_lock_inode(i1);
if (!i1) { } else if (!i1) {
if (i2) { hpfs_lock_inode(i2);
hpfs_i2 = hpfs_i(i2); } else {
struct hpfs_inode_info *hpfs_i1 = hpfs_i(i1);
struct hpfs_inode_info *hpfs_i2 = hpfs_i(i2);
if (i1->i_ino < i2->i_ino) {
down(&hpfs_i1->i_sem);
down(&hpfs_i2->i_sem);
} else {
down(&hpfs_i2->i_sem); down(&hpfs_i2->i_sem);
}
return;
}
if (!i2) {
if (i1) {
hpfs_i1 = hpfs_i(i1);
down(&hpfs_i1->i_sem); down(&hpfs_i1->i_sem);
} }
return;
} }
if (i1->i_ino < i2->i_ino) {
down(&hpfs_i1->i_sem);
down(&hpfs_i2->i_sem);
} else if (i1->i_ino > i2->i_ino) {
down(&hpfs_i2->i_sem);
down(&hpfs_i1->i_sem);
} else down(&hpfs_i1->i_sem);
} }
void hpfs_unlock_2inodes(struct inode *i1, struct inode *i2) void hpfs_unlock_2inodes(struct inode *i1, struct inode *i2)
{ {
struct hpfs_inode_info *hpfs_i1 = NULL, *hpfs_i2 = NULL; /* order of up() doesn't matter here */
hpfs_unlock_inode(i1);
if (!i1) { hpfs_unlock_inode(i2);
if (i2) {
hpfs_i2 = hpfs_i(i2);
up(&hpfs_i2->i_sem);
}
return;
}
if (!i2) {
if (i1) {
hpfs_i1 = hpfs_i(i1);
up(&hpfs_i1->i_sem);
}
return;
}
if (i1->i_ino < i2->i_ino) {
up(&hpfs_i2->i_sem);
up(&hpfs_i1->i_sem);
} else if (i1->i_ino > i2->i_ino) {
up(&hpfs_i1->i_sem);
up(&hpfs_i2->i_sem);
} else up(&hpfs_i1->i_sem);
} }
void hpfs_lock_3inodes(struct inode *i1, struct inode *i2, struct inode *i3) void hpfs_lock_3inodes(struct inode *i1, struct inode *i2, struct inode *i3)
......
...@@ -45,9 +45,9 @@ ...@@ -45,9 +45,9 @@
/* /*
* Mask bit * Mask bit
*/ */
#define IOSAPIC_MASK_SHIFT 16 #define IOSAPIC_MASK_SHIFT 16
#define IOSAPIC_UNMASK 0 #define IOSAPIC_MASK (1<<IOSAPIC_MASK_SHIFT)
#define IOSAPIC_MSAK 1
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
......
...@@ -140,8 +140,9 @@ reload_context (mm_context_t context) ...@@ -140,8 +140,9 @@ reload_context (mm_context_t context)
{ {
unsigned long rid; unsigned long rid;
unsigned long rid_incr = 0; unsigned long rid_incr = 0;
unsigned long rr0, rr1, rr2, rr3, rr4; unsigned long rr0, rr1, rr2, rr3, rr4, old_rr4;
old_rr4 = ia64_get_rr(0x8000000000000000);
rid = context << 3; /* make space for encoding the region number */ rid = context << 3; /* make space for encoding the region number */
rid_incr = 1 << 8; rid_incr = 1 << 8;
...@@ -152,7 +153,7 @@ reload_context (mm_context_t context) ...@@ -152,7 +153,7 @@ reload_context (mm_context_t context)
rr3 = rr0 + 3*rid_incr; rr3 = rr0 + 3*rid_incr;
rr4 = rr0 + 4*rid_incr; rr4 = rr0 + 4*rid_incr;
#ifdef CONFIG_HUGETLB_PAGE #ifdef CONFIG_HUGETLB_PAGE
rr4 = (rr4 & (~(0xfcUL))) | (HPAGE_SHIFT << 2); rr4 = (rr4 & (~(0xfcUL))) | (old_rr4 & 0xfc);
#endif #endif
ia64_set_rr(0x0000000000000000, rr0); ia64_set_rr(0x0000000000000000, rr0);
......
...@@ -37,31 +37,14 @@ ...@@ -37,31 +37,14 @@
#define RGN_MAP_LIMIT ((1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE) /* per region addr limit */ #define RGN_MAP_LIMIT ((1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE) /* per region addr limit */
#ifdef CONFIG_HUGETLB_PAGE #ifdef CONFIG_HUGETLB_PAGE
# define REGION_HPAGE (4UL) /* note: this is hardcoded in reload_context()!*/
# define REGION_SHIFT 61
# define HPAGE_REGION_BASE (REGION_HPAGE << REGION_SHIFT)
# define HPAGE_SHIFT hpage_shift
# define HPAGE_SHIFT_DEFAULT 28 /* check ia64 SDM for architecture supported size */
# define HPAGE_SIZE (__IA64_UL_CONST(1) << HPAGE_SHIFT)
# define HPAGE_MASK (~(HPAGE_SIZE - 1))
# if defined(CONFIG_HUGETLB_PAGE_SIZE_4GB)
# define HPAGE_SHIFT 32
# elif defined(CONFIG_HUGETLB_PAGE_SIZE_1GB)
# define HPAGE_SHIFT 30
# elif defined(CONFIG_HUGETLB_PAGE_SIZE_256MB)
# define HPAGE_SHIFT 28
# elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB)
# define HPAGE_SHIFT 26
# elif defined(CONFIG_HUGETLB_PAGE_SIZE_16MB)
# define HPAGE_SHIFT 24
# elif defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
# define HPAGE_SHIFT 22
# elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB)
# define HPAGE_SHIFT 20
# elif defined(CONFIG_HUGETLB_PAGE_SIZE_256KB)
# define HPAGE_SHIFT 18
# else
# error Unsupported IA-64 HugeTLB Page Size!
# endif
# define REGION_HPAGE (4UL) /* note: this is hardcoded in mmu_context.h:reload_context()!*/
# define REGION_SHIFT 61
# define HPAGE_SIZE (__IA64_UL_CONST(1) << HPAGE_SHIFT)
# define HPAGE_MASK (~(HPAGE_SIZE - 1))
# define HAVE_ARCH_HUGETLB_UNMAPPED_AREA # define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
# define ARCH_HAS_HUGEPAGE_ONLY_RANGE # define ARCH_HAS_HUGEPAGE_ONLY_RANGE
#endif /* CONFIG_HUGETLB_PAGE */ #endif /* CONFIG_HUGETLB_PAGE */
...@@ -140,6 +123,7 @@ typedef union ia64_va { ...@@ -140,6 +123,7 @@ typedef union ia64_va {
# define is_hugepage_only_range(addr, len) \ # define is_hugepage_only_range(addr, len) \
(REGION_NUMBER(addr) == REGION_HPAGE && \ (REGION_NUMBER(addr) == REGION_HPAGE && \
REGION_NUMBER((addr)+(len)) == REGION_HPAGE) REGION_NUMBER((addr)+(len)) == REGION_HPAGE)
extern unsigned int hpage_shift;
#endif #endif
static __inline__ int static __inline__ int
......
...@@ -59,7 +59,7 @@ typedef struct { ...@@ -59,7 +59,7 @@ typedef struct {
* last_reset_value member indicates the initial value of the overflowed PMD. * last_reset_value member indicates the initial value of the overflowed PMD.
*/ */
typedef struct { typedef struct {
int pid; /* active process at PMU interrupt point */ int pid; /* thread id (for NPTL, this is gettid()) */
unsigned char reserved1[3]; /* reserved for future use */ unsigned char reserved1[3]; /* reserved for future use */
unsigned char ovfl_pmd; /* index of overflowed PMD */ unsigned char ovfl_pmd; /* index of overflowed PMD */
...@@ -69,7 +69,7 @@ typedef struct { ...@@ -69,7 +69,7 @@ typedef struct {
unsigned short cpu; /* cpu on which the overfow occured */ unsigned short cpu; /* cpu on which the overfow occured */
unsigned short set; /* event set active when overflow ocurred */ unsigned short set; /* event set active when overflow ocurred */
unsigned int reserved2; /* for future use */ int tgid; /* thread group id (for NPTL, this is getpid()) */
} pfm_default_smpl_entry_t; } pfm_default_smpl_entry_t;
#define PFM_DEFAULT_MAX_PMDS 64 /* how many pmds supported by data structures (sizeof(unsigned long) */ #define PFM_DEFAULT_MAX_PMDS 64 /* how many pmds supported by data structures (sizeof(unsigned long) */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define _ASM_IA64_SCATTERLIST_H #define _ASM_IA64_SCATTERLIST_H
/* /*
* Modified 1998-1999, 2001-2002 * Modified 1998-1999, 2001-2002, 2004
* David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
*/ */
...@@ -15,6 +15,14 @@ struct scatterlist { ...@@ -15,6 +15,14 @@ struct scatterlist {
unsigned int dma_length; unsigned int dma_length;
}; };
#define ISA_DMA_THRESHOLD (~0UL) /*
* It used to be that ISA_DMA_THRESHOLD had something to do with the
* DMA-limits of ISA-devices. Nowadays, its only remaining use (apart
* from the aha1542.c driver, which isn't 64-bit clean anyhow) is to
* tell the block-layer (via BLK_BOUNCE_ISA) what the max. physical
* address of a page is that is allocated with GFP_DMA. On IA-64,
* that's 4GB - 1.
*/
#define ISA_DMA_THRESHOLD 0xffffffff
#endif /* _ASM_IA64_SCATTERLIST_H */ #endif /* _ASM_IA64_SCATTERLIST_H */
...@@ -94,8 +94,8 @@ static inline struct vio_driver *to_vio_driver(struct device_driver *drv) ...@@ -94,8 +94,8 @@ static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
struct vio_dev { struct vio_dev {
struct device_node *archdata; /* Open Firmware node */ struct device_node *archdata; /* Open Firmware node */
void *driver_data; /* data private to the driver */ void *driver_data; /* data private to the driver */
unsigned long unit_address;
struct iommu_table *iommu_table; /* vio_map_* uses this */ struct iommu_table *iommu_table; /* vio_map_* uses this */
uint32_t unit_address;
unsigned int irq; unsigned int irq;
struct device dev; struct device dev;
......
...@@ -263,7 +263,10 @@ static __inline__ int tw_del_dead_node(struct tcp_tw_bucket *tw) ...@@ -263,7 +263,10 @@ static __inline__ int tw_del_dead_node(struct tcp_tw_bucket *tw)
#define tw_for_each(tw, node, head) \ #define tw_for_each(tw, node, head) \
hlist_for_each_entry(tw, node, head, tw_node) hlist_for_each_entry(tw, node, head, tw_node)
#define tw_for_each_inmate(tw, node, safe, jail) \ #define tw_for_each_inmate(tw, node, jail) \
hlist_for_each_entry(tw, node, jail, tw_death_node)
#define tw_for_each_inmate_safe(tw, node, safe, jail) \
hlist_for_each_entry_safe(tw, node, safe, jail, tw_death_node) hlist_for_each_entry_safe(tw, node, safe, jail, tw_death_node)
#define tcptw_sk(__sk) ((struct tcp_tw_bucket *)(__sk)) #define tcptw_sk(__sk) ((struct tcp_tw_bucket *)(__sk))
......
...@@ -427,7 +427,7 @@ static u32 twkill_thread_slots; ...@@ -427,7 +427,7 @@ static u32 twkill_thread_slots;
static int tcp_do_twkill_work(int slot, unsigned int quota) static int tcp_do_twkill_work(int slot, unsigned int quota)
{ {
struct tcp_tw_bucket *tw; struct tcp_tw_bucket *tw;
struct hlist_node *node, *safe; struct hlist_node *node;
unsigned int killed; unsigned int killed;
int ret; int ret;
...@@ -439,8 +439,8 @@ static int tcp_do_twkill_work(int slot, unsigned int quota) ...@@ -439,8 +439,8 @@ static int tcp_do_twkill_work(int slot, unsigned int quota)
*/ */
killed = 0; killed = 0;
ret = 0; ret = 0;
tw_for_each_inmate(tw, node, safe, rescan:
&tcp_tw_death_row[slot]) { tw_for_each_inmate(tw, node, &tcp_tw_death_row[slot]) {
__tw_del_dead_node(tw); __tw_del_dead_node(tw);
spin_unlock(&tw_death_lock); spin_unlock(&tw_death_lock);
tcp_timewait_kill(tw); tcp_timewait_kill(tw);
...@@ -451,6 +451,14 @@ static int tcp_do_twkill_work(int slot, unsigned int quota) ...@@ -451,6 +451,14 @@ static int tcp_do_twkill_work(int slot, unsigned int quota)
ret = 1; ret = 1;
break; break;
} }
/* While we dropped tw_death_lock, another cpu may have
* killed off the next TW bucket in the list, therefore
* do a fresh re-read of the hlist head node with the
* lock reacquired. We still use the hlist traversal
* macro in order to get the prefetches.
*/
goto rescan;
} }
tcp_tw_count -= killed; tcp_tw_count -= killed;
...@@ -637,7 +645,7 @@ void tcp_twcal_tick(unsigned long dummy) ...@@ -637,7 +645,7 @@ void tcp_twcal_tick(unsigned long dummy)
struct hlist_node *node, *safe; struct hlist_node *node, *safe;
struct tcp_tw_bucket *tw; struct tcp_tw_bucket *tw;
tw_for_each_inmate(tw, node, safe, tw_for_each_inmate_safe(tw, node, safe,
&tcp_twcal_row[slot]) { &tcp_twcal_row[slot]) {
__tw_del_dead_node(tw); __tw_del_dead_node(tw);
tcp_timewait_kill(tw); tcp_timewait_kill(tw);
......
...@@ -1147,7 +1147,7 @@ config SOUND_RME96XX ...@@ -1147,7 +1147,7 @@ config SOUND_RME96XX
help help
Say Y or M if you have a Hammerfall or Hammerfall light Say Y or M if you have a Hammerfall or Hammerfall light
multichannel card from RME. If you want to acess advanced multichannel card from RME. If you want to acess advanced
features of the card, read Documentation/sound/rme96xx. features of the card, read Documentation/sound/oss/rme96xx.
config SOUND_AD1980 config SOUND_AD1980
tristate "AD1980 front/back switch plugin" tristate "AD1980 front/back switch plugin"
......
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