x86/intel_rdt: Add command line options for resource director technology

Command line options allow us to ignore features that we don't want.
Also we can re-enable options that have been disabled on a platform
(so long as the underlying h/w actually supports the option).

[ tglx: Marked the option array __initdata and the helper function __init ]

Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Fenghua" <fenghua.yu@intel.com>
Cc: Ravi V" <ravi.v.shankar@intel.com>
Cc: "Peter Zijlstra" <peterz@infradead.org>
Cc: "Stephane Eranian" <eranian@google.com>
Cc: "Andi Kleen" <ak@linux.intel.com>
Cc: "David Carrillo-Cisneros" <davidcc@google.com>
Cc: Vikas Shivappa <vikas.shivappa@linux.intel.com>
Link: http://lkml.kernel.org/r/0c37b0d4dbc30977a3c1cee08b66420f83662694.1503512900.git.tony.luck@intel.com

authored by

Tony Luck and committed by
Thomas Gleixner
1d9807fc 0576113a

+95 -8
+1
Documentation/admin-guide/kernel-parameters.rst
··· 138 PPT Parallel port support is enabled. 139 PS2 Appropriate PS/2 support is enabled. 140 RAM RAM disk support is enabled. 141 S390 S390 architecture is enabled. 142 SCSI Appropriate SCSI support is enabled. 143 A lot of drivers have their options described inside
··· 138 PPT Parallel port support is enabled. 139 PS2 Appropriate PS/2 support is enabled. 140 RAM RAM disk support is enabled. 141 + RDT Intel Resource Director Technology. 142 S390 S390 architecture is enabled. 143 SCSI Appropriate SCSI support is enabled. 144 A lot of drivers have their options described inside
+6
Documentation/admin-guide/kernel-parameters.txt
··· 3598 Run specified binary instead of /init from the ramdisk, 3599 used for early userspace startup. See initrd. 3600 3601 reboot= [KNL] 3602 Format (x86 or x86_64): 3603 [w[arm] | c[old] | h[ard] | s[oft] | g[pio]] \
··· 3598 Run specified binary instead of /init from the ramdisk, 3599 used for early userspace startup. See initrd. 3600 3601 + rdt= [HW,X86,RDT] 3602 + Turn on/off individual RDT features. List is: 3603 + cmt, mbmtotal, mbmlocal, l3cat, l3cdp, l2cat, mba. 3604 + E.g. to turn on cmt and turn off mba use: 3605 + rdt=cmt,!mba 3606 + 3607 reboot= [KNL] 3608 Format (x86 or x86_64): 3609 [w[arm] | c[old] | h[ard] | s[oft] | g[pio]] \
+88 -8
arch/x86/kernel/cpu/intel_rdt.c
··· 637 } 638 } 639 640 static __init bool get_rdt_alloc_resources(void) 641 { 642 bool ret = false; ··· 726 if (!boot_cpu_has(X86_FEATURE_RDT_A)) 727 return false; 728 729 - if (boot_cpu_has(X86_FEATURE_CAT_L3)) { 730 rdt_get_cache_alloc_cfg(1, &rdt_resources_all[RDT_RESOURCE_L3]); 731 - if (boot_cpu_has(X86_FEATURE_CDP_L3)) { 732 rdt_get_cdp_l3_config(RDT_RESOURCE_L3DATA); 733 rdt_get_cdp_l3_config(RDT_RESOURCE_L3CODE); 734 } 735 ret = true; 736 } 737 - if (boot_cpu_has(X86_FEATURE_CAT_L2)) { 738 /* CPUID 0x10.2 fields are same format at 0x10.1 */ 739 rdt_get_cache_alloc_cfg(2, &rdt_resources_all[RDT_RESOURCE_L2]); 740 ret = true; 741 } 742 743 - if (boot_cpu_has(X86_FEATURE_MBA)) { 744 if (rdt_get_mem_config(&rdt_resources_all[RDT_RESOURCE_MBA])) 745 ret = true; 746 } ··· 749 750 static __init bool get_rdt_mon_resources(void) 751 { 752 - if (boot_cpu_has(X86_FEATURE_CQM_OCCUP_LLC)) 753 rdt_mon_features |= (1 << QOS_L3_OCCUP_EVENT_ID); 754 - if (boot_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) 755 rdt_mon_features |= (1 << QOS_L3_MBM_TOTAL_EVENT_ID); 756 - if (boot_cpu_has(X86_FEATURE_CQM_MBM_LOCAL)) 757 rdt_mon_features |= (1 << QOS_L3_MBM_LOCAL_EVENT_ID); 758 759 if (!rdt_mon_features) ··· 766 { 767 switch (boot_cpu_data.x86_model) { 768 case INTEL_FAM6_HASWELL_X: 769 - cache_alloc_hsw_probe(); 770 break; 771 } 772 }
··· 637 } 638 } 639 640 + enum { 641 + RDT_FLAG_CMT, 642 + RDT_FLAG_MBM_TOTAL, 643 + RDT_FLAG_MBM_LOCAL, 644 + RDT_FLAG_L3_CAT, 645 + RDT_FLAG_L3_CDP, 646 + RDT_FLAG_L2_CAT, 647 + RDT_FLAG_MBA, 648 + }; 649 + 650 + #define RDT_OPT(idx, n, f) \ 651 + [idx] = { \ 652 + .name = n, \ 653 + .flag = f \ 654 + } 655 + 656 + struct rdt_options { 657 + char *name; 658 + int flag; 659 + bool force_off, force_on; 660 + }; 661 + 662 + static struct rdt_options rdt_options[] __initdata = { 663 + RDT_OPT(RDT_FLAG_CMT, "cmt", X86_FEATURE_CQM_OCCUP_LLC), 664 + RDT_OPT(RDT_FLAG_MBM_TOTAL, "mbmtotal", X86_FEATURE_CQM_MBM_TOTAL), 665 + RDT_OPT(RDT_FLAG_MBM_LOCAL, "mbmlocal", X86_FEATURE_CQM_MBM_LOCAL), 666 + RDT_OPT(RDT_FLAG_L3_CAT, "l3cat", X86_FEATURE_CAT_L3), 667 + RDT_OPT(RDT_FLAG_L3_CDP, "l3cdp", X86_FEATURE_CDP_L3), 668 + RDT_OPT(RDT_FLAG_L2_CAT, "l2cat", X86_FEATURE_CAT_L2), 669 + RDT_OPT(RDT_FLAG_MBA, "mba", X86_FEATURE_MBA), 670 + }; 671 + #define NUM_RDT_OPTIONS ARRAY_SIZE(rdt_options) 672 + 673 + static int __init set_rdt_options(char *str) 674 + { 675 + struct rdt_options *o; 676 + bool force_off; 677 + char *tok; 678 + 679 + if (*str == '=') 680 + str++; 681 + while ((tok = strsep(&str, ",")) != NULL) { 682 + force_off = *tok == '!'; 683 + if (force_off) 684 + tok++; 685 + for (o = rdt_options; o < &rdt_options[NUM_RDT_OPTIONS]; o++) { 686 + if (strcmp(tok, o->name) == 0) { 687 + if (force_off) 688 + o->force_off = true; 689 + else 690 + o->force_on = true; 691 + break; 692 + } 693 + } 694 + } 695 + return 1; 696 + } 697 + __setup("rdt", set_rdt_options); 698 + 699 + static bool __init rdt_cpu_has(int flag) 700 + { 701 + bool ret = boot_cpu_has(flag); 702 + struct rdt_options *o; 703 + 704 + if (!ret) 705 + return ret; 706 + 707 + for (o = rdt_options; o < &rdt_options[NUM_RDT_OPTIONS]; o++) { 708 + if (flag == o->flag) { 709 + if (o->force_off) 710 + ret = false; 711 + if (o->force_on) 712 + ret = true; 713 + break; 714 + } 715 + } 716 + return ret; 717 + } 718 + 719 static __init bool get_rdt_alloc_resources(void) 720 { 721 bool ret = false; ··· 647 if (!boot_cpu_has(X86_FEATURE_RDT_A)) 648 return false; 649 650 + if (rdt_cpu_has(X86_FEATURE_CAT_L3)) { 651 rdt_get_cache_alloc_cfg(1, &rdt_resources_all[RDT_RESOURCE_L3]); 652 + if (rdt_cpu_has(X86_FEATURE_CDP_L3)) { 653 rdt_get_cdp_l3_config(RDT_RESOURCE_L3DATA); 654 rdt_get_cdp_l3_config(RDT_RESOURCE_L3CODE); 655 } 656 ret = true; 657 } 658 + if (rdt_cpu_has(X86_FEATURE_CAT_L2)) { 659 /* CPUID 0x10.2 fields are same format at 0x10.1 */ 660 rdt_get_cache_alloc_cfg(2, &rdt_resources_all[RDT_RESOURCE_L2]); 661 ret = true; 662 } 663 664 + if (rdt_cpu_has(X86_FEATURE_MBA)) { 665 if (rdt_get_mem_config(&rdt_resources_all[RDT_RESOURCE_MBA])) 666 ret = true; 667 } ··· 670 671 static __init bool get_rdt_mon_resources(void) 672 { 673 + if (rdt_cpu_has(X86_FEATURE_CQM_OCCUP_LLC)) 674 rdt_mon_features |= (1 << QOS_L3_OCCUP_EVENT_ID); 675 + if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) 676 rdt_mon_features |= (1 << QOS_L3_MBM_TOTAL_EVENT_ID); 677 + if (rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL)) 678 rdt_mon_features |= (1 << QOS_L3_MBM_LOCAL_EVENT_ID); 679 680 if (!rdt_mon_features) ··· 687 { 688 switch (boot_cpu_data.x86_model) { 689 case INTEL_FAM6_HASWELL_X: 690 + if (!rdt_options[RDT_FLAG_L3_CAT].force_off) 691 + cache_alloc_hsw_probe(); 692 break; 693 } 694 }