Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 190816
b: refs/heads/master
c: 0fe1ac4
h: refs/heads/master
v: v3
  • Loading branch information
Paul Mackerras authored and Benjamin Herrenschmidt committed May 12, 2010
1 parent 7d6eb99 commit 7084446
Show file tree
Hide file tree
Showing 25 changed files with 224 additions and 206 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5ec390e046039942d59ef2634b967b8b23fc57c2
refs/heads/master: 0fe1ac48bef018bed896307cd12f6ca9b5e704ab
38 changes: 0 additions & 38 deletions trunk/arch/powerpc/include/asm/hw_irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,43 +130,5 @@ static inline int irqs_disabled_flags(unsigned long flags)
*/
struct irq_chip;

#ifdef CONFIG_PERF_EVENTS

#ifdef CONFIG_PPC64
static inline unsigned long test_perf_event_pending(void)
{
unsigned long x;

asm volatile("lbz %0,%1(13)"
: "=r" (x)
: "i" (offsetof(struct paca_struct, perf_event_pending)));
return x;
}

static inline void set_perf_event_pending(void)
{
asm volatile("stb %0,%1(13)" : :
"r" (1),
"i" (offsetof(struct paca_struct, perf_event_pending)));
}

static inline void clear_perf_event_pending(void)
{
asm volatile("stb %0,%1(13)" : :
"r" (0),
"i" (offsetof(struct paca_struct, perf_event_pending)));
}
#endif /* CONFIG_PPC64 */

#else /* CONFIG_PERF_EVENTS */

static inline unsigned long test_perf_event_pending(void)
{
return 0;
}

static inline void clear_perf_event_pending(void) {}
#endif /* CONFIG_PERF_EVENTS */

#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_HW_IRQ_H */
1 change: 0 additions & 1 deletion trunk/arch/powerpc/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ int main(void)
DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_event_pending));
DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
#ifdef CONFIG_PPC_MM_SLICES
DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
Expand Down
9 changes: 0 additions & 9 deletions trunk/arch/powerpc/kernel/entry_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -556,15 +556,6 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
2:
TRACE_AND_RESTORE_IRQ(r5);

#ifdef CONFIG_PERF_EVENTS
/* check paca->perf_event_pending if we're enabling ints */
lbz r3,PACAPERFPEND(r13)
and. r3,r3,r5
beq 27f
bl .perf_event_do_pending
27:
#endif /* CONFIG_PERF_EVENTS */

/* extract EE bit and use it to restore paca->hard_enabled */
ld r3,_MSR(r1)
rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
Expand Down
6 changes: 0 additions & 6 deletions trunk/arch/powerpc/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
#include <linux/bootmem.h>
#include <linux/pci.h>
#include <linux/debugfs.h>
#include <linux/perf_event.h>

#include <asm/uaccess.h>
#include <asm/system.h>
Expand Down Expand Up @@ -145,11 +144,6 @@ notrace void raw_local_irq_restore(unsigned long en)
}
#endif /* CONFIG_PPC_STD_MMU_64 */

if (test_perf_event_pending()) {
clear_perf_event_pending();
perf_event_do_pending();
}

/*
* if (get_paca()->hard_enabled) return;
* But again we need to take care that gcc gets hard_enabled directly
Expand Down
60 changes: 48 additions & 12 deletions trunk/arch/powerpc/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -532,25 +532,60 @@ void __init iSeries_time_init_early(void)
}
#endif /* CONFIG_PPC_ISERIES */

#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_PPC32)
DEFINE_PER_CPU(u8, perf_event_pending);
#ifdef CONFIG_PERF_EVENTS

void set_perf_event_pending(void)
/*
* 64-bit uses a byte in the PACA, 32-bit uses a per-cpu variable...
*/
#ifdef CONFIG_PPC64
static inline unsigned long test_perf_event_pending(void)
{
get_cpu_var(perf_event_pending) = 1;
set_dec(1);
put_cpu_var(perf_event_pending);
unsigned long x;

asm volatile("lbz %0,%1(13)"
: "=r" (x)
: "i" (offsetof(struct paca_struct, perf_event_pending)));
return x;
}

static inline void set_perf_event_pending_flag(void)
{
asm volatile("stb %0,%1(13)" : :
"r" (1),
"i" (offsetof(struct paca_struct, perf_event_pending)));
}

static inline void clear_perf_event_pending(void)
{
asm volatile("stb %0,%1(13)" : :
"r" (0),
"i" (offsetof(struct paca_struct, perf_event_pending)));
}

#else /* 32-bit */

DEFINE_PER_CPU(u8, perf_event_pending);

#define set_perf_event_pending_flag() __get_cpu_var(perf_event_pending) = 1
#define test_perf_event_pending() __get_cpu_var(perf_event_pending)
#define clear_perf_event_pending() __get_cpu_var(perf_event_pending) = 0

#else /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */
#endif /* 32 vs 64 bit */

void set_perf_event_pending(void)
{
preempt_disable();
set_perf_event_pending_flag();
set_dec(1);
preempt_enable();
}

#else /* CONFIG_PERF_EVENTS */

#define test_perf_event_pending() 0
#define clear_perf_event_pending()

#endif /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */
#endif /* CONFIG_PERF_EVENTS */

/*
* For iSeries shared processors, we have to let the hypervisor
Expand Down Expand Up @@ -582,10 +617,6 @@ void timer_interrupt(struct pt_regs * regs)
set_dec(DECREMENTER_MAX);

#ifdef CONFIG_PPC32
if (test_perf_event_pending()) {
clear_perf_event_pending();
perf_event_do_pending();
}
if (atomic_read(&ppc_n_lost_interrupts) != 0)
do_IRQ(regs);
#endif
Expand All @@ -604,6 +635,11 @@ void timer_interrupt(struct pt_regs * regs)

calculate_steal_time();

if (test_perf_event_pending()) {
clear_perf_event_pending();
perf_event_do_pending();
}

#ifdef CONFIG_PPC_ISERIES
if (firmware_has_feature(FW_FEATURE_ISERIES))
get_lppaca()->int_dword.fields.decr_int = 0;
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/s390/kernel/head31.S
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ startup_continue:
_ehead:

#ifdef CONFIG_SHARED_KERNEL
.org 0x100000 - 0x11000 # head.o ends at 0x11000
.org 0x100000
#endif

#
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/s390/kernel/head64.S
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ startup_continue:
_ehead:

#ifdef CONFIG_SHARED_KERNEL
.org 0x100000 - 0x11000 # head.o ends at 0x11000
.org 0x100000
#endif

#
Expand Down
5 changes: 3 additions & 2 deletions trunk/arch/s390/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,

asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
{
long ret = 0;
long ret;

/* Do the secure computing check first. */
secure_computing(regs->gprs[2]);
Expand All @@ -649,6 +649,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
* The sysc_tracesys code in entry.S stored the system
* call number to gprs[2].
*/
ret = regs->gprs[2];
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
(tracehook_report_syscall_entry(regs) ||
regs->gprs[2] >= NR_syscalls)) {
Expand All @@ -670,7 +671,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
regs->gprs[2], regs->orig_gpr2,
regs->gprs[3], regs->gprs[4],
regs->gprs[5]);
return ret ?: regs->gprs[2];
return ret;
}

asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
Expand Down
114 changes: 112 additions & 2 deletions trunk/drivers/pci/setup-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -838,21 +838,131 @@ static void pci_bus_dump_resources(struct pci_bus *bus)
}
}

static int __init pci_bus_get_depth(struct pci_bus *bus)
{
int depth = 0;
struct pci_dev *dev;

list_for_each_entry(dev, &bus->devices, bus_list) {
int ret;
struct pci_bus *b = dev->subordinate;
if (!b)
continue;

ret = pci_bus_get_depth(b);
if (ret + 1 > depth)
depth = ret + 1;
}

return depth;
}
static int __init pci_get_max_depth(void)
{
int depth = 0;
struct pci_bus *bus;

list_for_each_entry(bus, &pci_root_buses, node) {
int ret;

ret = pci_bus_get_depth(bus);
if (ret > depth)
depth = ret;
}

return depth;
}

/*
* first try will not touch pci bridge res
* second and later try will clear small leaf bridge res
* will stop till to the max deepth if can not find good one
*/
void __init
pci_assign_unassigned_resources(void)
{
struct pci_bus *bus;
int tried_times = 0;
enum release_type rel_type = leaf_only;
struct resource_list_x head, *list;
unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
IORESOURCE_PREFETCH;
unsigned long failed_type;
int max_depth = pci_get_max_depth();
int pci_try_num;

head.next = NULL;

pci_try_num = max_depth + 1;
printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
max_depth, pci_try_num);

again:
/* Depth first, calculate sizes and alignments of all
subordinate buses. */
list_for_each_entry(bus, &pci_root_buses, node) {
pci_bus_size_bridges(bus);
}
/* Depth last, allocate resources and update the hardware. */
list_for_each_entry(bus, &pci_root_buses, node) {
pci_bus_assign_resources(bus);
pci_enable_bridges(bus);
__pci_bus_assign_resources(bus, &head);
}
tried_times++;

/* any device complain? */
if (!head.next)
goto enable_and_dump;
failed_type = 0;
for (list = head.next; list;) {
failed_type |= list->flags;
list = list->next;
}
/*
* io port are tight, don't try extra
* or if reach the limit, don't want to try more
*/
failed_type &= type_mask;
if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) {
free_failed_list(&head);
goto enable_and_dump;
}

printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
tried_times + 1);

/* third times and later will not check if it is leaf */
if ((tried_times + 1) > 2)
rel_type = whole_subtree;

/*
* Try to release leaf bridge's resources that doesn't fit resource of
* child device under that bridge
*/
for (list = head.next; list;) {
bus = list->dev->bus;
pci_bus_release_bridge_resources(bus, list->flags & type_mask,
rel_type);
list = list->next;
}
/* restore size and flags */
for (list = head.next; list;) {
struct resource *res = list->res;

res->start = list->start;
res->end = list->end;
res->flags = list->flags;
if (list->dev->subordinate)
res->flags = 0;

list = list->next;
}
free_failed_list(&head);

goto again;

enable_and_dump:
/* Depth last, update the hardware. */
list_for_each_entry(bus, &pci_root_buses, node)
pci_enable_bridges(bus);

/* dump the resource on buses */
list_for_each_entry(bus, &pci_root_buses, node) {
Expand Down
Loading

0 comments on commit 7084446

Please sign in to comment.