diff options
author | Vikas Shivappa <vikas.shivappa@linux.intel.com> | 2017-07-25 17:14:44 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-08-01 16:41:28 -0400 |
commit | 895c663ecef16c8138e20a7d5c052e0fcc400241 (patch) | |
tree | 73db0eee0642e938a2eb90e7456542d8354bedf9 | |
parent | 748b6b881ccdda8f0663c68605f431279e06f49a (diff) |
x86/intel_rdt/cqm: Add CPU hotplug support
Resource groups have a per domain directory under "mon_data". Add or
remove these directories as and when domains come online and go offline.
Also update the per cpu rmids and cache upon onlining and offlining
cpus.
Signed-off-by: Vikas Shivappa <vikas.shivappa@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: ravi.v.shankar@intel.com
Cc: tony.luck@intel.com
Cc: fenghua.yu@intel.com
Cc: peterz@infradead.org
Cc: eranian@google.com
Cc: vikas.shivappa@intel.com
Cc: ak@linux.intel.com
Cc: davidcc@google.com
Cc: reinette.chatre@intel.com
Link: http://lkml.kernel.org/r/1501017287-28083-26-git-send-email-vikas.shivappa@linux.intel.com
-rw-r--r-- | arch/x86/kernel/cpu/intel_rdt.c | 41 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel_rdt.h | 9 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 47 |
3 files changed, 90 insertions, 7 deletions
diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c index 050ea15259ea..f12bb91b8c66 100644 --- a/arch/x86/kernel/cpu/intel_rdt.c +++ b/arch/x86/kernel/cpu/intel_rdt.c | |||
@@ -479,6 +479,13 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r) | |||
479 | 479 | ||
480 | cpumask_set_cpu(cpu, &d->cpu_mask); | 480 | cpumask_set_cpu(cpu, &d->cpu_mask); |
481 | list_add_tail(&d->list, add_pos); | 481 | list_add_tail(&d->list, add_pos); |
482 | |||
483 | /* | ||
484 | * If resctrl is mounted, add | ||
485 | * per domain monitor data directories. | ||
486 | */ | ||
487 | if (static_branch_unlikely(&rdt_mon_enable_key)) | ||
488 | mkdir_mondata_subdir_allrdtgrp(r, d); | ||
482 | } | 489 | } |
483 | 490 | ||
484 | static void domain_remove_cpu(int cpu, struct rdt_resource *r) | 491 | static void domain_remove_cpu(int cpu, struct rdt_resource *r) |
@@ -494,6 +501,12 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r) | |||
494 | 501 | ||
495 | cpumask_clear_cpu(cpu, &d->cpu_mask); | 502 | cpumask_clear_cpu(cpu, &d->cpu_mask); |
496 | if (cpumask_empty(&d->cpu_mask)) { | 503 | if (cpumask_empty(&d->cpu_mask)) { |
504 | /* | ||
505 | * If resctrl is mounted, remove all the | ||
506 | * per domain monitor data directories. | ||
507 | */ | ||
508 | if (static_branch_unlikely(&rdt_mon_enable_key)) | ||
509 | rmdir_mondata_subdir_allrdtgrp(r, d->id); | ||
497 | kfree(d->ctrl_val); | 510 | kfree(d->ctrl_val); |
498 | kfree(d->rmid_busy_llc); | 511 | kfree(d->rmid_busy_llc); |
499 | list_del(&d->list); | 512 | list_del(&d->list); |
@@ -501,13 +514,14 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r) | |||
501 | } | 514 | } |
502 | } | 515 | } |
503 | 516 | ||
504 | static void clear_closid(int cpu) | 517 | static void clear_closid_rmid(int cpu) |
505 | { | 518 | { |
506 | struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); | 519 | struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); |
507 | 520 | ||
508 | per_cpu(rdt_cpu_default.closid, cpu) = 0; | 521 | per_cpu(rdt_cpu_default.closid, cpu) = 0; |
509 | state->closid = 0; | 522 | state->closid = 0; |
510 | wrmsr(IA32_PQR_ASSOC, state->rmid, 0); | 523 | state->rmid = 0; |
524 | wrmsr(IA32_PQR_ASSOC, 0, 0); | ||
511 | } | 525 | } |
512 | 526 | ||
513 | static int intel_rdt_online_cpu(unsigned int cpu) | 527 | static int intel_rdt_online_cpu(unsigned int cpu) |
@@ -515,29 +529,42 @@ static int intel_rdt_online_cpu(unsigned int cpu) | |||
515 | struct rdt_resource *r; | 529 | struct rdt_resource *r; |
516 | 530 | ||
517 | mutex_lock(&rdtgroup_mutex); | 531 | mutex_lock(&rdtgroup_mutex); |
518 | for_each_alloc_capable_rdt_resource(r) | 532 | for_each_capable_rdt_resource(r) |
519 | domain_add_cpu(cpu, r); | 533 | domain_add_cpu(cpu, r); |
520 | /* The cpu is set in default rdtgroup after online. */ | 534 | /* The cpu is set in default rdtgroup after online. */ |
521 | cpumask_set_cpu(cpu, &rdtgroup_default.cpu_mask); | 535 | cpumask_set_cpu(cpu, &rdtgroup_default.cpu_mask); |
522 | clear_closid(cpu); | 536 | clear_closid_rmid(cpu); |
523 | mutex_unlock(&rdtgroup_mutex); | 537 | mutex_unlock(&rdtgroup_mutex); |
524 | 538 | ||
525 | return 0; | 539 | return 0; |
526 | } | 540 | } |
527 | 541 | ||
542 | static void clear_childcpus(struct rdtgroup *r, unsigned int cpu) | ||
543 | { | ||
544 | struct rdtgroup *cr; | ||
545 | |||
546 | list_for_each_entry(cr, &r->mon.crdtgrp_list, mon.crdtgrp_list) { | ||
547 | if (cpumask_test_and_clear_cpu(cpu, &cr->cpu_mask)) { | ||
548 | break; | ||
549 | } | ||
550 | } | ||
551 | } | ||
552 | |||
528 | static int intel_rdt_offline_cpu(unsigned int cpu) | 553 | static int intel_rdt_offline_cpu(unsigned int cpu) |
529 | { | 554 | { |
530 | struct rdtgroup *rdtgrp; | 555 | struct rdtgroup *rdtgrp; |
531 | struct rdt_resource *r; | 556 | struct rdt_resource *r; |
532 | 557 | ||
533 | mutex_lock(&rdtgroup_mutex); | 558 | mutex_lock(&rdtgroup_mutex); |
534 | for_each_alloc_capable_rdt_resource(r) | 559 | for_each_capable_rdt_resource(r) |
535 | domain_remove_cpu(cpu, r); | 560 | domain_remove_cpu(cpu, r); |
536 | list_for_each_entry(rdtgrp, &rdt_all_groups, rdtgroup_list) { | 561 | list_for_each_entry(rdtgrp, &rdt_all_groups, rdtgroup_list) { |
537 | if (cpumask_test_and_clear_cpu(cpu, &rdtgrp->cpu_mask)) | 562 | if (cpumask_test_and_clear_cpu(cpu, &rdtgrp->cpu_mask)) { |
563 | clear_childcpus(rdtgrp, cpu); | ||
538 | break; | 564 | break; |
565 | } | ||
539 | } | 566 | } |
540 | clear_closid(cpu); | 567 | clear_closid_rmid(cpu); |
541 | mutex_unlock(&rdtgroup_mutex); | 568 | mutex_unlock(&rdtgroup_mutex); |
542 | 569 | ||
543 | return 0; | 570 | return 0; |
diff --git a/arch/x86/kernel/cpu/intel_rdt.h b/arch/x86/kernel/cpu/intel_rdt.h index 7fcaa5f82bd0..2660d15d1712 100644 --- a/arch/x86/kernel/cpu/intel_rdt.h +++ b/arch/x86/kernel/cpu/intel_rdt.h | |||
@@ -301,6 +301,11 @@ enum { | |||
301 | RDT_NUM_RESOURCES, | 301 | RDT_NUM_RESOURCES, |
302 | }; | 302 | }; |
303 | 303 | ||
304 | #define for_each_capable_rdt_resource(r) \ | ||
305 | for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ | ||
306 | r++) \ | ||
307 | if (r->alloc_capable || r->mon_capable) | ||
308 | |||
304 | #define for_each_alloc_capable_rdt_resource(r) \ | 309 | #define for_each_alloc_capable_rdt_resource(r) \ |
305 | for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ | 310 | for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ |
306 | r++) \ | 311 | r++) \ |
@@ -360,5 +365,9 @@ void free_rmid(u32 rmid); | |||
360 | int rdt_get_mon_l3_config(struct rdt_resource *r); | 365 | int rdt_get_mon_l3_config(struct rdt_resource *r); |
361 | void mon_event_count(void *info); | 366 | void mon_event_count(void *info); |
362 | int rdtgroup_mondata_show(struct seq_file *m, void *arg); | 367 | int rdtgroup_mondata_show(struct seq_file *m, void *arg); |
368 | void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, | ||
369 | unsigned int dom_id); | ||
370 | void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, | ||
371 | struct rdt_domain *d); | ||
363 | 372 | ||
364 | #endif /* _ASM_X86_INTEL_RDT_H */ | 373 | #endif /* _ASM_X86_INTEL_RDT_H */ |
diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c index 0a7be9b7a201..ea37b972df4f 100644 --- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | |||
@@ -1323,6 +1323,27 @@ static int mon_addfile(struct kernfs_node *parent_kn, const char *name, | |||
1323 | return ret; | 1323 | return ret; |
1324 | } | 1324 | } |
1325 | 1325 | ||
1326 | /* | ||
1327 | * Remove all subdirectories of mon_data of ctrl_mon groups | ||
1328 | * and monitor groups with given domain id. | ||
1329 | */ | ||
1330 | void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, unsigned int dom_id) | ||
1331 | { | ||
1332 | struct rdtgroup *prgrp, *crgrp; | ||
1333 | char name[32]; | ||
1334 | |||
1335 | if (!r->mon_enabled) | ||
1336 | return; | ||
1337 | |||
1338 | list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { | ||
1339 | sprintf(name, "mon_%s_%02d", r->name, dom_id); | ||
1340 | kernfs_remove_by_name(prgrp->mon.mon_data_kn, name); | ||
1341 | |||
1342 | list_for_each_entry(crgrp, &prgrp->mon.crdtgrp_list, mon.crdtgrp_list) | ||
1343 | kernfs_remove_by_name(crgrp->mon.mon_data_kn, name); | ||
1344 | } | ||
1345 | } | ||
1346 | |||
1326 | static int mkdir_mondata_subdir(struct kernfs_node *parent_kn, | 1347 | static int mkdir_mondata_subdir(struct kernfs_node *parent_kn, |
1327 | struct rdt_domain *d, | 1348 | struct rdt_domain *d, |
1328 | struct rdt_resource *r, struct rdtgroup *prgrp) | 1349 | struct rdt_resource *r, struct rdtgroup *prgrp) |
@@ -1369,6 +1390,32 @@ out_destroy: | |||
1369 | return ret; | 1390 | return ret; |
1370 | } | 1391 | } |
1371 | 1392 | ||
1393 | /* | ||
1394 | * Add all subdirectories of mon_data for "ctrl_mon" groups | ||
1395 | * and "monitor" groups with given domain id. | ||
1396 | */ | ||
1397 | void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, | ||
1398 | struct rdt_domain *d) | ||
1399 | { | ||
1400 | struct kernfs_node *parent_kn; | ||
1401 | struct rdtgroup *prgrp, *crgrp; | ||
1402 | struct list_head *head; | ||
1403 | |||
1404 | if (!r->mon_enabled) | ||
1405 | return; | ||
1406 | |||
1407 | list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { | ||
1408 | parent_kn = prgrp->mon.mon_data_kn; | ||
1409 | mkdir_mondata_subdir(parent_kn, d, r, prgrp); | ||
1410 | |||
1411 | head = &prgrp->mon.crdtgrp_list; | ||
1412 | list_for_each_entry(crgrp, head, mon.crdtgrp_list) { | ||
1413 | parent_kn = crgrp->mon.mon_data_kn; | ||
1414 | mkdir_mondata_subdir(parent_kn, d, r, crgrp); | ||
1415 | } | ||
1416 | } | ||
1417 | } | ||
1418 | |||
1372 | static int mkdir_mondata_subdir_alldom(struct kernfs_node *parent_kn, | 1419 | static int mkdir_mondata_subdir_alldom(struct kernfs_node *parent_kn, |
1373 | struct rdt_resource *r, | 1420 | struct rdt_resource *r, |
1374 | struct rdtgroup *prgrp) | 1421 | struct rdtgroup *prgrp) |