Re: [PATCH net-next 0/6] bpf: Enable BPF JIT on ppc32
On 2/15/15, Daniel Borkmann wrote: > On 02/15/2015 07:06 PM, Denis Kirjanov wrote: >> This patch series enables BPF JIT on ppc32. There are relatevily >> few chnages in the code to make it work. >> >> All test_bpf tests passed both on 7447a and P2041-based machines. > > I'm just wondering, next to the feedback that has already been > provided, would opening this up for ppc32 make it significantly > more difficult in future to migrate from classic BPF JIT to eBPF > JIT eventually (which is what we want long-term)? Being curious, > is there any ongoing effort from ppc people? > Well, I don't see significant challenges to enable eBPF on ppc64 in the future. I'll start working on it after I get this merged ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] tick/broadcast-hrtimer : Fix suspicious RCU usage in idle loop
The hrtimer mode of broadcast queues hrtimers in the idle entry path so as to wakeup cpus in deep idle states. hrtimer_{start/cancel} functions call into tracing which uses RCU. But it is not legal to call into RCU in cpuidle because it is one of the quiescent states. Hence protect this region with RCU_NONIDLE which informs RCU that the cpu is momentarily non-idle. Signed-off-by: Preeti U Murthy Reviewed-by: Paul E. McKenney --- kernel/time/tick-broadcast-hrtimer.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/kernel/time/tick-broadcast-hrtimer.c b/kernel/time/tick-broadcast-hrtimer.c index eb682d5..6aac4be 100644 --- a/kernel/time/tick-broadcast-hrtimer.c +++ b/kernel/time/tick-broadcast-hrtimer.c @@ -49,6 +49,7 @@ static void bc_set_mode(enum clock_event_mode mode, */ static int bc_set_next(ktime_t expires, struct clock_event_device *bc) { + int bc_moved; /* * We try to cancel the timer first. If the callback is on * flight on some other cpu then we let it handle it. If we @@ -60,9 +61,15 @@ static int bc_set_next(ktime_t expires, struct clock_event_device *bc) * restart the timer because we are in the callback, but we * can set the expiry time and let the callback return * HRTIMER_RESTART. +* +* Since we are in the idle loop at this point and because +* hrtimer_{start/cancel} functions call into tracing, +* calls to these functions must be bound within RCU_NONIDLE. */ - if (hrtimer_try_to_cancel(&bctimer) >= 0) { - hrtimer_start(&bctimer, expires, HRTIMER_MODE_ABS_PINNED); + RCU_NONIDLE(bc_moved = (hrtimer_try_to_cancel(&bctimer) >= 0) ? + !hrtimer_start(&bctimer, expires, HRTIMER_MODE_ABS_PINNED) : + 0); + if (bc_moved) { /* Bind the "device" to the cpu */ bc->bound_on = smp_processor_id(); } else if (bc->bound_on == smp_processor_id()) { ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: suspicious RCU usage clockevents_lock, tick_broadcast_lock, hrtimer_bases.lock
On 02/16/2015 11:20 AM, Paul E. McKenney wrote: > On Mon, Feb 16, 2015 at 08:49:12AM +0530, Preeti U Murthy wrote: >> On 02/13/2015 07:56 PM, Paul E. McKenney wrote: >>> On Fri, Feb 13, 2015 at 12:52:45PM +0530, Preeti U Murthy wrote: On 02/13/2015 10:57 AM, Preeti U Murthy wrote: > On 02/13/2015 06:27 AM, Sam Bobroff wrote: >> Hello, >> >> I'm receiving this while booting a vanilla 3.19 kernel on a Power 8 >> machine: > > Does the below patch fix the issue ? > > From: Preeti U Murthy > > [PATCH] tick/hrtimer-broadcast: Fix a suspicious RCU usage in the tick > broadcast path > > --- > kernel/time/tick-broadcast-hrtimer.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/kernel/time/tick-broadcast-hrtimer.c > b/kernel/time/tick-broadcast-hrtimer.c > index eb682d5..57b8e32 100644 > --- a/kernel/time/tick-broadcast-hrtimer.c > +++ b/kernel/time/tick-broadcast-hrtimer.c > @@ -62,7 +62,7 @@ static int bc_set_next(ktime_t expires, struct > clock_event_device *bc) > * HRTIMER_RESTART. > */ > if (hrtimer_try_to_cancel(&bctimer) >= 0) { > - hrtimer_start(&bctimer, expires, HRTIMER_MODE_ABS_PINNED); > + RCU_NONIDLE(hrtimer_start(&bctimer, expires, > HRTIMER_MODE_ABS_PINNED)); > /* Bind the "device" to the cpu */ > bc->bound_on = smp_processor_id(); > } else if (bc->bound_on == smp_processor_id()) { > Actually the below patch is the complete fix. Paul can you please review this ? As an alternate solution I checked to see if its possible to move rcu_idle_enter()/exit() closer to the cpuidle_enter() call, but that won't work as you may have already tried earlier. - tick/broadcast-hrtimer : Fix suspicious RCU usage in idle loop From: Preeti U Murthy The hrtimer mode of broadcast queues hrtimers in the idle entry path so as to wakeup cpus in deep idle states. hrtimer_{start/cancel} functions call into tracing which uses RCU. But it is not legal to call into RCU in cpuidle because it is one of the quiescent states. Hence protect this region with RCU_NONIDLE which informs RCU that the cpu is momentarily non-idle. Signed-off-by: Preeti U Murthy >>> >>> Reviewed-by: Paul E. McKenney >>> >>> Another alternative would be to change the hrtimer_{start/cancel}() >>> functions' tracepoints to the _rcuidle form. The advantage of this >>> approach is less RCU-notification overhead when tracing is enabled. >> >> But since the hrtimer_{start/cancel} functions' tracepoints are more >> often called from paths which are in the non-quiescent states, wouldn't >> we be doing an rcu_irq_enter/exit() redundantly far too often in that case ? > > And the other advantage of doing it the way you did (and I -did- give > you a Reviewed-by!) is that you are incurring the extra overhead from > the idle loop, where that extra overhead is less likely to be holding > something else up. So, yes, I do agree with your patch. Ok. I was just unsure which approach you meant by 'this' in the above statement 'The advantage of this approach is less RCU-notification overhead..'. Hence wanted to make sure that I had understood you right. Alright, I'll send out this patch to tglx with your Reviewed-by then. Thanks! Regards Preeti U Murthy > Thanx, Paul > > ___ > Linuxppc-dev mailing list > Linuxppc-dev@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/linuxppc-dev > ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: suspicious RCU usage clockevents_lock, tick_broadcast_lock, hrtimer_bases.lock
On Mon, Feb 16, 2015 at 08:49:12AM +0530, Preeti U Murthy wrote: > On 02/13/2015 07:56 PM, Paul E. McKenney wrote: > > On Fri, Feb 13, 2015 at 12:52:45PM +0530, Preeti U Murthy wrote: > >> On 02/13/2015 10:57 AM, Preeti U Murthy wrote: > >>> On 02/13/2015 06:27 AM, Sam Bobroff wrote: > Hello, > > I'm receiving this while booting a vanilla 3.19 kernel on a Power 8 > machine: > >>> > >>> Does the below patch fix the issue ? > >>> > >>> From: Preeti U Murthy > >>> > >>> [PATCH] tick/hrtimer-broadcast: Fix a suspicious RCU usage in the tick > >>> broadcast path > >>> > >>> --- > >>> kernel/time/tick-broadcast-hrtimer.c | 2 +- > >>> 1 file changed, 1 insertion(+), 1 deletion(-) > >>> > >>> diff --git a/kernel/time/tick-broadcast-hrtimer.c > >>> b/kernel/time/tick-broadcast-hrtimer.c > >>> index eb682d5..57b8e32 100644 > >>> --- a/kernel/time/tick-broadcast-hrtimer.c > >>> +++ b/kernel/time/tick-broadcast-hrtimer.c > >>> @@ -62,7 +62,7 @@ static int bc_set_next(ktime_t expires, struct > >>> clock_event_device *bc) > >>> * HRTIMER_RESTART. > >>> */ > >>> if (hrtimer_try_to_cancel(&bctimer) >= 0) { > >>> - hrtimer_start(&bctimer, expires, HRTIMER_MODE_ABS_PINNED); > >>> + RCU_NONIDLE(hrtimer_start(&bctimer, expires, > >>> HRTIMER_MODE_ABS_PINNED)); > >>> /* Bind the "device" to the cpu */ > >>> bc->bound_on = smp_processor_id(); > >>> } else if (bc->bound_on == smp_processor_id()) { > >>> > >> Actually the below patch is the complete fix. Paul can you please > >> review this ? As an alternate solution I checked to see if its > >> possible to move rcu_idle_enter()/exit() closer to the > >> cpuidle_enter() call, but that won't work as you may have already > >> tried earlier. > >> > >> - > >> > >> tick/broadcast-hrtimer : Fix suspicious RCU usage in idle loop > >> > >> From: Preeti U Murthy > >> > >> The hrtimer mode of broadcast queues hrtimers in the idle entry > >> path so as to wakeup cpus in deep idle states. hrtimer_{start/cancel} > >> functions call into tracing which uses RCU. But it is not legal to call > >> into RCU in cpuidle because it is one of the quiescent states. Hence > >> protect this region with RCU_NONIDLE which informs RCU that the cpu > >> is momentarily non-idle. > >> > >> Signed-off-by: Preeti U Murthy > > > > Reviewed-by: Paul E. McKenney > > > > Another alternative would be to change the hrtimer_{start/cancel}() > > functions' tracepoints to the _rcuidle form. The advantage of this > > approach is less RCU-notification overhead when tracing is enabled. > > But since the hrtimer_{start/cancel} functions' tracepoints are more > often called from paths which are in the non-quiescent states, wouldn't > we be doing an rcu_irq_enter/exit() redundantly far too often in that case ? And the other advantage of doing it the way you did (and I -did- give you a Reviewed-by!) is that you are incurring the extra overhead from the idle loop, where that extra overhead is less likely to be holding something else up. So, yes, I do agree with your patch. Thanx, Paul ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: re-enable dynticks
On Mon, 2015-02-16 at 11:08 +1100, Michael Ellerman wrote: > On Fri, 2015-02-13 at 13:38 -0600, Paul Clarke wrote: > > implement arch_irq_work_has_interrupt() for powerpc > > > > Commit 9b01f5bf3 introduced a dependency on "IRQ work self-IPIs" for > > full dynamic ticks to be enabled, by expecting architectures to > > implement a suitable arch_irq_work_has_interrupt() routine. > > > > Several arches have implemented this routine, including x86 (3010279f) > > and arm (09f6edd4), but powerpc was omitted. > > > > This patch implements this routine for powerpc. > > .../... > > It makes the message change, but is that correct? ie. do we actually implement > "IRQ work self-IPIs"? I think so... Fred, do you think what we do will work ? We hijack our decrementer (local timer) by making it shoot almost immediately (1 tick away) and run the irq work at the beginning of __timer_interrupt(). At that point we are on our irq stack and have done irq_enter but that's about it. Cheers, Ben. > > diff --git a/arch/powerpc/include/asm/irq_work.h > > b/arch/powerpc/include/asm/irq_work.h > > new file mode 100644 > > index 000..18365ec > > --- /dev/null > > +++ b/arch/powerpc/include/asm/irq_work.h > > @@ -0,0 +1,11 @@ > > +#ifndef _ASM_IRQ_WORK_H > > +#define _ASM_IRQ_WORK_H > > + > > +#include > > + > > +static inline bool arch_irq_work_has_interrupt(void) > > +{ > > + return 1; > > Should be "true"; > > > +} > > cheers > > > ___ > Linuxppc-dev mailing list > Linuxppc-dev@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/linuxppc-dev ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 07/10] powerpc/powernv: Drop PHB operation get_state()
The patch drops PHB EEH operation get_state() and merges its logic to eeh_ops::get_state(). Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/eeh-ioda.c| 170 +--- arch/powerpc/platforms/powernv/eeh-powernv.c | 185 --- arch/powerpc/platforms/powernv/pci.h | 1 - 3 files changed, 170 insertions(+), 186 deletions(-) diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 349c083..dc34c36 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c @@ -46,173 +46,6 @@ static void ioda_eeh_phb_diag(struct eeh_pe *pe) __func__, pe->phb->global_number, rc); } -static int ioda_eeh_get_phb_state(struct eeh_pe *pe) -{ - struct pnv_phb *phb = pe->phb->private_data; - u8 fstate; - __be16 pcierr; - s64 rc; - int result = 0; - - rc = opal_pci_eeh_freeze_status(phb->opal_id, - pe->addr, - &fstate, - &pcierr, - NULL); - if (rc != OPAL_SUCCESS) { - pr_warn("%s: Failure %lld getting PHB#%x state\n", - __func__, rc, phb->hose->global_number); - return EEH_STATE_NOT_SUPPORT; - } - - /* -* Check PHB state. If the PHB is frozen for the -* first time, to dump the PHB diag-data. -*/ - if (be16_to_cpu(pcierr) != OPAL_EEH_PHB_ERROR) { - result = (EEH_STATE_MMIO_ACTIVE | - EEH_STATE_DMA_ACTIVE | - EEH_STATE_MMIO_ENABLED | - EEH_STATE_DMA_ENABLED); - } else if (!(pe->state & EEH_PE_ISOLATED)) { - eeh_pe_state_mark(pe, EEH_PE_ISOLATED); - ioda_eeh_phb_diag(pe); - - if (eeh_has_flag(EEH_EARLY_DUMP_LOG)) - pnv_pci_dump_phb_diag_data(pe->phb, pe->data); - } - - return result; -} - -static int ioda_eeh_get_pe_state(struct eeh_pe *pe) -{ - struct pnv_phb *phb = pe->phb->private_data; - u8 fstate; - __be16 pcierr; - s64 rc; - int result; - - /* -* We don't clobber hardware frozen state until PE -* reset is completed. In order to keep EEH core -* moving forward, we have to return operational -* state during PE reset. -*/ - if (pe->state & EEH_PE_RESET) { - result = (EEH_STATE_MMIO_ACTIVE | - EEH_STATE_DMA_ACTIVE | - EEH_STATE_MMIO_ENABLED | - EEH_STATE_DMA_ENABLED); - return result; - } - - /* -* Fetch PE state from hardware. If the PHB -* supports compound PE, let it handle that. -*/ - if (phb->get_pe_state) { - fstate = phb->get_pe_state(phb, pe->addr); - } else { - rc = opal_pci_eeh_freeze_status(phb->opal_id, - pe->addr, - &fstate, - &pcierr, - NULL); - if (rc != OPAL_SUCCESS) { - pr_warn("%s: Failure %lld getting PHB#%x-PE%x state\n", - __func__, rc, phb->hose->global_number, pe->addr); - return EEH_STATE_NOT_SUPPORT; - } - } - - /* Figure out state */ - switch (fstate) { - case OPAL_EEH_STOPPED_NOT_FROZEN: - result = (EEH_STATE_MMIO_ACTIVE | - EEH_STATE_DMA_ACTIVE | - EEH_STATE_MMIO_ENABLED | - EEH_STATE_DMA_ENABLED); - break; - case OPAL_EEH_STOPPED_MMIO_FREEZE: - result = (EEH_STATE_DMA_ACTIVE | - EEH_STATE_DMA_ENABLED); - break; - case OPAL_EEH_STOPPED_DMA_FREEZE: - result = (EEH_STATE_MMIO_ACTIVE | - EEH_STATE_MMIO_ENABLED); - break; - case OPAL_EEH_STOPPED_MMIO_DMA_FREEZE: - result = 0; - break; - case OPAL_EEH_STOPPED_RESET: - result = EEH_STATE_RESET_ACTIVE; - break; - case OPAL_EEH_STOPPED_TEMP_UNAVAIL: - result = EEH_STATE_UNAVAILABLE; - break; - case OPAL_EEH_STOPPED_PERM_UNAVAIL: - result = EEH_STATE_NOT_SUPPORT; - break; - default: - result = EEH_STATE_NOT_SUPPORT; - pr_warn("%s: Invalid PHB#%x-PE#%x state %x\n", - __func__, phb->hose->global_number, - pe->addr, fstate); - } - - /* -
[PATCH 09/10] powerpc/powernv: Drop PHB operation reset()
The patch drops PHB EEH operation reset() and merges its logic to eeh_ops::reset(). Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/eeh-ioda.c| 235 --- arch/powerpc/platforms/powernv/eeh-powernv.c | 225 - arch/powerpc/platforms/powernv/pci-ioda.c| 4 +- arch/powerpc/platforms/powernv/pci.h | 3 +- 4 files changed, 223 insertions(+), 244 deletions(-) diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 94d94b4..9fcfc45 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c @@ -34,240 +34,5 @@ #include "powernv.h" #include "pci.h" -static s64 ioda_eeh_phb_poll(struct pnv_phb *phb) -{ - s64 rc = OPAL_HARDWARE; - - while (1) { - rc = opal_pci_poll(phb->opal_id); - if (rc <= 0) - break; - - if (system_state < SYSTEM_RUNNING) - udelay(1000 * rc); - else - msleep(rc); - } - - return rc; -} - -int ioda_eeh_phb_reset(struct pci_controller *hose, int option) -{ - struct pnv_phb *phb = hose->private_data; - s64 rc = OPAL_HARDWARE; - - pr_debug("%s: Reset PHB#%x, option=%d\n", -__func__, hose->global_number, option); - - /* Issue PHB complete reset request */ - if (option == EEH_RESET_FUNDAMENTAL || - option == EEH_RESET_HOT) - rc = opal_pci_reset(phb->opal_id, - OPAL_RESET_PHB_COMPLETE, - OPAL_ASSERT_RESET); - else if (option == EEH_RESET_DEACTIVATE) - rc = opal_pci_reset(phb->opal_id, - OPAL_RESET_PHB_COMPLETE, - OPAL_DEASSERT_RESET); - if (rc < 0) - goto out; - - /* -* Poll state of the PHB until the request is done -* successfully. The PHB reset is usually PHB complete -* reset followed by hot reset on root bus. So we also -* need the PCI bus settlement delay. -*/ - rc = ioda_eeh_phb_poll(phb); - if (option == EEH_RESET_DEACTIVATE) { - if (system_state < SYSTEM_RUNNING) - udelay(1000 * EEH_PE_RST_SETTLE_TIME); - else - msleep(EEH_PE_RST_SETTLE_TIME); - } -out: - if (rc != OPAL_SUCCESS) - return -EIO; - - return 0; -} - -static int ioda_eeh_root_reset(struct pci_controller *hose, int option) -{ - struct pnv_phb *phb = hose->private_data; - s64 rc = OPAL_SUCCESS; - - pr_debug("%s: Reset PHB#%x, option=%d\n", -__func__, hose->global_number, option); - - /* -* During the reset deassert time, we needn't care -* the reset scope because the firmware does nothing -* for fundamental or hot reset during deassert phase. -*/ - if (option == EEH_RESET_FUNDAMENTAL) - rc = opal_pci_reset(phb->opal_id, - OPAL_RESET_PCI_FUNDAMENTAL, - OPAL_ASSERT_RESET); - else if (option == EEH_RESET_HOT) - rc = opal_pci_reset(phb->opal_id, - OPAL_RESET_PCI_HOT, - OPAL_ASSERT_RESET); - else if (option == EEH_RESET_DEACTIVATE) - rc = opal_pci_reset(phb->opal_id, - OPAL_RESET_PCI_HOT, - OPAL_DEASSERT_RESET); - if (rc < 0) - goto out; - - /* Poll state of the PHB until the request is done */ - rc = ioda_eeh_phb_poll(phb); - if (option == EEH_RESET_DEACTIVATE) - msleep(EEH_PE_RST_SETTLE_TIME); -out: - if (rc != OPAL_SUCCESS) - return -EIO; - - return 0; -} - -static int ioda_eeh_bridge_reset(struct pci_dev *dev, int option) - -{ - struct device_node *dn = pci_device_to_OF_node(dev); - struct eeh_dev *edev = of_node_to_eeh_dev(dn); - int aer = edev ? edev->aer_cap : 0; - u32 ctrl; - - pr_debug("%s: Reset PCI bus %04x:%02x with option %d\n", -__func__, pci_domain_nr(dev->bus), -dev->bus->number, option); - - switch (option) { - case EEH_RESET_FUNDAMENTAL: - case EEH_RESET_HOT: - /* Don't report linkDown event */ - if (aer) { - eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK, -4, &ctrl); - ctrl |= PCI_ERR_UNC_SURPDN; -eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK, - 4, ctrl); -} - - eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl); - ctrl |
[PATCH 08/10] powerpc/powernv: Drop PHB operation next_error()
The patch drops PHB EEH operation next_error() and merges its logic to eeh_ops::next_error(). Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/eeh-ioda.c| 351 --- arch/powerpc/platforms/powernv/eeh-powernv.c | 334 - arch/powerpc/platforms/powernv/pci.h | 1 - 3 files changed, 327 insertions(+), 359 deletions(-) diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index dc34c36..94d94b4 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c @@ -34,18 +34,6 @@ #include "powernv.h" #include "pci.h" -static void ioda_eeh_phb_diag(struct eeh_pe *pe) -{ - struct pnv_phb *phb = pe->phb->private_data; - long rc; - - rc = opal_pci_get_phb_diag_data2(phb->opal_id, pe->data, -PNV_PCI_DIAG_BUF_SIZE); - if (rc != OPAL_SUCCESS) - pr_warn("%s: Failed to get diag-data for PHB#%x (%ld)\n", - __func__, pe->phb->global_number, rc); -} - static s64 ioda_eeh_phb_poll(struct pnv_phb *phb) { s64 rc = OPAL_HARDWARE; @@ -280,345 +268,6 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option) return ret; } -static void ioda_eeh_hub_diag_common(struct OpalIoP7IOCErrorData *data) -{ - /* GEM */ - if (data->gemXfir || data->gemRfir || - data->gemRirqfir || data->gemMask || data->gemRwof) - pr_info(" GEM: %016llx %016llx %016llx %016llx %016llx\n", - be64_to_cpu(data->gemXfir), - be64_to_cpu(data->gemRfir), - be64_to_cpu(data->gemRirqfir), - be64_to_cpu(data->gemMask), - be64_to_cpu(data->gemRwof)); - - /* LEM */ - if (data->lemFir || data->lemErrMask || - data->lemAction0 || data->lemAction1 || data->lemWof) - pr_info(" LEM: %016llx %016llx %016llx %016llx %016llx\n", - be64_to_cpu(data->lemFir), - be64_to_cpu(data->lemErrMask), - be64_to_cpu(data->lemAction0), - be64_to_cpu(data->lemAction1), - be64_to_cpu(data->lemWof)); -} - -static void ioda_eeh_hub_diag(struct pci_controller *hose) -{ - struct pnv_phb *phb = hose->private_data; - struct OpalIoP7IOCErrorData *data = &phb->diag.hub_diag; - long rc; - - rc = opal_pci_get_hub_diag_data(phb->hub_id, data, sizeof(*data)); - if (rc != OPAL_SUCCESS) { - pr_warn("%s: Failed to get HUB#%llx diag-data (%ld)\n", - __func__, phb->hub_id, rc); - return; - } - - switch (data->type) { - case OPAL_P7IOC_DIAG_TYPE_RGC: - pr_info("P7IOC diag-data for RGC\n\n"); - ioda_eeh_hub_diag_common(data); - if (data->rgc.rgcStatus || data->rgc.rgcLdcp) - pr_info(" RGC: %016llx %016llx\n", - be64_to_cpu(data->rgc.rgcStatus), - be64_to_cpu(data->rgc.rgcLdcp)); - break; - case OPAL_P7IOC_DIAG_TYPE_BI: - pr_info("P7IOC diag-data for BI %s\n\n", - data->bi.biDownbound ? "Downbound" : "Upbound"); - ioda_eeh_hub_diag_common(data); - if (data->bi.biLdcp0 || data->bi.biLdcp1 || - data->bi.biLdcp2 || data->bi.biFenceStatus) - pr_info(" BI: %016llx %016llx %016llx %016llx\n", - be64_to_cpu(data->bi.biLdcp0), - be64_to_cpu(data->bi.biLdcp1), - be64_to_cpu(data->bi.biLdcp2), - be64_to_cpu(data->bi.biFenceStatus)); - break; - case OPAL_P7IOC_DIAG_TYPE_CI: - pr_info("P7IOC diag-data for CI Port %d\n\n", - data->ci.ciPort); - ioda_eeh_hub_diag_common(data); - if (data->ci.ciPortStatus || data->ci.ciPortLdcp) - pr_info(" CI: %016llx %016llx\n", - be64_to_cpu(data->ci.ciPortStatus), - be64_to_cpu(data->ci.ciPortLdcp)); - break; - case OPAL_P7IOC_DIAG_TYPE_MISC: - pr_info("P7IOC diag-data for MISC\n\n"); - ioda_eeh_hub_diag_common(data); - break; - case OPAL_P7IOC_DIAG_TYPE_I2C: - pr_info("P7IOC diag-data for I2C\n\n"); - ioda_eeh_hub_diag_common(data); - break; - default: - pr_warn("%s: Invalid type of HUB#%llx diag-data (%d)\n", - __func__, phb->hub_id, data->type); - } -} - -static int ioda_eeh_get_pe(struct pci_controller *hose, - u16
[PATCH 10/10] powerpc/powernv: Remove unused file
The patch removes unused file eeh-ioda.c and updates makefile accordingly. Besides, the definition of "struct pnv_eeh_ops" and the instances are all removed. Until now, the chip layer of EEH implementation for PowerNV platform is removed completely. Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/Makefile | 2 +- arch/powerpc/platforms/powernv/eeh-ioda.c | 38 --- arch/powerpc/platforms/powernv/pci-ioda.c | 3 --- arch/powerpc/platforms/powernv/pci.h | 13 --- 4 files changed, 1 insertion(+), 55 deletions(-) delete mode 100644 arch/powerpc/platforms/powernv/eeh-ioda.c diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index 6f3c5d3..33e44f3 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -5,7 +5,7 @@ obj-y += opal-msglog.o opal-hmi.o opal-power.o obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o -obj-$(CONFIG_EEH) += eeh-ioda.o eeh-powernv.o +obj-$(CONFIG_EEH) += eeh-powernv.o obj-$(CONFIG_PPC_SCOM) += opal-xscom.o obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o obj-$(CONFIG_TRACEPOINTS) += opal-tracepoints.o diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c deleted file mode 100644 index 9fcfc45..000 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * The file intends to implement the functions needed by EEH, which is - * built on IODA compliant chip. Actually, lots of functions related - * to EEH would be built based on the OPAL APIs. - * - * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2013. - * - * 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "powernv.h" -#include "pci.h" - -struct pnv_eeh_ops ioda_eeh_ops = { -}; diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 4e21596..26fe099 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2078,9 +2078,6 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, phb->get_pe_state = pnv_ioda_get_pe_state; phb->freeze_pe = pnv_ioda_freeze_pe; phb->unfreeze_pe = pnv_ioda_unfreeze_pe; -#ifdef CONFIG_EEH - phb->eeh_ops = &ioda_eeh_ops; -#endif /* Setup RID -> PE mapping function */ phb->bdfn_to_pe = pnv_ioda_bdfn_to_pe; diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 39f2ca3..18ae927 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -75,12 +75,6 @@ struct pnv_ioda_pe { struct list_headlist; }; -/* IOC dependent EEH operations */ -#ifdef CONFIG_EEH -struct pnv_eeh_ops { -}; -#endif /* CONFIG_EEH */ - #define PNV_PHB_FLAG_EEH (1 << 0) struct pnv_phb { @@ -94,10 +88,6 @@ struct pnv_phb { int initialized; spinlock_t lock; -#ifdef CONFIG_EEH - struct pnv_eeh_ops *eeh_ops; -#endif - #ifdef CONFIG_DEBUG_FS int has_dbgfs; struct dentry *dbgfs; @@ -203,9 +193,6 @@ struct pnv_phb { }; extern struct pci_ops pnv_pci_ops; -#ifdef CONFIG_EEH -extern struct pnv_eeh_ops ioda_eeh_ops; -#endif void pnv_pci_dump_phb_diag_data(struct pci_controller *hose, unsigned char *log_buff); -- 1.8.3.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 05/10] powerpc/powernv: Drop PHB operation configure_bridge()
The patch drops PHB EEH operation configure_bridge() and merges its logic to eeh_ops::configure_bridge(). Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/eeh-ioda.c| 15 --- arch/powerpc/platforms/powernv/eeh-powernv.c | 9 + arch/powerpc/platforms/powernv/pci.h | 1 - 3 files changed, 1 insertion(+), 24 deletions(-) diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 7eb6e72..6459516 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c @@ -530,20 +530,6 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option) return ret; } -/** - * ioda_eeh_configure_bridge - Configure the PCI bridges for the indicated PE - * @pe: EEH PE - * - * For particular PE, it might have included PCI bridges. In order - * to make the PE work properly, those PCI bridges should be configured - * correctly. However, we need do nothing on P7IOC since the reset - * function will do everything that should be covered by the function. - */ -static int ioda_eeh_configure_bridge(struct eeh_pe *pe) -{ - return 0; -} - static void ioda_eeh_hub_diag_common(struct OpalIoP7IOCErrorData *data) { /* GEM */ @@ -886,6 +872,5 @@ struct pnv_eeh_ops ioda_eeh_ops = { .set_option = ioda_eeh_set_option, .get_state = ioda_eeh_get_state, .reset = ioda_eeh_reset, - .configure_bridge = ioda_eeh_configure_bridge, .next_error = ioda_eeh_next_error }; diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 465deb5..a7087f4 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -549,14 +549,7 @@ static int pnv_eeh_get_log(struct eeh_pe *pe, int severity, */ static int pnv_eeh_configure_bridge(struct eeh_pe *pe) { - struct pci_controller *hose = pe->phb; - struct pnv_phb *phb = hose->private_data; - int ret = 0; - - if (phb->eeh_ops && phb->eeh_ops->configure_bridge) - ret = phb->eeh_ops->configure_bridge(pe); - - return ret; + return 0; } /** diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 1e7a623..d8808ca 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -81,7 +81,6 @@ struct pnv_eeh_ops { int (*set_option)(struct eeh_pe *pe, int option); int (*get_state)(struct eeh_pe *pe); int (*reset)(struct eeh_pe *pe, int option); - int (*configure_bridge)(struct eeh_pe *pe); int (*next_error)(struct eeh_pe **pe); }; #endif /* CONFIG_EEH */ -- 1.8.3.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 06/10] powerpc/powernv: Drop PHB operation set_option()
The patch drops PHB EEH operation set_option() and merges its logic to eeh_ops::set_option(). Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/eeh-ioda.c| 84 arch/powerpc/platforms/powernv/eeh-powernv.c | 61 +--- arch/powerpc/platforms/powernv/pci.h | 1 - 3 files changed, 54 insertions(+), 92 deletions(-) diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 6459516..349c083 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c @@ -34,89 +34,6 @@ #include "powernv.h" #include "pci.h" -/** - * ioda_eeh_set_option - Set EEH operation or I/O setting - * @pe: EEH PE - * @option: options - * - * Enable or disable EEH option for the indicated PE. The - * function also can be used to enable I/O or DMA for the - * PE. - */ -static int ioda_eeh_set_option(struct eeh_pe *pe, int option) -{ - struct pci_controller *hose = pe->phb; - struct pnv_phb *phb = hose->private_data; - bool freeze_pe = false; - int enable, ret = 0; - s64 rc; - - /* Check on PE number */ - if (pe->addr < 0 || pe->addr >= phb->ioda.total_pe) { - pr_err("%s: PE address %x out of range [0, %x] " - "on PHB#%x\n", - __func__, pe->addr, phb->ioda.total_pe, - hose->global_number); - return -EINVAL; - } - - switch (option) { - case EEH_OPT_DISABLE: - return -EPERM; - case EEH_OPT_ENABLE: - return 0; - case EEH_OPT_THAW_MMIO: - enable = OPAL_EEH_ACTION_CLEAR_FREEZE_MMIO; - break; - case EEH_OPT_THAW_DMA: - enable = OPAL_EEH_ACTION_CLEAR_FREEZE_DMA; - break; - case EEH_OPT_FREEZE_PE: - freeze_pe = true; - enable = OPAL_EEH_ACTION_SET_FREEZE_ALL; - break; - default: - pr_warn("%s: Invalid option %d\n", - __func__, option); - return -EINVAL; - } - - /* If PHB supports compound PE, to handle it */ - if (freeze_pe) { - if (phb->freeze_pe) { - phb->freeze_pe(phb, pe->addr); - } else { - rc = opal_pci_eeh_freeze_set(phb->opal_id, -pe->addr, -enable); - if (rc != OPAL_SUCCESS) { - pr_warn("%s: Failure %lld freezing " - "PHB#%x-PE#%x\n", - __func__, rc, - phb->hose->global_number, pe->addr); - ret = -EIO; - } - } - } else { - if (phb->unfreeze_pe) { - ret = phb->unfreeze_pe(phb, pe->addr, enable); - } else { - rc = opal_pci_eeh_freeze_clear(phb->opal_id, - pe->addr, - enable); - if (rc != OPAL_SUCCESS) { - pr_warn("%s: Failure %lld enable %d " - "for PHB#%x-PE#%x\n", - __func__, rc, option, - phb->hose->global_number, pe->addr); - ret = -EIO; - } - } - } - - return ret; -} - static void ioda_eeh_phb_diag(struct eeh_pe *pe) { struct pnv_phb *phb = pe->phb->private_data; @@ -869,7 +786,6 @@ static int ioda_eeh_next_error(struct eeh_pe **pe) } struct pnv_eeh_ops ioda_eeh_ops = { - .set_option = ioda_eeh_set_option, .get_state = ioda_eeh_get_state, .reset = ioda_eeh_reset, .next_error = ioda_eeh_next_error diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index a7087f4..2429a23 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -407,14 +407,61 @@ static int pnv_eeh_set_option(struct eeh_pe *pe, int option) { struct pci_controller *hose = pe->phb; struct pnv_phb *phb = hose->private_data; - int ret = -EEXIST; + bool freeze_pe = false; + int opt, ret = 0; + s64 rc; - /* -* What we need do is pass it down for hardware -* implementation to handle it. -*/ - if (phb->eeh_ops && phb->eeh_ops->set_option) - ret = phb->eeh_ops->set_option(pe, option); + /* Sanity check on option */ + switch (
[PATCH 04/10] powerpc/powernv: Drop PHB operation get_log()
The patch drops PHB operation get_log() and merges its logic to eeh_ops::get_log(). Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/eeh-ioda.c| 20 arch/powerpc/platforms/powernv/eeh-powernv.c | 10 +++--- arch/powerpc/platforms/powernv/pci.h | 2 -- 3 files changed, 3 insertions(+), 29 deletions(-) diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index bd509ad..7eb6e72 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c @@ -531,25 +531,6 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option) } /** - * ioda_eeh_get_log - Retrieve error log - * @pe: frozen PE - * @severity: permanent or temporary error - * @drv_log: device driver log - * @len: length of device driver log - * - * Retrieve error log, which contains log from device driver - * and firmware. - */ -static int ioda_eeh_get_log(struct eeh_pe *pe, int severity, - char *drv_log, unsigned long len) -{ - if (!eeh_has_flag(EEH_EARLY_DUMP_LOG)) - pnv_pci_dump_phb_diag_data(pe->phb, pe->data); - - return 0; -} - -/** * ioda_eeh_configure_bridge - Configure the PCI bridges for the indicated PE * @pe: EEH PE * @@ -905,7 +886,6 @@ struct pnv_eeh_ops ioda_eeh_ops = { .set_option = ioda_eeh_set_option, .get_state = ioda_eeh_get_state, .reset = ioda_eeh_reset, - .get_log= ioda_eeh_get_log, .configure_bridge = ioda_eeh_configure_bridge, .next_error = ioda_eeh_next_error }; diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 641ba33..465deb5 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -533,14 +533,10 @@ static int pnv_eeh_wait_state(struct eeh_pe *pe, int max_wait) static int pnv_eeh_get_log(struct eeh_pe *pe, int severity, char *drv_log, unsigned long len) { - struct pci_controller *hose = pe->phb; - struct pnv_phb *phb = hose->private_data; - int ret = -EEXIST; + if (!eeh_has_flag(EEH_EARLY_DUMP_LOG)) + pnv_pci_dump_phb_diag_data(pe->phb, pe->data); - if (phb->eeh_ops && phb->eeh_ops->get_log) - ret = phb->eeh_ops->get_log(pe, severity, drv_log, len); - - return ret; + return 0; } /** diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index c7e047f..1e7a623 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -81,8 +81,6 @@ struct pnv_eeh_ops { int (*set_option)(struct eeh_pe *pe, int option); int (*get_state)(struct eeh_pe *pe); int (*reset)(struct eeh_pe *pe, int option); - int (*get_log)(struct eeh_pe *pe, int severity, - char *drv_log, unsigned long len); int (*configure_bridge)(struct eeh_pe *pe); int (*next_error)(struct eeh_pe **pe); }; -- 1.8.3.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 03/10] powerpc/powernv: Drop PHB operation post_init()
The patch drops PHB EEH operation post_init() and merge its logic to eeh_ops::post_init(). Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/eeh-ioda.c| 193 --- arch/powerpc/platforms/powernv/eeh-powernv.c | 184 - arch/powerpc/platforms/powernv/pci.h | 1 - 3 files changed, 179 insertions(+), 199 deletions(-) diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index dd154cf..bd509ad 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c @@ -34,198 +34,6 @@ #include "powernv.h" #include "pci.h" -static int ioda_eeh_nb_init = 0; - -static int ioda_eeh_event(struct notifier_block *nb, - unsigned long events, void *change) -{ - uint64_t changed_evts = (uint64_t)change; - - /* -* We simply send special EEH event if EEH has -* been enabled, or clear pending events in -* case that we enable EEH soon -*/ - if (!(changed_evts & OPAL_EVENT_PCI_ERROR) || - !(events & OPAL_EVENT_PCI_ERROR)) - return 0; - - if (eeh_enabled()) - eeh_send_failure_event(NULL); - else - opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul); - - return 0; -} - -static struct notifier_block ioda_eeh_nb = { - .notifier_call = ioda_eeh_event, - .next = NULL, - .priority = 0 -}; - -#ifdef CONFIG_DEBUG_FS -static ssize_t ioda_eeh_ei_write(struct file *filp, -const char __user *user_buf, -size_t count, loff_t *ppos) -{ - struct pci_controller *hose = filp->private_data; - struct eeh_dev *edev; - struct eeh_pe *pe; - int pe_no, type, func; - unsigned long addr, mask; - char buf[50]; - int ret; - - if (!eeh_ops || !eeh_ops->err_inject) - return -ENXIO; - - ret = simple_write_to_buffer(buf, sizeof(buf), ppos, user_buf, count); - if (!ret) - return -EFAULT; - - /* Retrieve parameters */ - ret = sscanf(buf, "%x:%x:%x:%lx:%lx", -&pe_no, &type, &func, &addr, &mask); - if (ret != 5) - return -EINVAL; - - /* Retrieve PE */ - edev = kzalloc(sizeof(*edev), GFP_KERNEL); - if (!edev) - return -ENOMEM; - edev->phb = hose; - edev->pe_config_addr = pe_no; - pe = eeh_pe_get(edev); - kfree(edev); - if (!pe) - return -ENODEV; - - /* Do error injection */ - ret = eeh_ops->err_inject(pe, type, func, addr, mask); - return ret < 0 ? ret : count; -} - -static const struct file_operations ioda_eeh_ei_fops = { - .open = simple_open, - .llseek = no_llseek, - .write = ioda_eeh_ei_write, -}; - -static int ioda_eeh_dbgfs_set(void *data, int offset, u64 val) -{ - struct pci_controller *hose = data; - struct pnv_phb *phb = hose->private_data; - - out_be64(phb->regs + offset, val); - return 0; -} - -static int ioda_eeh_dbgfs_get(void *data, int offset, u64 *val) -{ - struct pci_controller *hose = data; - struct pnv_phb *phb = hose->private_data; - - *val = in_be64(phb->regs + offset); - return 0; -} - -static int ioda_eeh_outb_dbgfs_set(void *data, u64 val) -{ - return ioda_eeh_dbgfs_set(data, 0xD10, val); -} - -static int ioda_eeh_outb_dbgfs_get(void *data, u64 *val) -{ - return ioda_eeh_dbgfs_get(data, 0xD10, val); -} - -static int ioda_eeh_inbA_dbgfs_set(void *data, u64 val) -{ - return ioda_eeh_dbgfs_set(data, 0xD90, val); -} - -static int ioda_eeh_inbA_dbgfs_get(void *data, u64 *val) -{ - return ioda_eeh_dbgfs_get(data, 0xD90, val); -} - -static int ioda_eeh_inbB_dbgfs_set(void *data, u64 val) -{ - return ioda_eeh_dbgfs_set(data, 0xE10, val); -} - -static int ioda_eeh_inbB_dbgfs_get(void *data, u64 *val) -{ - return ioda_eeh_dbgfs_get(data, 0xE10, val); -} - -DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_outb_dbgfs_ops, ioda_eeh_outb_dbgfs_get, - ioda_eeh_outb_dbgfs_set, "0x%llx\n"); -DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_inbA_dbgfs_ops, ioda_eeh_inbA_dbgfs_get, - ioda_eeh_inbA_dbgfs_set, "0x%llx\n"); -DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_inbB_dbgfs_ops, ioda_eeh_inbB_dbgfs_get, - ioda_eeh_inbB_dbgfs_set, "0x%llx\n"); -#endif /* CONFIG_DEBUG_FS */ - - -/** - * ioda_eeh_post_init - Chip dependent post initialization - * @hose: PCI controller - * - * The function will be called after eeh PEs and devices - * have been built. That means the EEH is ready to supply - * service with I/O cache. - */ -static int ioda_eeh_post_init(struct pci_controller *hose) -{ - struct pnv_phb *phb = hose->private_data; - int ret; - - /* Register OPAL event notifier */ - if (!ioda_eeh
[PATCH 02/10] powerpc/powernv: Drop PHB operation err_inject()
The patch drops PHB EEH operation err_inject() and merge its logic to eeh_ops::err_inject(). Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/eeh-ioda.c| 49 ++-- arch/powerpc/platforms/powernv/eeh-powernv.c | 38 ++--- arch/powerpc/platforms/powernv/pci.h | 2 -- 3 files changed, 36 insertions(+), 53 deletions(-) diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 2809c98..dd154cf 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c @@ -70,7 +70,6 @@ static ssize_t ioda_eeh_ei_write(struct file *filp, size_t count, loff_t *ppos) { struct pci_controller *hose = filp->private_data; - struct pnv_phb *phb = hose->private_data; struct eeh_dev *edev; struct eeh_pe *pe; int pe_no, type, func; @@ -78,7 +77,7 @@ static ssize_t ioda_eeh_ei_write(struct file *filp, char buf[50]; int ret; - if (!phb->eeh_ops || !phb->eeh_ops->err_inject) + if (!eeh_ops || !eeh_ops->err_inject) return -ENXIO; ret = simple_write_to_buffer(buf, sizeof(buf), ppos, user_buf, count); @@ -103,7 +102,7 @@ static ssize_t ioda_eeh_ei_write(struct file *filp, return -ENODEV; /* Do error injection */ - ret = phb->eeh_ops->err_inject(pe, type, func, addr, mask); + ret = eeh_ops->err_inject(pe, type, func, addr, mask); return ret < 0 ? ret : count; } @@ -756,49 +755,6 @@ static int ioda_eeh_configure_bridge(struct eeh_pe *pe) return 0; } -static int ioda_eeh_err_inject(struct eeh_pe *pe, int type, int func, - unsigned long addr, unsigned long mask) -{ - struct pci_controller *hose = pe->phb; - struct pnv_phb *phb = hose->private_data; - s64 ret; - - /* Sanity check on error type */ - if (type != OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR && - type != OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR64) { - pr_warn("%s: Invalid error type %d\n", - __func__, type); - return -ERANGE; - } - - if (func < OPAL_ERR_INJECT_FUNC_IOA_LD_MEM_ADDR || - func > OPAL_ERR_INJECT_FUNC_IOA_DMA_WR_TARGET) { - pr_warn("%s: Invalid error function %d\n", - __func__, func); - return -ERANGE; - } - - /* Firmware supports error injection ? */ - if (!opal_check_token(OPAL_PCI_ERR_INJECT)) { - pr_warn("%s: Firmware doesn't support error injection\n", - __func__); - return -ENXIO; - } - - /* Do error injection */ - ret = opal_pci_err_inject(phb->opal_id, pe->addr, - type, func, addr, mask); - if (ret != OPAL_SUCCESS) { - pr_warn("%s: Failure %lld injecting error " - "%d-%d to PHB#%x-PE#%x\n", - __func__, ret, type, func, - hose->global_number, pe->addr); - return -EIO; - } - - return 0; -} - static void ioda_eeh_hub_diag_common(struct OpalIoP7IOCErrorData *data) { /* GEM */ @@ -1144,6 +1100,5 @@ struct pnv_eeh_ops ioda_eeh_ops = { .reset = ioda_eeh_reset, .get_log= ioda_eeh_get_log, .configure_bridge = ioda_eeh_configure_bridge, - .err_inject = ioda_eeh_err_inject, .next_error = ioda_eeh_next_error }; diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index f562dd1..df33daa 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -406,12 +406,42 @@ static int pnv_eeh_err_inject(struct eeh_pe *pe, int type, int func, { struct pci_controller *hose = pe->phb; struct pnv_phb *phb = hose->private_data; - int ret = -EEXIST; + s64 rc; + + /* Sanity check on error type */ + if (type != OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR && + type != OPAL_ERR_INJECT_TYPE_IOA_BUS_ERR64) { + pr_warn("%s: Invalid error type %d\n", + __func__, type); + return -ERANGE; + } - if (phb->eeh_ops && phb->eeh_ops->err_inject) - ret = phb->eeh_ops->err_inject(pe, type, func, addr, mask); + if (func < OPAL_ERR_INJECT_FUNC_IOA_LD_MEM_ADDR || + func > OPAL_ERR_INJECT_FUNC_IOA_DMA_WR_TARGET) { + pr_warn("%s: Invalid error function %d\n", + __func__, func); + return -ERANGE; + } - return ret; + /* Firmware supports error injection ? */ + if (!opal_check_token(OPAL_PCI_ERR_INJECT)) { + pr_warn("%s: Firmware doesn't support error i
[PATCH 01/10] powerpc/powernv: Shorten EEH function names
The patch shortens names of EEH functions in powernv-eeh.c and no logic change introduced by this patch. Signed-off-by: Gavin Shan --- arch/powerpc/platforms/powernv/eeh-powernv.c | 104 +-- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index e261869..f562dd1 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -39,11 +39,11 @@ #include "pci.h" /** - * powernv_eeh_init - EEH platform dependent initialization + * pnv_eeh_init - EEH platform dependent initialization * * EEH platform dependent initialization on powernv */ -static int powernv_eeh_init(void) +static int pnv_eeh_init(void) { struct pci_controller *hose; struct pnv_phb *phb; @@ -86,14 +86,14 @@ static int powernv_eeh_init(void) } /** - * powernv_eeh_post_init - EEH platform dependent post initialization + * pnv_eeh_post_init - EEH platform dependent post initialization * * EEH platform dependent post initialization on powernv. When * the function is called, the EEH PEs and devices should have * been built. If the I/O cache staff has been built, EEH is * ready to supply service. */ -static int powernv_eeh_post_init(void) +static int pnv_eeh_post_init(void) { struct pci_controller *hose; struct pnv_phb *phb; @@ -113,7 +113,7 @@ static int powernv_eeh_post_init(void) } /** - * powernv_eeh_dev_probe - Do probe on PCI device + * pnv_eeh_dev_probe - Do probe on PCI device * @dev: PCI device * @flag: unused * @@ -129,7 +129,7 @@ static int powernv_eeh_post_init(void) * was possiblly triggered by EEH core, the binding between EEH device * and the PCI device isn't built yet. */ -static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag) +static int pnv_eeh_dev_probe(struct pci_dev *dev, void *flag) { struct pci_controller *hose = pci_bus_to_host(dev->bus); struct pnv_phb *phb = hose->private_data; @@ -221,7 +221,7 @@ static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag) } /** - * powernv_eeh_set_option - Initialize EEH or MMIO/DMA reenable + * pnv_eeh_set_option - Initialize EEH or MMIO/DMA reenable * @pe: EEH PE * @option: operation to be issued * @@ -229,7 +229,7 @@ static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag) * Currently, following options are support according to PAPR: * Enable EEH, Disable EEH, Enable MMIO and Enable DMA */ -static int powernv_eeh_set_option(struct eeh_pe *pe, int option) +static int pnv_eeh_set_option(struct eeh_pe *pe, int option) { struct pci_controller *hose = pe->phb; struct pnv_phb *phb = hose->private_data; @@ -246,19 +246,19 @@ static int powernv_eeh_set_option(struct eeh_pe *pe, int option) } /** - * powernv_eeh_get_pe_addr - Retrieve PE address + * pnv_eeh_get_pe_addr - Retrieve PE address * @pe: EEH PE * * Retrieve the PE address according to the given tranditional * PCI BDF (Bus/Device/Function) address. */ -static int powernv_eeh_get_pe_addr(struct eeh_pe *pe) +static int pnv_eeh_get_pe_addr(struct eeh_pe *pe) { return pe->addr; } /** - * powernv_eeh_get_state - Retrieve PE state + * pnv_eeh_get_state - Retrieve PE state * @pe: EEH PE * @delay: delay while PE state is temporarily unavailable * @@ -267,7 +267,7 @@ static int powernv_eeh_get_pe_addr(struct eeh_pe *pe) * we prefer passing down to hardware implementation to handle * it. */ -static int powernv_eeh_get_state(struct eeh_pe *pe, int *delay) +static int pnv_eeh_get_state(struct eeh_pe *pe, int *delay) { struct pci_controller *hose = pe->phb; struct pnv_phb *phb = hose->private_data; @@ -292,13 +292,13 @@ static int powernv_eeh_get_state(struct eeh_pe *pe, int *delay) } /** - * powernv_eeh_reset - Reset the specified PE + * pnv_eeh_reset - Reset the specified PE * @pe: EEH PE * @option: reset option * * Reset the specified PE */ -static int powernv_eeh_reset(struct eeh_pe *pe, int option) +static int pnv_eeh_reset(struct eeh_pe *pe, int option) { struct pci_controller *hose = pe->phb; struct pnv_phb *phb = hose->private_data; @@ -311,20 +311,20 @@ static int powernv_eeh_reset(struct eeh_pe *pe, int option) } /** - * powernv_eeh_wait_state - Wait for PE state + * pnv_eeh_wait_state - Wait for PE state * @pe: EEH PE * @max_wait: maximal period in microsecond * * Wait for the state of associated PE. It might take some time * to retrieve the PE's state. */ -static int powernv_eeh_wait_state(struct eeh_pe *pe, int max_wait) +static int pnv_eeh_wait_state(struct eeh_pe *pe, int max_wait) { int ret; int mwait; while (1) { - ret = powernv_eeh_get_state(pe, &mwait); + ret = pnv_eeh_get_state(pe, &mwait); /* * If the PE's s
[PATCH 00/10] powerpc/powernv: Simplify EEH Implementation
The EEH was implemented for PowerNV platform with 2 layers, which are supported by "struct eeh_ops" and "struct pnv_eeh_ops" separately. The latter, called chip layer, was introduced for EEH guest support initially. However, the EEH guest support was implemented depending on "struct eeh_ops" completely. So it's uncessary to maintain 2 layers for EEH implementation on PowerNV platform, as Ben pointed out. The series of patches is pretty much mechanically to move all functions in eeh-ioda.c to eeh-powernv.c, which enables us to remove the chip layer, equivalently to remove "struct pnv_eeh_ops" and eeh-ioda.c, to have simplifed EEH implementation on PowerNV platform. Gavin Shan (10): powerpc/powernv: Shorten EEH function names powerpc/powernv: Drop PHB operation err_inject() powerpc/powernv: Drop PHB operation post_init() powerpc/powernv: Drop PHB operation get_log() powerpc/powernv: Drop PHB operation configure_bridge() powerpc/powernv: Drop PHB operation set_option() powerpc/powernv: Drop PHB operation get_state() powerpc/powernv: Drop PHB operation next_error() powerpc/powernv: Drop PHB operation reset() powerpc/powernv: Remove unused file arch/powerpc/platforms/powernv/Makefile |2 +- arch/powerpc/platforms/powernv/eeh-ioda.c| 1149 -- arch/powerpc/platforms/powernv/eeh-powernv.c | 1146 ++--- arch/powerpc/platforms/powernv/pci-ioda.c|7 +- arch/powerpc/platforms/powernv/pci.h | 25 +- 5 files changed, 1041 insertions(+), 1288 deletions(-) delete mode 100644 arch/powerpc/platforms/powernv/eeh-ioda.c -- 1.8.3.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: suspicious RCU usage clockevents_lock, tick_broadcast_lock, hrtimer_bases.lock
On 02/13/2015 07:56 PM, Paul E. McKenney wrote: > On Fri, Feb 13, 2015 at 12:52:45PM +0530, Preeti U Murthy wrote: >> On 02/13/2015 10:57 AM, Preeti U Murthy wrote: >>> On 02/13/2015 06:27 AM, Sam Bobroff wrote: Hello, I'm receiving this while booting a vanilla 3.19 kernel on a Power 8 machine: >>> >>> Does the below patch fix the issue ? >>> >>> From: Preeti U Murthy >>> >>> [PATCH] tick/hrtimer-broadcast: Fix a suspicious RCU usage in the tick >>> broadcast path >>> >>> --- >>> kernel/time/tick-broadcast-hrtimer.c | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/kernel/time/tick-broadcast-hrtimer.c >>> b/kernel/time/tick-broadcast-hrtimer.c >>> index eb682d5..57b8e32 100644 >>> --- a/kernel/time/tick-broadcast-hrtimer.c >>> +++ b/kernel/time/tick-broadcast-hrtimer.c >>> @@ -62,7 +62,7 @@ static int bc_set_next(ktime_t expires, struct >>> clock_event_device *bc) >>> * HRTIMER_RESTART. >>> */ >>> if (hrtimer_try_to_cancel(&bctimer) >= 0) { >>> - hrtimer_start(&bctimer, expires, HRTIMER_MODE_ABS_PINNED); >>> + RCU_NONIDLE(hrtimer_start(&bctimer, expires, >>> HRTIMER_MODE_ABS_PINNED)); >>> /* Bind the "device" to the cpu */ >>> bc->bound_on = smp_processor_id(); >>> } else if (bc->bound_on == smp_processor_id()) { >>> >> Actually the below patch is the complete fix. Paul can you please >> review this ? As an alternate solution I checked to see if its >> possible to move rcu_idle_enter()/exit() closer to the >> cpuidle_enter() call, but that won't work as you may have already >> tried earlier. >> >> - >> >> tick/broadcast-hrtimer : Fix suspicious RCU usage in idle loop >> >> From: Preeti U Murthy >> >> The hrtimer mode of broadcast queues hrtimers in the idle entry >> path so as to wakeup cpus in deep idle states. hrtimer_{start/cancel} >> functions call into tracing which uses RCU. But it is not legal to call >> into RCU in cpuidle because it is one of the quiescent states. Hence >> protect this region with RCU_NONIDLE which informs RCU that the cpu >> is momentarily non-idle. >> >> Signed-off-by: Preeti U Murthy > > Reviewed-by: Paul E. McKenney > > Another alternative would be to change the hrtimer_{start/cancel}() > functions' tracepoints to the _rcuidle form. The advantage of this > approach is less RCU-notification overhead when tracing is enabled. But since the hrtimer_{start/cancel} functions' tracepoints are more often called from paths which are in the non-quiescent states, wouldn't we be doing an rcu_irq_enter/exit() redundantly far too often in that case ? Regards Preeti U Murthy ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Problems with Kernels 3.17-rc1 and onwards on Acube Sam460 AMCC 460ex board
On Sun, 2015-02-15 at 08:16 -0400, Julian Margetson wrote: > Hi > > I am unable to get any kernel beyond the 3.16 branch working on an > Acube Sam460ex > AMCC 460ex based motherboard. Kernel up 3.16.7-ckt6 working. Does reverting b0345bbc6d09 change anything? > [6.364350] snd_hda_intel 0001:81:00.1: enabling device ( -> 0002) > [6.453794] snd_hda_intel 0001:81:00.1: ppc4xx_setup_msi_irqs: fail > mapping irq > [6.487530] Unable to handle kernel paging request for data at address > 0x0fa06c7c > [6.495055] Faulting instruction address: 0xc032202c > [6.500033] Vector: 300 (Data Access) at [efa31cf0] > [6.504922] pc: c032202c: __reg_op+0xe8/0x100 > [6.509697] lr: c0014f88: msi_bitmap_free_hwirqs+0x50/0x94 > [6.515600] sp: efa31da0 > [6.518491]msr: 21000 > [6.521112]dar: fa06c7c > [6.523915] dsisr: 0 > [6.526190] current = 0xef8bab00 > [6.529603] pid = 115, comm = kworker/0:1 > [6.534163] enter ? for help > [6.537054] [link register ] c0014f88 msi_bitmap_free_hwirqs+0x50/0x94 > [6.543811] [efa31da0] c0014f78 msi_bitmap_free_hwirqs+0x40/0x94 > (unreliable) > [6.551001] [efa31dc0] c001aee8 ppc4xx_setup_msi_irqs+0xac/0xf4 > [6.556973] [efa31e00] c03503a4 pci_enable_msi_range+0x1e0/0x280 > [6.563032] [efa31e40] f92c2f74 azx_probe_work+0xe0/0x57c [snd_hda_intel] > [6.569906] [efa31e80] c0036344 process_one_work+0x1e8/0x2f0 > [6.575627] [efa31eb0] c003677c worker_thread+0x2f4/0x438 > [6.581079] [efa31ef0] c003a3e4 kthread+0xc8/0xcc > [6.585844] [efa31f40] c000aec4 ret_from_kernel_thread+0x5c/0x64 > [6.591910] mon> cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: re-enable dynticks
On Fri, 2015-02-13 at 13:38 -0600, Paul Clarke wrote: > implement arch_irq_work_has_interrupt() for powerpc > > Commit 9b01f5bf3 introduced a dependency on "IRQ work self-IPIs" for > full dynamic ticks to be enabled, by expecting architectures to > implement a suitable arch_irq_work_has_interrupt() routine. > > Several arches have implemented this routine, including x86 (3010279f) > and arm (09f6edd4), but powerpc was omitted. > > This patch implements this routine for powerpc. > > The symptom, at boot (on powerpc arch systems) with "nohz_full= list>" is displayed: > NO_HZ: Can't run full dynticks because arch doesn't support irq > work self-IPIs > > after this patch: > NO_HZ: Full dynticks CPUs: . > > Tested against 3.19. It makes the message change, but is that correct? ie. do we actually implement "IRQ work self-IPIs"? > diff --git a/arch/powerpc/include/asm/irq_work.h > b/arch/powerpc/include/asm/irq_work.h > new file mode 100644 > index 000..18365ec > --- /dev/null > +++ b/arch/powerpc/include/asm/irq_work.h > @@ -0,0 +1,11 @@ > +#ifndef _ASM_IRQ_WORK_H > +#define _ASM_IRQ_WORK_H > + > +#include > + > +static inline bool arch_irq_work_has_interrupt(void) > +{ > + return 1; Should be "true"; > +} cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH net-next 0/6] bpf: Enable BPF JIT on ppc32
On 02/15/2015 07:06 PM, Denis Kirjanov wrote: This patch series enables BPF JIT on ppc32. There are relatevily few chnages in the code to make it work. All test_bpf tests passed both on 7447a and P2041-based machines. I'm just wondering, next to the feedback that has already been provided, would opening this up for ppc32 make it significantly more difficult in future to migrate from classic BPF JIT to eBPF JIT eventually (which is what we want long-term)? Being curious, is there any ongoing effort from ppc people? ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH net-next 1/6] ppc: Kconfig: Enable BPF JIT on ppc32
On 2/15/15, David Miller wrote: > From: Joe Perches > Date: Sun, 15 Feb 2015 10:15:54 -0800 > >> On Sun, 2015-02-15 at 21:06 +0300, Denis Kirjanov wrote: >> [] >>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig >> [] >>> @@ -126,7 +126,7 @@ config PPC >>> select IRQ_FORCED_THREADING >>> select HAVE_RCU_TABLE_FREE if SMP >>> select HAVE_SYSCALL_TRACEPOINTS >>> - select HAVE_BPF_JIT if PPC64 >>> + select HAVE_BPF_JIT >> >> trivia: >> >> Should this be the last patch of the series? > > Yes, that's the way I see it too. > Ok, I'll resend the series if the such thing matters. Thank you. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH net-next 1/6] ppc: Kconfig: Enable BPF JIT on ppc32
From: Joe Perches Date: Sun, 15 Feb 2015 10:15:54 -0800 > On Sun, 2015-02-15 at 21:06 +0300, Denis Kirjanov wrote: > [] >> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > [] >> @@ -126,7 +126,7 @@ config PPC >> select IRQ_FORCED_THREADING >> select HAVE_RCU_TABLE_FREE if SMP >> select HAVE_SYSCALL_TRACEPOINTS >> -select HAVE_BPF_JIT if PPC64 >> +select HAVE_BPF_JIT > > trivia: > > Should this be the last patch of the series? Yes, that's the way I see it too. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH net-next 1/6] ppc: Kconfig: Enable BPF JIT on ppc32
On Sun, 2015-02-15 at 21:06 +0300, Denis Kirjanov wrote: [] > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig [] > @@ -126,7 +126,7 @@ config PPC > select IRQ_FORCED_THREADING > select HAVE_RCU_TABLE_FREE if SMP > select HAVE_SYSCALL_TRACEPOINTS > - select HAVE_BPF_JIT if PPC64 > + select HAVE_BPF_JIT trivia: Should this be the last patch of the series? ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH net-next 6/6] ppc: bpf: Add SKF_AD_CPU for ppc32
Signed-off-by: Denis Kirjanov --- arch/powerpc/net/bpf_jit.h | 17 + arch/powerpc/net/bpf_jit_comp.c | 14 +- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h index 2d5e715..889fd19 100644 --- a/arch/powerpc/net/bpf_jit.h +++ b/arch/powerpc/net/bpf_jit.h @@ -154,6 +154,23 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); #define PPC_LL_OFFS(r, base, i) do { PPC_LWZ_OFFS(r, base, i); } while(0) #endif +#ifdef CONFIG_SMP +#ifdef CONFIG_PPC64 +#define PPC_BPF_LOAD_CPU(r)\ + do { BUILD_BUG_ON(FIELD_SIZEOF(struct paca_struct, paca_index) != 2); \ + PPC_LHZ_OFFS(r, 13, offsetof(struct paca_struct, paca_index)); \ + } while (0) +#else +#define PPC_BPF_LOAD_CPU(r) \ + do { BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4); \ + PPC_LHZ_OFFS(r, (1 & ~(THREAD_SIZE - 1)), \ + offsetof(struct thread_info, cpu)); \ + } while(0) +#endif +#else +#define PPC_BPF_LOAD_CPU(r) do { PPC_LI(r, 0); } while(0) +#endif + #define PPC_CMPWI(a, i)EMIT(PPC_INST_CMPWI | ___PPC_RA(a) | IMM_L(i)) #define PPC_CMPDI(a, i)EMIT(PPC_INST_CMPDI | ___PPC_RA(a) | IMM_L(i)) #define PPC_CMPLWI(a, i) EMIT(PPC_INST_CMPLWI | ___PPC_RA(a) | IMM_L(i)) diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 8b29268..17cea18 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -411,20 +411,8 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, PPC_SRWI(r_A, r_A, 5); break; case BPF_ANC | SKF_AD_CPU: -#ifdef CONFIG_SMP - /* -* PACA ptr is r13: -* raw_smp_processor_id() = local_paca->paca_index -*/ - BUILD_BUG_ON(FIELD_SIZEOF(struct paca_struct, - paca_index) != 2); - PPC_LHZ_OFFS(r_A, 13, -offsetof(struct paca_struct, paca_index)); -#else - PPC_LI(r_A, 0); -#endif + PPC_BPF_LOAD_CPU(r_A); break; - /*** Absolute loads from packet header/data ***/ case BPF_LD | BPF_W | BPF_ABS: func = CHOOSE_LOAD_FUNC(K, sk_load_word); -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH net-next 5/6] ppc: bpf: rename bpf_jit_64.S to bpf_jit_asm.S
Signed-off-by: Denis Kirjanov --- arch/powerpc/net/Makefile| 2 +- arch/powerpc/net/{bpf_jit_64.S => bpf_jit_asm.S} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename arch/powerpc/net/{bpf_jit_64.S => bpf_jit_asm.S} (100%) diff --git a/arch/powerpc/net/Makefile b/arch/powerpc/net/Makefile index 266b395..1306a58 100644 --- a/arch/powerpc/net/Makefile +++ b/arch/powerpc/net/Makefile @@ -1,4 +1,4 @@ # # Arch-specific network modules # -obj-$(CONFIG_BPF_JIT) += bpf_jit_64.o bpf_jit_comp.o +obj-$(CONFIG_BPF_JIT) += bpf_jit_asm.o bpf_jit_comp.o diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_asm.S similarity index 100% rename from arch/powerpc/net/bpf_jit_64.S rename to arch/powerpc/net/bpf_jit_asm.S -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH net-next 4/6] ppc: bpf: update jit to use compatibility macros
Use helpers from the asm-compat.h to wrap up assembly mnemonics Signed-off-by: Denis Kirjanov --- arch/powerpc/net/bpf_jit.h | 47 ++- arch/powerpc/net/bpf_jit_64.S | 70 - arch/powerpc/net/bpf_jit_comp.c | 32 ++- 3 files changed, 98 insertions(+), 51 deletions(-) diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h index c406aa9..2d5e715 100644 --- a/arch/powerpc/net/bpf_jit.h +++ b/arch/powerpc/net/bpf_jit.h @@ -10,12 +10,25 @@ #ifndef _BPF_JIT_H #define _BPF_JIT_H +#ifdef CONFIG_PPC64 +#define BPF_PPC_STACK_R3_OFF 48 #define BPF_PPC_STACK_LOCALS 32 #define BPF_PPC_STACK_BASIC(48+64) #define BPF_PPC_STACK_SAVE (18*8) #define BPF_PPC_STACKFRAME (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \ BPF_PPC_STACK_SAVE) #define BPF_PPC_SLOWPATH_FRAME (48+64) +#else +#define BPF_PPC_STACK_R3_OFF 24 +#define BPF_PPC_STACK_LOCALS 16 +#define BPF_PPC_STACK_BASIC(24+32) +#define BPF_PPC_STACK_SAVE (18*4) +#define BPF_PPC_STACKFRAME (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \ +BPF_PPC_STACK_SAVE) +#define BPF_PPC_SLOWPATH_FRAME (24+32) +#endif + +#define REG_SZ (BITS_PER_LONG/8) /* * Generated code register usage: @@ -57,7 +70,11 @@ DECLARE_LOAD_FUNC(sk_load_half); DECLARE_LOAD_FUNC(sk_load_byte); DECLARE_LOAD_FUNC(sk_load_byte_msh); +#ifdef CONFIG_PPC64 #define FUNCTION_DESCR_SIZE24 +#else +#define FUNCTION_DESCR_SIZE0 +#endif /* * 16-bit immediate helper macros: HA() is for use with sign-extending instrs @@ -86,7 +103,12 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); #define PPC_LIS(r, i) PPC_ADDIS(r, 0, i) #define PPC_STD(r, base, i)EMIT(PPC_INST_STD | ___PPC_RS(r) |\ ___PPC_RA(base) | ((i) & 0xfffc)) - +#define PPC_STDU(r, base, i) EMIT(PPC_INST_STDU | ___PPC_RS(r) | \ +___PPC_RA(base) | ((i) & 0xfffc)) +#define PPC_STW(r, base, i)EMIT(PPC_INST_STW | ___PPC_RS(r) |\ +___PPC_RA(base) | ((i) & 0xfffc)) +#define PPC_STWU(r, base, i) EMIT(PPC_INST_STWU | ___PPC_RS(r) | \ +___PPC_RA(base) | ((i) & 0xfffc)) #define PPC_LBZ(r, base, i)EMIT(PPC_INST_LBZ | ___PPC_RT(r) |\ ___PPC_RA(base) | IMM_L(i)) @@ -98,6 +120,17 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); ___PPC_RA(base) | IMM_L(i)) #define PPC_LHBRX(r, base, b) EMIT(PPC_INST_LHBRX | ___PPC_RT(r) | \ ___PPC_RA(base) | ___PPC_RB(b)) + +#ifdef CONFIG_PPC64 +#define PPC_BPF_LL(r, base, i) do { PPC_LD(r, base, i); } while(0) +#define PPC_BPF_STL(r, base, i) do { PPC_STD(r, base, i); } while(0) +#define PPC_BPF_STLU(r, base, i) do { PPC_STDU(r, base, i); } while(0) +#else +#define PPC_BPF_LL(r, base, i) do { PPC_LWZ(r, base, i); } while(0) +#define PPC_BPF_STL(r, base, i) do { PPC_STW(r, base, i); } while(0) +#define PPC_BPF_STLU(r, base, i) do { PPC_STWU(r, base, i); } while(0) +#endif + /* Convenience helpers for the above with 'far' offsets: */ #define PPC_LBZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LBZ(r, base, i); \ else { PPC_ADDIS(r, base, IMM_HA(i));\ @@ -115,6 +148,12 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); else { PPC_ADDIS(r, base, IMM_HA(i));\ PPC_LHZ(r, r, IMM_L(i)); } } while(0) +#ifdef CONFIG_PPC64 +#define PPC_LL_OFFS(r, base, i) do { PPC_LD_OFFS(r, base, i); } while(0) +#else +#define PPC_LL_OFFS(r, base, i) do { PPC_LWZ_OFFS(r, base, i); } while(0) +#endif + #define PPC_CMPWI(a, i)EMIT(PPC_INST_CMPWI | ___PPC_RA(a) | IMM_L(i)) #define PPC_CMPDI(a, i)EMIT(PPC_INST_CMPDI | ___PPC_RA(a) | IMM_L(i)) #define PPC_CMPLWI(a, i) EMIT(PPC_INST_CMPLWI | ___PPC_RA(a) | IMM_L(i)) @@ -196,6 +235,12 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh); PPC_ORI(d, d, (uintptr_t)(i) & 0x); \ } } while (0); +#ifdef CONFIG_PPC64 +#define PPC_FUNC_ADDR(d,i) do { PPC_LI64(d, i); } while(0) +#else +#define PPC_FUNC_ADDR(d,i) do { PPC_LI32(d, i); } while(0) +#endif + #define PPC_LHBRX_OFFS(r, base, i) \ do { PPC_LI32(r, i); PPC_LHBRX(r, r, base); } while(0) #ifdef __LITTLE_ENDIAN__ diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_64.S index 8f87d92..8ff5a3b 100644 --- a/arch/powerpc/net/bpf_jit_64.S +++ b/arch/powerpc/net/bpf_jit_64.S @@ -34,13 +34,13 @@ */ .globl sk_load_word sk_load_word: - cmpdi r_addr, 0 + PPC_LCMPI r_addr, 0 blt bpf_slow_path_word_neg .globl sk_load_word_positive_offset sk_load_word_positive_off
[PATCH net-next 3/6] ppc: bpf: add reqired opcodes for ppc32
Signed-off-by: Denis Kirjanov --- arch/powerpc/include/asm/ppc-opcode.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index 03cd858..2eadde0 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -212,6 +212,8 @@ #define PPC_INST_LWZ 0x8000 #define PPC_INST_STD 0xf800 #define PPC_INST_STDU 0xf801 +#define PPC_INST_STW 0x9000 +#define PPC_INST_STWU 0x9400 #define PPC_INST_MFLR 0x7c0802a6 #define PPC_INST_MTLR 0x7c0803a6 #define PPC_INST_CMPWI 0x2c00 -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH net-next 1/6] ppc: Kconfig: Enable BPF JIT on ppc32
Signed-off-by: Denis Kirjanov --- arch/powerpc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 22b0940..5084bdc 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -126,7 +126,7 @@ config PPC select IRQ_FORCED_THREADING select HAVE_RCU_TABLE_FREE if SMP select HAVE_SYSCALL_TRACEPOINTS - select HAVE_BPF_JIT if PPC64 + select HAVE_BPF_JIT select HAVE_ARCH_JUMP_LABEL select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_HAS_GCOV_PROFILE_ALL -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH net-next 2/6] ppc: bpf: add required compatibility macros for jit
Signed-off-by: Denis Kirjanov --- arch/powerpc/include/asm/asm-compat.h | 4 1 file changed, 4 insertions(+) diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index 21be8ae..dc85dcb 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h @@ -23,6 +23,8 @@ #define PPC_STLstringify_in_c(std) #define PPC_STLU stringify_in_c(stdu) #define PPC_LCMPI stringify_in_c(cmpdi) +#define PPC_LCMPLI stringify_in_c(cmpldi) +#define PPC_LCMP stringify_in_c(cmpd) #define PPC_LONG stringify_in_c(.llong) #define PPC_LONG_ALIGN stringify_in_c(.balign 8) #define PPC_TLNEI stringify_in_c(tdnei) @@ -52,6 +54,8 @@ #define PPC_STLstringify_in_c(stw) #define PPC_STLU stringify_in_c(stwu) #define PPC_LCMPI stringify_in_c(cmpwi) +#define PPC_LCMPLI stringify_in_c(cmplwi) +#define PPC_LCMP stringify_in_c(cmpw) #define PPC_LONG stringify_in_c(.long) #define PPC_LONG_ALIGN stringify_in_c(.balign 4) #define PPC_TLNEI stringify_in_c(twnei) -- 2.1.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH net-next 0/6] bpf: Enable BPF JIT on ppc32
This patch series enables BPF JIT on ppc32. There are relatevily few chnages in the code to make it work. All test_bpf tests passed both on 7447a and P2041-based machines. arch/powerpc/Kconfig | 2 +- arch/powerpc/include/asm/asm-compat.h | 4 + arch/powerpc/include/asm/ppc-opcode.h | 2 + arch/powerpc/net/Makefile | 2 +- arch/powerpc/net/bpf_jit.h| 47 ++- arch/powerpc/net/bpf_jit_64.S | 229 -- arch/powerpc/net/bpf_jit_asm.S| 229 ++ arch/powerpc/net/bpf_jit_comp.c | 32 ++--- 8 files changed, 300 insertions(+), 247 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: embedding dtb file into kernel
Hi Richard, On 13/02/2015 18:41, K Richard Pixley wrote: > I'm having trouble figuring out how to embed a dtb file into my kernel. > I'm thinking that there should be a standard, architecture independent > facility for this akin to initramfs, yes? > > Could someone please either point me to the standard facility, relevant > doc, a currently building board that uses the standard facility, or > outline what needs to be done to do this with a new board? > > If it matters, (I can't think why it would), I'm working with powerpc on > a 3.10 kernel. But if there are better facilities in other versions I'd > appreciate hearing about that too. > Maybe it is worth to take a look at the fitImage, which can embed pretty much anything (including DTB). Best regards, Stefano Babic -- = DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sba...@denx.de = ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Problems with Kernels 3.17-rc1 and onwards on Acube Sam460 AMCC 460ex board
Hi I am unable to get any kernel beyond the 3.16 branch working on an Acube Sam460ex AMCC 460ex based motherboard. Kernel up 3.16.7-ckt6 working. These are the patches applied diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 49b0659..fa33568 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1066,7 +1066,7 @@ int radeon_device_init(struct radeon_device *rdev, if (rdev->rmmio == NULL) { return -ENOMEM; } - DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); + DRM_INFO("register mmio base: 0x%llx\n", (uint64_t)rdev->rmmio_base); DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); /* io port mapping */ diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 3cb5d84..fcdb208 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -81,7 +81,7 @@ struct ttm_placement { */ struct ttm_bus_placement { void*addr; - unsigned long base; + phys_addr_t base; unsigned long size; unsigned long offset; boolis_iomem; These are the serial boot messages U-Boot 2010.06.05a (Jan 30 2012 - 16:06:56) CPU: AMCC PowerPC 460EX Rev. B at 1155 MHz (PLB=231 OPB=115 EBC=115) No Security/Kasumi support Bootstrap Option H - Boot ROM Location I2C (Addr 0x52) Internal PCI arbiter enabled 32 kB I-Cache 32 kB D-Cache Board: Sam460ex, PCIe 4x + PCIe 1x I2C: ready DRAM: 2 GiB (ECC not enabled, 462 MHz, CL4) PCI: Bus Dev VenId DevId Class Int 00 04 1095 3512 0104 00 00 06 126f 0501 0380 00 PCIE0: successfully set as root-complex 03 00 1412 1724 0401 ff 02 00 1b21 1080 0604 00 PCIE1: successfully set as root-complex 05 00 1002 6758 0300 ff Net: ppc_4xx_eth0 FPGA: Revision 03 (2010-10-07) SM502: found VGA: 1 VESA: OK [0.00] Using Canyonlands machine description [0.00] Initializing cgroup subsys cpu [0.00] Linux version 3.17.0-rc1-Sam460ex (root@julian-VirtualBox) (gcc version 4.8.2 (Ubuntu 4.8.2-16ubuntu3) ) #1 PREEMPT Sat Feb 14 19:45:33 AST 2015 [0.00] Zone ranges: [0.00] DMA [mem 0x-0x2fff] [0.00] Normal empty [0.00] HighMem [mem 0x3000-0x7fff] [0.00] Movable zone start for each node [0.00] Early memory node ranges [0.00] node 0: [mem 0x-0x7fff] [0.00] MMU: Allocated 1088 bytes of context maps for 255 contexts [0.00] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 522752 [0.00] Kernel command line: root=/dev/sda12 console=ttyS0,115200 console=tty0 [0.00] PID hash table entries: 4096 (order: 2, 16384 bytes) [0.00] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes) [0.00] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) [0.00] Sorting __ex_table... [0.00] Memory: 2004844K/2097152K available (5764K kernel code, 232K rwdata, 1456K rodata, 236K init, 1333K bss, 92308K reserved, 1310720K highmem) [0.00] Kernel virtual memory layout: [0.00] * 0xfffcf000..0xf000 : fixmap [0.00] * 0xffc0..0xffe0 : highmem PTEs [0.00] * 0xffa0..0xffc0 : consistent mem [0.00] * 0xffa0..0xffa0 : early ioremap [0.00] * 0xf100..0xffa0 : vmalloc & ioremap [0.00] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 [0.00] Preemptible hierarchical RCU implementation. [0.00] NR_IRQS:512 nr_irqs:512 16 [0.00] UIC0 (32 IRQ sources) at DCR 0xc0 [0.00] UIC1 (32 IRQ sources) at DCR 0xd0 [0.00] UIC2 (32 IRQ sources) at DCR 0xe0 [0.00] UIC3 (32 IRQ sources) at DCR 0xf0 [0.13] clocksource: timebase mult[dda520] shift[24] registered [0.000138] Console: colour dummy device 80x25 [0.000557] console [tty0] enabled [0.000581] pid_max: default: 32768 minimum: 301 [0.000683] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes) [0.000706] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes) [0.002800] devtmpfs: initialized [0.003674] xor: measuring software checksum speed [0.013505]8regs : 856.000 MB/sec [0.023276]8regs_prefetch: 780.000 MB/sec [0.033309]32regs: 1120.000 MB/sec [0.043362]32regs_prefetch: 996.000 MB/sec [0.043388] xor: using function: 32regs (1120.000 MB/sec) [0.045174] NET: Registered protocol family 16 [0.046996] 256k L2-cache enabled [0.047113] PCIE0: Checking link... [0.047126] PCIE0: Device detected, waiting for link... [0.047140] PCIE0: link is up ! [0.149234] PCI host bridge /plb/pciex@d (primary) ranges: [
[RFC PATCH powerpc] perf/hv-24x7 set the attr group to NULL if events failed to be initialized
sysfs_create_groups() creates groups one by one in the attr_groups array before a NULL entry is encountered. But if an error is seen, it stops and removes all the groups already created: for (i = 0; groups[i]; i++) { error = sysfs_create_group(kobj, groups[i]); if (error) { while (--i >= 0) sysfs_remove_group(kobj, groups[i]); break; } } And for the three event groups of 24x7, if it is not supported, according to the above logic, it causes format and interface group to be removed because of the error. This patch moves the three events groups to the end of the attr groups, and if create_events_from_catalog() fails to set their attributes, we set them to NULL in attr_groups. Signed-off-by: Li Zhong --- arch/powerpc/perf/hv-24x7.c | 37 - 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 9445a82..1e433f7 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -637,7 +637,7 @@ static ssize_t catalog_event_len_validate(struct hv_24x7_event_data *event, #define MAX_4K (SIZE_MAX / 4096) -static void create_events_from_catalog(struct attribute ***events_, +static int create_events_from_catalog(struct attribute ***events_, struct attribute ***event_descs_, struct attribute ***event_long_descs_) { @@ -843,7 +843,7 @@ static void create_events_from_catalog(struct attribute ***events_, *events_ = events; *event_descs_ = event_descs; *event_long_descs_ = event_long_descs; - return; + return 0; e_event_descs: kfree(event_descs); @@ -857,6 +857,7 @@ e_out: *events_ = NULL; *event_descs_ = NULL; *event_long_descs_ = NULL; + return -1; } static ssize_t catalog_read(struct file *filp, struct kobject *kobj, @@ -967,13 +968,25 @@ static struct attribute_group if_group = { .attrs = if_attrs, }; +enum GROUP_INDEX { + FORMAT, + IF, + EVENT, + EVENT_DESC, + EVENT_LONG_DESC, + MAX +}; + +/* + * keep the attr group whose attr is set in init (may fail) + * at the end + */ static const struct attribute_group *attr_groups[] = { - &format_group, - &event_group, - &event_desc_group, - &event_long_desc_group, - &if_group, - NULL, + [FORMAT] = &format_group, + [IF] = &if_group, + [EVENT] = &event_group, + [EVENT_DESC] = &event_desc_group, + [EVENT_LONG_DESC] = &event_long_desc_group }; DEFINE_PER_CPU(char, hv_24x7_reqb[4096]) __aligned(4096); @@ -1219,10 +1232,16 @@ static int hv_24x7_init(void) /* sampling not supported */ h_24x7_pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; - create_events_from_catalog(&event_group.attrs, + r = create_events_from_catalog(&event_group.attrs, &event_desc_group.attrs, &event_long_desc_group.attrs); + if (r) { + h_24x7_pmu.attr_groups[EVENT] = + h_24x7_pmu.attr_groups[EVENT_DESC] = + h_24x7_pmu.attr_groups[EVENT_LONG_DESC] = 0; + } + r = perf_pmu_register(&h_24x7_pmu, h_24x7_pmu.name, -1); if (r) return r; ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev