mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
To: dvhart@infradead.org, andy@infradead.org,
	andriy.shevchenko@intel.com, corbet@lwn.net
Cc: rjw@rjwysocki.net, alan@linux.intel.com, lenb@kernel.org,
	prarit@redhat.com, darcari@redhat.com, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	platform-driver-x86@vger.kernel.org,
	Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Subject: [PATCH 03/10] platform/x86: ISST: Store per CPU information
Date: Wed, 26 Jun 2019 15:38:44 -0700	[thread overview]
Message-ID: <20190626223851.19138-4-srinivas.pandruvada@linux.intel.com> (raw)
In-Reply-To: <20190626223851.19138-1-srinivas.pandruvada@linux.intel.com>

There are two per CPU data needs to be stored and cached to avoid repeated
MSR readings for accessing them later:

- Physical to logical CPU conversion
The PUNIT uses a different CPU numbering scheme which is not APIC id based.
So we need to establish relationship between PUNIT CPU number and Linux
logical CPU numbering which is based on APIC id. There is an MSR 0x53
(MSR_THREAD_ID), which gets physical CPU number for the local CPU where it
is read. Also the CPU mask in some messages will inform which CPUs needs
to be online/offline for a TDP level. During TDP switch if user offlined
some CPUs, then the physical CPU mask can't be converted as we can't
read MSR on an offlined CPU to go to a lower TDP level by onlining more
CPUs. So the mapping needs to be established at the boot up time.

- Bus number corresponding to a CPU
A group of CPUs are in a control of a PUNIT. The PUNIT device is exported
as PCI device. To do operation on a PUNIT for a CPU, we need to find out
to which PCI device it is related to. This is done by reading MSR 0x128
(MSR_CPU_BUS_NUMBER).

So during CPU online stages the above MSRs are read and stored. Later
this stored information is used to process IOCTLs request from the user
space.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 .../intel_speed_select_if/isst_if_common.c    | 114 +++++++++++++++++-
 .../intel_speed_select_if/isst_if_common.h    |   1 +
 2 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/intel_speed_select_if/isst_if_common.c b/drivers/platform/x86/intel_speed_select_if/isst_if_common.c
index ab2bb4862dc8..0e16cbf685d0 100644
--- a/drivers/platform/x86/intel_speed_select_if/isst_if_common.c
+++ b/drivers/platform/x86/intel_speed_select_if/isst_if_common.c
@@ -7,14 +7,22 @@
  * Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
  */
 
+#include <linux/cpufeature.h>
+#include <linux/cpuhotplug.h>
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/sched/signal.h>
+#include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <uapi/linux/isst_if.h>
 
 #include "isst_if_common.h"
 
+#define MSR_THREAD_ID_INFO	0x53
+#define MSR_CPU_BUS_NUMBER	0x128
+
 static struct isst_if_cmd_cb punit_callbacks[ISST_IF_DEV_MAX];
 
 static int isst_if_get_platform_info(void __user *argp)
@@ -33,6 +41,99 @@ static int isst_if_get_platform_info(void __user *argp)
 	return 0;
 }
 
+
+struct isst_if_cpu_info {
+	/* For BUS 0 and BUS 1 only, which we need for PUNIT interface */
+	int bus_info[2];
+	int punit_cpu_id;
+};
+
+static struct isst_if_cpu_info *isst_cpu_info;
+
+/**
+ * isst_if_get_pci_dev() - Get the PCI device instance for a CPU
+ * @cpu: Logical CPU number.
+ * @bus_number: The bus number assigned by the hardware.
+ * @dev: The device number assigned by the hardware.
+ * @fn: The function number assigned by the hardware.
+ *
+ * Using cached bus information, find out the PCI device for a bus number,
+ * device and function.
+ *
+ * Return: Return pci_dev pointer or NULL.
+ */
+struct pci_dev *isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn)
+{
+	int bus_number;
+
+	if (bus_no < 0 || bus_no > 1 || cpu < 0 || cpu >= nr_cpu_ids ||
+	    cpu >= num_possible_cpus())
+		return NULL;
+
+	bus_number = isst_cpu_info[cpu].bus_info[bus_no];
+	if (bus_number < 0)
+		return NULL;
+
+	return pci_get_domain_bus_and_slot(0, bus_number, PCI_DEVFN(dev, fn));
+}
+EXPORT_SYMBOL_GPL(isst_if_get_pci_dev);
+
+static int isst_if_cpu_online(unsigned int cpu)
+{
+	u64 data;
+	int ret;
+
+	ret = rdmsrl_safe(MSR_CPU_BUS_NUMBER, &data);
+	if (ret) {
+		/* This is not a fatal error on MSR mailbox only I/F */
+		isst_cpu_info[cpu].bus_info[0] = -1;
+		isst_cpu_info[cpu].bus_info[1] = -1;
+	} else {
+		isst_cpu_info[cpu].bus_info[0] = data & 0xff;
+		isst_cpu_info[cpu].bus_info[1] = (data >> 8) & 0xff;
+	}
+
+	ret = rdmsrl_safe(MSR_THREAD_ID_INFO, &data);
+	if (ret) {
+		isst_cpu_info[cpu].punit_cpu_id = -1;
+		return ret;
+	}
+	isst_cpu_info[cpu].punit_cpu_id = data;
+
+	return 0;
+}
+
+static int isst_if_online_id;
+
+static int isst_if_cpu_info_init(void)
+{
+	int ret;
+
+	isst_cpu_info = kcalloc(num_possible_cpus(),
+				sizeof(*isst_cpu_info),
+				GFP_KERNEL);
+	if (!isst_cpu_info)
+		return -ENOMEM;
+
+	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
+				"platform/x86/isst-if:online",
+				isst_if_cpu_online, NULL);
+	if (ret < 0) {
+		kfree(isst_cpu_info);
+		return ret;
+	}
+
+	isst_if_online_id = ret;
+
+	return 0;
+}
+
+static void isst_if_cpu_info_exit(void)
+{
+	cpuhp_remove_state(isst_if_online_id);
+	kfree(isst_cpu_info);
+};
+
 static long isst_if_def_ioctl(struct file *file, unsigned int cmd,
 			      unsigned long arg)
 {
@@ -145,9 +246,18 @@ int isst_if_cdev_register(int device_type, struct isst_if_cmd_cb *cb)
 		return -EAGAIN;
 	}
 	if (!misc_usage_count) {
+		int ret;
+
 		misc_device_ret = misc_register(&isst_if_char_driver);
 		if (misc_device_ret)
 			goto unlock_exit;
+
+		ret = isst_if_cpu_info_init();
+		if (ret) {
+			misc_deregister(&isst_if_char_driver);
+			misc_device_ret = ret;
+			goto unlock_exit;
+		}
 	}
 	memcpy(&punit_callbacks[device_type], cb, sizeof(*cb));
 	punit_callbacks[device_type].registered = 1;
@@ -173,8 +283,10 @@ void isst_if_cdev_unregister(int device_type)
 	mutex_lock(&punit_misc_dev_lock);
 	misc_usage_count--;
 	punit_callbacks[device_type].registered = 0;
-	if (!misc_usage_count && !misc_device_ret)
+	if (!misc_usage_count && !misc_device_ret) {
 		misc_deregister(&isst_if_char_driver);
+		isst_if_cpu_info_exit();
+	}
 	mutex_unlock(&punit_misc_dev_lock);
 }
 EXPORT_SYMBOL_GPL(isst_if_cdev_unregister);
diff --git a/drivers/platform/x86/intel_speed_select_if/isst_if_common.h b/drivers/platform/x86/intel_speed_select_if/isst_if_common.h
index 11f339226fb4..dade77c58b22 100644
--- a/drivers/platform/x86/intel_speed_select_if/isst_if_common.h
+++ b/drivers/platform/x86/intel_speed_select_if/isst_if_common.h
@@ -57,4 +57,5 @@ struct isst_if_cmd_cb {
 /* Internal interface functions */
 int isst_if_cdev_register(int type, struct isst_if_cmd_cb *cb);
 void isst_if_cdev_unregister(int type);
+struct pci_dev *isst_if_get_pci_dev(int cpu, int bus, int dev, int fn);
 #endif
-- 
2.17.2


  parent reply	other threads:[~2019-06-26 22:39 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-26 22:38 [PATCH 00/10] Intel(R) Speed Select Technology Srinivas Pandruvada
2019-06-26 22:38 ` [PATCH 01/10] platform/x86: ISST: Update ioctl-number.txt for Intel Speed Select interface Srinivas Pandruvada
2019-06-26 22:38 ` [PATCH 02/10] platform/x86: ISST: Add common API to register and handle ioctls Srinivas Pandruvada
2019-06-26 22:38 ` Srinivas Pandruvada [this message]
2019-06-26 22:38 ` [PATCH 04/10] platform/x86: ISST: Add IOCTL to Translate Linux logical CPU to PUNIT CPU number Srinivas Pandruvada
2019-06-26 22:38 ` [PATCH 05/10] platform/x86: ISST: Add Intel Speed Select mmio interface Srinivas Pandruvada
2019-06-26 22:38 ` [PATCH 06/10] platform/x86: ISST: Add Intel Speed Select mailbox interface via PCI Srinivas Pandruvada
2019-06-26 22:38 ` [PATCH 07/10] platform/x86: ISST: Add Intel Speed Select mailbox interface via MSRs Srinivas Pandruvada
2019-06-26 22:38 ` [PATCH 08/10] platform/x86: ISST: Add Intel Speed Select PUNIT MSR interface Srinivas Pandruvada
2019-06-26 22:38 ` [PATCH 09/10] platform/x86: ISST: Restore state on resume Srinivas Pandruvada
2019-06-26 22:38 ` [PATCH 10/10] tools/power/x86: A tool to validate Intel Speed Select commands Srinivas Pandruvada
2019-06-29 14:31   ` Andy Shevchenko
2019-06-29 14:53     ` Srinivas Pandruvada
2019-06-29 16:00       ` Andy Shevchenko
2019-06-30 17:11         ` Srinivas Pandruvada
2019-06-29 16:03       ` Andy Shevchenko
2019-06-29 22:17         ` Srinivas Pandruvada
2019-07-02 14:42     ` Len Brown
2019-07-02 15:39       ` Andy Shevchenko
2019-07-03 14:06         ` Len Brown
2019-06-29 14:29 ` [PATCH 00/10] Intel(R) Speed Select Technology Andy Shevchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190626223851.19138-4-srinivas.pandruvada@linux.intel.com \
    --to=srinivas.pandruvada@linux.intel.com \
    --cc=alan@linux.intel.com \
    --cc=andriy.shevchenko@intel.com \
    --cc=andy@infradead.org \
    --cc=corbet@lwn.net \
    --cc=darcari@redhat.com \
    --cc=dvhart@infradead.org \
    --cc=lenb@kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=prarit@redhat.com \
    --cc=rjw@rjwysocki.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®