Commit c506fff3 authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky

s390/pci: resize iomap

On s390 we need to maintain a mapping between iomem addresses
and arch specific function identifiers. Currently the mapping
table is created as such that we could span the whole iomem
address space. Since we can only map each bar space from each
possible function we have an upper bound for the number of
mapping entries.

This reduces the size of the iomap from 256K to less than 4K
(using the defconfig).
Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Reviewed-by: default avatarGerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent bf19c94d
...@@ -68,9 +68,12 @@ static struct airq_struct zpci_airq = { ...@@ -68,9 +68,12 @@ static struct airq_struct zpci_airq = {
.isc = PCI_ISC, .isc = PCI_ISC,
}; };
/* I/O Map */ #define ZPCI_IOMAP_ENTRIES \
min(((unsigned long) CONFIG_PCI_NR_FUNCTIONS * PCI_BAR_COUNT), \
ZPCI_IOMAP_MAX_ENTRIES)
static DEFINE_SPINLOCK(zpci_iomap_lock); static DEFINE_SPINLOCK(zpci_iomap_lock);
static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); static unsigned long *zpci_iomap_bitmap;
struct zpci_iomap_entry *zpci_iomap_start; struct zpci_iomap_entry *zpci_iomap_start;
EXPORT_SYMBOL_GPL(zpci_iomap_start); EXPORT_SYMBOL_GPL(zpci_iomap_start);
...@@ -544,12 +547,12 @@ static int zpci_alloc_iomap(struct zpci_dev *zdev) ...@@ -544,12 +547,12 @@ static int zpci_alloc_iomap(struct zpci_dev *zdev)
unsigned long entry; unsigned long entry;
spin_lock(&zpci_iomap_lock); spin_lock(&zpci_iomap_lock);
entry = find_first_zero_bit(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); entry = find_first_zero_bit(zpci_iomap_bitmap, ZPCI_IOMAP_ENTRIES);
if (entry == ZPCI_IOMAP_MAX_ENTRIES) { if (entry == ZPCI_IOMAP_ENTRIES) {
spin_unlock(&zpci_iomap_lock); spin_unlock(&zpci_iomap_lock);
return -ENOSPC; return -ENOSPC;
} }
set_bit(entry, zpci_iomap); set_bit(entry, zpci_iomap_bitmap);
spin_unlock(&zpci_iomap_lock); spin_unlock(&zpci_iomap_lock);
return entry; return entry;
} }
...@@ -558,7 +561,7 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry) ...@@ -558,7 +561,7 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry)
{ {
spin_lock(&zpci_iomap_lock); spin_lock(&zpci_iomap_lock);
memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry)); memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry));
clear_bit(entry, zpci_iomap); clear_bit(entry, zpci_iomap_bitmap);
spin_unlock(&zpci_iomap_lock); spin_unlock(&zpci_iomap_lock);
} }
...@@ -869,23 +872,30 @@ static int zpci_mem_init(void) ...@@ -869,23 +872,30 @@ static int zpci_mem_init(void)
zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb), zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb),
16, 0, NULL); 16, 0, NULL);
if (!zdev_fmb_cache) if (!zdev_fmb_cache)
goto error_zdev; goto error_fmb;
/* TODO: use realloc */ zpci_iomap_start = kcalloc(ZPCI_IOMAP_ENTRIES,
zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), sizeof(*zpci_iomap_start), GFP_KERNEL);
GFP_KERNEL);
if (!zpci_iomap_start) if (!zpci_iomap_start)
goto error_iomap; goto error_iomap;
return 0;
zpci_iomap_bitmap = kcalloc(BITS_TO_LONGS(ZPCI_IOMAP_ENTRIES),
sizeof(*zpci_iomap_bitmap), GFP_KERNEL);
if (!zpci_iomap_bitmap)
goto error_iomap_bitmap;
return 0;
error_iomap_bitmap:
kfree(zpci_iomap_start);
error_iomap: error_iomap:
kmem_cache_destroy(zdev_fmb_cache); kmem_cache_destroy(zdev_fmb_cache);
error_zdev: error_fmb:
return -ENOMEM; return -ENOMEM;
} }
static void zpci_mem_exit(void) static void zpci_mem_exit(void)
{ {
kfree(zpci_iomap_bitmap);
kfree(zpci_iomap_start); kfree(zpci_iomap_start);
kmem_cache_destroy(zdev_fmb_cache); kmem_cache_destroy(zdev_fmb_cache);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment