Skip to content

Commit

Permalink
x86/intel_rdt/mbm: Basic counting of MBM events (total and local)
Browse files Browse the repository at this point in the history
Check CPUID bits for whether each of the MBM events is supported.
Allocate space for each RMID for each counter in each domain to save
previous MSR counter value and running total of data.
Create files in each of the monitor directories.

Signed-off-by: Tony Luck <[email protected]>
Signed-off-by: Vikas Shivappa <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/1501017287-28083-27-git-send-email-vikas.shivappa@linux.intel.com
  • Loading branch information
aegl authored and KAGA-KOKO committed Aug 1, 2017
1 parent 895c663 commit 9f52425
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 2 deletions.
23 changes: 22 additions & 1 deletion arch/x86/kernel/cpu/intel_rdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,13 +420,32 @@ static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d)

static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_domain *d)
{
size_t tsize;

if (is_llc_occupancy_enabled()) {
d->rmid_busy_llc = kcalloc(BITS_TO_LONGS(r->num_rmid),
sizeof(unsigned long),
GFP_KERNEL);
if (!d->rmid_busy_llc)
return -ENOMEM;
}
if (is_mbm_total_enabled()) {
tsize = sizeof(*d->mbm_total);
d->mbm_total = kcalloc(r->num_rmid, tsize, GFP_KERNEL);
if (!d->mbm_total) {
kfree(d->rmid_busy_llc);
return -ENOMEM;
}
}
if (is_mbm_local_enabled()) {
tsize = sizeof(*d->mbm_local);
d->mbm_local = kcalloc(r->num_rmid, tsize, GFP_KERNEL);
if (!d->mbm_local) {
kfree(d->rmid_busy_llc);
kfree(d->mbm_total);
return -ENOMEM;
}
}

return 0;
}
Expand Down Expand Up @@ -466,6 +485,7 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
return;

d->id = id;
cpumask_set_cpu(cpu, &d->cpu_mask);

if (r->alloc_capable && domain_setup_ctrlval(r, d)) {
kfree(d);
Expand All @@ -477,7 +497,6 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
return;
}

cpumask_set_cpu(cpu, &d->cpu_mask);
list_add_tail(&d->list, add_pos);

/*
Expand Down Expand Up @@ -509,6 +528,8 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r)
rmdir_mondata_subdir_allrdtgrp(r, d->id);
kfree(d->ctrl_val);
kfree(d->rmid_busy_llc);
kfree(d->mbm_total);
kfree(d->mbm_local);
list_del(&d->list);
kfree(d);
}
Expand Down
33 changes: 33 additions & 0 deletions arch/x86/kernel/cpu/intel_rdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#define QOS_L3_OCCUP_EVENT_ID 0x01
#define QOS_L3_MBM_TOTAL_EVENT_ID 0x02
#define QOS_L3_MBM_LOCAL_EVENT_ID 0x03

#define MBM_CNTR_WIDTH 24

#define RMID_VAL_ERROR BIT_ULL(63)
#define RMID_VAL_UNAVAIL BIT_ULL(62)

Expand Down Expand Up @@ -50,6 +53,7 @@ union mon_data_bits {

struct rmid_read {
struct rdtgroup *rgrp;
struct rdt_domain *d;
int evtid;
u64 val;
};
Expand Down Expand Up @@ -159,13 +163,25 @@ struct rftype {
char *buf, size_t nbytes, loff_t off);
};

/**
* struct mbm_state - status for each MBM counter in each domain
* @chunks: Total data moved (multiply by rdt_group.mon_scale to get bytes)
* @prev_msr Value of IA32_QM_CTR for this RMID last time we read it
*/
struct mbm_state {
u64 chunks;
u64 prev_msr;
};

/**
* struct rdt_domain - group of cpus sharing an RDT resource
* @list: all instances of this resource
* @id: unique id for this instance
* @cpu_mask: which cpus share this resource
* @rmid_busy_llc:
* bitmap of which limbo RMIDs are above threshold
* @mbm_total: saved state for MBM total bandwidth
* @mbm_local: saved state for MBM local bandwidth
* @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID)
* @new_ctrl: new ctrl value to be loaded
* @have_new_ctrl: did user provide new_ctrl for this domain
Expand All @@ -175,6 +191,8 @@ struct rdt_domain {
int id;
struct cpumask cpu_mask;
unsigned long *rmid_busy_llc;
struct mbm_state *mbm_total;
struct mbm_state *mbm_local;
u32 *ctrl_val;
u32 new_ctrl;
bool have_new_ctrl;
Expand Down Expand Up @@ -230,6 +248,21 @@ static inline bool is_llc_occupancy_enabled(void)
return (rdt_mon_features & (1 << QOS_L3_OCCUP_EVENT_ID));
}

static inline bool is_mbm_total_enabled(void)
{
return (rdt_mon_features & (1 << QOS_L3_MBM_TOTAL_EVENT_ID));
}

static inline bool is_mbm_local_enabled(void)
{
return (rdt_mon_features & (1 << QOS_L3_MBM_LOCAL_EVENT_ID));
}

static inline bool is_mbm_enabled(void)
{
return (is_mbm_total_enabled() || is_mbm_local_enabled());
}

/**
* struct rdt_resource - attributes of an RDT resource
* @rid: The index of the resource
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ void mon_event_read(struct rmid_read *rr, struct rdt_domain *d,
*/
rr->rgrp = rdtgrp;
rr->evtid = evtid;
rr->d = d;
rr->val = 0;

smp_call_function_any(&d->cpu_mask, mon_event_count, rr, 1);
Expand Down
31 changes: 30 additions & 1 deletion arch/x86/kernel/cpu/intel_rdt_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,8 @@ void free_rmid(u32 rmid)

static int __mon_event_count(u32 rmid, struct rmid_read *rr)
{
u64 tval;
u64 chunks, shift, tval;
struct mbm_state *m;

tval = __rmid_read(rmid, rr->evtid);
if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) {
Expand All @@ -307,13 +308,27 @@ static int __mon_event_count(u32 rmid, struct rmid_read *rr)
case QOS_L3_OCCUP_EVENT_ID:
rr->val += tval;
return 0;
case QOS_L3_MBM_TOTAL_EVENT_ID:
m = &rr->d->mbm_total[rmid];
break;
case QOS_L3_MBM_LOCAL_EVENT_ID:
m = &rr->d->mbm_local[rmid];
break;
default:
/*
* Code would never reach here because
* an invalid event id would fail the __rmid_read.
*/
return -EINVAL;
}
shift = 64 - MBM_CNTR_WIDTH;
chunks = (tval << shift) - (m->prev_msr << shift);
chunks >>= shift;
m->chunks += chunks;
m->prev_msr = tval;

rr->val += m->chunks;
return 0;
}

/*
Expand Down Expand Up @@ -377,6 +392,16 @@ static struct mon_evt llc_occupancy_event = {
.evtid = QOS_L3_OCCUP_EVENT_ID,
};

static struct mon_evt mbm_total_event = {
.name = "mbm_total_bytes",
.evtid = QOS_L3_MBM_TOTAL_EVENT_ID,
};

static struct mon_evt mbm_local_event = {
.name = "mbm_local_bytes",
.evtid = QOS_L3_MBM_LOCAL_EVENT_ID,
};

/*
* Initialize the event list for the resource.
*
Expand All @@ -390,6 +415,10 @@ static void l3_mon_evt_init(struct rdt_resource *r)

if (is_llc_occupancy_enabled())
list_add_tail(&llc_occupancy_event.list, &r->evt_list);
if (is_mbm_total_enabled())
list_add_tail(&mbm_total_event.list, &r->evt_list);
if (is_mbm_local_enabled())
list_add_tail(&mbm_local_event.list, &r->evt_list);
}

int rdt_get_mon_l3_config(struct rdt_resource *r)
Expand Down

0 comments on commit 9f52425

Please sign in to comment.