Skip to content

Support for Intel Sapphire Rapids #6

@zelenyaz

Description

@zelenyaz

Because my experimental platform is based on Intel Sapphire Rapids, I consulted Intel’s documentation [1] and found that the MSR addresses have changed in this generation (see Section 1.8.1 of [1]). I added support for Sapphire Rapids accordingly, referencing the implementation in tpp/colloid-mon/backend/icx-native.c. The code is as follows (in case anyone needs it):

// tpp/colloid-mon/backend/spr-native.c
#include "backend_iface.h"
#include <linux/kernel.h>
#include <asm/msr.h>

#define CHA_BOX_STRIDE           0x10ULL
#define CHA_MSR_PMON_BASE        0x2000ULL
#define CHA_MSR_CTL0_BASE        0x2002ULL
#define CHA_MSR_CTR0_BASE        0x2008ULL
#define CHA_MSR_FILTER0_BASE     0x200EULL
#define CHA_MSR_STATUS_BASE      0x2001ULL

#define NUM_CHA_BOXES 34
#define NUM_CHA_COUNTERS 4

static int core_mon;

int backend_init(struct backend_config* config) {
    int cha, ret;
    u32 msr_num;
    u64 msr_val;

    if (!config) {
        printk(KERN_ERR "spr-native: invalid backend_config passed\n");
        return -1;
    }

    core_mon = config->core;
    pr_info("colloid: core mon %d\n", core_mon);

    for (cha = 0; cha < NUM_CHA_BOXES; cha++) {
        msr_num = CHA_MSR_FILTER0_BASE + (CHA_BOX_STRIDE * cha); // Filter0
        msr_val = 0x00000000; // default; no filtering
        ret = wrmsr_on_cpu(core_mon, msr_num, msr_val & 0xFFFFFFFF, msr_val >> 32);
        if (ret != 0) {
            printk(KERN_ERR "spr-native: wrmsr FILTER0 failed\n");
            return -1;
        }

        msr_num = CHA_MSR_CTL0_BASE + (CHA_BOX_STRIDE * cha) + 0; // counter 0
        msr_val = (cha%2==0)?(0x00c8168600400136):(0x00c8170600400136); // TOR Occupancy, DRd, Miss, local/remote on even/odd CHA boxes
        ret = wrmsr_on_cpu(core_mon, msr_num, msr_val & 0xFFFFFFFF, msr_val >> 32);
        if(ret != 0) {
            printk(KERN_ERR "icx-native: wrmsr COUNTER 0 failed\n");
            return -1;
        }

        msr_num = CHA_MSR_CTL0_BASE + (CHA_BOX_STRIDE * cha) + 1; // counter 1
        msr_val = (cha%2==0)?(0x00c8168600400135):(0x00c8170600400135); // TOR Inserts, DRd, Miss, local/remote on even/odd CHA boxes
        ret = wrmsr_on_cpu(core_mon, msr_num, msr_val & 0xFFFFFFFF, msr_val >> 32);
        if(ret != 0) {
            printk(KERN_ERR " icx-native: wrmsr COUNTER 1 failed\n");
            return -1;
        }

        msr_num = CHA_MSR_CTL0_BASE + (CHA_BOX_STRIDE * cha) + 2; // counter 2
        msr_val = 0x400000; // CLOCKTICKS
        ret = wrmsr_on_cpu(core_mon, msr_num, msr_val & 0xFFFFFFFF, msr_val >> 32);
        if(ret != 0) {
            printk(KERN_ERR "icx-native: wrmsr COUNTER 2 failed\n");
            return -1;
        }
    }

    return 0;
}

int backend_destroy() {
    return 0;
}

u64 backend_read_occupancy(int tier) {
    int cha, ctr;
    u32 msr_num, msr_high, msr_low;
    cha = tier; // Default tier on CHA slice 0, Alternate tier on CHA slice 1
    ctr = 0; // Occupancy
    msr_num = CHA_MSR_CTR0_BASE + (CHA_BOX_STRIDE * cha) + ctr;    
    rdmsr_on_cpu(core_mon, msr_num, &msr_low, &msr_high);
    return ((((u64)msr_high) << 32) | ((u64)msr_low));
}

u64 backend_read_inserts(int tier) {
    int cha, ctr;
    u32 msr_num, msr_high, msr_low;
    cha = tier; // Default tier on CHA slice 0, Alternate tier on CHA slice 1
    ctr = 1; // Inserts
    msr_num = CHA_MSR_CTR0_BASE + (CHA_BOX_STRIDE * cha) + ctr;    
    rdmsr_on_cpu(core_mon, msr_num, &msr_low, &msr_high);
    return ((((u64)msr_high) << 32) | ((u64)msr_low));
}

Link:
[1] https://www.intel.com/content/www/us/en/content-details/639667/4th-gen-intel-xeon-scalable-processor-xcc-codename-sapphire-rapids-uncore-performance-monitoring-guide.html

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions