aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-sysfs.c
diff options
context:
space:
mode:
authorPrarit Bhargava <prarit@redhat.com>2014-10-23 14:22:12 -0400
committerBjorn Helgaas <bhelgaas@google.com>2014-11-06 17:10:06 -0500
commit63692df103e9c76b26c382ce8079283b7df9a99a (patch)
tree677204f229cd7ad3dcf072d8d7eb44ce01018e9e /drivers/pci/pci-sysfs.c
parentf114040e3ea6e07372334ade75d1ee0775c355e1 (diff)
PCI: Allow numa_node override via sysfs
NUMA systems with ACPI normally describe the physical topology via _PXM methods. But many BIOSes don't implement _PXM, which leaves the kernel with no way to discover the device topology, which reduces performance because we can't put memory and processes close to the device. The NUMA node of a PCI device is already exported in the sysfs "numa_node" file. Make that file writable so users can workaround the lack of _PXM methods in the BIOS. For example: echo 3 > /sys/devices/pci0000:ff/0000:03:1f.3/numa_node sets the node for PCI device 0000:03:1f.3. Writing the file emits a FW_BUG warning to encourage users to request firmware updates. It also taints the kernel with TAINT_FIRMWARE_WORKAROUND because overriding the node incorrectly can cause performance issues. [bhelgaas: changelog, documentation text] Signed-off-by: Prarit Bhargava <prarit@redhat.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> CC: Myron Stowe <mstowe@redhat.com> CC: Alexander Ducyk <alexander.h.duyck@redhat.com> CC: Jiang Liu <jiang.liu@linux.intel.com>
Diffstat (limited to 'drivers/pci/pci-sysfs.c')
-rw-r--r--drivers/pci/pci-sysfs.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 92b6d9ab00e4..91e760f9655b 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -221,12 +221,37 @@ static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
221static DEVICE_ATTR_RW(enabled); 221static DEVICE_ATTR_RW(enabled);
222 222
223#ifdef CONFIG_NUMA 223#ifdef CONFIG_NUMA
224static ssize_t numa_node_store(struct device *dev,
225 struct device_attribute *attr, const char *buf,
226 size_t count)
227{
228 struct pci_dev *pdev = to_pci_dev(dev);
229 int node, ret;
230
231 if (!capable(CAP_SYS_ADMIN))
232 return -EPERM;
233
234 ret = kstrtoint(buf, 0, &node);
235 if (ret)
236 return ret;
237
238 if (!node_online(node))
239 return -EINVAL;
240
241 add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
242 dev_alert(&pdev->dev, FW_BUG "Overriding NUMA node to %d. Contact your vendor for updates.",
243 node);
244
245 dev->numa_node = node;
246 return count;
247}
248
224static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr, 249static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr,
225 char *buf) 250 char *buf)
226{ 251{
227 return sprintf(buf, "%d\n", dev->numa_node); 252 return sprintf(buf, "%d\n", dev->numa_node);
228} 253}
229static DEVICE_ATTR_RO(numa_node); 254static DEVICE_ATTR_RW(numa_node);
230#endif 255#endif
231 256
232static ssize_t dma_mask_bits_show(struct device *dev, 257static ssize_t dma_mask_bits_show(struct device *dev,