summaryrefslogtreecommitdiff
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorLogan Gunthorpe <logang@deltatee.com>2019-08-22 19:10:11 +0300
committerBjorn Helgaas <bhelgaas@google.com>2019-09-05 21:26:46 +0300
commit70aaf61a9b8b86eb08da96344efd1c0f0925ee6e (patch)
tree7c67f440c4ee9a588b70cce1c922dcbecb88d5ef /drivers/pci/pci.c
parent8050f3f6645ae0f7e4c1304593f6f7eb2ee7d85c (diff)
downloadlinux-70aaf61a9b8b86eb08da96344efd1c0f0925ee6e.tar.xz
PCI: Clean up resource_alignment parameter to not require static buffer
Clean up the 'resource_alignment' parameter code to use kstrdup() in the initcall routine instead of a static buffer that wastes memory regardless of whether the feature is used. This allows us to drop 'COMMAND_LINE_SIZE' bytes (typically 256-4096 depending on architecture) of static data. This is similar to what has been done for the 'disable_acs_redir' parameter. Link: https://lore.kernel.org/r/20190822161013.5481-2-logang@deltatee.com Signed-off-by: Logan Gunthorpe <logang@deltatee.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 08dfb16bd084..fbfb64ba447d 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -5932,8 +5932,7 @@ resource_size_t __weak pcibios_default_alignment(void)
return 0;
}
-#define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE
-static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0};
+static char *resource_alignment_param;
static DEFINE_SPINLOCK(resource_alignment_lock);
/**
@@ -5954,7 +5953,7 @@ static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev,
spin_lock(&resource_alignment_lock);
p = resource_alignment_param;
- if (!*p && !align)
+ if (!p || !*p)
goto out;
if (pci_has_flag(PCI_PROBE_ONLY)) {
align = 0;
@@ -6120,21 +6119,25 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)
static ssize_t pci_set_resource_alignment_param(const char *buf, size_t count)
{
- if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1)
- count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1;
spin_lock(&resource_alignment_lock);
- strncpy(resource_alignment_param, buf, count);
- resource_alignment_param[count] = '\0';
+
+ kfree(resource_alignment_param);
+ resource_alignment_param = kstrndup(buf, count, GFP_KERNEL);
+
spin_unlock(&resource_alignment_lock);
- return count;
+
+ return resource_alignment_param ? count : -ENOMEM;
}
static ssize_t pci_get_resource_alignment_param(char *buf, size_t size)
{
- size_t count;
+ size_t count = 0;
+
spin_lock(&resource_alignment_lock);
- count = snprintf(buf, size, "%s", resource_alignment_param);
+ if (resource_alignment_param)
+ count = snprintf(buf, size, "%s", resource_alignment_param);
spin_unlock(&resource_alignment_lock);
+
return count;
}
@@ -6275,8 +6278,7 @@ static int __init pci_setup(char *str)
} else if (!strncmp(str, "cbmemsize=", 10)) {
pci_cardbus_mem_size = memparse(str + 10, &str);
} else if (!strncmp(str, "resource_alignment=", 19)) {
- pci_set_resource_alignment_param(str + 19,
- strlen(str + 19));
+ resource_alignment_param = str + 19;
} else if (!strncmp(str, "ecrc=", 5)) {
pcie_ecrc_get_policy(str + 5);
} else if (!strncmp(str, "hpiosize=", 9)) {
@@ -6311,15 +6313,18 @@ static int __init pci_setup(char *str)
early_param("pci", pci_setup);
/*
- * 'disable_acs_redir_param' is initialized in pci_setup(), above, to point
- * to data in the __initdata section which will be freed after the init
- * sequence is complete. We can't allocate memory in pci_setup() because some
- * architectures do not have any memory allocation service available during
- * an early_param() call. So we allocate memory and copy the variable here
- * before the init section is freed.
+ * 'resource_alignment_param' and 'disable_acs_redir_param' are initialized
+ * in pci_setup(), above, to point to data in the __initdata section which
+ * will be freed after the init sequence is complete. We can't allocate memory
+ * in pci_setup() because some architectures do not have any memory allocation
+ * service available during an early_param() call. So we allocate memory and
+ * copy the variable here before the init section is freed.
+ *
*/
static int __init pci_realloc_setup_params(void)
{
+ resource_alignment_param = kstrdup(resource_alignment_param,
+ GFP_KERNEL);
disable_acs_redir_param = kstrdup(disable_acs_redir_param, GFP_KERNEL);
return 0;