Skip to content

Commit

Permalink
Merge branch 'x86-cache-for-linus' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/tip/tip

Pull x86 cache resource updates from Thomas Gleixner:
 "This update provides updates to RDT:

  - A diagnostic framework for the Resource Director Technology (RDT)
    user interface (sysfs). The failure modes of the user interface are
    hard to diagnose from the error codes. An extra last command status
    file provides now sensible textual information about the failure so
    its simpler to use.

  - A few minor cleanups and updates in the RDT code"

* 'x86-cache-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/intel_rdt: Fix a silent failure when writing zero value schemata
  x86/intel_rdt: Fix potential deadlock during resctrl mount
  x86/intel_rdt: Fix potential deadlock during resctrl unmount
  x86/intel_rdt: Initialize bitmask of shareable resource if CDP enabled
  x86/intel_rdt: Remove redundant assignment
  x86/intel_rdt/cqm: Make integer rmid_limbo_count static
  x86/intel_rdt: Add documentation for "info/last_cmd_status"
  x86/intel_rdt: Add diagnostics when making directories
  x86/intel_rdt: Add diagnostics when writing the cpus file
  x86/intel_rdt: Add diagnostics when writing the tasks file
  x86/intel_rdt: Add diagnostics when writing the schemata file
  x86/intel_rdt: Add framework for better RDT UI diagnostics
  • Loading branch information
torvalds committed Nov 14, 2017
2 parents b18d628 + 2244645 commit 3643b7e
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 32 deletions.
11 changes: 11 additions & 0 deletions Documentation/x86/intel_rdt_ui.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,17 @@ with the following files:
bytes) at which a previously used LLC_occupancy
counter can be considered for re-use.

Finally, in the top level of the "info" directory there is a file
named "last_cmd_status". This is reset with every "command" issued
via the file system (making new directories or writing to any of the
control files). If the command was successful, it will read as "ok".
If the command failed, it will provide more information that can be
conveyed in the error returns from file operations. E.g.

# echo L3:0=f7 > schemata
bash: echo: write error: Invalid argument
# cat info/last_cmd_status
mask f7 has non-consecutive 1-bits

Resource alloc and monitor groups
---------------------------------
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/cpu/intel_rdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ static void rdt_get_cdp_l3_config(int type)
r->num_closid = r_l3->num_closid / 2;
r->cache.cbm_len = r_l3->cache.cbm_len;
r->default_ctrl = r_l3->default_ctrl;
r->cache.shareable_bits = r_l3->cache.shareable_bits;
r->data_width = (r->cache.cbm_len + 3) / 4;
r->alloc_capable = true;
/*
Expand Down
7 changes: 7 additions & 0 deletions arch/x86/kernel/cpu/intel_rdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,15 @@ struct rdtgroup {
#define RFTYPE_BASE BIT(1)
#define RF_CTRLSHIFT 4
#define RF_MONSHIFT 5
#define RF_TOPSHIFT 6
#define RFTYPE_CTRL BIT(RF_CTRLSHIFT)
#define RFTYPE_MON BIT(RF_MONSHIFT)
#define RFTYPE_TOP BIT(RF_TOPSHIFT)
#define RFTYPE_RES_CACHE BIT(8)
#define RFTYPE_RES_MB BIT(9)
#define RF_CTRL_INFO (RFTYPE_INFO | RFTYPE_CTRL)
#define RF_MON_INFO (RFTYPE_INFO | RFTYPE_MON)
#define RF_TOP_INFO (RFTYPE_INFO | RFTYPE_TOP)
#define RF_CTRL_BASE (RFTYPE_BASE | RFTYPE_CTRL)

/* List of all resource groups */
Expand Down Expand Up @@ -409,6 +412,10 @@ union cpuid_0x10_x_edx {
unsigned int full;
};

void rdt_last_cmd_clear(void);
void rdt_last_cmd_puts(const char *s);
void rdt_last_cmd_printf(const char *fmt, ...);

void rdt_ctrl_update(void *arg);
struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn);
void rdtgroup_kn_unlock(struct kernfs_node *kn);
Expand Down
50 changes: 40 additions & 10 deletions arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,22 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r)
/*
* Only linear delay values is supported for current Intel SKUs.
*/
if (!r->membw.delay_linear)
if (!r->membw.delay_linear) {
rdt_last_cmd_puts("No support for non-linear MB domains\n");
return false;
}

ret = kstrtoul(buf, 10, &bw);
if (ret)
if (ret) {
rdt_last_cmd_printf("Non-decimal digit in MB value %s\n", buf);
return false;
}

if (bw < r->membw.min_bw || bw > r->default_ctrl)
if (bw < r->membw.min_bw || bw > r->default_ctrl) {
rdt_last_cmd_printf("MB value %ld out of range [%d,%d]\n", bw,
r->membw.min_bw, r->default_ctrl);
return false;
}

*data = roundup(bw, (unsigned long)r->membw.bw_gran);
return true;
Expand All @@ -60,8 +67,10 @@ int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d)
{
unsigned long data;

if (d->have_new_ctrl)
if (d->have_new_ctrl) {
rdt_last_cmd_printf("duplicate domain %d\n", d->id);
return -EINVAL;
}

if (!bw_validate(buf, &data, r))
return -EINVAL;
Expand All @@ -84,20 +93,29 @@ static bool cbm_validate(char *buf, unsigned long *data, struct rdt_resource *r)
int ret;

ret = kstrtoul(buf, 16, &val);
if (ret)
if (ret) {
rdt_last_cmd_printf("non-hex character in mask %s\n", buf);
return false;
}

if (val == 0 || val > r->default_ctrl)
if (val == 0 || val > r->default_ctrl) {
rdt_last_cmd_puts("mask out of range\n");
return false;
}

first_bit = find_first_bit(&val, cbm_len);
zero_bit = find_next_zero_bit(&val, cbm_len, first_bit);

if (find_next_bit(&val, cbm_len, zero_bit) < cbm_len)
if (find_next_bit(&val, cbm_len, zero_bit) < cbm_len) {
rdt_last_cmd_printf("mask %lx has non-consecutive 1-bits\n", val);
return false;
}

if ((zero_bit - first_bit) < r->cache.min_cbm_bits)
if ((zero_bit - first_bit) < r->cache.min_cbm_bits) {
rdt_last_cmd_printf("Need at least %d bits in mask\n",
r->cache.min_cbm_bits);
return false;
}

*data = val;
return true;
Expand All @@ -111,8 +129,10 @@ int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d)
{
unsigned long data;

if (d->have_new_ctrl)
if (d->have_new_ctrl) {
rdt_last_cmd_printf("duplicate domain %d\n", d->id);
return -EINVAL;
}

if(!cbm_validate(buf, &data, r))
return -EINVAL;
Expand All @@ -139,8 +159,10 @@ static int parse_line(char *line, struct rdt_resource *r)
return 0;
dom = strsep(&line, ";");
id = strsep(&dom, "=");
if (!dom || kstrtoul(id, 10, &dom_id))
if (!dom || kstrtoul(id, 10, &dom_id)) {
rdt_last_cmd_puts("Missing '=' or non-numeric domain\n");
return -EINVAL;
}
dom = strim(dom);
list_for_each_entry(d, &r->domains, list) {
if (d->id == dom_id) {
Expand Down Expand Up @@ -196,6 +218,7 @@ static int rdtgroup_parse_resource(char *resname, char *tok, int closid)
if (!strcmp(resname, r->name) && closid < r->num_closid)
return parse_line(tok, r);
}
rdt_last_cmd_printf("unknown/unsupported resource name '%s'\n", resname);
return -EINVAL;
}

Expand All @@ -218,6 +241,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
rdtgroup_kn_unlock(of->kn);
return -ENOENT;
}
rdt_last_cmd_clear();

closid = rdtgrp->closid;

Expand All @@ -229,6 +253,12 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
while ((tok = strsep(&buf, "\n")) != NULL) {
resname = strim(strsep(&tok, ":"));
if (!tok) {
rdt_last_cmd_puts("Missing ':'\n");
ret = -EINVAL;
goto out;
}
if (tok[0] == '\0') {
rdt_last_cmd_printf("Missing '%s' value\n", resname);
ret = -EINVAL;
goto out;
}
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/cpu/intel_rdt_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ static LIST_HEAD(rmid_free_lru);
* may have a occupancy value > intel_cqm_threshold. User can change
* the threshold occupancy value.
*/
unsigned int rmid_limbo_count;
static unsigned int rmid_limbo_count;

/**
* @rmid_entry - The entry in the limbo and free lists.
Expand Down
Loading

0 comments on commit 3643b7e

Please sign in to comment.