diff options
| author | Pekka Enberg <penberg@kernel.org> | 2011-03-20 12:13:26 -0400 |
|---|---|---|
| committer | Pekka Enberg <penberg@kernel.org> | 2011-03-20 12:13:26 -0400 |
| commit | e8c500c2b64b6e237e67ecba7249e72363c47047 (patch) | |
| tree | e9c62e59a879ebef45b0fc2823d318b2fb2fed84 /include/linux | |
| parent | c53badd0801728feedfcccae04239410b52b0d03 (diff) | |
| parent | a24c5a0ea902bcda348f086bd909cc2d6e305bf8 (diff) | |
Merge branch 'slub/lockless' into for-linus
Conflicts:
include/linux/slub_def.h
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/percpu.h | 128 | ||||
| -rw-r--r-- | include/linux/slub_def.h | 7 |
2 files changed, 133 insertions, 2 deletions
diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 27c3c6fcfad3..3a5c4449fd36 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h | |||
| @@ -255,6 +255,30 @@ extern void __bad_size_call_parameter(void); | |||
| 255 | pscr2_ret__; \ | 255 | pscr2_ret__; \ |
| 256 | }) | 256 | }) |
| 257 | 257 | ||
| 258 | /* | ||
| 259 | * Special handling for cmpxchg_double. cmpxchg_double is passed two | ||
| 260 | * percpu variables. The first has to be aligned to a double word | ||
| 261 | * boundary and the second has to follow directly thereafter. | ||
| 262 | */ | ||
| 263 | #define __pcpu_double_call_return_bool(stem, pcp1, pcp2, ...) \ | ||
| 264 | ({ \ | ||
| 265 | bool pdcrb_ret__; \ | ||
| 266 | __verify_pcpu_ptr(&pcp1); \ | ||
| 267 | BUILD_BUG_ON(sizeof(pcp1) != sizeof(pcp2)); \ | ||
| 268 | VM_BUG_ON((unsigned long)(&pcp1) % (2 * sizeof(pcp1))); \ | ||
| 269 | VM_BUG_ON((unsigned long)(&pcp2) != \ | ||
| 270 | (unsigned long)(&pcp1) + sizeof(pcp1)); \ | ||
| 271 | switch(sizeof(pcp1)) { \ | ||
| 272 | case 1: pdcrb_ret__ = stem##1(pcp1, pcp2, __VA_ARGS__); break; \ | ||
| 273 | case 2: pdcrb_ret__ = stem##2(pcp1, pcp2, __VA_ARGS__); break; \ | ||
| 274 | case 4: pdcrb_ret__ = stem##4(pcp1, pcp2, __VA_ARGS__); break; \ | ||
| 275 | case 8: pdcrb_ret__ = stem##8(pcp1, pcp2, __VA_ARGS__); break; \ | ||
| 276 | default: \ | ||
| 277 | __bad_size_call_parameter(); break; \ | ||
| 278 | } \ | ||
| 279 | pdcrb_ret__; \ | ||
| 280 | }) | ||
| 281 | |||
| 258 | #define __pcpu_size_call(stem, variable, ...) \ | 282 | #define __pcpu_size_call(stem, variable, ...) \ |
| 259 | do { \ | 283 | do { \ |
| 260 | __verify_pcpu_ptr(&(variable)); \ | 284 | __verify_pcpu_ptr(&(variable)); \ |
| @@ -501,6 +525,45 @@ do { \ | |||
| 501 | #endif | 525 | #endif |
| 502 | 526 | ||
| 503 | /* | 527 | /* |
| 528 | * cmpxchg_double replaces two adjacent scalars at once. The first | ||
| 529 | * two parameters are per cpu variables which have to be of the same | ||
| 530 | * size. A truth value is returned to indicate success or failure | ||
| 531 | * (since a double register result is difficult to handle). There is | ||
| 532 | * very limited hardware support for these operations, so only certain | ||
| 533 | * sizes may work. | ||
| 534 | */ | ||
| 535 | #define _this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 536 | ({ \ | ||
| 537 | int ret__; \ | ||
| 538 | preempt_disable(); \ | ||
| 539 | ret__ = __this_cpu_generic_cmpxchg_double(pcp1, pcp2, \ | ||
| 540 | oval1, oval2, nval1, nval2); \ | ||
| 541 | preempt_enable(); \ | ||
| 542 | ret__; \ | ||
| 543 | }) | ||
| 544 | |||
| 545 | #ifndef this_cpu_cmpxchg_double | ||
| 546 | # ifndef this_cpu_cmpxchg_double_1 | ||
| 547 | # define this_cpu_cmpxchg_double_1(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 548 | _this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) | ||
| 549 | # endif | ||
| 550 | # ifndef this_cpu_cmpxchg_double_2 | ||
| 551 | # define this_cpu_cmpxchg_double_2(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 552 | _this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) | ||
| 553 | # endif | ||
| 554 | # ifndef this_cpu_cmpxchg_double_4 | ||
| 555 | # define this_cpu_cmpxchg_double_4(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 556 | _this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) | ||
| 557 | # endif | ||
| 558 | # ifndef this_cpu_cmpxchg_double_8 | ||
| 559 | # define this_cpu_cmpxchg_double_8(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 560 | _this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) | ||
| 561 | # endif | ||
| 562 | # define this_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 563 | __pcpu_double_call_return_bool(this_cpu_cmpxchg_double_, (pcp1), (pcp2), (oval1), (oval2), (nval1), (nval2)) | ||
| 564 | #endif | ||
| 565 | |||
| 566 | /* | ||
| 504 | * Generic percpu operations that do not require preemption handling. | 567 | * Generic percpu operations that do not require preemption handling. |
| 505 | * Either we do not care about races or the caller has the | 568 | * Either we do not care about races or the caller has the |
| 506 | * responsibility of handling preemptions issues. Arch code can still | 569 | * responsibility of handling preemptions issues. Arch code can still |
| @@ -703,6 +766,39 @@ do { \ | |||
| 703 | __pcpu_size_call_return2(__this_cpu_cmpxchg_, pcp, oval, nval) | 766 | __pcpu_size_call_return2(__this_cpu_cmpxchg_, pcp, oval, nval) |
| 704 | #endif | 767 | #endif |
| 705 | 768 | ||
| 769 | #define __this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 770 | ({ \ | ||
| 771 | int __ret = 0; \ | ||
| 772 | if (__this_cpu_read(pcp1) == (oval1) && \ | ||
| 773 | __this_cpu_read(pcp2) == (oval2)) { \ | ||
| 774 | __this_cpu_write(pcp1, (nval1)); \ | ||
| 775 | __this_cpu_write(pcp2, (nval2)); \ | ||
| 776 | __ret = 1; \ | ||
| 777 | } \ | ||
| 778 | (__ret); \ | ||
| 779 | }) | ||
| 780 | |||
| 781 | #ifndef __this_cpu_cmpxchg_double | ||
| 782 | # ifndef __this_cpu_cmpxchg_double_1 | ||
| 783 | # define __this_cpu_cmpxchg_double_1(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 784 | __this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) | ||
| 785 | # endif | ||
| 786 | # ifndef __this_cpu_cmpxchg_double_2 | ||
| 787 | # define __this_cpu_cmpxchg_double_2(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 788 | __this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) | ||
| 789 | # endif | ||
| 790 | # ifndef __this_cpu_cmpxchg_double_4 | ||
| 791 | # define __this_cpu_cmpxchg_double_4(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 792 | __this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) | ||
| 793 | # endif | ||
| 794 | # ifndef __this_cpu_cmpxchg_double_8 | ||
| 795 | # define __this_cpu_cmpxchg_double_8(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 796 | __this_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) | ||
| 797 | # endif | ||
| 798 | # define __this_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 799 | __pcpu_double_call_return_bool(__this_cpu_cmpxchg_double_, (pcp1), (pcp2), (oval1), (oval2), (nval1), (nval2)) | ||
| 800 | #endif | ||
| 801 | |||
| 706 | /* | 802 | /* |
| 707 | * IRQ safe versions of the per cpu RMW operations. Note that these operations | 803 | * IRQ safe versions of the per cpu RMW operations. Note that these operations |
| 708 | * are *not* safe against modification of the same variable from another | 804 | * are *not* safe against modification of the same variable from another |
| @@ -823,4 +919,36 @@ do { \ | |||
| 823 | __pcpu_size_call_return2(irqsafe_cpu_cmpxchg_, (pcp), oval, nval) | 919 | __pcpu_size_call_return2(irqsafe_cpu_cmpxchg_, (pcp), oval, nval) |
| 824 | #endif | 920 | #endif |
| 825 | 921 | ||
| 922 | #define irqsafe_generic_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 923 | ({ \ | ||
| 924 | int ret__; \ | ||
| 925 | unsigned long flags; \ | ||
| 926 | local_irq_save(flags); \ | ||
| 927 | ret__ = __this_cpu_generic_cmpxchg_double(pcp1, pcp2, \ | ||
| 928 | oval1, oval2, nval1, nval2); \ | ||
| 929 | local_irq_restore(flags); \ | ||
| 930 | ret__; \ | ||
| 931 | }) | ||
| 932 | |||
| 933 | #ifndef irqsafe_cpu_cmpxchg_double | ||
| 934 | # ifndef irqsafe_cpu_cmpxchg_double_1 | ||
| 935 | # define irqsafe_cpu_cmpxchg_double_1(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 936 | irqsafe_generic_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) | ||
| 937 | # endif | ||
| 938 | # ifndef irqsafe_cpu_cmpxchg_double_2 | ||
| 939 | # define irqsafe_cpu_cmpxchg_double_2(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 940 | irqsafe_generic_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) | ||
| 941 | # endif | ||
| 942 | # ifndef irqsafe_cpu_cmpxchg_double_4 | ||
| 943 | # define irqsafe_cpu_cmpxchg_double_4(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 944 | irqsafe_generic_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) | ||
| 945 | # endif | ||
| 946 | # ifndef irqsafe_cpu_cmpxchg_double_8 | ||
| 947 | # define irqsafe_cpu_cmpxchg_double_8(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 948 | irqsafe_generic_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) | ||
| 949 | # endif | ||
| 950 | # define irqsafe_cpu_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \ | ||
| 951 | __pcpu_double_call_return_int(irqsafe_cpu_cmpxchg_double_, (pcp1), (pcp2), (oval1), (oval2), (nval1), (nval2)) | ||
| 952 | #endif | ||
| 953 | |||
| 826 | #endif /* __LINUX_PERCPU_H */ | 954 | #endif /* __LINUX_PERCPU_H */ |
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index ae0093cc5189..90fbb6d87e11 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h | |||
| @@ -35,7 +35,10 @@ enum stat_item { | |||
| 35 | NR_SLUB_STAT_ITEMS }; | 35 | NR_SLUB_STAT_ITEMS }; |
| 36 | 36 | ||
| 37 | struct kmem_cache_cpu { | 37 | struct kmem_cache_cpu { |
| 38 | void **freelist; /* Pointer to first free per cpu object */ | 38 | void **freelist; /* Pointer to next available object */ |
| 39 | #ifdef CONFIG_CMPXCHG_LOCAL | ||
| 40 | unsigned long tid; /* Globally unique transaction id */ | ||
| 41 | #endif | ||
| 39 | struct page *page; /* The slab from which we are allocating */ | 42 | struct page *page; /* The slab from which we are allocating */ |
| 40 | int node; /* The node of the page (or -1 for debug) */ | 43 | int node; /* The node of the page (or -1 for debug) */ |
| 41 | #ifdef CONFIG_SLUB_STATS | 44 | #ifdef CONFIG_SLUB_STATS |
| @@ -70,6 +73,7 @@ struct kmem_cache { | |||
| 70 | struct kmem_cache_cpu __percpu *cpu_slab; | 73 | struct kmem_cache_cpu __percpu *cpu_slab; |
| 71 | /* Used for retriving partial slabs etc */ | 74 | /* Used for retriving partial slabs etc */ |
| 72 | unsigned long flags; | 75 | unsigned long flags; |
| 76 | unsigned long min_partial; | ||
| 73 | int size; /* The size of an object including meta data */ | 77 | int size; /* The size of an object including meta data */ |
| 74 | int objsize; /* The size of an object without meta data */ | 78 | int objsize; /* The size of an object without meta data */ |
| 75 | int offset; /* Free pointer offset. */ | 79 | int offset; /* Free pointer offset. */ |
| @@ -84,7 +88,6 @@ struct kmem_cache { | |||
| 84 | int inuse; /* Offset to metadata */ | 88 | int inuse; /* Offset to metadata */ |
| 85 | int align; /* Alignment */ | 89 | int align; /* Alignment */ |
| 86 | int reserved; /* Reserved bytes at the end of slabs */ | 90 | int reserved; /* Reserved bytes at the end of slabs */ |
| 87 | unsigned long min_partial; | ||
| 88 | const char *name; /* Name (only for display!) */ | 91 | const char *name; /* Name (only for display!) */ |
| 89 | struct list_head list; /* List of slab caches */ | 92 | struct list_head list; /* List of slab caches */ |
| 90 | #ifdef CONFIG_SYSFS | 93 | #ifdef CONFIG_SYSFS |
