From a341ad97245d01c923995cfe7deacd0c8aee6e16 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 28 Jun 2005 20:33:49 +1000 Subject: [PATCH] ppc64: simplify nvram partition scanning code Convert nvram_create_os_partition to use list_for_each_entry instead of list_for_each, as this reduces the code size by two lines. Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/nvram.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c index 4e71781a441..4fb1a9f5060 100644 --- a/arch/ppc64/kernel/nvram.c +++ b/arch/ppc64/kernel/nvram.c @@ -338,9 +338,8 @@ static int nvram_remove_os_partition(void) */ static int nvram_create_os_partition(void) { - struct list_head * p; - struct nvram_partition *part = NULL; - struct nvram_partition *new_part = NULL; + struct nvram_partition *part; + struct nvram_partition *new_part; struct nvram_partition *free_part = NULL; int seq_init[2] = { 0, 0 }; loff_t tmp_index; @@ -349,8 +348,7 @@ static int nvram_create_os_partition(void) /* Find a free partition that will give us the maximum needed size If can't find one that will give us the minimum size needed */ - list_for_each(p, &nvram_part->partition) { - part = list_entry(p, struct nvram_partition, partition); + list_for_each_entry(part, &nvram_part->partition, partition) { if (part->header.signature != NVRAM_SIG_FREE) continue; -- cgit v1.2.3 From f5f1cc5437961a4bd93d615099f26780819e72d3 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Tue, 28 Jun 2005 20:55:25 +1000 Subject: [PATCH] ppc64: don't create spurious symlinks under node0 sysdev On partitioned systems we can wind up creating spurious symlinks in /sys/devices/system/node/node0 to non-present cpus. The symlinks are not broken; the problem is that we're potentially misinforming userspace that there is a relationship between node0 and cpus which are to be added later. There's no guarantee at all that a cpu which is added later will belong to node 0. Signed-off-by: Nathan Lynch Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/sysfs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c index c8fa6569b2f..2f704a2cafb 100644 --- a/arch/ppc64/kernel/sysfs.c +++ b/arch/ppc64/kernel/sysfs.c @@ -400,7 +400,12 @@ static int __init topology_init(void) struct cpu *c = &per_cpu(cpu_devices, cpu); #ifdef CONFIG_NUMA - parent = &node_devices[cpu_to_node(cpu)]; + /* The node to which a cpu belongs can't be known + * until the cpu is made present. + */ + parent = NULL; + if (cpu_present(cpu)) + parent = &node_devices[cpu_to_node(cpu)]; #endif /* * For now, we just see if the system supports making -- cgit v1.2.3 From 45891f7660c02fdd7b044a04d71b965c795e9df5 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 28 Jun 2005 21:01:21 +1000 Subject: [PATCH] remove unused arch/ppc64/boot/piggyback.c piggyback is not called in arch/ppc64/boot/Makefile Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- arch/ppc64/boot/Makefile | 5 +-- arch/ppc64/boot/piggyback.c | 83 --------------------------------------------- 2 files changed, 1 insertion(+), 87 deletions(-) delete mode 100644 arch/ppc64/boot/piggyback.c (limited to 'arch') diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index d3e1d6af920..683b2d43c15 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -52,7 +52,7 @@ obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section))) src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) -hostprogs-y := piggy addnote addRamDisk +hostprogs-y := addnote addRamDisk targets += zImage zImage.initrd imagesize.c \ $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ @@ -78,9 +78,6 @@ addsection = $(CROSS32OBJCOPY) $(1) \ quiet_cmd_addnote = ADDNOTE $@ cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ -quiet_cmd_piggy = PIGGY $@ - cmd_piggy = $(obj)/piggyback $(@:.o=) < $< | $(CROSS32AS) -o $@ - $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE $(call if_changed,gzip) diff --git a/arch/ppc64/boot/piggyback.c b/arch/ppc64/boot/piggyback.c deleted file mode 100644 index 235c7a87269..00000000000 --- a/arch/ppc64/boot/piggyback.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2001 IBM Corp - * - * 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 -#include -#include - -extern long ce_exec_config[]; - -int main(int argc, char *argv[]) -{ - int i, cnt, pos, len; - unsigned int cksum, val; - unsigned char *lp; - unsigned char buf[8192]; - char *varname; - if (argc != 2) - { - fprintf(stderr, "usage: %s name out-file\n", - argv[0]); - exit(1); - } - - varname = strrchr(argv[1], '/'); - if (varname) - varname++; - else - varname = argv[1]; - - fprintf(stdout, "#\n"); - fprintf(stdout, "# Miscellaneous data structures:\n"); - fprintf(stdout, "# WARNING - this file is automatically generated!\n"); - fprintf(stdout, "#\n"); - fprintf(stdout, "\n"); - fprintf(stdout, "\t.data\n"); - fprintf(stdout, "\t.globl %s_data\n", varname); - fprintf(stdout, "%s_data:\n", varname); - pos = 0; - cksum = 0; - while ((len = read(0, buf, sizeof(buf))) > 0) - { - cnt = 0; - lp = (unsigned char *)buf; - len = (len + 3) & ~3; /* Round up to longwords */ - for (i = 0; i < len; i += 4) - { - if (cnt == 0) - { - fprintf(stdout, "\t.long\t"); - } - fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); - val = *(unsigned long *)lp; - cksum ^= val; - lp += 4; - if (++cnt == 4) - { - cnt = 0; - fprintf(stdout, " # %x \n", pos+i-12); - fflush(stdout); - } else - { - fprintf(stdout, ","); - } - } - if (cnt) - { - fprintf(stdout, "0\n"); - } - pos += len; - } - fprintf(stdout, "\t.globl %s_len\n", varname); - fprintf(stdout, "%s_len:\t.long\t0x%x\n", varname, pos); - fflush(stdout); - fclose(stdout); - fprintf(stderr, "cksum = %x\n", cksum); - exit(0); -} - -- cgit v1.2.3 From a58dfbbb2a350808253a8b5037f5ec5b9a68516d Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 28 Jun 2005 21:01:28 +1000 Subject: [PATCH] remove unused arch/ppc64/boot/mknote.c mknote is not called in arch/ppc64/boot/Makefile Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- arch/ppc64/boot/mknote.c | 43 ------------------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 arch/ppc64/boot/mknote.c (limited to 'arch') diff --git a/arch/ppc64/boot/mknote.c b/arch/ppc64/boot/mknote.c deleted file mode 100644 index 120cc1d8973..00000000000 --- a/arch/ppc64/boot/mknote.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) Cort Dougan 1999. - * - * 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. - * - * Generate a note section as per the CHRP specification. - * - */ - -#include - -#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); - -int main(void) -{ -/* header */ - /* namesz */ - PL(strlen("PowerPC")+1); - /* descrsz */ - PL(6*4); - /* type */ - PL(0x1275); - /* name */ - printf("PowerPC"); printf("%c", 0); - -/* descriptor */ - /* real-mode */ - PL(0xffffffff); - /* real-base */ - PL(0x00c00000); - /* real-size */ - PL(0xffffffff); - /* virt-base */ - PL(0xffffffff); - /* virt-size */ - PL(0xffffffff); - /* load-base */ - PL(0x4000); - return 0; -} -- cgit v1.2.3 From e6019db5a7f110839c62cefc073b6dc1143d6403 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 28 Jun 2005 21:01:35 +1000 Subject: [PATCH] remove printk usage in arch/ppc64/boot/prom.c remove the printk usage in the zImage. we are not there, yet. Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- arch/ppc64/boot/main.c | 1 - arch/ppc64/boot/prom.c | 16 ++-------------- 2 files changed, 2 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index da12ea2ca46..677e4187497 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -17,7 +17,6 @@ extern void *finddevice(const char *); extern int getprop(void *, const char *, void *, int); -extern void printk(char *fmt, ...); extern void printf(const char *fmt, ...); extern int sprintf(char *buf, const char *fmt, ...); void gunzip(void *, int, unsigned char *, int *); diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c index d5218b15824..5e48b80ff5a 100644 --- a/arch/ppc64/boot/prom.c +++ b/arch/ppc64/boot/prom.c @@ -40,7 +40,7 @@ void *finddevice(const char *name); int getprop(void *phandle, const char *name, void *buf, int buflen); void chrpboot(int a1, int a2, void *prom); /* in main.c */ -void printk(char *fmt, ...); +int printf(char *fmt, ...); /* there is no convenient header to get this from... -- paulus */ extern unsigned long strlen(const char *); @@ -220,7 +220,7 @@ readchar(void) case 1: return ch; case -1: - printk("read(stdin) returned -1\r\n"); + printf("read(stdin) returned -1\r\n"); return -1; } } @@ -627,18 +627,6 @@ int sprintf(char * buf, const char *fmt, ...) static char sprint_buf[1024]; -void -printk(char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - write(stdout, sprint_buf, n); -} - int printf(char *fmt, ...) { -- cgit v1.2.3 From b1bdfbd0a29d6da4dbe42736faac02c43a9afe76 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 28 Jun 2005 21:01:46 +1000 Subject: [PATCH] remove duplicate printf in arch/ppc64/boot/main.c initrd size is printed as hex, add a missing 0x remove a duplicate printf when initrd is used. remove use of kernel type to access the first bytes of the initrd memarea. Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- arch/ppc64/boot/main.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index 677e4187497..199d9804f61 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -146,10 +146,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr) } a1 = initrd.addr; a2 = initrd.size; - printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r", + printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r", initrd.addr, (unsigned long)_initrd_start, initrd.size); memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size); - printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr)); + printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr)); } /* Eventually gunzip the kernel */ @@ -200,9 +200,6 @@ void start(unsigned long a1, unsigned long a2, void *promptr) flush_cache((void *)vmlinux.addr, vmlinux.size); - if (a1) - printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr)); - kernel_entry = (kernel_entry_t)vmlinux.addr; #ifdef DEBUG printf( "kernel:\n\r" -- cgit v1.2.3 From bea248fb30c3122ece8c34798527fac431c1d7b0 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:07:09 +1000 Subject: [PATCH] ppc64: Remove lpqueue pointer from the paca on iSeries The iSeries code keeps a pointer to the ItLpQueue in its paca struct. But all these pointers end up pointing to the one place, ie. xItLpQueue. So remove the pointer from the paca struct and just refer to xItLpQueue directly where needed. The only complication is that the spread_lpevents logic was implemented by having a NULL lpqueue pointer in the paca on CPUs that weren't supposed to process events. Instead we just compare the spread_lpevents value to the processor id to get the same behaviour. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 16 +++++++++------- arch/ppc64/kernel/iSeries_setup.c | 6 ++---- arch/ppc64/kernel/idle.c | 4 ++-- arch/ppc64/kernel/irq.c | 6 ++---- arch/ppc64/kernel/mf.c | 5 ++--- arch/ppc64/kernel/pacaData.c | 1 - arch/ppc64/kernel/time.c | 7 ++----- 7 files changed, 19 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index cdea00d7707..e90dca8bd13 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -69,15 +69,17 @@ struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) return nextLpEvent; } +unsigned long spread_lpevents = 1; + int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) { - int retval = 0; - struct HvLpEvent * nextLpEvent; - if ( lpQueue ) { - nextLpEvent = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; - retval = nextLpEvent->xFlags.xValid | lpQueue->xPlicOverflowIntPending; - } - return retval; + struct HvLpEvent *next_event; + + if (smp_processor_id() >= spread_lpevents) + return 0; + + next_event = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; + return next_event->xFlags.xValid | lpQueue->xPlicOverflowIntPending; } void ItLpQueue_clearValid( struct HvLpEvent * event ) diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 86966ce76b5..2049b6dbafc 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -855,17 +855,15 @@ late_initcall(iSeries_src_init); static int set_spread_lpevents(char *str) { - unsigned long i; unsigned long val = simple_strtoul(str, NULL, 0); + extern unsigned long spread_lpevents; /* * The parameter is the number of processors to share in processing * lp events. */ if (( val > 0) && (val <= NR_CPUS)) { - for (i = 1; i < val; ++i) - paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; - + spread_lpevents = val; printk("lpevent processing spread over %ld processors\n", val); } else { printk("invalid spread_lpevents %ld\n", val); diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index bdf13b4dc1c..63977a7a309 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -88,7 +88,7 @@ static int iSeries_idle(void) while (1) { if (lpaca->lppaca.shared_proc) { - if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr)) + if (ItLpQueue_isLpIntPending(&xItLpQueue)) process_iSeries_events(); if (!need_resched()) yield_shared_processor(); @@ -100,7 +100,7 @@ static int iSeries_idle(void) while (!need_resched()) { HMT_medium(); - if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr)) + if (ItLpQueue_isLpIntPending(&xItLpQueue)) process_iSeries_events(); HMT_low(); } diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 3defc8c33ad..b1e6acb02a9 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -269,7 +269,6 @@ out: void do_IRQ(struct pt_regs *regs) { struct paca_struct *lpaca; - struct ItLpQueue *lpq; irq_enter(); @@ -295,9 +294,8 @@ void do_IRQ(struct pt_regs *regs) iSeries_smp_message_recv(regs); } #endif /* CONFIG_SMP */ - lpq = lpaca->lpqueue_ptr; - if (lpq && ItLpQueue_isLpIntPending(lpq)) - lpevent_count += ItLpQueue_process(lpq, regs); + if (ItLpQueue_isLpIntPending(&xItLpQueue)) + lpevent_count += ItLpQueue_process(&xItLpQueue, regs); irq_exit(); diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index d98bebf7042..d6a297a4feb 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c @@ -802,9 +802,8 @@ int mf_get_boot_rtc(struct rtc_time *tm) /* We need to poll here as we are not yet taking interrupts */ while (rtc_data.busy) { extern unsigned long lpevent_count; - struct ItLpQueue *lpq = get_paca()->lpqueue_ptr; - if (lpq && ItLpQueue_isLpIntPending(lpq)) - lpevent_count += ItLpQueue_process(lpq, NULL); + if (ItLpQueue_isLpIntPending(&xItLpQueue)) + lpevent_count += ItLpQueue_process(&xItLpQueue, NULL); } return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); } diff --git a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c index a3e0975c26c..ebfb517019e 100644 --- a/arch/ppc64/kernel/pacaData.c +++ b/arch/ppc64/kernel/pacaData.c @@ -45,7 +45,6 @@ extern unsigned long __toc_start; #ifdef CONFIG_PPC_ISERIES #define EXTRA_INITS(number, lpq) \ .lppaca_ptr = &paca[number].lppaca, \ - .lpqueue_ptr = (lpq), /* &xItLpQueue, */ \ .reg_save_ptr = &paca[number].reg_save, \ .reg_save = { \ .xDesc = 0xd397d9e2, /* "LpRS" */ \ diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 2a532db9138..cdc43afb563 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -367,11 +367,8 @@ int timer_interrupt(struct pt_regs * regs) set_dec(next_dec); #ifdef CONFIG_PPC_ISERIES - { - struct ItLpQueue *lpq = lpaca->lpqueue_ptr; - if (lpq && ItLpQueue_isLpIntPending(lpq)) - lpevent_count += ItLpQueue_process(lpq, regs); - } + if (ItLpQueue_isLpIntPending(&xItLpQueue)) + lpevent_count += ItLpQueue_process(&xItLpQueue, regs); #endif /* collect purr register values often, for accurate calculations */ -- cgit v1.2.3 From fc07695386067a4abbd5ac8c7974059eae0b0a79 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:07:21 +1000 Subject: [PATCH] ppc64: Spread lpevents by default on iSeries With the previous patch in place, spreading lpevents by default becomes a one liner. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index e90dca8bd13..d3779346780 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -69,7 +69,7 @@ struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) return nextLpEvent; } -unsigned long spread_lpevents = 1; +unsigned long spread_lpevents = NR_CPUS; int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) { -- cgit v1.2.3 From 0c885c175c06bdfe13e88d974d56a5e93ad2f544 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:07:33 +1000 Subject: [PATCH] ppc64: Move set_spread_lpevents() into ItLpQueue.c The only code outside ItLpQueue.c that refers to spread_lpevents is in set_apread_lpevents(), so move it inside ItLpQueue.c and make spread_lpevents static. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 22 +++++++++++++++++++++- arch/ppc64/kernel/iSeries_setup.c | 20 -------------------- 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index d3779346780..61be23ed500 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -69,7 +69,7 @@ struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) return nextLpEvent; } -unsigned long spread_lpevents = NR_CPUS; +static unsigned long spread_lpevents = NR_CPUS; int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) { @@ -166,3 +166,23 @@ unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) return numIntsProcessed; } + +static int set_spread_lpevents(char *str) +{ + unsigned long val = simple_strtoul(str, NULL, 0); + + /* + * The parameter is the number of processors to share in processing + * lp events. + */ + if (( val > 0) && (val <= NR_CPUS)) { + spread_lpevents = val; + printk("lpevent processing spread over %ld processors\n", val); + } else { + printk("invalid spread_lpevents %ld\n", val); + } + + return 1; +} +__setup("spread_lpevents=", set_spread_lpevents); + diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 2049b6dbafc..78f28356025 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -853,26 +853,6 @@ static int __init iSeries_src_init(void) late_initcall(iSeries_src_init); -static int set_spread_lpevents(char *str) -{ - unsigned long val = simple_strtoul(str, NULL, 0); - extern unsigned long spread_lpevents; - - /* - * The parameter is the number of processors to share in processing - * lp events. - */ - if (( val > 0) && (val <= NR_CPUS)) { - spread_lpevents = val; - printk("lpevent processing spread over %ld processors\n", val); - } else { - printk("invalid spread_lpevents %ld\n", val); - } - - return 1; -} -__setup("spread_lpevents=", set_spread_lpevents); - #ifndef CONFIG_PCI void __init iSeries_init_IRQ(void) { } #endif -- cgit v1.2.3 From ee48444b85f498d99592835f61125385d8e9c975 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:07:48 +1000 Subject: [PATCH] ppc64: Reorganise the paca initialisation macros This patch updates the macros that initialise the paca to remove the lpq parameter. It also rearranges them a bit with the hope of making them a bit clearer. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/pacaData.c | 211 +++++++++++++------------------------------ 1 file changed, 65 insertions(+), 146 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c index ebfb517019e..6316188737b 100644 --- a/arch/ppc64/kernel/pacaData.c +++ b/arch/ppc64/kernel/pacaData.c @@ -42,20 +42,7 @@ extern unsigned long __toc_start; * processors. The processor VPD array needs one entry per physical * processor (not thread). */ -#ifdef CONFIG_PPC_ISERIES -#define EXTRA_INITS(number, lpq) \ - .lppaca_ptr = &paca[number].lppaca, \ - .reg_save_ptr = &paca[number].reg_save, \ - .reg_save = { \ - .xDesc = 0xd397d9e2, /* "LpRS" */ \ - .xSize = sizeof(struct ItLpRegSave) \ - }, -#else -#define EXTRA_INITS(number, lpq) -#endif - -#define PACAINITDATA(number,start,lpq,asrr,asrv) \ -{ \ +#define PACA_INIT_COMMON(number, start, asrr, asrv) \ .lock_token = 0x8000, \ .paca_index = (number), /* Paca Index */ \ .default_decr = 0x00ff0000, /* Initial Decr */ \ @@ -73,147 +60,79 @@ extern unsigned long __toc_start; .end_of_quantum = 0xfffffffffffffffful, \ .slb_count = 64, \ }, \ - EXTRA_INITS((number), (lpq)) \ -} -struct paca_struct paca[] = { #ifdef CONFIG_PPC_ISERIES - PACAINITDATA( 0, 1, &xItLpQueue, 0, STAB0_VIRT_ADDR), +#define PACA_INIT_ISERIES(number) \ + .lppaca_ptr = &paca[number].lppaca, \ + .reg_save_ptr = &paca[number].reg_save, \ + .reg_save = { \ + .xDesc = 0xd397d9e2, /* "LpRS" */ \ + .xSize = sizeof(struct ItLpRegSave) \ + } + +#define PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 0, 0, 0) \ + PACA_INIT_ISERIES(number) \ +} + +#define BOOTCPU_PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 1, 0, STAB0_VIRT_ADDR) \ + PACA_INIT_ISERIES(number) \ +} + #else - PACAINITDATA( 0, 1, NULL, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR), +#define PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 0, 0, 0) \ +} + +#define BOOTCPU_PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR) \ +} #endif + +struct paca_struct paca[] = { + BOOTCPU_PACA_INIT(0), #if NR_CPUS > 1 - PACAINITDATA( 1, 0, NULL, 0, 0), - PACAINITDATA( 2, 0, NULL, 0, 0), - PACAINITDATA( 3, 0, NULL, 0, 0), + PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3), #if NR_CPUS > 4 - PACAINITDATA( 4, 0, NULL, 0, 0), - PACAINITDATA( 5, 0, NULL, 0, 0), - PACAINITDATA( 6, 0, NULL, 0, 0), - PACAINITDATA( 7, 0, NULL, 0, 0), + PACA_INIT( 4), PACA_INIT( 5), PACA_INIT( 6), PACA_INIT( 7), #if NR_CPUS > 8 - PACAINITDATA( 8, 0, NULL, 0, 0), - PACAINITDATA( 9, 0, NULL, 0, 0), - PACAINITDATA(10, 0, NULL, 0, 0), - PACAINITDATA(11, 0, NULL, 0, 0), - PACAINITDATA(12, 0, NULL, 0, 0), - PACAINITDATA(13, 0, NULL, 0, 0), - PACAINITDATA(14, 0, NULL, 0, 0), - PACAINITDATA(15, 0, NULL, 0, 0), - PACAINITDATA(16, 0, NULL, 0, 0), - PACAINITDATA(17, 0, NULL, 0, 0), - PACAINITDATA(18, 0, NULL, 0, 0), - PACAINITDATA(19, 0, NULL, 0, 0), - PACAINITDATA(20, 0, NULL, 0, 0), - PACAINITDATA(21, 0, NULL, 0, 0), - PACAINITDATA(22, 0, NULL, 0, 0), - PACAINITDATA(23, 0, NULL, 0, 0), - PACAINITDATA(24, 0, NULL, 0, 0), - PACAINITDATA(25, 0, NULL, 0, 0), - PACAINITDATA(26, 0, NULL, 0, 0), - PACAINITDATA(27, 0, NULL, 0, 0), - PACAINITDATA(28, 0, NULL, 0, 0), - PACAINITDATA(29, 0, NULL, 0, 0), - PACAINITDATA(30, 0, NULL, 0, 0), - PACAINITDATA(31, 0, NULL, 0, 0), + PACA_INIT( 8), PACA_INIT( 9), PACA_INIT( 10), PACA_INIT( 11), + PACA_INIT( 12), PACA_INIT( 13), PACA_INIT( 14), PACA_INIT( 15), + PACA_INIT( 16), PACA_INIT( 17), PACA_INIT( 18), PACA_INIT( 19), + PACA_INIT( 20), PACA_INIT( 21), PACA_INIT( 22), PACA_INIT( 23), + PACA_INIT( 24), PACA_INIT( 25), PACA_INIT( 26), PACA_INIT( 27), + PACA_INIT( 28), PACA_INIT( 29), PACA_INIT( 30), PACA_INIT( 31), #if NR_CPUS > 32 - PACAINITDATA(32, 0, NULL, 0, 0), - PACAINITDATA(33, 0, NULL, 0, 0), - PACAINITDATA(34, 0, NULL, 0, 0), - PACAINITDATA(35, 0, NULL, 0, 0), - PACAINITDATA(36, 0, NULL, 0, 0), - PACAINITDATA(37, 0, NULL, 0, 0), - PACAINITDATA(38, 0, NULL, 0, 0), - PACAINITDATA(39, 0, NULL, 0, 0), - PACAINITDATA(40, 0, NULL, 0, 0), - PACAINITDATA(41, 0, NULL, 0, 0), - PACAINITDATA(42, 0, NULL, 0, 0), - PACAINITDATA(43, 0, NULL, 0, 0), - PACAINITDATA(44, 0, NULL, 0, 0), - PACAINITDATA(45, 0, NULL, 0, 0), - PACAINITDATA(46, 0, NULL, 0, 0), - PACAINITDATA(47, 0, NULL, 0, 0), - PACAINITDATA(48, 0, NULL, 0, 0), - PACAINITDATA(49, 0, NULL, 0, 0), - PACAINITDATA(50, 0, NULL, 0, 0), - PACAINITDATA(51, 0, NULL, 0, 0), - PACAINITDATA(52, 0, NULL, 0, 0), - PACAINITDATA(53, 0, NULL, 0, 0), - PACAINITDATA(54, 0, NULL, 0, 0), - PACAINITDATA(55, 0, NULL, 0, 0), - PACAINITDATA(56, 0, NULL, 0, 0), - PACAINITDATA(57, 0, NULL, 0, 0), - PACAINITDATA(58, 0, NULL, 0, 0), - PACAINITDATA(59, 0, NULL, 0, 0), - PACAINITDATA(60, 0, NULL, 0, 0), - PACAINITDATA(61, 0, NULL, 0, 0), - PACAINITDATA(62, 0, NULL, 0, 0), - PACAINITDATA(63, 0, NULL, 0, 0), + PACA_INIT( 32), PACA_INIT( 33), PACA_INIT( 34), PACA_INIT( 35), + PACA_INIT( 36), PACA_INIT( 37), PACA_INIT( 38), PACA_INIT( 39), + PACA_INIT( 40), PACA_INIT( 41), PACA_INIT( 42), PACA_INIT( 43), + PACA_INIT( 44), PACA_INIT( 45), PACA_INIT( 46), PACA_INIT( 47), + PACA_INIT( 48), PACA_INIT( 49), PACA_INIT( 50), PACA_INIT( 51), + PACA_INIT( 52), PACA_INIT( 53), PACA_INIT( 54), PACA_INIT( 55), + PACA_INIT( 56), PACA_INIT( 57), PACA_INIT( 58), PACA_INIT( 59), + PACA_INIT( 60), PACA_INIT( 61), PACA_INIT( 62), PACA_INIT( 63), #if NR_CPUS > 64 - PACAINITDATA(64, 0, NULL, 0, 0), - PACAINITDATA(65, 0, NULL, 0, 0), - PACAINITDATA(66, 0, NULL, 0, 0), - PACAINITDATA(67, 0, NULL, 0, 0), - PACAINITDATA(68, 0, NULL, 0, 0), - PACAINITDATA(69, 0, NULL, 0, 0), - PACAINITDATA(70, 0, NULL, 0, 0), - PACAINITDATA(71, 0, NULL, 0, 0), - PACAINITDATA(72, 0, NULL, 0, 0), - PACAINITDATA(73, 0, NULL, 0, 0), - PACAINITDATA(74, 0, NULL, 0, 0), - PACAINITDATA(75, 0, NULL, 0, 0), - PACAINITDATA(76, 0, NULL, 0, 0), - PACAINITDATA(77, 0, NULL, 0, 0), - PACAINITDATA(78, 0, NULL, 0, 0), - PACAINITDATA(79, 0, NULL, 0, 0), - PACAINITDATA(80, 0, NULL, 0, 0), - PACAINITDATA(81, 0, NULL, 0, 0), - PACAINITDATA(82, 0, NULL, 0, 0), - PACAINITDATA(83, 0, NULL, 0, 0), - PACAINITDATA(84, 0, NULL, 0, 0), - PACAINITDATA(85, 0, NULL, 0, 0), - PACAINITDATA(86, 0, NULL, 0, 0), - PACAINITDATA(87, 0, NULL, 0, 0), - PACAINITDATA(88, 0, NULL, 0, 0), - PACAINITDATA(89, 0, NULL, 0, 0), - PACAINITDATA(90, 0, NULL, 0, 0), - PACAINITDATA(91, 0, NULL, 0, 0), - PACAINITDATA(92, 0, NULL, 0, 0), - PACAINITDATA(93, 0, NULL, 0, 0), - PACAINITDATA(94, 0, NULL, 0, 0), - PACAINITDATA(95, 0, NULL, 0, 0), - PACAINITDATA(96, 0, NULL, 0, 0), - PACAINITDATA(97, 0, NULL, 0, 0), - PACAINITDATA(98, 0, NULL, 0, 0), - PACAINITDATA(99, 0, NULL, 0, 0), - PACAINITDATA(100, 0, NULL, 0, 0), - PACAINITDATA(101, 0, NULL, 0, 0), - PACAINITDATA(102, 0, NULL, 0, 0), - PACAINITDATA(103, 0, NULL, 0, 0), - PACAINITDATA(104, 0, NULL, 0, 0), - PACAINITDATA(105, 0, NULL, 0, 0), - PACAINITDATA(106, 0, NULL, 0, 0), - PACAINITDATA(107, 0, NULL, 0, 0), - PACAINITDATA(108, 0, NULL, 0, 0), - PACAINITDATA(109, 0, NULL, 0, 0), - PACAINITDATA(110, 0, NULL, 0, 0), - PACAINITDATA(111, 0, NULL, 0, 0), - PACAINITDATA(112, 0, NULL, 0, 0), - PACAINITDATA(113, 0, NULL, 0, 0), - PACAINITDATA(114, 0, NULL, 0, 0), - PACAINITDATA(115, 0, NULL, 0, 0), - PACAINITDATA(116, 0, NULL, 0, 0), - PACAINITDATA(117, 0, NULL, 0, 0), - PACAINITDATA(118, 0, NULL, 0, 0), - PACAINITDATA(119, 0, NULL, 0, 0), - PACAINITDATA(120, 0, NULL, 0, 0), - PACAINITDATA(121, 0, NULL, 0, 0), - PACAINITDATA(122, 0, NULL, 0, 0), - PACAINITDATA(123, 0, NULL, 0, 0), - PACAINITDATA(124, 0, NULL, 0, 0), - PACAINITDATA(125, 0, NULL, 0, 0), - PACAINITDATA(126, 0, NULL, 0, 0), - PACAINITDATA(127, 0, NULL, 0, 0), + PACA_INIT( 64), PACA_INIT( 65), PACA_INIT( 66), PACA_INIT( 67), + PACA_INIT( 68), PACA_INIT( 69), PACA_INIT( 70), PACA_INIT( 71), + PACA_INIT( 72), PACA_INIT( 73), PACA_INIT( 74), PACA_INIT( 75), + PACA_INIT( 76), PACA_INIT( 77), PACA_INIT( 78), PACA_INIT( 79), + PACA_INIT( 80), PACA_INIT( 81), PACA_INIT( 82), PACA_INIT( 83), + PACA_INIT( 84), PACA_INIT( 85), PACA_INIT( 86), PACA_INIT( 87), + PACA_INIT( 88), PACA_INIT( 89), PACA_INIT( 90), PACA_INIT( 91), + PACA_INIT( 92), PACA_INIT( 93), PACA_INIT( 94), PACA_INIT( 95), + PACA_INIT( 96), PACA_INIT( 97), PACA_INIT( 98), PACA_INIT( 99), + PACA_INIT(100), PACA_INIT(101), PACA_INIT(102), PACA_INIT(103), + PACA_INIT(104), PACA_INIT(105), PACA_INIT(106), PACA_INIT(107), + PACA_INIT(108), PACA_INIT(109), PACA_INIT(110), PACA_INIT(111), + PACA_INIT(112), PACA_INIT(113), PACA_INIT(114), PACA_INIT(115), + PACA_INIT(116), PACA_INIT(117), PACA_INIT(118), PACA_INIT(119), + PACA_INIT(120), PACA_INIT(121), PACA_INIT(122), PACA_INIT(123), + PACA_INIT(124), PACA_INIT(125), PACA_INIT(126), PACA_INIT(127), #endif #endif #endif -- cgit v1.2.3 From 1b19bc721416ae5bc813521d9e010a89f4816120 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:07:57 +1000 Subject: [PATCH] ppc64: Don't pass the pointers to xItLpQueue around Because there's only one ItLpQueue and we know where it is, ie. xItLpQueue, there's no point passing pointers to it it around all over the place. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 46 +++++++++++++++++++++---------------------- arch/ppc64/kernel/idle.c | 4 ++-- arch/ppc64/kernel/irq.c | 4 ++-- arch/ppc64/kernel/mf.c | 4 ++-- arch/ppc64/kernel/time.c | 4 ++-- 5 files changed, 31 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 61be23ed500..35f6deac0b9 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -17,10 +17,10 @@ #include #include -static __inline__ int set_inUse( struct ItLpQueue * lpQueue ) +static __inline__ int set_inUse(void) { int t; - u32 * inUseP = &(lpQueue->xInUseWord); + u32 * inUseP = &xItLpQueue.xInUseWord; __asm__ __volatile__("\n\ 1: lwarx %0,0,%2 \n\ @@ -31,37 +31,37 @@ static __inline__ int set_inUse( struct ItLpQueue * lpQueue ) stwcx. %0,0,%2 \n\ bne- 1b \n\ 2: eieio" - : "=&r" (t), "=m" (lpQueue->xInUseWord) - : "r" (inUseP), "m" (lpQueue->xInUseWord) + : "=&r" (t), "=m" (xItLpQueue.xInUseWord) + : "r" (inUseP), "m" (xItLpQueue.xInUseWord) : "cc"); return t; } -static __inline__ void clear_inUse( struct ItLpQueue * lpQueue ) +static __inline__ void clear_inUse(void) { - lpQueue->xInUseWord = 0; + xItLpQueue.xInUseWord = 0; } /* Array of LpEvent handler functions */ extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; unsigned long ItLpQueueInProcess = 0; -struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) +struct HvLpEvent * ItLpQueue_getNextLpEvent(void) { struct HvLpEvent * nextLpEvent = - (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; + (struct HvLpEvent *)xItLpQueue.xSlicCurEventPtr; if ( nextLpEvent->xFlags.xValid ) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ - lpQueue->xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + + xItLpQueue.xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + LpEventAlign ) / LpEventAlign ) * LpEventAlign; /* Wrap to beginning if no room at end */ - if (lpQueue->xSlicCurEventPtr > lpQueue->xSlicLastValidEventPtr) - lpQueue->xSlicCurEventPtr = lpQueue->xSlicEventStackPtr; + if (xItLpQueue.xSlicCurEventPtr > xItLpQueue.xSlicLastValidEventPtr) + xItLpQueue.xSlicCurEventPtr = xItLpQueue.xSlicEventStackPtr; } else nextLpEvent = NULL; @@ -71,15 +71,15 @@ struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) static unsigned long spread_lpevents = NR_CPUS; -int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) +int ItLpQueue_isLpIntPending(void) { struct HvLpEvent *next_event; if (smp_processor_id() >= spread_lpevents) return 0; - next_event = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; - return next_event->xFlags.xValid | lpQueue->xPlicOverflowIntPending; + next_event = (struct HvLpEvent *)xItLpQueue.xSlicCurEventPtr; + return next_event->xFlags.xValid | xItLpQueue.xPlicOverflowIntPending; } void ItLpQueue_clearValid( struct HvLpEvent * event ) @@ -104,13 +104,13 @@ void ItLpQueue_clearValid( struct HvLpEvent * event ) event->xFlags.xValid = 0; } -unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) +unsigned ItLpQueue_process(struct pt_regs *regs) { unsigned numIntsProcessed = 0; struct HvLpEvent * nextLpEvent; /* If we have recursed, just return */ - if ( !set_inUse( lpQueue ) ) + if ( !set_inUse() ) return 0; if (ItLpQueueInProcess == 0) @@ -119,13 +119,13 @@ unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) BUG(); for (;;) { - nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue ); + nextLpEvent = ItLpQueue_getNextLpEvent(); if ( nextLpEvent ) { /* Count events to return to caller - * and count processed events in lpQueue + * and count processed events in xItLpQueue */ ++numIntsProcessed; - lpQueue->xLpIntCount++; + xItLpQueue.xLpIntCount++; /* Call appropriate handler here, passing * a pointer to the LpEvent. The handler * must make a copy of the LpEvent if it @@ -140,7 +140,7 @@ unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) * here! */ if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) - lpQueue->xLpIntCountByType[nextLpEvent->xType]++; + xItLpQueue.xLpIntCountByType[nextLpEvent->xType]++; if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && lpEventHandler[nextLpEvent->xType] ) lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); @@ -148,19 +148,19 @@ unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); ItLpQueue_clearValid( nextLpEvent ); - } else if ( lpQueue->xPlicOverflowIntPending ) + } else if ( xItLpQueue.xPlicOverflowIntPending ) /* * No more valid events. If overflow events are * pending process them */ - HvCallEvent_getOverflowLpEvents( lpQueue->xIndex); + HvCallEvent_getOverflowLpEvents( xItLpQueue.xIndex); else break; } ItLpQueueInProcess = 0; mb(); - clear_inUse( lpQueue ); + clear_inUse(); get_paca()->lpevent_count += numIntsProcessed; diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index 63977a7a309..a7ebd0238d3 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -88,7 +88,7 @@ static int iSeries_idle(void) while (1) { if (lpaca->lppaca.shared_proc) { - if (ItLpQueue_isLpIntPending(&xItLpQueue)) + if (ItLpQueue_isLpIntPending()) process_iSeries_events(); if (!need_resched()) yield_shared_processor(); @@ -100,7 +100,7 @@ static int iSeries_idle(void) while (!need_resched()) { HMT_medium(); - if (ItLpQueue_isLpIntPending(&xItLpQueue)) + if (ItLpQueue_isLpIntPending()) process_iSeries_events(); HMT_low(); } diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index b1e6acb02a9..46a7151ad6d 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -294,8 +294,8 @@ void do_IRQ(struct pt_regs *regs) iSeries_smp_message_recv(regs); } #endif /* CONFIG_SMP */ - if (ItLpQueue_isLpIntPending(&xItLpQueue)) - lpevent_count += ItLpQueue_process(&xItLpQueue, regs); + if (ItLpQueue_isLpIntPending()) + lpevent_count += ItLpQueue_process(regs); irq_exit(); diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index d6a297a4feb..ef920699802 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c @@ -802,8 +802,8 @@ int mf_get_boot_rtc(struct rtc_time *tm) /* We need to poll here as we are not yet taking interrupts */ while (rtc_data.busy) { extern unsigned long lpevent_count; - if (ItLpQueue_isLpIntPending(&xItLpQueue)) - lpevent_count += ItLpQueue_process(&xItLpQueue, NULL); + if (ItLpQueue_isLpIntPending()) + lpevent_count += ItLpQueue_process(NULL); } return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); } diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index cdc43afb563..c133f9c28c5 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -367,8 +367,8 @@ int timer_interrupt(struct pt_regs * regs) set_dec(next_dec); #ifdef CONFIG_PPC_ISERIES - if (ItLpQueue_isLpIntPending(&xItLpQueue)) - lpevent_count += ItLpQueue_process(&xItLpQueue, regs); + if (ItLpQueue_isLpIntPending()) + lpevent_count += ItLpQueue_process(regs); #endif /* collect purr register values often, for accurate calculations */ -- cgit v1.2.3 From 512d31d6a824a961f39b418f11480f678320e4f3 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:08:27 +1000 Subject: [PATCH] ppc64: Move initialisation of xItLpQueue into ItLpQueue.c The xItLpQueue is initalised manually in iSeries_setup_arch(). Move this code into ItLpQueue.c for a cleaner separation. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 22 ++++++++++++++++++++++ arch/ppc64/kernel/iSeries_setup.c | 21 +-------------------- 2 files changed, 23 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 35f6deac0b9..091aaed4842 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -186,3 +187,24 @@ static int set_spread_lpevents(char *str) } __setup("spread_lpevents=", set_spread_lpevents); +void setup_hvlpevent_queue(void) +{ + void *eventStack; + + /* + * Allocate a page for the Event Stack. The Hypervisor needs the + * absolute real address, so we subtract out the KERNELBASE and add + * in the absolute real address of the kernel load area. + */ + eventStack = alloc_bootmem_pages(LpEventStackSize); + memset(eventStack, 0, LpEventStackSize); + + /* Invoke the hypervisor to initialize the event stack */ + HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); + + xItLpQueue.xSlicEventStackPtr = (char *)eventStack; + xItLpQueue.xSlicCurEventPtr = (char *)eventStack; + xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack + + (LpEventStackSize - LpEventMaxSize); + xItLpQueue.xIndex = 0; +} diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 78f28356025..b3f770f6d40 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -676,7 +675,6 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) */ static void __init iSeries_setup_arch(void) { - void *eventStack; unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index; /* Add an eye catcher and the systemcfg layout version number */ @@ -685,24 +683,7 @@ static void __init iSeries_setup_arch(void) systemcfg->version.minor = SYSTEMCFG_MINOR; /* Setup the Lp Event Queue */ - - /* Allocate a page for the Event Stack - * The hypervisor wants the absolute real address, so - * we subtract out the KERNELBASE and add in the - * absolute real address of the kernel load area - */ - eventStack = alloc_bootmem_pages(LpEventStackSize); - memset(eventStack, 0, LpEventStackSize); - - /* Invoke the hypervisor to initialize the event stack */ - HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); - - /* Initialize fields in our Lp Event Queue */ - xItLpQueue.xSlicEventStackPtr = (char *)eventStack; - xItLpQueue.xSlicCurEventPtr = (char *)eventStack; - xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack + - (LpEventStackSize - LpEventMaxSize); - xItLpQueue.xIndex = 0; + setup_hvlpevent_queue(); /* Compute processor frequency */ procFreqHz = ((1UL << 34) * 1000000) / -- cgit v1.2.3 From 7b01328d455b50ff040d3a06b342ca370b1d8b0a Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:08:44 +1000 Subject: [PATCH] ppc64: Move xItLpQueue proc code into ItLpQueue.c Move the code that displays xItLpQueue values in /proc into ItLpQueue.c. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 59 ++++++++++++++++++++++++++++++++++++++++ arch/ppc64/kernel/iSeries_proc.c | 48 -------------------------------- 2 files changed, 59 insertions(+), 48 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 091aaed4842..11cd31dfcef 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -12,12 +12,26 @@ #include #include #include +#include +#include #include #include #include #include #include +static char *event_types[9] = { + "Hypervisor\t\t", + "Machine Facilities\t", + "Session Manager\t", + "SPD I/O\t\t", + "Virtual Bus\t\t", + "PCI I/O\t\t", + "RIO I/O\t\t", + "Virtual Lan\t\t", + "Virtual I/O\t\t" +}; + static __inline__ int set_inUse(void) { int t; @@ -208,3 +222,48 @@ void setup_hvlpevent_queue(void) (LpEventStackSize - LpEventMaxSize); xItLpQueue.xIndex = 0; } + +static int proc_lpevents_show(struct seq_file *m, void *v) +{ + unsigned int i; + + seq_printf(m, "LpEventQueue 0\n"); + seq_printf(m, " events processed:\t%lu\n", + (unsigned long)xItLpQueue.xLpIntCount); + + for (i = 0; i < 9; ++i) + seq_printf(m, " %s %10lu\n", event_types[i], + (unsigned long)xItLpQueue.xLpIntCountByType[i]); + + seq_printf(m, "\n events processed by processor:\n"); + + for_each_online_cpu(i) + seq_printf(m, " CPU%02d %10u\n", i, paca[i].lpevent_count); + + return 0; +} + +static int proc_lpevents_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_lpevents_show, NULL); +} + +static struct file_operations proc_lpevents_operations = { + .open = proc_lpevents_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init proc_lpevents_init(void) +{ + struct proc_dir_entry *e; + + e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL); + if (e) + e->proc_fops = &proc_lpevents_operations; + + return 0; +} +__initcall(proc_lpevents_init); + diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/ppc64/kernel/iSeries_proc.c index 356bd9931fc..0fe3116eba2 100644 --- a/arch/ppc64/kernel/iSeries_proc.c +++ b/arch/ppc64/kernel/iSeries_proc.c @@ -40,50 +40,6 @@ static int __init iseries_proc_create(void) } core_initcall(iseries_proc_create); -static char *event_types[9] = { - "Hypervisor\t\t", - "Machine Facilities\t", - "Session Manager\t", - "SPD I/O\t\t", - "Virtual Bus\t\t", - "PCI I/O\t\t", - "RIO I/O\t\t", - "Virtual Lan\t\t", - "Virtual I/O\t\t" -}; - -static int proc_lpevents_show(struct seq_file *m, void *v) -{ - unsigned int i; - - seq_printf(m, "LpEventQueue 0\n"); - seq_printf(m, " events processed:\t%lu\n", - (unsigned long)xItLpQueue.xLpIntCount); - - for (i = 0; i < 9; ++i) - seq_printf(m, " %s %10lu\n", event_types[i], - (unsigned long)xItLpQueue.xLpIntCountByType[i]); - - seq_printf(m, "\n events processed by processor:\n"); - - for_each_online_cpu(i) - seq_printf(m, " CPU%02d %10u\n", i, paca[i].lpevent_count); - - return 0; -} - -static int proc_lpevents_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_lpevents_show, NULL); -} - -static struct file_operations proc_lpevents_operations = { - .open = proc_lpevents_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static unsigned long startTitan = 0; static unsigned long startTb = 0; @@ -148,10 +104,6 @@ static int __init iseries_proc_init(void) { struct proc_dir_entry *e; - e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL); - if (e) - e->proc_fops = &proc_lpevents_operations; - e = create_proc_entry("iSeries/titanTod", S_IFREG|S_IRUGO, NULL); if (e) e->proc_fops = &proc_titantod_operations; -- cgit v1.2.3 From 0f6014b37e25e50724867c0a4127615427ec2a75 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:08:56 +1000 Subject: [PATCH] ppc64: Make two ItLpQueue related functions static External parties don't need to use ItLpQueue_getNextLpEvent() or ItLpQueue_clearValid(), they're internal to ItLpQueue.c Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 11cd31dfcef..ac0b05a6e06 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -62,7 +62,7 @@ static __inline__ void clear_inUse(void) extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; unsigned long ItLpQueueInProcess = 0; -struct HvLpEvent * ItLpQueue_getNextLpEvent(void) +static struct HvLpEvent * ItLpQueue_getNextLpEvent(void) { struct HvLpEvent * nextLpEvent = (struct HvLpEvent *)xItLpQueue.xSlicCurEventPtr; @@ -97,7 +97,7 @@ int ItLpQueue_isLpIntPending(void) return next_event->xFlags.xValid | xItLpQueue.xPlicOverflowIntPending; } -void ItLpQueue_clearValid( struct HvLpEvent * event ) +static void ItLpQueue_clearValid( struct HvLpEvent * event ) { /* Clear the valid bit of the event * Also clear bits within this event that might -- cgit v1.2.3 From ab354b637924beb33dcc23eedc9482f2c692188f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:12:21 +1000 Subject: [PATCH] ppc64: Move definition of xItLpQueue The xItLpQueue is declared in LparData.c, move it into ItLpQueue.c. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 8 ++++++++ arch/ppc64/kernel/LparData.c | 7 ------- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index ac0b05a6e06..7ddbfb9750d 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -20,6 +20,14 @@ #include #include +/* + * The LpQueue is used to pass event data from the hypervisor to + * the partition. This is where I/O interrupt events are communicated. + * + * It is written to by the hypervisor so cannot end up in the BSS. + */ +struct ItLpQueue xItLpQueue __attribute__((__section__(".data"))); + static char *event_types[9] = { "Hypervisor\t\t", "Machine Facilities\t", diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c index badc5a44361..f42ee35f927 100644 --- a/arch/ppc64/kernel/LparData.c +++ b/arch/ppc64/kernel/LparData.c @@ -28,13 +28,6 @@ #include #include -/* The LpQueue is used to pass event data from the hypervisor to - * the partition. This is where I/O interrupt events are communicated. - */ - -/* May be filled in by the hypervisor so cannot end up in the BSS */ -struct ItLpQueue xItLpQueue __attribute__((__section__(".data"))); - /* The HvReleaseData is the root of the information shared between * the hypervisor and Linux. -- cgit v1.2.3 From a61874648d14450f4d397489527998e3dd1119de Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:15:32 +1000 Subject: [PATCH] ppc64: Rename xItLpQueue to hvlpevent_queue The xItLpQueue is a queue of HvLpEvents that we're given by the Hypervisor. Rename xItLpQueue to hvlpevent_queue and make the type struct hvlpevent_queue. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 44 +++++++++++++++++++++---------------------- arch/ppc64/kernel/LparData.c | 4 ++-- 2 files changed, 24 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 7ddbfb9750d..e55fe1a2725 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -26,7 +26,7 @@ * * It is written to by the hypervisor so cannot end up in the BSS. */ -struct ItLpQueue xItLpQueue __attribute__((__section__(".data"))); +struct hvlpevent_queue hvlpevent_queue __attribute__((__section__(".data"))); static char *event_types[9] = { "Hypervisor\t\t", @@ -43,7 +43,7 @@ static char *event_types[9] = { static __inline__ int set_inUse(void) { int t; - u32 * inUseP = &xItLpQueue.xInUseWord; + u32 * inUseP = &hvlpevent_queue.xInUseWord; __asm__ __volatile__("\n\ 1: lwarx %0,0,%2 \n\ @@ -54,8 +54,8 @@ static __inline__ int set_inUse(void) stwcx. %0,0,%2 \n\ bne- 1b \n\ 2: eieio" - : "=&r" (t), "=m" (xItLpQueue.xInUseWord) - : "r" (inUseP), "m" (xItLpQueue.xInUseWord) + : "=&r" (t), "=m" (hvlpevent_queue.xInUseWord) + : "r" (inUseP), "m" (hvlpevent_queue.xInUseWord) : "cc"); return t; @@ -63,7 +63,7 @@ static __inline__ int set_inUse(void) static __inline__ void clear_inUse(void) { - xItLpQueue.xInUseWord = 0; + hvlpevent_queue.xInUseWord = 0; } /* Array of LpEvent handler functions */ @@ -73,18 +73,18 @@ unsigned long ItLpQueueInProcess = 0; static struct HvLpEvent * ItLpQueue_getNextLpEvent(void) { struct HvLpEvent * nextLpEvent = - (struct HvLpEvent *)xItLpQueue.xSlicCurEventPtr; + (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; if ( nextLpEvent->xFlags.xValid ) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ - xItLpQueue.xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + + hvlpevent_queue.xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + LpEventAlign ) / LpEventAlign ) * LpEventAlign; /* Wrap to beginning if no room at end */ - if (xItLpQueue.xSlicCurEventPtr > xItLpQueue.xSlicLastValidEventPtr) - xItLpQueue.xSlicCurEventPtr = xItLpQueue.xSlicEventStackPtr; + if (hvlpevent_queue.xSlicCurEventPtr > hvlpevent_queue.xSlicLastValidEventPtr) + hvlpevent_queue.xSlicCurEventPtr = hvlpevent_queue.xSlicEventStackPtr; } else nextLpEvent = NULL; @@ -101,8 +101,8 @@ int ItLpQueue_isLpIntPending(void) if (smp_processor_id() >= spread_lpevents) return 0; - next_event = (struct HvLpEvent *)xItLpQueue.xSlicCurEventPtr; - return next_event->xFlags.xValid | xItLpQueue.xPlicOverflowIntPending; + next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + return next_event->xFlags.xValid | hvlpevent_queue.xPlicOverflowIntPending; } static void ItLpQueue_clearValid( struct HvLpEvent * event ) @@ -145,10 +145,10 @@ unsigned ItLpQueue_process(struct pt_regs *regs) nextLpEvent = ItLpQueue_getNextLpEvent(); if ( nextLpEvent ) { /* Count events to return to caller - * and count processed events in xItLpQueue + * and count processed events in hvlpevent_queue */ ++numIntsProcessed; - xItLpQueue.xLpIntCount++; + hvlpevent_queue.xLpIntCount++; /* Call appropriate handler here, passing * a pointer to the LpEvent. The handler * must make a copy of the LpEvent if it @@ -163,7 +163,7 @@ unsigned ItLpQueue_process(struct pt_regs *regs) * here! */ if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) - xItLpQueue.xLpIntCountByType[nextLpEvent->xType]++; + hvlpevent_queue.xLpIntCountByType[nextLpEvent->xType]++; if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && lpEventHandler[nextLpEvent->xType] ) lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); @@ -171,12 +171,12 @@ unsigned ItLpQueue_process(struct pt_regs *regs) printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); ItLpQueue_clearValid( nextLpEvent ); - } else if ( xItLpQueue.xPlicOverflowIntPending ) + } else if ( hvlpevent_queue.xPlicOverflowIntPending ) /* * No more valid events. If overflow events are * pending process them */ - HvCallEvent_getOverflowLpEvents( xItLpQueue.xIndex); + HvCallEvent_getOverflowLpEvents( hvlpevent_queue.xIndex); else break; } @@ -224,11 +224,11 @@ void setup_hvlpevent_queue(void) /* Invoke the hypervisor to initialize the event stack */ HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); - xItLpQueue.xSlicEventStackPtr = (char *)eventStack; - xItLpQueue.xSlicCurEventPtr = (char *)eventStack; - xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack + + hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack; + hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack; + hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack + (LpEventStackSize - LpEventMaxSize); - xItLpQueue.xIndex = 0; + hvlpevent_queue.xIndex = 0; } static int proc_lpevents_show(struct seq_file *m, void *v) @@ -237,11 +237,11 @@ static int proc_lpevents_show(struct seq_file *m, void *v) seq_printf(m, "LpEventQueue 0\n"); seq_printf(m, " events processed:\t%lu\n", - (unsigned long)xItLpQueue.xLpIntCount); + (unsigned long)hvlpevent_queue.xLpIntCount); for (i = 0; i < 9; ++i) seq_printf(m, " %s %10lu\n", event_types[i], - (unsigned long)xItLpQueue.xLpIntCountByType[i]); + (unsigned long)hvlpevent_queue.xLpIntCountByType[i]); seq_printf(m, "\n events processed by processor:\n"); diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c index f42ee35f927..6ffcf67dd50 100644 --- a/arch/ppc64/kernel/LparData.c +++ b/arch/ppc64/kernel/LparData.c @@ -193,7 +193,7 @@ struct ItVpdAreas itVpdAreas = { 0,0,0, /* 13 - 15 */ sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */ 0,0,0,0,0,0, /* 17 - 22 */ - sizeof(struct ItLpQueue),/* 23 length of Lp Queue */ + sizeof(struct hvlpevent_queue), /* 23 length of Lp Queue */ 0,0 /* 24 - 25 */ }, .xSlicVpdAdrs = { /* VPD addresses */ @@ -211,7 +211,7 @@ struct ItVpdAreas itVpdAreas = { 0,0,0, /* 13 - 15 */ &xIoHriProcessorVpd, /* 16 Proc Vpd */ 0,0,0,0,0,0, /* 17 - 22 */ - &xItLpQueue, /* 23 Lp Queue */ + &hvlpevent_queue, /* 23 Lp Queue */ 0,0 } }; -- cgit v1.2.3 From 937b31b114b5540f456ce1566aae67e02db41f2c Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:15:42 +1000 Subject: [PATCH] ppc64: Rename ItLpQueue_* functions to hvlpevent_queue_* Now that we've renamed the xItLpQueue structure, rename the functions that operate on it also. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 12 ++++++------ arch/ppc64/kernel/idle.c | 4 ++-- arch/ppc64/kernel/irq.c | 4 ++-- arch/ppc64/kernel/mf.c | 4 ++-- arch/ppc64/kernel/time.c | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index e55fe1a2725..a81e49b91af 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -70,7 +70,7 @@ static __inline__ void clear_inUse(void) extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; unsigned long ItLpQueueInProcess = 0; -static struct HvLpEvent * ItLpQueue_getNextLpEvent(void) +static struct HvLpEvent * get_next_hvlpevent(void) { struct HvLpEvent * nextLpEvent = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; @@ -94,7 +94,7 @@ static struct HvLpEvent * ItLpQueue_getNextLpEvent(void) static unsigned long spread_lpevents = NR_CPUS; -int ItLpQueue_isLpIntPending(void) +int hvlpevent_is_pending(void) { struct HvLpEvent *next_event; @@ -105,7 +105,7 @@ int ItLpQueue_isLpIntPending(void) return next_event->xFlags.xValid | hvlpevent_queue.xPlicOverflowIntPending; } -static void ItLpQueue_clearValid( struct HvLpEvent * event ) +static void hvlpevent_clear_valid( struct HvLpEvent * event ) { /* Clear the valid bit of the event * Also clear bits within this event that might @@ -127,7 +127,7 @@ static void ItLpQueue_clearValid( struct HvLpEvent * event ) event->xFlags.xValid = 0; } -unsigned ItLpQueue_process(struct pt_regs *regs) +unsigned process_hvlpevents(struct pt_regs *regs) { unsigned numIntsProcessed = 0; struct HvLpEvent * nextLpEvent; @@ -142,7 +142,7 @@ unsigned ItLpQueue_process(struct pt_regs *regs) BUG(); for (;;) { - nextLpEvent = ItLpQueue_getNextLpEvent(); + nextLpEvent = get_next_hvlpevent(); if ( nextLpEvent ) { /* Count events to return to caller * and count processed events in hvlpevent_queue @@ -170,7 +170,7 @@ unsigned ItLpQueue_process(struct pt_regs *regs) else printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); - ItLpQueue_clearValid( nextLpEvent ); + hvlpevent_clear_valid( nextLpEvent ); } else if ( hvlpevent_queue.xPlicOverflowIntPending ) /* * No more valid events. If overflow events are diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index a7ebd0238d3..08952c7e621 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -88,7 +88,7 @@ static int iSeries_idle(void) while (1) { if (lpaca->lppaca.shared_proc) { - if (ItLpQueue_isLpIntPending()) + if (hvlpevent_is_pending()) process_iSeries_events(); if (!need_resched()) yield_shared_processor(); @@ -100,7 +100,7 @@ static int iSeries_idle(void) while (!need_resched()) { HMT_medium(); - if (ItLpQueue_isLpIntPending()) + if (hvlpevent_is_pending()) process_iSeries_events(); HMT_low(); } diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 46a7151ad6d..bd4b035af62 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -294,8 +294,8 @@ void do_IRQ(struct pt_regs *regs) iSeries_smp_message_recv(regs); } #endif /* CONFIG_SMP */ - if (ItLpQueue_isLpIntPending()) - lpevent_count += ItLpQueue_process(regs); + if (hvlpevent_is_pending()) + lpevent_count += process_hvlpevents(regs); irq_exit(); diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index ef920699802..609bf1bda7b 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c @@ -802,8 +802,8 @@ int mf_get_boot_rtc(struct rtc_time *tm) /* We need to poll here as we are not yet taking interrupts */ while (rtc_data.busy) { extern unsigned long lpevent_count; - if (ItLpQueue_isLpIntPending()) - lpevent_count += ItLpQueue_process(NULL); + if (hvlpevent_is_pending()) + lpevent_count += process_hvlpevents(NULL); } return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); } diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index c133f9c28c5..f9c18400ebf 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -367,8 +367,8 @@ int timer_interrupt(struct pt_regs * regs) set_dec(next_dec); #ifdef CONFIG_PPC_ISERIES - if (ItLpQueue_isLpIntPending()) - lpevent_count += ItLpQueue_process(regs); + if (hvlpevent_is_pending()) + lpevent_count += process_hvlpevents(regs); #endif /* collect purr register values often, for accurate calculations */ -- cgit v1.2.3 From 74889802a1585af4e1652f0cb853ac22a65816a4 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:15:53 +1000 Subject: [PATCH] ppc64: Don't count number of events processed for caller Currently we count the number of lpevents processed in 3 seperate places. One of these counters is never read, so just remove it. This means hvlpevent_queue_process() no longer needs to return the number of events processed. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 9 ++------- arch/ppc64/kernel/irq.c | 3 +-- arch/ppc64/kernel/mf.c | 3 +-- arch/ppc64/kernel/time.c | 3 +-- 4 files changed, 5 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index a81e49b91af..a849f6775ad 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -127,14 +127,14 @@ static void hvlpevent_clear_valid( struct HvLpEvent * event ) event->xFlags.xValid = 0; } -unsigned process_hvlpevents(struct pt_regs *regs) +void process_hvlpevents(struct pt_regs *regs) { unsigned numIntsProcessed = 0; struct HvLpEvent * nextLpEvent; /* If we have recursed, just return */ if ( !set_inUse() ) - return 0; + return; if (ItLpQueueInProcess == 0) ItLpQueueInProcess = 1; @@ -144,9 +144,6 @@ unsigned process_hvlpevents(struct pt_regs *regs) for (;;) { nextLpEvent = get_next_hvlpevent(); if ( nextLpEvent ) { - /* Count events to return to caller - * and count processed events in hvlpevent_queue - */ ++numIntsProcessed; hvlpevent_queue.xLpIntCount++; /* Call appropriate handler here, passing @@ -186,8 +183,6 @@ unsigned process_hvlpevents(struct pt_regs *regs) clear_inUse(); get_paca()->lpevent_count += numIntsProcessed; - - return numIntsProcessed; } static int set_spread_lpevents(char *str) diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index bd4b035af62..e79420bb72a 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -66,7 +66,6 @@ EXPORT_SYMBOL(irq_desc); int distribute_irqs = 1; int __irq_offset_value; int ppc_spurious_interrupts; -unsigned long lpevent_count; u64 ppc64_interrupt_controller; int show_interrupts(struct seq_file *p, void *v) @@ -295,7 +294,7 @@ void do_IRQ(struct pt_regs *regs) } #endif /* CONFIG_SMP */ if (hvlpevent_is_pending()) - lpevent_count += process_hvlpevents(regs); + process_hvlpevents(regs); irq_exit(); diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index 609bf1bda7b..ef4a338ebd0 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c @@ -801,9 +801,8 @@ int mf_get_boot_rtc(struct rtc_time *tm) return rc; /* We need to poll here as we are not yet taking interrupts */ while (rtc_data.busy) { - extern unsigned long lpevent_count; if (hvlpevent_is_pending()) - lpevent_count += process_hvlpevents(NULL); + process_hvlpevents(NULL); } return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); } diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index f9c18400ebf..909462e1ade 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -99,7 +99,6 @@ unsigned long tb_to_ns_shift; struct gettimeofday_struct do_gtod; extern unsigned long wall_jiffies; -extern unsigned long lpevent_count; extern int smp_tb_synchronized; extern struct timezone sys_tz; @@ -368,7 +367,7 @@ int timer_interrupt(struct pt_regs * regs) #ifdef CONFIG_PPC_ISERIES if (hvlpevent_is_pending()) - lpevent_count += process_hvlpevents(regs); + process_hvlpevents(regs); #endif /* collect purr register values often, for accurate calculations */ -- cgit v1.2.3 From ed094150bdeb6eca691f1b7a05bd34d4d1a95488 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:16:09 +1000 Subject: [PATCH] ppc64: Simplify counting of lpevents, remove lpevent_count from paca Currently there's a per-cpu count of lpevents processed, a per-queue (ie. global) total count, and a count by event type. Replace all that with a count by event for each cpu. We only need to add it up int the proc code. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 44 ++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index a849f6775ad..4a6ab9de629 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -28,7 +28,9 @@ */ struct hvlpevent_queue hvlpevent_queue __attribute__((__section__(".data"))); -static char *event_types[9] = { +DEFINE_PER_CPU(unsigned long[HvLpEvent_Type_NumTypes], hvlpevent_counts); + +static char *event_types[HvLpEvent_Type_NumTypes] = { "Hypervisor\t\t", "Machine Facilities\t", "Session Manager\t", @@ -129,7 +131,6 @@ static void hvlpevent_clear_valid( struct HvLpEvent * event ) void process_hvlpevents(struct pt_regs *regs) { - unsigned numIntsProcessed = 0; struct HvLpEvent * nextLpEvent; /* If we have recursed, just return */ @@ -144,8 +145,6 @@ void process_hvlpevents(struct pt_regs *regs) for (;;) { nextLpEvent = get_next_hvlpevent(); if ( nextLpEvent ) { - ++numIntsProcessed; - hvlpevent_queue.xLpIntCount++; /* Call appropriate handler here, passing * a pointer to the LpEvent. The handler * must make a copy of the LpEvent if it @@ -160,7 +159,7 @@ void process_hvlpevents(struct pt_regs *regs) * here! */ if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) - hvlpevent_queue.xLpIntCountByType[nextLpEvent->xType]++; + __get_cpu_var(hvlpevent_counts)[nextLpEvent->xType]++; if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && lpEventHandler[nextLpEvent->xType] ) lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); @@ -181,8 +180,6 @@ void process_hvlpevents(struct pt_regs *regs) ItLpQueueInProcess = 0; mb(); clear_inUse(); - - get_paca()->lpevent_count += numIntsProcessed; } static int set_spread_lpevents(char *str) @@ -228,20 +225,37 @@ void setup_hvlpevent_queue(void) static int proc_lpevents_show(struct seq_file *m, void *v) { - unsigned int i; + int cpu, i; + unsigned long sum; + static unsigned long cpu_totals[NR_CPUS]; + + /* FIXME: do we care that there's no locking here? */ + sum = 0; + for_each_online_cpu(cpu) { + cpu_totals[cpu] = 0; + for (i = 0; i < HvLpEvent_Type_NumTypes; i++) { + cpu_totals[cpu] += per_cpu(hvlpevent_counts, cpu)[i]; + } + sum += cpu_totals[cpu]; + } seq_printf(m, "LpEventQueue 0\n"); - seq_printf(m, " events processed:\t%lu\n", - (unsigned long)hvlpevent_queue.xLpIntCount); + seq_printf(m, " events processed:\t%lu\n", sum); - for (i = 0; i < 9; ++i) - seq_printf(m, " %s %10lu\n", event_types[i], - (unsigned long)hvlpevent_queue.xLpIntCountByType[i]); + for (i = 0; i < HvLpEvent_Type_NumTypes; ++i) { + sum = 0; + for_each_online_cpu(cpu) { + sum += per_cpu(hvlpevent_counts, cpu)[i]; + } + + seq_printf(m, " %s %10lu\n", event_types[i], sum); + } seq_printf(m, "\n events processed by processor:\n"); - for_each_online_cpu(i) - seq_printf(m, " CPU%02d %10u\n", i, paca[i].lpevent_count); + for_each_online_cpu(cpu) { + seq_printf(m, " CPU%02d %10lu\n", cpu, cpu_totals[cpu]); + } return 0; } -- cgit v1.2.3 From 9b0470200a2441766599ad84f92ab9daca8ed86d Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:16:18 +1000 Subject: [PATCH] ppc64: Cleanup proc printing of event types The code that prints event counts by type uses a hand-coded number of tabs to get the alignment right. Instead use a printf alignment which will allow allow us to use the event_type strings elsewhere in the future. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 4a6ab9de629..83fb36a9bc0 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -31,15 +31,15 @@ struct hvlpevent_queue hvlpevent_queue __attribute__((__section__(".data"))); DEFINE_PER_CPU(unsigned long[HvLpEvent_Type_NumTypes], hvlpevent_counts); static char *event_types[HvLpEvent_Type_NumTypes] = { - "Hypervisor\t\t", - "Machine Facilities\t", - "Session Manager\t", - "SPD I/O\t\t", - "Virtual Bus\t\t", - "PCI I/O\t\t", - "RIO I/O\t\t", - "Virtual Lan\t\t", - "Virtual I/O\t\t" + "Hypervisor", + "Machine Facilities", + "Session Manager", + "SPD I/O", + "Virtual Bus", + "PCI I/O", + "RIO I/O", + "Virtual Lan", + "Virtual I/O" }; static __inline__ int set_inUse(void) @@ -248,7 +248,7 @@ static int proc_lpevents_show(struct seq_file *m, void *v) sum += per_cpu(hvlpevent_counts, cpu)[i]; } - seq_printf(m, " %s %10lu\n", event_types[i], sum); + seq_printf(m, " %-20s %10lu\n", event_types[i], sum); } seq_printf(m, "\n events processed by processor:\n"); -- cgit v1.2.3 From 38fcdcfe38fc3f8972c906db64cd7d540b7760e8 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:16:28 +1000 Subject: [PATCH] ppc64: Cleanup whitespace in arch/ppc64/kernel/ItLpQueue.c Just cleanup white space. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 58 +++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 83fb36a9bc0..61a9dbdd295 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -1,7 +1,7 @@ /* * ItLpQueue.c * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -74,21 +74,21 @@ unsigned long ItLpQueueInProcess = 0; static struct HvLpEvent * get_next_hvlpevent(void) { - struct HvLpEvent * nextLpEvent = + struct HvLpEvent * nextLpEvent = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; - if ( nextLpEvent->xFlags.xValid ) { + if (nextLpEvent->xFlags.xValid) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ hvlpevent_queue.xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + - LpEventAlign ) / - LpEventAlign ) * + LpEventAlign) / + LpEventAlign) * LpEventAlign; /* Wrap to beginning if no room at end */ if (hvlpevent_queue.xSlicCurEventPtr > hvlpevent_queue.xSlicLastValidEventPtr) hvlpevent_queue.xSlicCurEventPtr = hvlpevent_queue.xSlicEventStackPtr; } - else + else nextLpEvent = NULL; return nextLpEvent; @@ -107,23 +107,23 @@ int hvlpevent_is_pending(void) return next_event->xFlags.xValid | hvlpevent_queue.xPlicOverflowIntPending; } -static void hvlpevent_clear_valid( struct HvLpEvent * event ) +static void hvlpevent_clear_valid(struct HvLpEvent * event) { /* Clear the valid bit of the event * Also clear bits within this event that might * look like valid bits (on 64-byte boundaries) - */ - unsigned extra = (( event->xSizeMinus1 + LpEventAlign ) / - LpEventAlign ) - 1; - switch ( extra ) { - case 3: + */ + unsigned extra = ((event->xSizeMinus1 + LpEventAlign) / + LpEventAlign) - 1; + switch (extra) { + case 3: ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0; - case 2: + case 2: ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0; - case 1: + case 1: ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0; - case 0: - ; + case 0: + ; } mb(); event->xFlags.xValid = 0; @@ -136,7 +136,7 @@ void process_hvlpevents(struct pt_regs *regs) /* If we have recursed, just return */ if ( !set_inUse() ) return; - + if (ItLpQueueInProcess == 0) ItLpQueueInProcess = 1; else @@ -144,35 +144,35 @@ void process_hvlpevents(struct pt_regs *regs) for (;;) { nextLpEvent = get_next_hvlpevent(); - if ( nextLpEvent ) { - /* Call appropriate handler here, passing + if (nextLpEvent) { + /* Call appropriate handler here, passing * a pointer to the LpEvent. The handler * must make a copy of the LpEvent if it * needs it in a bottom half. (perhaps for * an ACK) - * - * Handlers are responsible for ACK processing + * + * Handlers are responsible for ACK processing * * The Hypervisor guarantees that LpEvents will * only be delivered with types that we have * registered for, so no type check is necessary * here! - */ - if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) + */ + if (nextLpEvent->xType < HvLpEvent_Type_NumTypes) __get_cpu_var(hvlpevent_counts)[nextLpEvent->xType]++; - if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && - lpEventHandler[nextLpEvent->xType] ) + if (nextLpEvent->xType < HvLpEvent_Type_NumTypes && + lpEventHandler[nextLpEvent->xType]) lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); else printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); - - hvlpevent_clear_valid( nextLpEvent ); - } else if ( hvlpevent_queue.xPlicOverflowIntPending ) + + hvlpevent_clear_valid(nextLpEvent); + } else if (hvlpevent_queue.xPlicOverflowIntPending) /* * No more valid events. If overflow events are * pending process them */ - HvCallEvent_getOverflowLpEvents( hvlpevent_queue.xIndex); + HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex); else break; } -- cgit v1.2.3 From ffe1b7e14e6b606bd84cab564aa2f481dbd4e418 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:16:48 +1000 Subject: [PATCH] ppc64: Formatting cleanups in arch/ppc64/kernel/ItLpQueue.c Just formatting cleanups: * rename some "nextLpEvent" variables to just "event" * make code fit in 80 columns * use brackets around if/else * use a temporary to make hvlpevent_clear_valid clearer Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 72 ++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 61a9dbdd295..a4f32cbf529 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -74,24 +74,27 @@ unsigned long ItLpQueueInProcess = 0; static struct HvLpEvent * get_next_hvlpevent(void) { - struct HvLpEvent * nextLpEvent = - (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; - if (nextLpEvent->xFlags.xValid) { + struct HvLpEvent * event; + event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + + if (event->xFlags.xValid) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ - hvlpevent_queue.xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + - LpEventAlign) / - LpEventAlign) * - LpEventAlign; + hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 + + LpEventAlign) / LpEventAlign) * LpEventAlign; + /* Wrap to beginning if no room at end */ - if (hvlpevent_queue.xSlicCurEventPtr > hvlpevent_queue.xSlicLastValidEventPtr) - hvlpevent_queue.xSlicCurEventPtr = hvlpevent_queue.xSlicEventStackPtr; + if (hvlpevent_queue.xSlicCurEventPtr > + hvlpevent_queue.xSlicLastValidEventPtr) { + hvlpevent_queue.xSlicCurEventPtr = + hvlpevent_queue.xSlicEventStackPtr; + } + } else { + event = NULL; } - else - nextLpEvent = NULL; - return nextLpEvent; + return event; } static unsigned long spread_lpevents = NR_CPUS; @@ -104,34 +107,41 @@ int hvlpevent_is_pending(void) return 0; next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; - return next_event->xFlags.xValid | hvlpevent_queue.xPlicOverflowIntPending; + + return next_event->xFlags.xValid | + hvlpevent_queue.xPlicOverflowIntPending; } static void hvlpevent_clear_valid(struct HvLpEvent * event) { - /* Clear the valid bit of the event - * Also clear bits within this event that might - * look like valid bits (on 64-byte boundaries) + /* Tell the Hypervisor that we're done with this event. + * Also clear bits within this event that might look like valid bits. + * ie. on 64-byte boundaries. */ + struct HvLpEvent *tmp; unsigned extra = ((event->xSizeMinus1 + LpEventAlign) / LpEventAlign) - 1; + switch (extra) { case 3: - ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0; + tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign); + tmp->xFlags.xValid = 0; case 2: - ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0; + tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign); + tmp->xFlags.xValid = 0; case 1: - ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0; - case 0: - ; + tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign); + tmp->xFlags.xValid = 0; } + mb(); + event->xFlags.xValid = 0; } void process_hvlpevents(struct pt_regs *regs) { - struct HvLpEvent * nextLpEvent; + struct HvLpEvent * event; /* If we have recursed, just return */ if ( !set_inUse() ) @@ -143,8 +153,8 @@ void process_hvlpevents(struct pt_regs *regs) BUG(); for (;;) { - nextLpEvent = get_next_hvlpevent(); - if (nextLpEvent) { + event = get_next_hvlpevent(); + if (event) { /* Call appropriate handler here, passing * a pointer to the LpEvent. The handler * must make a copy of the LpEvent if it @@ -158,15 +168,15 @@ void process_hvlpevents(struct pt_regs *regs) * registered for, so no type check is necessary * here! */ - if (nextLpEvent->xType < HvLpEvent_Type_NumTypes) - __get_cpu_var(hvlpevent_counts)[nextLpEvent->xType]++; - if (nextLpEvent->xType < HvLpEvent_Type_NumTypes && - lpEventHandler[nextLpEvent->xType]) - lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); + if (event->xType < HvLpEvent_Type_NumTypes) + __get_cpu_var(hvlpevent_counts)[event->xType]++; + if (event->xType < HvLpEvent_Type_NumTypes && + lpEventHandler[event->xType]) + lpEventHandler[event->xType](event, regs); else - printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); + printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); - hvlpevent_clear_valid(nextLpEvent); + hvlpevent_clear_valid(event); } else if (hvlpevent_queue.xPlicOverflowIntPending) /* * No more valid events. If overflow events are -- cgit v1.2.3 From 719d1cd86780c156f954fc34f34481adac197aec Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:17:02 +1000 Subject: [PATCH] ppc64: Replace custom locking code with a spinlock The hvlpevent_queue (formally ItLpQueue) has a member called xInUseWord which is used for serialising access to the queue. Because it's a word (ie. 32 bit) there's a custom 32-bit version of test_and_set_bit() or thereabouts in ItLpQueue.c. The xInUseWord is not shared with they hypervisor, so we can replace it with a spinlock and remove the custom code. There is also another locking mechanism (ItLpQueueInProcess). This is redundant because it's only manipulated while the lock's held. Remove it. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 38 ++------------------------------------ 1 file changed, 2 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index a4f32cbf529..4231861288a 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -42,35 +42,8 @@ static char *event_types[HvLpEvent_Type_NumTypes] = { "Virtual I/O" }; -static __inline__ int set_inUse(void) -{ - int t; - u32 * inUseP = &hvlpevent_queue.xInUseWord; - - __asm__ __volatile__("\n\ -1: lwarx %0,0,%2 \n\ - cmpwi 0,%0,0 \n\ - li %0,0 \n\ - bne- 2f \n\ - addi %0,%0,1 \n\ - stwcx. %0,0,%2 \n\ - bne- 1b \n\ -2: eieio" - : "=&r" (t), "=m" (hvlpevent_queue.xInUseWord) - : "r" (inUseP), "m" (hvlpevent_queue.xInUseWord) - : "cc"); - - return t; -} - -static __inline__ void clear_inUse(void) -{ - hvlpevent_queue.xInUseWord = 0; -} - /* Array of LpEvent handler functions */ extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; -unsigned long ItLpQueueInProcess = 0; static struct HvLpEvent * get_next_hvlpevent(void) { @@ -144,14 +117,9 @@ void process_hvlpevents(struct pt_regs *regs) struct HvLpEvent * event; /* If we have recursed, just return */ - if ( !set_inUse() ) + if (!spin_trylock(&hvlpevent_queue.lock)) return; - if (ItLpQueueInProcess == 0) - ItLpQueueInProcess = 1; - else - BUG(); - for (;;) { event = get_next_hvlpevent(); if (event) { @@ -187,9 +155,7 @@ void process_hvlpevents(struct pt_regs *regs) break; } - ItLpQueueInProcess = 0; - mb(); - clear_inUse(); + spin_unlock(&hvlpevent_queue.lock); } static int set_spread_lpevents(char *str) -- cgit v1.2.3