From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934387AbcIHHAH (ORCPT ); Thu, 8 Sep 2016 03:00:07 -0400 Received: from mga05.intel.com ([192.55.52.43]:22481 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933008AbcIHG62 (ORCPT ); Thu, 8 Sep 2016 02:58:28 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.30,298,1470726000"; d="scan'208";a="1052967078" From: "Fenghua Yu" To: "Thomas Gleixner" , "H. Peter Anvin" , "Ingo Molnar" , "Tony Luck" , "Peter Zijlstra" , "Tejun Heo" , "Borislav Petkov" , "Stephane Eranian" , "Marcelo Tosatti" , "David Carrillo-Cisneros" , "Shaohua Li" , "Ravi V Shankar" , "Vikas Shivappa" , "Sai Prakhya" Cc: "linux-kernel" , "x86" , Fenghua Yu Subject: [PATCH v2 28/33] x86/intel_rdt_rdtgroup.c: Read and write cpus Date: Thu, 8 Sep 2016 02:57:22 -0700 Message-Id: <1473328647-33116-29-git-send-email-fenghua.yu@intel.com> X-Mailer: git-send-email 1.8.0.1 In-Reply-To: <1473328647-33116-1-git-send-email-fenghua.yu@intel.com> References: <1473328647-33116-1-git-send-email-fenghua.yu@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fenghua Yu Normally each task is associated with one rdtgroup and we use the schema for that rdtgroup whenever the task is running. The user can designate some cpus to always use the same schema, regardless of which task is running. To do that the user write a cpumask bit string to the "cpus" file. A cpu can only be listed in one rdtgroup. If the user specifies a cpu that is currently assigned to a different rdtgroup, it is removed from that rdtgroup. See Documentation/x86/intel_rdt_ui.txt Signed-off-by: Fenghua Yu Reviewed-by: Tony Luck --- arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 92 ++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c index 71231ba..6c3161a 100644 --- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c @@ -59,6 +59,10 @@ static struct dentry *rdt_mount(struct file_system_type *fs_type, void *data); static void rdt_kill_sb(struct super_block *sb); +static int rdtgroup_cpus_show(struct seq_file *s, void *v); +static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off); + /* rdtgroup core interface files */ static struct rftype rdtgroup_root_base_files[] = { { @@ -1189,3 +1193,91 @@ static void rdt_kill_sb(struct super_block *sb) mutex_unlock(&rdtgroup_mutex); } + +static int rdtgroup_cpus_show(struct seq_file *s, void *v) +{ + struct kernfs_open_file *of = s->private; + struct rdtgroup *rdtgrp; + + rdtgrp = rdtgroup_kn_lock_live(of->kn); + if (!rdtgrp) + return -ENODEV; + + seq_printf(s, "%*pb\n", cpumask_pr_args(&rdtgrp->cpu_mask)); + rdtgroup_kn_unlock(of->kn); + + return 0; +} + +static int cpus_validate(struct cpumask *cpumask, struct rdtgroup *rdtgrp) +{ + int old_cpumask_bit, new_cpumask_bit; + int cpu; + + for_each_online_cpu(cpu) { + old_cpumask_bit = cpumask_test_cpu(cpu, &rdtgrp->cpu_mask); + new_cpumask_bit = cpumask_test_cpu(cpu, cpumask); + /* Cannot clear a "cpus" bit in a rdtgroup. */ + if (old_cpumask_bit == 1 && new_cpumask_bit == 0) + return -EINVAL; + } + + /* If a cpu is not online, cannot set it. */ + for_each_cpu(cpu, cpumask) { + if (!cpu_online(cpu)) + return -EINVAL; + } + + return 0; +} + +static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + struct rdtgroup *rdtgrp; + unsigned long bitmap[BITS_TO_LONGS(NR_CPUS)]; + struct cpumask *cpumask; + int cpu; + struct list_head *l; + struct rdtgroup *r; + int ret = 0; + + if (!buf) + return -EINVAL; + + rdtgrp = rdtgroup_kn_lock_live(of->kn); + if (!rdtgrp) + return -ENODEV; + + if (list_empty(&rdtgroup_lists)) { + ret = -EINVAL; + goto end; + } + + ret = __bitmap_parse(buf, strlen(buf), 0, bitmap, nr_cpu_ids); + if (ret) + goto end; + + cpumask = to_cpumask(bitmap); + ret = cpus_validate(cpumask, rdtgrp); + if (ret) + goto end; + + list_for_each(l, &rdtgroup_lists) { + r = list_entry(l, struct rdtgroup, rdtgroup_list); + if (r == rdtgrp) + continue; + + for_each_cpu_and(cpu, &r->cpu_mask, cpumask) + cpumask_clear_cpu(cpu, &r->cpu_mask); + } + + cpumask_copy(&rdtgrp->cpu_mask, cpumask); + for_each_cpu(cpu, cpumask) + per_cpu(cpu_rdtgroup, cpu) = rdtgrp; + +end: + rdtgroup_kn_unlock(of->kn); + + return ret ?: nbytes; +} -- 2.5.0