diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Makefile | 2 | ||||
| -rw-r--r-- | lib/bitmap.c | 22 | ||||
| -rw-r--r-- | lib/cpumask.c | 79 | ||||
| -rw-r--r-- | lib/dynamic_printk.c | 4 | ||||
| -rw-r--r-- | lib/idr.c | 14 | ||||
| -rw-r--r-- | lib/scatterlist.c | 2 | ||||
| -rw-r--r-- | lib/string_helpers.c | 34 | ||||
| -rw-r--r-- | lib/swiotlb.c | 16 |
8 files changed, 148 insertions, 25 deletions
diff --git a/lib/Makefile b/lib/Makefile index 16feaab057b2..7cb65d85aeb0 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Makefile for some libs needed in the kernel. | 2 | # Makefile for some libs needed in the kernel. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | ifdef CONFIG_FTRACE | 5 | ifdef CONFIG_FUNCTION_TRACER |
| 6 | ORIG_CFLAGS := $(KBUILD_CFLAGS) | 6 | ORIG_CFLAGS := $(KBUILD_CFLAGS) |
| 7 | KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) | 7 | KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) |
| 8 | endif | 8 | endif |
diff --git a/lib/bitmap.c b/lib/bitmap.c index 482df94ea21e..1338469ac849 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c | |||
| @@ -996,3 +996,25 @@ int bitmap_allocate_region(unsigned long *bitmap, int pos, int order) | |||
| 996 | return 0; | 996 | return 0; |
| 997 | } | 997 | } |
| 998 | EXPORT_SYMBOL(bitmap_allocate_region); | 998 | EXPORT_SYMBOL(bitmap_allocate_region); |
| 999 | |||
| 1000 | /** | ||
| 1001 | * bitmap_copy_le - copy a bitmap, putting the bits into little-endian order. | ||
| 1002 | * @dst: destination buffer | ||
| 1003 | * @src: bitmap to copy | ||
| 1004 | * @nbits: number of bits in the bitmap | ||
| 1005 | * | ||
| 1006 | * Require nbits % BITS_PER_LONG == 0. | ||
| 1007 | */ | ||
| 1008 | void bitmap_copy_le(void *dst, const unsigned long *src, int nbits) | ||
| 1009 | { | ||
| 1010 | unsigned long *d = dst; | ||
| 1011 | int i; | ||
| 1012 | |||
| 1013 | for (i = 0; i < nbits/BITS_PER_LONG; i++) { | ||
| 1014 | if (BITS_PER_LONG == 64) | ||
| 1015 | d[i] = cpu_to_le64(src[i]); | ||
| 1016 | else | ||
| 1017 | d[i] = cpu_to_le32(src[i]); | ||
| 1018 | } | ||
| 1019 | } | ||
| 1020 | EXPORT_SYMBOL(bitmap_copy_le); | ||
diff --git a/lib/cpumask.c b/lib/cpumask.c index 5f97dc25ef9c..8d03f22c6ced 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #include <linux/bitops.h> | 2 | #include <linux/bitops.h> |
| 3 | #include <linux/cpumask.h> | 3 | #include <linux/cpumask.h> |
| 4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
| 5 | #include <linux/bootmem.h> | ||
| 5 | 6 | ||
| 6 | int __first_cpu(const cpumask_t *srcp) | 7 | int __first_cpu(const cpumask_t *srcp) |
| 7 | { | 8 | { |
| @@ -35,3 +36,81 @@ int __any_online_cpu(const cpumask_t *mask) | |||
| 35 | return cpu; | 36 | return cpu; |
| 36 | } | 37 | } |
| 37 | EXPORT_SYMBOL(__any_online_cpu); | 38 | EXPORT_SYMBOL(__any_online_cpu); |
| 39 | |||
| 40 | /** | ||
| 41 | * cpumask_next_and - get the next cpu in *src1p & *src2p | ||
| 42 | * @n: the cpu prior to the place to search (ie. return will be > @n) | ||
| 43 | * @src1p: the first cpumask pointer | ||
| 44 | * @src2p: the second cpumask pointer | ||
| 45 | * | ||
| 46 | * Returns >= nr_cpu_ids if no further cpus set in both. | ||
| 47 | */ | ||
| 48 | int cpumask_next_and(int n, const struct cpumask *src1p, | ||
| 49 | const struct cpumask *src2p) | ||
| 50 | { | ||
| 51 | while ((n = cpumask_next(n, src1p)) < nr_cpu_ids) | ||
| 52 | if (cpumask_test_cpu(n, src2p)) | ||
| 53 | break; | ||
| 54 | return n; | ||
| 55 | } | ||
| 56 | EXPORT_SYMBOL(cpumask_next_and); | ||
| 57 | |||
| 58 | /** | ||
| 59 | * cpumask_any_but - return a "random" in a cpumask, but not this one. | ||
| 60 | * @mask: the cpumask to search | ||
| 61 | * @cpu: the cpu to ignore. | ||
| 62 | * | ||
| 63 | * Often used to find any cpu but smp_processor_id() in a mask. | ||
| 64 | * Returns >= nr_cpu_ids if no cpus set. | ||
| 65 | */ | ||
| 66 | int cpumask_any_but(const struct cpumask *mask, unsigned int cpu) | ||
| 67 | { | ||
| 68 | unsigned int i; | ||
| 69 | |||
| 70 | cpumask_check(cpu); | ||
| 71 | for_each_cpu(i, mask) | ||
| 72 | if (i != cpu) | ||
| 73 | break; | ||
| 74 | return i; | ||
| 75 | } | ||
| 76 | |||
| 77 | /* These are not inline because of header tangles. */ | ||
| 78 | #ifdef CONFIG_CPUMASK_OFFSTACK | ||
| 79 | bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags) | ||
| 80 | { | ||
| 81 | if (likely(slab_is_available())) | ||
| 82 | *mask = kmalloc(cpumask_size(), flags); | ||
| 83 | else { | ||
| 84 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | ||
| 85 | printk(KERN_ERR | ||
| 86 | "=> alloc_cpumask_var: kmalloc not available!\n"); | ||
| 87 | dump_stack(); | ||
| 88 | #endif | ||
| 89 | *mask = NULL; | ||
| 90 | } | ||
| 91 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS | ||
| 92 | if (!*mask) { | ||
| 93 | printk(KERN_ERR "=> alloc_cpumask_var: failed!\n"); | ||
| 94 | dump_stack(); | ||
| 95 | } | ||
| 96 | #endif | ||
| 97 | return *mask != NULL; | ||
| 98 | } | ||
| 99 | EXPORT_SYMBOL(alloc_cpumask_var); | ||
| 100 | |||
| 101 | void __init alloc_bootmem_cpumask_var(cpumask_var_t *mask) | ||
| 102 | { | ||
| 103 | *mask = alloc_bootmem(cpumask_size()); | ||
| 104 | } | ||
| 105 | |||
| 106 | void free_cpumask_var(cpumask_var_t mask) | ||
| 107 | { | ||
| 108 | kfree(mask); | ||
| 109 | } | ||
| 110 | EXPORT_SYMBOL(free_cpumask_var); | ||
| 111 | |||
| 112 | void __init free_bootmem_cpumask_var(cpumask_var_t mask) | ||
| 113 | { | ||
| 114 | free_bootmem((unsigned long)mask, cpumask_size()); | ||
| 115 | } | ||
| 116 | #endif | ||
diff --git a/lib/dynamic_printk.c b/lib/dynamic_printk.c index d640f87bdc9e..d83660fd6fdd 100644 --- a/lib/dynamic_printk.c +++ b/lib/dynamic_printk.c | |||
| @@ -402,6 +402,8 @@ static int __init dynamic_printk_init(void) | |||
| 402 | iter->logical_modname, | 402 | iter->logical_modname, |
| 403 | iter->flag_names, iter->hash, iter->hash2); | 403 | iter->flag_names, iter->hash, iter->hash2); |
| 404 | } | 404 | } |
| 405 | if (dynamic_enabled == DYNAMIC_ENABLED_ALL) | ||
| 406 | set_all(true); | ||
| 405 | return 0; | 407 | return 0; |
| 406 | } | 408 | } |
| 407 | module_init(dynamic_printk_init); | 409 | module_init(dynamic_printk_init); |
| @@ -411,7 +413,7 @@ static int __init dynamic_printk_setup(char *str) | |||
| 411 | { | 413 | { |
| 412 | if (str) | 414 | if (str) |
| 413 | return -ENOENT; | 415 | return -ENOENT; |
| 414 | set_all(true); | 416 | dynamic_enabled = DYNAMIC_ENABLED_ALL; |
| 415 | return 0; | 417 | return 0; |
| 416 | } | 418 | } |
| 417 | /* Use early_param(), so we can get debug output as early as possible */ | 419 | /* Use early_param(), so we can get debug output as early as possible */ |
| @@ -185,6 +185,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa) | |||
| 185 | new = get_from_free_list(idp); | 185 | new = get_from_free_list(idp); |
| 186 | if (!new) | 186 | if (!new) |
| 187 | return -1; | 187 | return -1; |
| 188 | new->layer = l-1; | ||
| 188 | rcu_assign_pointer(p->ary[m], new); | 189 | rcu_assign_pointer(p->ary[m], new); |
| 189 | p->count++; | 190 | p->count++; |
| 190 | } | 191 | } |
| @@ -210,6 +211,7 @@ build_up: | |||
| 210 | if (unlikely(!p)) { | 211 | if (unlikely(!p)) { |
| 211 | if (!(p = get_from_free_list(idp))) | 212 | if (!(p = get_from_free_list(idp))) |
| 212 | return -1; | 213 | return -1; |
| 214 | p->layer = 0; | ||
| 213 | layers = 1; | 215 | layers = 1; |
| 214 | } | 216 | } |
| 215 | /* | 217 | /* |
| @@ -237,6 +239,7 @@ build_up: | |||
| 237 | } | 239 | } |
| 238 | new->ary[0] = p; | 240 | new->ary[0] = p; |
| 239 | new->count = 1; | 241 | new->count = 1; |
| 242 | new->layer = layers-1; | ||
| 240 | if (p->bitmap == IDR_FULL) | 243 | if (p->bitmap == IDR_FULL) |
| 241 | __set_bit(0, &new->bitmap); | 244 | __set_bit(0, &new->bitmap); |
| 242 | p = new; | 245 | p = new; |
| @@ -493,17 +496,21 @@ void *idr_find(struct idr *idp, int id) | |||
| 493 | int n; | 496 | int n; |
| 494 | struct idr_layer *p; | 497 | struct idr_layer *p; |
| 495 | 498 | ||
| 496 | n = idp->layers * IDR_BITS; | ||
| 497 | p = rcu_dereference(idp->top); | 499 | p = rcu_dereference(idp->top); |
| 500 | if (!p) | ||
| 501 | return NULL; | ||
| 502 | n = (p->layer+1) * IDR_BITS; | ||
| 498 | 503 | ||
| 499 | /* Mask off upper bits we don't use for the search. */ | 504 | /* Mask off upper bits we don't use for the search. */ |
| 500 | id &= MAX_ID_MASK; | 505 | id &= MAX_ID_MASK; |
| 501 | 506 | ||
| 502 | if (id >= (1 << n)) | 507 | if (id >= (1 << n)) |
| 503 | return NULL; | 508 | return NULL; |
| 509 | BUG_ON(n == 0); | ||
| 504 | 510 | ||
| 505 | while (n > 0 && p) { | 511 | while (n > 0 && p) { |
| 506 | n -= IDR_BITS; | 512 | n -= IDR_BITS; |
| 513 | BUG_ON(n != p->layer*IDR_BITS); | ||
| 507 | p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]); | 514 | p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]); |
| 508 | } | 515 | } |
| 509 | return((void *)p); | 516 | return((void *)p); |
| @@ -582,8 +589,11 @@ void *idr_replace(struct idr *idp, void *ptr, int id) | |||
| 582 | int n; | 589 | int n; |
| 583 | struct idr_layer *p, *old_p; | 590 | struct idr_layer *p, *old_p; |
| 584 | 591 | ||
| 585 | n = idp->layers * IDR_BITS; | ||
| 586 | p = idp->top; | 592 | p = idp->top; |
| 593 | if (!p) | ||
| 594 | return ERR_PTR(-EINVAL); | ||
| 595 | |||
| 596 | n = (p->layer+1) * IDR_BITS; | ||
| 587 | 597 | ||
| 588 | id &= MAX_ID_MASK; | 598 | id &= MAX_ID_MASK; |
| 589 | 599 | ||
diff --git a/lib/scatterlist.c b/lib/scatterlist.c index 8d2688ff1352..b7b449dafbe5 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c | |||
| @@ -395,7 +395,7 @@ void sg_miter_stop(struct sg_mapping_iter *miter) | |||
| 395 | WARN_ON(!irqs_disabled()); | 395 | WARN_ON(!irqs_disabled()); |
| 396 | kunmap_atomic(miter->addr, KM_BIO_SRC_IRQ); | 396 | kunmap_atomic(miter->addr, KM_BIO_SRC_IRQ); |
| 397 | } else | 397 | } else |
| 398 | kunmap(miter->addr); | 398 | kunmap(miter->page); |
| 399 | 399 | ||
| 400 | miter->page = NULL; | 400 | miter->page = NULL; |
| 401 | miter->addr = NULL; | 401 | miter->addr = NULL; |
diff --git a/lib/string_helpers.c b/lib/string_helpers.c index 8347925030ff..ab431d4cc970 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | int string_get_size(u64 size, const enum string_size_units units, | 23 | int string_get_size(u64 size, const enum string_size_units units, |
| 24 | char *buf, int len) | 24 | char *buf, int len) |
| 25 | { | 25 | { |
| 26 | const char *units_10[] = { "B", "KB", "MB", "GB", "TB", "PB", | 26 | const char *units_10[] = { "B", "kB", "MB", "GB", "TB", "PB", |
| 27 | "EB", "ZB", "YB", NULL}; | 27 | "EB", "ZB", "YB", NULL}; |
| 28 | const char *units_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", | 28 | const char *units_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", |
| 29 | "EiB", "ZiB", "YiB", NULL }; | 29 | "EiB", "ZiB", "YiB", NULL }; |
| @@ -31,7 +31,7 @@ int string_get_size(u64 size, const enum string_size_units units, | |||
| 31 | [STRING_UNITS_10] = units_10, | 31 | [STRING_UNITS_10] = units_10, |
| 32 | [STRING_UNITS_2] = units_2, | 32 | [STRING_UNITS_2] = units_2, |
| 33 | }; | 33 | }; |
| 34 | const int divisor[] = { | 34 | const unsigned int divisor[] = { |
| 35 | [STRING_UNITS_10] = 1000, | 35 | [STRING_UNITS_10] = 1000, |
| 36 | [STRING_UNITS_2] = 1024, | 36 | [STRING_UNITS_2] = 1024, |
| 37 | }; | 37 | }; |
| @@ -40,23 +40,27 @@ int string_get_size(u64 size, const enum string_size_units units, | |||
| 40 | char tmp[8]; | 40 | char tmp[8]; |
| 41 | 41 | ||
| 42 | tmp[0] = '\0'; | 42 | tmp[0] = '\0'; |
| 43 | i = 0; | ||
| 44 | if (size >= divisor[units]) { | ||
| 45 | while (size >= divisor[units] && units_str[units][i]) { | ||
| 46 | remainder = do_div(size, divisor[units]); | ||
| 47 | i++; | ||
| 48 | } | ||
| 43 | 49 | ||
| 44 | for (i = 0; size > divisor[units] && units_str[units][i]; i++) | 50 | sf_cap = size; |
| 45 | remainder = do_div(size, divisor[units]); | 51 | for (j = 0; sf_cap*10 < 1000; j++) |
| 52 | sf_cap *= 10; | ||
| 46 | 53 | ||
| 47 | sf_cap = size; | 54 | if (j) { |
| 48 | for (j = 0; sf_cap*10 < 1000; j++) | 55 | remainder *= 1000; |
| 49 | sf_cap *= 10; | 56 | do_div(remainder, divisor[units]); |
| 50 | 57 | snprintf(tmp, sizeof(tmp), ".%03lld", | |
| 51 | if (j) { | 58 | (unsigned long long)remainder); |
| 52 | remainder *= 1000; | 59 | tmp[j+1] = '\0'; |
| 53 | do_div(remainder, divisor[units]); | 60 | } |
| 54 | snprintf(tmp, sizeof(tmp), ".%03lld", | ||
| 55 | (unsigned long long)remainder); | ||
| 56 | tmp[j+1] = '\0'; | ||
| 57 | } | 61 | } |
| 58 | 62 | ||
| 59 | snprintf(buf, len, "%lld%s%s", (unsigned long long)size, | 63 | snprintf(buf, len, "%lld%s %s", (unsigned long long)size, |
| 60 | tmp, units_str[units][i]); | 64 | tmp, units_str[units][i]); |
| 61 | 65 | ||
| 62 | return 0; | 66 | return 0; |
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index f8eebd489149..5f6c629a924d 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
| @@ -467,9 +467,13 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
| 467 | dma_addr_t dev_addr; | 467 | dma_addr_t dev_addr; |
| 468 | void *ret; | 468 | void *ret; |
| 469 | int order = get_order(size); | 469 | int order = get_order(size); |
| 470 | u64 dma_mask = DMA_32BIT_MASK; | ||
| 471 | |||
| 472 | if (hwdev && hwdev->coherent_dma_mask) | ||
| 473 | dma_mask = hwdev->coherent_dma_mask; | ||
| 470 | 474 | ||
| 471 | ret = (void *)__get_free_pages(flags, order); | 475 | ret = (void *)__get_free_pages(flags, order); |
| 472 | if (ret && address_needs_mapping(hwdev, virt_to_bus(ret), size)) { | 476 | if (ret && !is_buffer_dma_capable(dma_mask, virt_to_bus(ret), size)) { |
| 473 | /* | 477 | /* |
| 474 | * The allocated memory isn't reachable by the device. | 478 | * The allocated memory isn't reachable by the device. |
| 475 | * Fall back on swiotlb_map_single(). | 479 | * Fall back on swiotlb_map_single(). |
| @@ -493,12 +497,14 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
| 493 | dev_addr = virt_to_bus(ret); | 497 | dev_addr = virt_to_bus(ret); |
| 494 | 498 | ||
| 495 | /* Confirm address can be DMA'd by device */ | 499 | /* Confirm address can be DMA'd by device */ |
| 496 | if (address_needs_mapping(hwdev, dev_addr, size)) { | 500 | if (!is_buffer_dma_capable(dma_mask, dev_addr, size)) { |
| 497 | printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n", | 501 | printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n", |
| 498 | (unsigned long long)*hwdev->dma_mask, | 502 | (unsigned long long)dma_mask, |
| 499 | (unsigned long long)dev_addr); | 503 | (unsigned long long)dev_addr); |
| 500 | panic("swiotlb_alloc_coherent: allocated memory is out of " | 504 | |
| 501 | "range for device"); | 505 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ |
| 506 | unmap_single(hwdev, ret, size, DMA_TO_DEVICE); | ||
| 507 | return NULL; | ||
| 502 | } | 508 | } |
| 503 | *dma_handle = dev_addr; | 509 | *dma_handle = dev_addr; |
| 504 | return ret; | 510 | return ret; |
