Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70aaf61a authored by Logan Gunthorpe's avatar Logan Gunthorpe Committed by Bjorn Helgaas
Browse files

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: default avatarLogan Gunthorpe <logang@deltatee.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 8050f3f6
Loading
Loading
Loading
Loading
+23 −18
Original line number Diff line number Diff line
@@ -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);
	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;