lkml.org 
[lkml]   [2019]   [Jun]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip:perf/core] perf/x86/intel/uncore: Support MMIO type uncore blocks
    Commit-ID:  3da04b8a00dd6d39970b9e764b78c5dfb40ec013
    Gitweb: https://git.kernel.org/tip/3da04b8a00dd6d39970b9e764b78c5dfb40ec013
    Author: Kan Liang <kan.liang@linux.intel.com>
    AuthorDate: Tue, 30 Apr 2019 17:53:46 -0700
    Committer: Ingo Molnar <mingo@kernel.org>
    CommitDate: Mon, 17 Jun 2019 12:36:20 +0200

    perf/x86/intel/uncore: Support MMIO type uncore blocks

    A new MMIO type uncore box is introduced on Snow Ridge server. The
    counters of MMIO type uncore box can only be accessed by MMIO.

    Add a new uncore type, uncore_mmio_uncores, for MMIO type uncore blocks.

    Support MMIO type uncore blocks in CPU hot plug. The MMIO space has to
    be map/unmap for the first/last CPU. The context also need to be
    migrated if the bind CPU changes.

    Add mmio_init() to init and register PMUs for MMIO type uncore blocks.

    Add a helper to calculate the box_ctl address.

    The helpers which calculate ctl/ctr can be shared with PCI type uncore
    blocks.

    Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: acme@kernel.org
    Cc: eranian@google.com
    Link: https://lkml.kernel.org/r/1556672028-119221-5-git-send-email-kan.liang@linux.intel.com
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    ---
    arch/x86/events/intel/uncore.c | 51 ++++++++++++++++++++++++++++++++++++------
    arch/x86/events/intel/uncore.h | 21 ++++++++++++-----
    2 files changed, 60 insertions(+), 12 deletions(-)

    diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
    index 7b0c88903d47..442f30e5e49a 100644
    --- a/arch/x86/events/intel/uncore.c
    +++ b/arch/x86/events/intel/uncore.c
    @@ -8,6 +8,7 @@
    static struct intel_uncore_type *empty_uncore[] = { NULL, };
    struct intel_uncore_type **uncore_msr_uncores = empty_uncore;
    struct intel_uncore_type **uncore_pci_uncores = empty_uncore;
    +struct intel_uncore_type **uncore_mmio_uncores = empty_uncore;

    static bool pcidrv_registered;
    struct pci_driver *uncore_pci_driver;
    @@ -1178,12 +1179,14 @@ static int uncore_event_cpu_offline(unsigned int cpu)
    target = -1;

    uncore_change_context(uncore_msr_uncores, cpu, target);
    + uncore_change_context(uncore_mmio_uncores, cpu, target);
    uncore_change_context(uncore_pci_uncores, cpu, target);

    unref:
    /* Clear the references */
    die = topology_logical_die_id(cpu);
    uncore_box_unref(uncore_msr_uncores, die);
    + uncore_box_unref(uncore_mmio_uncores, die);
    return 0;
    }

    @@ -1252,12 +1255,13 @@ static int uncore_box_ref(struct intel_uncore_type **types,

    static int uncore_event_cpu_online(unsigned int cpu)
    {
    - int ret, die, target;
    + int die, target, msr_ret, mmio_ret;

    die = topology_logical_die_id(cpu);
    - ret = uncore_box_ref(uncore_msr_uncores, die, cpu);
    - if (ret)
    - return ret;
    + msr_ret = uncore_box_ref(uncore_msr_uncores, die, cpu);
    + mmio_ret = uncore_box_ref(uncore_mmio_uncores, die, cpu);
    + if (msr_ret && mmio_ret)
    + return -ENOMEM;

    /*
    * Check if there is an online cpu in the package
    @@ -1269,7 +1273,10 @@ static int uncore_event_cpu_online(unsigned int cpu)

    cpumask_set_cpu(cpu, &uncore_cpu_mask);

    - uncore_change_context(uncore_msr_uncores, -1, cpu);
    + if (!msr_ret)
    + uncore_change_context(uncore_msr_uncores, -1, cpu);
    + if (!mmio_ret)
    + uncore_change_context(uncore_mmio_uncores, -1, cpu);
    uncore_change_context(uncore_pci_uncores, -1, cpu);
    return 0;
    }
    @@ -1317,12 +1324,35 @@ err:
    return ret;
    }

    +static int __init uncore_mmio_init(void)
    +{
    + struct intel_uncore_type **types = uncore_mmio_uncores;
    + int ret;
    +
    + ret = uncore_types_init(types, true);
    + if (ret)
    + goto err;
    +
    + for (; *types; types++) {
    + ret = type_pmu_register(*types);
    + if (ret)
    + goto err;
    + }
    + return 0;
    +err:
    + uncore_types_exit(uncore_mmio_uncores);
    + uncore_mmio_uncores = empty_uncore;
    + return ret;
    +}
    +
    +
    #define X86_UNCORE_MODEL_MATCH(model, init) \
    { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&init }

    struct intel_uncore_init_fun {
    void (*cpu_init)(void);
    int (*pci_init)(void);
    + void (*mmio_init)(void);
    };

    static const struct intel_uncore_init_fun nhm_uncore_init __initconst = {
    @@ -1437,7 +1467,7 @@ static int __init intel_uncore_init(void)
    {
    const struct x86_cpu_id *id;
    struct intel_uncore_init_fun *uncore_init;
    - int pret = 0, cret = 0, ret;
    + int pret = 0, cret = 0, mret = 0, ret;

    id = x86_match_cpu(intel_uncore_match);
    if (!id)
    @@ -1460,7 +1490,12 @@ static int __init intel_uncore_init(void)
    cret = uncore_cpu_init();
    }

    - if (cret && pret)
    + if (uncore_init->mmio_init) {
    + uncore_init->mmio_init();
    + mret = uncore_mmio_init();
    + }
    +
    + if (cret && pret && mret)
    return -ENODEV;

    /* Install hotplug callbacks to setup the targets for each package */
    @@ -1474,6 +1509,7 @@ static int __init intel_uncore_init(void)

    err:
    uncore_types_exit(uncore_msr_uncores);
    + uncore_types_exit(uncore_mmio_uncores);
    uncore_pci_exit();
    return ret;
    }
    @@ -1483,6 +1519,7 @@ static void __exit intel_uncore_exit(void)
    {
    cpuhp_remove_state(CPUHP_AP_PERF_X86_UNCORE_ONLINE);
    uncore_types_exit(uncore_msr_uncores);
    + uncore_types_exit(uncore_mmio_uncores);
    uncore_pci_exit();
    }
    module_exit(intel_uncore_exit);
    diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
    index b444ed35d6f7..fc5f48816005 100644
    --- a/arch/x86/events/intel/uncore.h
    +++ b/arch/x86/events/intel/uncore.h
    @@ -56,7 +56,10 @@ struct intel_uncore_type {
    unsigned fixed_ctr;
    unsigned fixed_ctl;
    unsigned box_ctl;
    - unsigned msr_offset;
    + union {
    + unsigned msr_offset;
    + unsigned mmio_offset;
    + };
    unsigned num_shared_regs:8;
    unsigned single_fixed:1;
    unsigned pair_ctr_ctl:1;
    @@ -190,6 +193,13 @@ static inline bool uncore_pmc_freerunning(int idx)
    return idx == UNCORE_PMC_IDX_FREERUNNING;
    }

    +static inline
    +unsigned int uncore_mmio_box_ctl(struct intel_uncore_box *box)
    +{
    + return box->pmu->type->box_ctl +
    + box->pmu->type->mmio_offset * box->pmu->pmu_idx;
    +}
    +
    static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box)
    {
    return box->pmu->type->box_ctl;
    @@ -330,7 +340,7 @@ unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx)
    static inline
    unsigned uncore_fixed_ctl(struct intel_uncore_box *box)
    {
    - if (box->pci_dev)
    + if (box->pci_dev || box->io_addr)
    return uncore_pci_fixed_ctl(box);
    else
    return uncore_msr_fixed_ctl(box);
    @@ -339,7 +349,7 @@ unsigned uncore_fixed_ctl(struct intel_uncore_box *box)
    static inline
    unsigned uncore_fixed_ctr(struct intel_uncore_box *box)
    {
    - if (box->pci_dev)
    + if (box->pci_dev || box->io_addr)
    return uncore_pci_fixed_ctr(box);
    else
    return uncore_msr_fixed_ctr(box);
    @@ -348,7 +358,7 @@ unsigned uncore_fixed_ctr(struct intel_uncore_box *box)
    static inline
    unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx)
    {
    - if (box->pci_dev)
    + if (box->pci_dev || box->io_addr)
    return uncore_pci_event_ctl(box, idx);
    else
    return uncore_msr_event_ctl(box, idx);
    @@ -357,7 +367,7 @@ unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx)
    static inline
    unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx)
    {
    - if (box->pci_dev)
    + if (box->pci_dev || box->io_addr)
    return uncore_pci_perf_ctr(box, idx);
    else
    return uncore_msr_perf_ctr(box, idx);
    @@ -507,6 +517,7 @@ u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx);

    extern struct intel_uncore_type **uncore_msr_uncores;
    extern struct intel_uncore_type **uncore_pci_uncores;
    +extern struct intel_uncore_type **uncore_mmio_uncores;
    extern struct pci_driver *uncore_pci_driver;
    extern raw_spinlock_t pci2phy_map_lock;
    extern struct list_head pci2phy_map_head;
    \
     
     \ /
      Last update: 2019-06-17 16:38    [W:2.714 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site