diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-05-01 11:47:44 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-05-01 11:47:44 -0400 |
commit | bf61c8840efe60fd8f91446860b63338fb424158 (patch) | |
tree | 7a71832407a4f0d6346db773343f4c3ae2257b19 /lib | |
parent | 5846115b30f3a881e542c8bfde59a699c1c13740 (diff) | |
parent | 0c6a61657da78098472fd0eb71cc01f2387fa1bb (diff) |
Merge branch 'next' into for-linus
Prepare first set of updates for 3.10 merge window.
Diffstat (limited to 'lib')
56 files changed, 3537 insertions, 1372 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index 4b31a46fb307..3958dc4389f9 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
@@ -42,6 +42,9 @@ config GENERIC_IO | |||
42 | config STMP_DEVICE | 42 | config STMP_DEVICE |
43 | bool | 43 | bool |
44 | 44 | ||
45 | config PERCPU_RWSEM | ||
46 | boolean | ||
47 | |||
45 | config CRC_CCITT | 48 | config CRC_CCITT |
46 | tristate "CRC-CCITT functions" | 49 | tristate "CRC-CCITT functions" |
47 | help | 50 | help |
@@ -319,7 +322,7 @@ config CPUMASK_OFFSTACK | |||
319 | 322 | ||
320 | config DISABLE_OBSOLETE_CPUMASK_FUNCTIONS | 323 | config DISABLE_OBSOLETE_CPUMASK_FUNCTIONS |
321 | bool "Disable obsolete cpumask functions" if DEBUG_PER_CPU_MAPS | 324 | bool "Disable obsolete cpumask functions" if DEBUG_PER_CPU_MAPS |
322 | depends on EXPERIMENTAL && BROKEN | 325 | depends on BROKEN |
323 | 326 | ||
324 | config CPU_RMAP | 327 | config CPU_RMAP |
325 | bool | 328 | bool |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 28e9d6c98941..28be08c09bab 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -134,7 +134,7 @@ config DEBUG_SECTION_MISMATCH | |||
134 | any use of code/data previously in these sections would | 134 | any use of code/data previously in these sections would |
135 | most likely result in an oops. | 135 | most likely result in an oops. |
136 | In the code, functions and variables are annotated with | 136 | In the code, functions and variables are annotated with |
137 | __init, __devinit, etc. (see the full list in include/linux/init.h), | 137 | __init, __cpuinit, etc. (see the full list in include/linux/init.h), |
138 | which results in the code/data being placed in specific sections. | 138 | which results in the code/data being placed in specific sections. |
139 | The section mismatch analysis is always performed after a full | 139 | The section mismatch analysis is always performed after a full |
140 | kernel build, and enabling this option causes the following | 140 | kernel build, and enabling this option causes the following |
@@ -243,8 +243,7 @@ config BOOTPARAM_SOFTLOCKUP_PANIC_VALUE | |||
243 | default 1 if BOOTPARAM_SOFTLOCKUP_PANIC | 243 | default 1 if BOOTPARAM_SOFTLOCKUP_PANIC |
244 | 244 | ||
245 | config PANIC_ON_OOPS | 245 | config PANIC_ON_OOPS |
246 | bool "Panic on Oops" if EXPERT | 246 | bool "Panic on Oops" |
247 | default n | ||
248 | help | 247 | help |
249 | Say Y here to enable the kernel to panic when it oopses. This | 248 | Say Y here to enable the kernel to panic when it oopses. This |
250 | has the same effect as setting oops=panic on the kernel command | 249 | has the same effect as setting oops=panic on the kernel command |
@@ -455,7 +454,7 @@ config HAVE_DEBUG_KMEMLEAK | |||
455 | 454 | ||
456 | config DEBUG_KMEMLEAK | 455 | config DEBUG_KMEMLEAK |
457 | bool "Kernel memory leak detector" | 456 | bool "Kernel memory leak detector" |
458 | depends on DEBUG_KERNEL && EXPERIMENTAL && HAVE_DEBUG_KMEMLEAK | 457 | depends on DEBUG_KERNEL && HAVE_DEBUG_KMEMLEAK |
459 | select DEBUG_FS | 458 | select DEBUG_FS |
460 | select STACKTRACE if STACKTRACE_SUPPORT | 459 | select STACKTRACE if STACKTRACE_SUPPORT |
461 | select KALLSYMS | 460 | select KALLSYMS |
@@ -605,61 +604,6 @@ config PROVE_LOCKING | |||
605 | 604 | ||
606 | For more details, see Documentation/lockdep-design.txt. | 605 | For more details, see Documentation/lockdep-design.txt. |
607 | 606 | ||
608 | config PROVE_RCU | ||
609 | bool "RCU debugging: prove RCU correctness" | ||
610 | depends on PROVE_LOCKING | ||
611 | default n | ||
612 | help | ||
613 | This feature enables lockdep extensions that check for correct | ||
614 | use of RCU APIs. This is currently under development. Say Y | ||
615 | if you want to debug RCU usage or help work on the PROVE_RCU | ||
616 | feature. | ||
617 | |||
618 | Say N if you are unsure. | ||
619 | |||
620 | config PROVE_RCU_REPEATEDLY | ||
621 | bool "RCU debugging: don't disable PROVE_RCU on first splat" | ||
622 | depends on PROVE_RCU | ||
623 | default n | ||
624 | help | ||
625 | By itself, PROVE_RCU will disable checking upon issuing the | ||
626 | first warning (or "splat"). This feature prevents such | ||
627 | disabling, allowing multiple RCU-lockdep warnings to be printed | ||
628 | on a single reboot. | ||
629 | |||
630 | Say Y to allow multiple RCU-lockdep warnings per boot. | ||
631 | |||
632 | Say N if you are unsure. | ||
633 | |||
634 | config PROVE_RCU_DELAY | ||
635 | bool "RCU debugging: preemptible RCU race provocation" | ||
636 | depends on DEBUG_KERNEL && PREEMPT_RCU | ||
637 | default n | ||
638 | help | ||
639 | There is a class of races that involve an unlikely preemption | ||
640 | of __rcu_read_unlock() just after ->rcu_read_lock_nesting has | ||
641 | been set to INT_MIN. This feature inserts a delay at that | ||
642 | point to increase the probability of these races. | ||
643 | |||
644 | Say Y to increase probability of preemption of __rcu_read_unlock(). | ||
645 | |||
646 | Say N if you are unsure. | ||
647 | |||
648 | config SPARSE_RCU_POINTER | ||
649 | bool "RCU debugging: sparse-based checks for pointer usage" | ||
650 | default n | ||
651 | help | ||
652 | This feature enables the __rcu sparse annotation for | ||
653 | RCU-protected pointers. This annotation will cause sparse | ||
654 | to flag any non-RCU used of annotated pointers. This can be | ||
655 | helpful when debugging RCU usage. Please note that this feature | ||
656 | is not intended to enforce code cleanliness; it is instead merely | ||
657 | a debugging aid. | ||
658 | |||
659 | Say Y to make sparse flag questionable use of RCU-protected pointers | ||
660 | |||
661 | Say N if you are unsure. | ||
662 | |||
663 | config LOCKDEP | 607 | config LOCKDEP |
664 | bool | 608 | bool |
665 | depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT | 609 | depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT |
@@ -730,7 +674,7 @@ config STACKTRACE | |||
730 | 674 | ||
731 | config DEBUG_STACK_USAGE | 675 | config DEBUG_STACK_USAGE |
732 | bool "Stack utilization instrumentation" | 676 | bool "Stack utilization instrumentation" |
733 | depends on DEBUG_KERNEL && !IA64 && !PARISC | 677 | depends on DEBUG_KERNEL && !IA64 && !PARISC && !METAG |
734 | help | 678 | help |
735 | Enables the display of the minimum amount of free stack which each | 679 | Enables the display of the minimum amount of free stack which each |
736 | task has ever had available in the sysrq-T and sysrq-P debug output. | 680 | task has ever had available in the sysrq-T and sysrq-P debug output. |
@@ -911,7 +855,7 @@ config FRAME_POINTER | |||
911 | bool "Compile the kernel with frame pointers" | 855 | bool "Compile the kernel with frame pointers" |
912 | depends on DEBUG_KERNEL && \ | 856 | depends on DEBUG_KERNEL && \ |
913 | (CRIS || M68K || FRV || UML || \ | 857 | (CRIS || M68K || FRV || UML || \ |
914 | AVR32 || SUPERH || BLACKFIN || MN10300) || \ | 858 | AVR32 || SUPERH || BLACKFIN || MN10300 || METAG) || \ |
915 | ARCH_WANT_FRAME_POINTERS | 859 | ARCH_WANT_FRAME_POINTERS |
916 | default y if (DEBUG_INFO && UML) || ARCH_WANT_FRAME_POINTERS | 860 | default y if (DEBUG_INFO && UML) || ARCH_WANT_FRAME_POINTERS |
917 | help | 861 | help |
@@ -937,6 +881,63 @@ config BOOT_PRINTK_DELAY | |||
937 | BOOT_PRINTK_DELAY also may cause LOCKUP_DETECTOR to detect | 881 | BOOT_PRINTK_DELAY also may cause LOCKUP_DETECTOR to detect |
938 | what it believes to be lockup conditions. | 882 | what it believes to be lockup conditions. |
939 | 883 | ||
884 | menu "RCU Debugging" | ||
885 | |||
886 | config PROVE_RCU | ||
887 | bool "RCU debugging: prove RCU correctness" | ||
888 | depends on PROVE_LOCKING | ||
889 | default n | ||
890 | help | ||
891 | This feature enables lockdep extensions that check for correct | ||
892 | use of RCU APIs. This is currently under development. Say Y | ||
893 | if you want to debug RCU usage or help work on the PROVE_RCU | ||
894 | feature. | ||
895 | |||
896 | Say N if you are unsure. | ||
897 | |||
898 | config PROVE_RCU_REPEATEDLY | ||
899 | bool "RCU debugging: don't disable PROVE_RCU on first splat" | ||
900 | depends on PROVE_RCU | ||
901 | default n | ||
902 | help | ||
903 | By itself, PROVE_RCU will disable checking upon issuing the | ||
904 | first warning (or "splat"). This feature prevents such | ||
905 | disabling, allowing multiple RCU-lockdep warnings to be printed | ||
906 | on a single reboot. | ||
907 | |||
908 | Say Y to allow multiple RCU-lockdep warnings per boot. | ||
909 | |||
910 | Say N if you are unsure. | ||
911 | |||
912 | config PROVE_RCU_DELAY | ||
913 | bool "RCU debugging: preemptible RCU race provocation" | ||
914 | depends on DEBUG_KERNEL && PREEMPT_RCU | ||
915 | default n | ||
916 | help | ||
917 | There is a class of races that involve an unlikely preemption | ||
918 | of __rcu_read_unlock() just after ->rcu_read_lock_nesting has | ||
919 | been set to INT_MIN. This feature inserts a delay at that | ||
920 | point to increase the probability of these races. | ||
921 | |||
922 | Say Y to increase probability of preemption of __rcu_read_unlock(). | ||
923 | |||
924 | Say N if you are unsure. | ||
925 | |||
926 | config SPARSE_RCU_POINTER | ||
927 | bool "RCU debugging: sparse-based checks for pointer usage" | ||
928 | default n | ||
929 | help | ||
930 | This feature enables the __rcu sparse annotation for | ||
931 | RCU-protected pointers. This annotation will cause sparse | ||
932 | to flag any non-RCU used of annotated pointers. This can be | ||
933 | helpful when debugging RCU usage. Please note that this feature | ||
934 | is not intended to enforce code cleanliness; it is instead merely | ||
935 | a debugging aid. | ||
936 | |||
937 | Say Y to make sparse flag questionable use of RCU-protected pointers | ||
938 | |||
939 | Say N if you are unsure. | ||
940 | |||
940 | config RCU_TORTURE_TEST | 941 | config RCU_TORTURE_TEST |
941 | tristate "torture tests for RCU" | 942 | tristate "torture tests for RCU" |
942 | depends on DEBUG_KERNEL | 943 | depends on DEBUG_KERNEL |
@@ -970,9 +971,9 @@ config RCU_TORTURE_TEST_RUNNABLE | |||
970 | 971 | ||
971 | config RCU_CPU_STALL_TIMEOUT | 972 | config RCU_CPU_STALL_TIMEOUT |
972 | int "RCU CPU stall timeout in seconds" | 973 | int "RCU CPU stall timeout in seconds" |
973 | depends on TREE_RCU || TREE_PREEMPT_RCU | 974 | depends on RCU_STALL_COMMON |
974 | range 3 300 | 975 | range 3 300 |
975 | default 60 | 976 | default 21 |
976 | help | 977 | help |
977 | If a given RCU grace period extends more than the specified | 978 | If a given RCU grace period extends more than the specified |
978 | number of seconds, a CPU stall warning is printed. If the | 979 | number of seconds, a CPU stall warning is printed. If the |
@@ -1008,6 +1009,7 @@ config RCU_CPU_STALL_INFO | |||
1008 | config RCU_TRACE | 1009 | config RCU_TRACE |
1009 | bool "Enable tracing for RCU" | 1010 | bool "Enable tracing for RCU" |
1010 | depends on DEBUG_KERNEL | 1011 | depends on DEBUG_KERNEL |
1012 | select TRACE_CLOCK | ||
1011 | help | 1013 | help |
1012 | This option provides tracing in RCU which presents stats | 1014 | This option provides tracing in RCU which presents stats |
1013 | in debugfs for debugging RCU implementation. | 1015 | in debugfs for debugging RCU implementation. |
@@ -1015,6 +1017,8 @@ config RCU_TRACE | |||
1015 | Say Y here if you want to enable RCU tracing | 1017 | Say Y here if you want to enable RCU tracing |
1016 | Say N if you are unsure. | 1018 | Say N if you are unsure. |
1017 | 1019 | ||
1020 | endmenu # "RCU Debugging" | ||
1021 | |||
1018 | config KPROBES_SANITY_TEST | 1022 | config KPROBES_SANITY_TEST |
1019 | bool "Kprobes sanity tests" | 1023 | bool "Kprobes sanity tests" |
1020 | depends on DEBUG_KERNEL | 1024 | depends on DEBUG_KERNEL |
@@ -1115,7 +1119,7 @@ config NOTIFIER_ERROR_INJECTION | |||
1115 | depends on DEBUG_KERNEL | 1119 | depends on DEBUG_KERNEL |
1116 | select DEBUG_FS | 1120 | select DEBUG_FS |
1117 | help | 1121 | help |
1118 | This option provides the ability to inject artifical errors to | 1122 | This option provides the ability to inject artificial errors to |
1119 | specified notifier chain callbacks. It is useful to test the error | 1123 | specified notifier chain callbacks. It is useful to test the error |
1120 | handling of notifier call chain failures. | 1124 | handling of notifier call chain failures. |
1121 | 1125 | ||
@@ -1126,7 +1130,7 @@ config CPU_NOTIFIER_ERROR_INJECT | |||
1126 | depends on HOTPLUG_CPU && NOTIFIER_ERROR_INJECTION | 1130 | depends on HOTPLUG_CPU && NOTIFIER_ERROR_INJECTION |
1127 | help | 1131 | help |
1128 | This option provides a kernel module that can be used to test | 1132 | This option provides a kernel module that can be used to test |
1129 | the error handling of the cpu notifiers by injecting artifical | 1133 | the error handling of the cpu notifiers by injecting artificial |
1130 | errors to CPU notifier chain callbacks. It is controlled through | 1134 | errors to CPU notifier chain callbacks. It is controlled through |
1131 | debugfs interface under /sys/kernel/debug/notifier-error-inject/cpu | 1135 | debugfs interface under /sys/kernel/debug/notifier-error-inject/cpu |
1132 | 1136 | ||
@@ -1150,7 +1154,7 @@ config PM_NOTIFIER_ERROR_INJECT | |||
1150 | depends on PM && NOTIFIER_ERROR_INJECTION | 1154 | depends on PM && NOTIFIER_ERROR_INJECTION |
1151 | default m if PM_DEBUG | 1155 | default m if PM_DEBUG |
1152 | help | 1156 | help |
1153 | This option provides the ability to inject artifical errors to | 1157 | This option provides the ability to inject artificial errors to |
1154 | PM notifier chain callbacks. It is controlled through debugfs | 1158 | PM notifier chain callbacks. It is controlled through debugfs |
1155 | interface /sys/kernel/debug/notifier-error-inject/pm | 1159 | interface /sys/kernel/debug/notifier-error-inject/pm |
1156 | 1160 | ||
@@ -1173,7 +1177,7 @@ config MEMORY_NOTIFIER_ERROR_INJECT | |||
1173 | tristate "Memory hotplug notifier error injection module" | 1177 | tristate "Memory hotplug notifier error injection module" |
1174 | depends on MEMORY_HOTPLUG_SPARSE && NOTIFIER_ERROR_INJECTION | 1178 | depends on MEMORY_HOTPLUG_SPARSE && NOTIFIER_ERROR_INJECTION |
1175 | help | 1179 | help |
1176 | This option provides the ability to inject artifical errors to | 1180 | This option provides the ability to inject artificial errors to |
1177 | memory hotplug notifier chain callbacks. It is controlled through | 1181 | memory hotplug notifier chain callbacks. It is controlled through |
1178 | debugfs interface under /sys/kernel/debug/notifier-error-inject/memory | 1182 | debugfs interface under /sys/kernel/debug/notifier-error-inject/memory |
1179 | 1183 | ||
@@ -1192,14 +1196,14 @@ config MEMORY_NOTIFIER_ERROR_INJECT | |||
1192 | 1196 | ||
1193 | If unsure, say N. | 1197 | If unsure, say N. |
1194 | 1198 | ||
1195 | config PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT | 1199 | config OF_RECONFIG_NOTIFIER_ERROR_INJECT |
1196 | tristate "pSeries reconfig notifier error injection module" | 1200 | tristate "OF reconfig notifier error injection module" |
1197 | depends on PPC_PSERIES && NOTIFIER_ERROR_INJECTION | 1201 | depends on OF_DYNAMIC && NOTIFIER_ERROR_INJECTION |
1198 | help | 1202 | help |
1199 | This option provides the ability to inject artifical errors to | 1203 | This option provides the ability to inject artificial errors to |
1200 | pSeries reconfig notifier chain callbacks. It is controlled | 1204 | OF reconfig notifier chain callbacks. It is controlled |
1201 | through debugfs interface under | 1205 | through debugfs interface under |
1202 | /sys/kernel/debug/notifier-error-inject/pSeries-reconfig/ | 1206 | /sys/kernel/debug/notifier-error-inject/OF-reconfig/ |
1203 | 1207 | ||
1204 | If the notifier call chain should be failed with some events | 1208 | If the notifier call chain should be failed with some events |
1205 | notified, write the error code to "actions/<notifier event>/error". | 1209 | notified, write the error code to "actions/<notifier event>/error". |
diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb index 43cb93fa2651..140e87824173 100644 --- a/lib/Kconfig.kgdb +++ b/lib/Kconfig.kgdb | |||
@@ -5,7 +5,7 @@ config HAVE_ARCH_KGDB | |||
5 | menuconfig KGDB | 5 | menuconfig KGDB |
6 | bool "KGDB: kernel debugger" | 6 | bool "KGDB: kernel debugger" |
7 | depends on HAVE_ARCH_KGDB | 7 | depends on HAVE_ARCH_KGDB |
8 | depends on DEBUG_KERNEL && EXPERIMENTAL | 8 | depends on DEBUG_KERNEL |
9 | help | 9 | help |
10 | If you say Y here, it will be possible to remotely debug the | 10 | If you say Y here, it will be possible to remotely debug the |
11 | kernel using gdb. It is recommended but not required, that | 11 | kernel using gdb. It is recommended but not required, that |
@@ -22,6 +22,7 @@ config KGDB_SERIAL_CONSOLE | |||
22 | tristate "KGDB: use kgdb over the serial console" | 22 | tristate "KGDB: use kgdb over the serial console" |
23 | select CONSOLE_POLL | 23 | select CONSOLE_POLL |
24 | select MAGIC_SYSRQ | 24 | select MAGIC_SYSRQ |
25 | depends on TTY | ||
25 | default y | 26 | default y |
26 | help | 27 | help |
27 | Share a serial console with kgdb. Sysrq-g must be used | 28 | Share a serial console with kgdb. Sysrq-g must be used |
@@ -79,4 +80,22 @@ config KDB_KEYBOARD | |||
79 | help | 80 | help |
80 | KDB can use a PS/2 type keyboard for an input device | 81 | KDB can use a PS/2 type keyboard for an input device |
81 | 82 | ||
83 | config KDB_CONTINUE_CATASTROPHIC | ||
84 | int "KDB: continue after catastrophic errors" | ||
85 | depends on KGDB_KDB | ||
86 | default "0" | ||
87 | help | ||
88 | This integer controls the behaviour of kdb when the kernel gets a | ||
89 | catastrophic error, i.e. for a panic or oops. | ||
90 | When KDB is active and a catastrophic error occurs, nothing extra | ||
91 | will happen until you type 'go'. | ||
92 | CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default). The first time | ||
93 | you type 'go', you will be warned by kdb. The secend time you type | ||
94 | 'go', KDB tries to continue. No guarantees that the | ||
95 | kernel is still usable in this situation. | ||
96 | CONFIG_KDB_CONTINUE_CATASTROPHIC == 1. KDB tries to continue. | ||
97 | No guarantees that the kernel is still usable in this situation. | ||
98 | CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. KDB forces a reboot. | ||
99 | If you are not sure, say 0. | ||
100 | |||
82 | endif # KGDB | 101 | endif # KGDB |
diff --git a/lib/Makefile b/lib/Makefile index 821a16229111..d7946ff75b2e 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -12,7 +12,8 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ | |||
12 | idr.o int_sqrt.o extable.o \ | 12 | idr.o int_sqrt.o extable.o \ |
13 | sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \ | 13 | sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \ |
14 | proportions.o flex_proportions.o prio_heap.o ratelimit.o show_mem.o \ | 14 | proportions.o flex_proportions.o prio_heap.o ratelimit.o show_mem.o \ |
15 | is_single_threaded.o plist.o decompress.o | 15 | is_single_threaded.o plist.o decompress.o kobject_uevent.o \ |
16 | earlycpio.o | ||
16 | 17 | ||
17 | lib-$(CONFIG_MMU) += ioremap.o | 18 | lib-$(CONFIG_MMU) += ioremap.o |
18 | lib-$(CONFIG_SMP) += cpumask.o | 19 | lib-$(CONFIG_SMP) += cpumask.o |
@@ -22,7 +23,7 @@ lib-y += kobject.o klist.o | |||
22 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ | 23 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ |
23 | bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ | 24 | bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ |
24 | string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \ | 25 | string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \ |
25 | bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o | 26 | bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o |
26 | obj-y += kstrtox.o | 27 | obj-y += kstrtox.o |
27 | obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o | 28 | obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o |
28 | 29 | ||
@@ -31,7 +32,6 @@ CFLAGS_kobject.o += -DDEBUG | |||
31 | CFLAGS_kobject_uevent.o += -DDEBUG | 32 | CFLAGS_kobject_uevent.o += -DDEBUG |
32 | endif | 33 | endif |
33 | 34 | ||
34 | lib-$(CONFIG_HOTPLUG) += kobject_uevent.o | ||
35 | obj-$(CONFIG_GENERIC_IOMAP) += iomap.o | 35 | obj-$(CONFIG_GENERIC_IOMAP) += iomap.o |
36 | obj-$(CONFIG_GENERIC_PCI_IOMAP) += pci_iomap.o | 36 | obj-$(CONFIG_GENERIC_PCI_IOMAP) += pci_iomap.o |
37 | obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o | 37 | obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o |
@@ -40,6 +40,7 @@ obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o | |||
40 | obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o | 40 | obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o |
41 | lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o | 41 | lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o |
42 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o | 42 | lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o |
43 | lib-$(CONFIG_PERCPU_RWSEM) += percpu-rwsem.o | ||
43 | 44 | ||
44 | CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) | 45 | CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) |
45 | obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o | 46 | obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o |
@@ -94,8 +95,8 @@ obj-$(CONFIG_NOTIFIER_ERROR_INJECTION) += notifier-error-inject.o | |||
94 | obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o | 95 | obj-$(CONFIG_CPU_NOTIFIER_ERROR_INJECT) += cpu-notifier-error-inject.o |
95 | obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o | 96 | obj-$(CONFIG_PM_NOTIFIER_ERROR_INJECT) += pm-notifier-error-inject.o |
96 | obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o | 97 | obj-$(CONFIG_MEMORY_NOTIFIER_ERROR_INJECT) += memory-notifier-error-inject.o |
97 | obj-$(CONFIG_PSERIES_RECONFIG_NOTIFIER_ERROR_INJECT) += \ | 98 | obj-$(CONFIG_OF_RECONFIG_NOTIFIER_ERROR_INJECT) += \ |
98 | pSeries-reconfig-notifier-error-inject.o | 99 | of-reconfig-notifier-error-inject.o |
99 | 100 | ||
100 | lib-$(CONFIG_GENERIC_BUG) += bug.o | 101 | lib-$(CONFIG_GENERIC_BUG) += bug.o |
101 | 102 | ||
@@ -163,7 +164,7 @@ $(obj)/crc32table.h: $(obj)/gen_crc32table | |||
163 | # | 164 | # |
164 | obj-$(CONFIG_OID_REGISTRY) += oid_registry.o | 165 | obj-$(CONFIG_OID_REGISTRY) += oid_registry.o |
165 | 166 | ||
166 | $(obj)/oid_registry.c: $(obj)/oid_registry_data.c | 167 | $(obj)/oid_registry.o: $(obj)/oid_registry_data.c |
167 | 168 | ||
168 | $(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \ | 169 | $(obj)/oid_registry_data.c: $(srctree)/include/linux/oid_registry.h \ |
169 | $(src)/build_OID_registry | 170 | $(src)/build_OID_registry |
diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c index de2c8b5a715b..11b9b01fda6b 100644 --- a/lib/asn1_decoder.c +++ b/lib/asn1_decoder.c | |||
@@ -81,7 +81,7 @@ next_tag: | |||
81 | goto next_tag; | 81 | goto next_tag; |
82 | } | 82 | } |
83 | 83 | ||
84 | if (unlikely((tag & 0x1f) == 0x1f)) { | 84 | if (unlikely((tag & 0x1f) == ASN1_LONG_TAG)) { |
85 | do { | 85 | do { |
86 | if (unlikely(datalen - dp < 2)) | 86 | if (unlikely(datalen - dp < 2)) |
87 | goto data_overrun_error; | 87 | goto data_overrun_error; |
@@ -91,12 +91,12 @@ next_tag: | |||
91 | 91 | ||
92 | /* Extract the length */ | 92 | /* Extract the length */ |
93 | len = data[dp++]; | 93 | len = data[dp++]; |
94 | if (len < 0x7f) { | 94 | if (len <= 0x7f) { |
95 | dp += len; | 95 | dp += len; |
96 | goto next_tag; | 96 | goto next_tag; |
97 | } | 97 | } |
98 | 98 | ||
99 | if (unlikely(len == 0x80)) { | 99 | if (unlikely(len == ASN1_INDEFINITE_LENGTH)) { |
100 | /* Indefinite length */ | 100 | /* Indefinite length */ |
101 | if (unlikely((tag & ASN1_CONS_BIT) == ASN1_PRIM << 5)) | 101 | if (unlikely((tag & ASN1_CONS_BIT) == ASN1_PRIM << 5)) |
102 | goto indefinite_len_primitive; | 102 | goto indefinite_len_primitive; |
@@ -222,7 +222,7 @@ next_op: | |||
222 | if (unlikely(dp >= datalen - 1)) | 222 | if (unlikely(dp >= datalen - 1)) |
223 | goto data_overrun_error; | 223 | goto data_overrun_error; |
224 | tag = data[dp++]; | 224 | tag = data[dp++]; |
225 | if (unlikely((tag & 0x1f) == 0x1f)) | 225 | if (unlikely((tag & 0x1f) == ASN1_LONG_TAG)) |
226 | goto long_tag_not_supported; | 226 | goto long_tag_not_supported; |
227 | 227 | ||
228 | if (op & ASN1_OP_MATCH__ANY) { | 228 | if (op & ASN1_OP_MATCH__ANY) { |
@@ -254,7 +254,7 @@ next_op: | |||
254 | 254 | ||
255 | len = data[dp++]; | 255 | len = data[dp++]; |
256 | if (len > 0x7f) { | 256 | if (len > 0x7f) { |
257 | if (unlikely(len == 0x80)) { | 257 | if (unlikely(len == ASN1_INDEFINITE_LENGTH)) { |
258 | /* Indefinite length */ | 258 | /* Indefinite length */ |
259 | if (unlikely(!(tag & ASN1_CONS_BIT))) | 259 | if (unlikely(!(tag & ASN1_CONS_BIT))) |
260 | goto indefinite_len_primitive; | 260 | goto indefinite_len_primitive; |
diff --git a/lib/atomic64.c b/lib/atomic64.c index 978537809d84..08a4f068e61e 100644 --- a/lib/atomic64.c +++ b/lib/atomic64.c | |||
@@ -31,7 +31,11 @@ | |||
31 | static union { | 31 | static union { |
32 | raw_spinlock_t lock; | 32 | raw_spinlock_t lock; |
33 | char pad[L1_CACHE_BYTES]; | 33 | char pad[L1_CACHE_BYTES]; |
34 | } atomic64_lock[NR_LOCKS] __cacheline_aligned_in_smp; | 34 | } atomic64_lock[NR_LOCKS] __cacheline_aligned_in_smp = { |
35 | [0 ... (NR_LOCKS - 1)] = { | ||
36 | .lock = __RAW_SPIN_LOCK_UNLOCKED(atomic64_lock.lock), | ||
37 | }, | ||
38 | }; | ||
35 | 39 | ||
36 | static inline raw_spinlock_t *lock_addr(const atomic64_t *v) | 40 | static inline raw_spinlock_t *lock_addr(const atomic64_t *v) |
37 | { | 41 | { |
@@ -173,14 +177,3 @@ int atomic64_add_unless(atomic64_t *v, long long a, long long u) | |||
173 | return ret; | 177 | return ret; |
174 | } | 178 | } |
175 | EXPORT_SYMBOL(atomic64_add_unless); | 179 | EXPORT_SYMBOL(atomic64_add_unless); |
176 | |||
177 | static int init_atomic64_lock(void) | ||
178 | { | ||
179 | int i; | ||
180 | |||
181 | for (i = 0; i < NR_LOCKS; ++i) | ||
182 | raw_spin_lock_init(&atomic64_lock[i].lock); | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | pure_initcall(init_atomic64_lock); | ||
diff --git a/lib/bitmap.c b/lib/bitmap.c index 06fdfa1aeba7..06f7e4fe8d2d 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c | |||
@@ -353,7 +353,7 @@ again: | |||
353 | EXPORT_SYMBOL(bitmap_find_next_zero_area); | 353 | EXPORT_SYMBOL(bitmap_find_next_zero_area); |
354 | 354 | ||
355 | /* | 355 | /* |
356 | * Bitmap printing & parsing functions: first version by Bill Irwin, | 356 | * Bitmap printing & parsing functions: first version by Nadia Yvette Chambers, |
357 | * second version by Paul Jackson, third by Joe Korty. | 357 | * second version by Paul Jackson, third by Joe Korty. |
358 | */ | 358 | */ |
359 | 359 | ||
@@ -55,6 +55,7 @@ static inline unsigned long bug_addr(const struct bug_entry *bug) | |||
55 | } | 55 | } |
56 | 56 | ||
57 | #ifdef CONFIG_MODULES | 57 | #ifdef CONFIG_MODULES |
58 | /* Updates are protected by module mutex */ | ||
58 | static LIST_HEAD(module_bug_list); | 59 | static LIST_HEAD(module_bug_list); |
59 | 60 | ||
60 | static const struct bug_entry *module_find_bug(unsigned long bugaddr) | 61 | static const struct bug_entry *module_find_bug(unsigned long bugaddr) |
@@ -165,7 +166,8 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) | |||
165 | print_modules(); | 166 | print_modules(); |
166 | show_regs(regs); | 167 | show_regs(regs); |
167 | print_oops_end_marker(); | 168 | print_oops_end_marker(); |
168 | add_taint(BUG_GET_TAINT(bug)); | 169 | /* Just a warning, don't kill lockdep. */ |
170 | add_taint(BUG_GET_TAINT(bug), LOCKDEP_STILL_OK); | ||
169 | return BUG_TRAP_TYPE_WARN; | 171 | return BUG_TRAP_TYPE_WARN; |
170 | } | 172 | } |
171 | 173 | ||
diff --git a/lib/checksum.c b/lib/checksum.c index 12dceb27ff20..129775eb6de6 100644 --- a/lib/checksum.c +++ b/lib/checksum.c | |||
@@ -102,6 +102,7 @@ out: | |||
102 | } | 102 | } |
103 | #endif | 103 | #endif |
104 | 104 | ||
105 | #ifndef ip_fast_csum | ||
105 | /* | 106 | /* |
106 | * This is a version of ip_compute_csum() optimized for IP headers, | 107 | * This is a version of ip_compute_csum() optimized for IP headers, |
107 | * which always checksum on 4 octet boundaries. | 108 | * which always checksum on 4 octet boundaries. |
@@ -111,6 +112,7 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) | |||
111 | return (__force __sum16)~do_csum(iph, ihl*4); | 112 | return (__force __sum16)~do_csum(iph, ihl*4); |
112 | } | 113 | } |
113 | EXPORT_SYMBOL(ip_fast_csum); | 114 | EXPORT_SYMBOL(ip_fast_csum); |
115 | #endif | ||
114 | 116 | ||
115 | /* | 117 | /* |
116 | * computes the checksum of a memory block at buff, length len, | 118 | * computes the checksum of a memory block at buff, length len, |
diff --git a/lib/cpu_rmap.c b/lib/cpu_rmap.c index 145dec5267c9..5fbed5caba6e 100644 --- a/lib/cpu_rmap.c +++ b/lib/cpu_rmap.c | |||
@@ -45,6 +45,7 @@ struct cpu_rmap *alloc_cpu_rmap(unsigned int size, gfp_t flags) | |||
45 | if (!rmap) | 45 | if (!rmap) |
46 | return NULL; | 46 | return NULL; |
47 | 47 | ||
48 | kref_init(&rmap->refcount); | ||
48 | rmap->obj = (void **)((char *)rmap + obj_offset); | 49 | rmap->obj = (void **)((char *)rmap + obj_offset); |
49 | 50 | ||
50 | /* Initially assign CPUs to objects on a rota, since we have | 51 | /* Initially assign CPUs to objects on a rota, since we have |
@@ -63,6 +64,35 @@ struct cpu_rmap *alloc_cpu_rmap(unsigned int size, gfp_t flags) | |||
63 | } | 64 | } |
64 | EXPORT_SYMBOL(alloc_cpu_rmap); | 65 | EXPORT_SYMBOL(alloc_cpu_rmap); |
65 | 66 | ||
67 | /** | ||
68 | * cpu_rmap_release - internal reclaiming helper called from kref_put | ||
69 | * @ref: kref to struct cpu_rmap | ||
70 | */ | ||
71 | static void cpu_rmap_release(struct kref *ref) | ||
72 | { | ||
73 | struct cpu_rmap *rmap = container_of(ref, struct cpu_rmap, refcount); | ||
74 | kfree(rmap); | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * cpu_rmap_get - internal helper to get new ref on a cpu_rmap | ||
79 | * @rmap: reverse-map allocated with alloc_cpu_rmap() | ||
80 | */ | ||
81 | static inline void cpu_rmap_get(struct cpu_rmap *rmap) | ||
82 | { | ||
83 | kref_get(&rmap->refcount); | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * cpu_rmap_put - release ref on a cpu_rmap | ||
88 | * @rmap: reverse-map allocated with alloc_cpu_rmap() | ||
89 | */ | ||
90 | int cpu_rmap_put(struct cpu_rmap *rmap) | ||
91 | { | ||
92 | return kref_put(&rmap->refcount, cpu_rmap_release); | ||
93 | } | ||
94 | EXPORT_SYMBOL(cpu_rmap_put); | ||
95 | |||
66 | /* Reevaluate nearest object for given CPU, comparing with the given | 96 | /* Reevaluate nearest object for given CPU, comparing with the given |
67 | * neighbours at the given distance. | 97 | * neighbours at the given distance. |
68 | */ | 98 | */ |
@@ -197,8 +227,7 @@ struct irq_glue { | |||
197 | * free_irq_cpu_rmap - free a CPU affinity reverse-map used for IRQs | 227 | * free_irq_cpu_rmap - free a CPU affinity reverse-map used for IRQs |
198 | * @rmap: Reverse-map allocated with alloc_irq_cpu_map(), or %NULL | 228 | * @rmap: Reverse-map allocated with alloc_irq_cpu_map(), or %NULL |
199 | * | 229 | * |
200 | * Must be called in process context, before freeing the IRQs, and | 230 | * Must be called in process context, before freeing the IRQs. |
201 | * without holding any locks required by global workqueue items. | ||
202 | */ | 231 | */ |
203 | void free_irq_cpu_rmap(struct cpu_rmap *rmap) | 232 | void free_irq_cpu_rmap(struct cpu_rmap *rmap) |
204 | { | 233 | { |
@@ -212,12 +241,18 @@ void free_irq_cpu_rmap(struct cpu_rmap *rmap) | |||
212 | glue = rmap->obj[index]; | 241 | glue = rmap->obj[index]; |
213 | irq_set_affinity_notifier(glue->notify.irq, NULL); | 242 | irq_set_affinity_notifier(glue->notify.irq, NULL); |
214 | } | 243 | } |
215 | irq_run_affinity_notifiers(); | ||
216 | 244 | ||
217 | kfree(rmap); | 245 | cpu_rmap_put(rmap); |
218 | } | 246 | } |
219 | EXPORT_SYMBOL(free_irq_cpu_rmap); | 247 | EXPORT_SYMBOL(free_irq_cpu_rmap); |
220 | 248 | ||
249 | /** | ||
250 | * irq_cpu_rmap_notify - callback for IRQ subsystem when IRQ affinity updated | ||
251 | * @notify: struct irq_affinity_notify passed by irq/manage.c | ||
252 | * @mask: cpu mask for new SMP affinity | ||
253 | * | ||
254 | * This is executed in workqueue context. | ||
255 | */ | ||
221 | static void | 256 | static void |
222 | irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask) | 257 | irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask) |
223 | { | 258 | { |
@@ -230,10 +265,16 @@ irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask) | |||
230 | pr_warning("irq_cpu_rmap_notify: update failed: %d\n", rc); | 265 | pr_warning("irq_cpu_rmap_notify: update failed: %d\n", rc); |
231 | } | 266 | } |
232 | 267 | ||
268 | /** | ||
269 | * irq_cpu_rmap_release - reclaiming callback for IRQ subsystem | ||
270 | * @ref: kref to struct irq_affinity_notify passed by irq/manage.c | ||
271 | */ | ||
233 | static void irq_cpu_rmap_release(struct kref *ref) | 272 | static void irq_cpu_rmap_release(struct kref *ref) |
234 | { | 273 | { |
235 | struct irq_glue *glue = | 274 | struct irq_glue *glue = |
236 | container_of(ref, struct irq_glue, notify.kref); | 275 | container_of(ref, struct irq_glue, notify.kref); |
276 | |||
277 | cpu_rmap_put(glue->rmap); | ||
237 | kfree(glue); | 278 | kfree(glue); |
238 | } | 279 | } |
239 | 280 | ||
@@ -258,10 +299,13 @@ int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq) | |||
258 | glue->notify.notify = irq_cpu_rmap_notify; | 299 | glue->notify.notify = irq_cpu_rmap_notify; |
259 | glue->notify.release = irq_cpu_rmap_release; | 300 | glue->notify.release = irq_cpu_rmap_release; |
260 | glue->rmap = rmap; | 301 | glue->rmap = rmap; |
302 | cpu_rmap_get(rmap); | ||
261 | glue->index = cpu_rmap_add(rmap, glue); | 303 | glue->index = cpu_rmap_add(rmap, glue); |
262 | rc = irq_set_affinity_notifier(irq, &glue->notify); | 304 | rc = irq_set_affinity_notifier(irq, &glue->notify); |
263 | if (rc) | 305 | if (rc) { |
306 | cpu_rmap_put(glue->rmap); | ||
264 | kfree(glue); | 307 | kfree(glue); |
308 | } | ||
265 | return rc; | 309 | return rc; |
266 | } | 310 | } |
267 | EXPORT_SYMBOL(irq_cpu_rmap_add); | 311 | EXPORT_SYMBOL(irq_cpu_rmap_add); |
diff --git a/lib/cpumask.c b/lib/cpumask.c index 402a54ac35cb..d327b87c99b7 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c | |||
@@ -161,6 +161,6 @@ EXPORT_SYMBOL(free_cpumask_var); | |||
161 | */ | 161 | */ |
162 | void __init free_bootmem_cpumask_var(cpumask_var_t mask) | 162 | void __init free_bootmem_cpumask_var(cpumask_var_t mask) |
163 | { | 163 | { |
164 | free_bootmem((unsigned long)mask, cpumask_size()); | 164 | free_bootmem(__pa(mask), cpumask_size()); |
165 | } | 165 | } |
166 | #endif | 166 | #endif |
diff --git a/lib/debugobjects.c b/lib/debugobjects.c index d11808ca4bc4..37061ede8b81 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c | |||
@@ -109,11 +109,10 @@ static void fill_pool(void) | |||
109 | */ | 109 | */ |
110 | static struct debug_obj *lookup_object(void *addr, struct debug_bucket *b) | 110 | static struct debug_obj *lookup_object(void *addr, struct debug_bucket *b) |
111 | { | 111 | { |
112 | struct hlist_node *node; | ||
113 | struct debug_obj *obj; | 112 | struct debug_obj *obj; |
114 | int cnt = 0; | 113 | int cnt = 0; |
115 | 114 | ||
116 | hlist_for_each_entry(obj, node, &b->list, node) { | 115 | hlist_for_each_entry(obj, &b->list, node) { |
117 | cnt++; | 116 | cnt++; |
118 | if (obj->object == addr) | 117 | if (obj->object == addr) |
119 | return obj; | 118 | return obj; |
@@ -213,7 +212,7 @@ static void free_object(struct debug_obj *obj) | |||
213 | static void debug_objects_oom(void) | 212 | static void debug_objects_oom(void) |
214 | { | 213 | { |
215 | struct debug_bucket *db = obj_hash; | 214 | struct debug_bucket *db = obj_hash; |
216 | struct hlist_node *node, *tmp; | 215 | struct hlist_node *tmp; |
217 | HLIST_HEAD(freelist); | 216 | HLIST_HEAD(freelist); |
218 | struct debug_obj *obj; | 217 | struct debug_obj *obj; |
219 | unsigned long flags; | 218 | unsigned long flags; |
@@ -227,7 +226,7 @@ static void debug_objects_oom(void) | |||
227 | raw_spin_unlock_irqrestore(&db->lock, flags); | 226 | raw_spin_unlock_irqrestore(&db->lock, flags); |
228 | 227 | ||
229 | /* Now free them */ | 228 | /* Now free them */ |
230 | hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) { | 229 | hlist_for_each_entry_safe(obj, tmp, &freelist, node) { |
231 | hlist_del(&obj->node); | 230 | hlist_del(&obj->node); |
232 | free_object(obj); | 231 | free_object(obj); |
233 | } | 232 | } |
@@ -658,7 +657,7 @@ debug_object_active_state(void *addr, struct debug_obj_descr *descr, | |||
658 | static void __debug_check_no_obj_freed(const void *address, unsigned long size) | 657 | static void __debug_check_no_obj_freed(const void *address, unsigned long size) |
659 | { | 658 | { |
660 | unsigned long flags, oaddr, saddr, eaddr, paddr, chunks; | 659 | unsigned long flags, oaddr, saddr, eaddr, paddr, chunks; |
661 | struct hlist_node *node, *tmp; | 660 | struct hlist_node *tmp; |
662 | HLIST_HEAD(freelist); | 661 | HLIST_HEAD(freelist); |
663 | struct debug_obj_descr *descr; | 662 | struct debug_obj_descr *descr; |
664 | enum debug_obj_state state; | 663 | enum debug_obj_state state; |
@@ -678,7 +677,7 @@ static void __debug_check_no_obj_freed(const void *address, unsigned long size) | |||
678 | repeat: | 677 | repeat: |
679 | cnt = 0; | 678 | cnt = 0; |
680 | raw_spin_lock_irqsave(&db->lock, flags); | 679 | raw_spin_lock_irqsave(&db->lock, flags); |
681 | hlist_for_each_entry_safe(obj, node, tmp, &db->list, node) { | 680 | hlist_for_each_entry_safe(obj, tmp, &db->list, node) { |
682 | cnt++; | 681 | cnt++; |
683 | oaddr = (unsigned long) obj->object; | 682 | oaddr = (unsigned long) obj->object; |
684 | if (oaddr < saddr || oaddr >= eaddr) | 683 | if (oaddr < saddr || oaddr >= eaddr) |
@@ -702,7 +701,7 @@ repeat: | |||
702 | raw_spin_unlock_irqrestore(&db->lock, flags); | 701 | raw_spin_unlock_irqrestore(&db->lock, flags); |
703 | 702 | ||
704 | /* Now free them */ | 703 | /* Now free them */ |
705 | hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) { | 704 | hlist_for_each_entry_safe(obj, tmp, &freelist, node) { |
706 | hlist_del(&obj->node); | 705 | hlist_del(&obj->node); |
707 | free_object(obj); | 706 | free_object(obj); |
708 | } | 707 | } |
@@ -1013,7 +1012,7 @@ void __init debug_objects_early_init(void) | |||
1013 | static int __init debug_objects_replace_static_objects(void) | 1012 | static int __init debug_objects_replace_static_objects(void) |
1014 | { | 1013 | { |
1015 | struct debug_bucket *db = obj_hash; | 1014 | struct debug_bucket *db = obj_hash; |
1016 | struct hlist_node *node, *tmp; | 1015 | struct hlist_node *tmp; |
1017 | struct debug_obj *obj, *new; | 1016 | struct debug_obj *obj, *new; |
1018 | HLIST_HEAD(objects); | 1017 | HLIST_HEAD(objects); |
1019 | int i, cnt = 0; | 1018 | int i, cnt = 0; |
@@ -1033,7 +1032,7 @@ static int __init debug_objects_replace_static_objects(void) | |||
1033 | local_irq_disable(); | 1032 | local_irq_disable(); |
1034 | 1033 | ||
1035 | /* Remove the statically allocated objects from the pool */ | 1034 | /* Remove the statically allocated objects from the pool */ |
1036 | hlist_for_each_entry_safe(obj, node, tmp, &obj_pool, node) | 1035 | hlist_for_each_entry_safe(obj, tmp, &obj_pool, node) |
1037 | hlist_del(&obj->node); | 1036 | hlist_del(&obj->node); |
1038 | /* Move the allocated objects to the pool */ | 1037 | /* Move the allocated objects to the pool */ |
1039 | hlist_move_list(&objects, &obj_pool); | 1038 | hlist_move_list(&objects, &obj_pool); |
@@ -1042,7 +1041,7 @@ static int __init debug_objects_replace_static_objects(void) | |||
1042 | for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) { | 1041 | for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) { |
1043 | hlist_move_list(&db->list, &objects); | 1042 | hlist_move_list(&db->list, &objects); |
1044 | 1043 | ||
1045 | hlist_for_each_entry(obj, node, &objects, node) { | 1044 | hlist_for_each_entry(obj, &objects, node) { |
1046 | new = hlist_entry(obj_pool.first, typeof(*obj), node); | 1045 | new = hlist_entry(obj_pool.first, typeof(*obj), node); |
1047 | hlist_del(&new->node); | 1046 | hlist_del(&new->node); |
1048 | /* copy object data */ | 1047 | /* copy object data */ |
@@ -1057,7 +1056,7 @@ static int __init debug_objects_replace_static_objects(void) | |||
1057 | obj_pool_used); | 1056 | obj_pool_used); |
1058 | return 0; | 1057 | return 0; |
1059 | free: | 1058 | free: |
1060 | hlist_for_each_entry_safe(obj, node, tmp, &objects, node) { | 1059 | hlist_for_each_entry_safe(obj, tmp, &objects, node) { |
1061 | hlist_del(&obj->node); | 1060 | hlist_del(&obj->node); |
1062 | kmem_cache_free(obj_cache, obj); | 1061 | kmem_cache_free(obj_cache, obj); |
1063 | } | 1062 | } |
diff --git a/lib/decompress_unlzo.c b/lib/decompress_unlzo.c index 4531294fa62f..960183d4258f 100644 --- a/lib/decompress_unlzo.c +++ b/lib/decompress_unlzo.c | |||
@@ -31,7 +31,7 @@ | |||
31 | */ | 31 | */ |
32 | 32 | ||
33 | #ifdef STATIC | 33 | #ifdef STATIC |
34 | #include "lzo/lzo1x_decompress.c" | 34 | #include "lzo/lzo1x_decompress_safe.c" |
35 | #else | 35 | #else |
36 | #include <linux/decompress/unlzo.h> | 36 | #include <linux/decompress/unlzo.h> |
37 | #endif | 37 | #endif |
diff --git a/lib/devres.c b/lib/devres.c index 80b9c76d436a..823533138fa0 100644 --- a/lib/devres.c +++ b/lib/devres.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/err.h> | ||
1 | #include <linux/pci.h> | 2 | #include <linux/pci.h> |
2 | #include <linux/io.h> | 3 | #include <linux/io.h> |
3 | #include <linux/gfp.h> | 4 | #include <linux/gfp.h> |
@@ -86,22 +87,24 @@ void devm_iounmap(struct device *dev, void __iomem *addr) | |||
86 | EXPORT_SYMBOL(devm_iounmap); | 87 | EXPORT_SYMBOL(devm_iounmap); |
87 | 88 | ||
88 | /** | 89 | /** |
89 | * devm_request_and_ioremap() - Check, request region, and ioremap resource | 90 | * devm_ioremap_resource() - check, request region, and ioremap resource |
90 | * @dev: Generic device to handle the resource for | 91 | * @dev: generic device to handle the resource for |
91 | * @res: resource to be handled | 92 | * @res: resource to be handled |
92 | * | 93 | * |
93 | * Takes all necessary steps to ioremap a mem resource. Uses managed device, so | 94 | * Checks that a resource is a valid memory region, requests the memory region |
94 | * everything is undone on driver detach. Checks arguments, so you can feed | 95 | * and ioremaps it either as cacheable or as non-cacheable memory depending on |
95 | * it the result from e.g. platform_get_resource() directly. Returns the | 96 | * the resource's flags. All operations are managed and will be undone on |
96 | * remapped pointer or NULL on error. Usage example: | 97 | * driver detach. |
98 | * | ||
99 | * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code | ||
100 | * on failure. Usage example: | ||
97 | * | 101 | * |
98 | * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 102 | * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
99 | * base = devm_request_and_ioremap(&pdev->dev, res); | 103 | * base = devm_ioremap_resource(&pdev->dev, res); |
100 | * if (!base) | 104 | * if (IS_ERR(base)) |
101 | * return -EADDRNOTAVAIL; | 105 | * return PTR_ERR(base); |
102 | */ | 106 | */ |
103 | void __iomem *devm_request_and_ioremap(struct device *dev, | 107 | void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res) |
104 | struct resource *res) | ||
105 | { | 108 | { |
106 | resource_size_t size; | 109 | resource_size_t size; |
107 | const char *name; | 110 | const char *name; |
@@ -111,7 +114,7 @@ void __iomem *devm_request_and_ioremap(struct device *dev, | |||
111 | 114 | ||
112 | if (!res || resource_type(res) != IORESOURCE_MEM) { | 115 | if (!res || resource_type(res) != IORESOURCE_MEM) { |
113 | dev_err(dev, "invalid resource\n"); | 116 | dev_err(dev, "invalid resource\n"); |
114 | return NULL; | 117 | return ERR_PTR(-EINVAL); |
115 | } | 118 | } |
116 | 119 | ||
117 | size = resource_size(res); | 120 | size = resource_size(res); |
@@ -119,7 +122,7 @@ void __iomem *devm_request_and_ioremap(struct device *dev, | |||
119 | 122 | ||
120 | if (!devm_request_mem_region(dev, res->start, size, name)) { | 123 | if (!devm_request_mem_region(dev, res->start, size, name)) { |
121 | dev_err(dev, "can't request region for resource %pR\n", res); | 124 | dev_err(dev, "can't request region for resource %pR\n", res); |
122 | return NULL; | 125 | return ERR_PTR(-EBUSY); |
123 | } | 126 | } |
124 | 127 | ||
125 | if (res->flags & IORESOURCE_CACHEABLE) | 128 | if (res->flags & IORESOURCE_CACHEABLE) |
@@ -130,10 +133,39 @@ void __iomem *devm_request_and_ioremap(struct device *dev, | |||
130 | if (!dest_ptr) { | 133 | if (!dest_ptr) { |
131 | dev_err(dev, "ioremap failed for resource %pR\n", res); | 134 | dev_err(dev, "ioremap failed for resource %pR\n", res); |
132 | devm_release_mem_region(dev, res->start, size); | 135 | devm_release_mem_region(dev, res->start, size); |
136 | dest_ptr = ERR_PTR(-ENOMEM); | ||
133 | } | 137 | } |
134 | 138 | ||
135 | return dest_ptr; | 139 | return dest_ptr; |
136 | } | 140 | } |
141 | EXPORT_SYMBOL(devm_ioremap_resource); | ||
142 | |||
143 | /** | ||
144 | * devm_request_and_ioremap() - Check, request region, and ioremap resource | ||
145 | * @dev: Generic device to handle the resource for | ||
146 | * @res: resource to be handled | ||
147 | * | ||
148 | * Takes all necessary steps to ioremap a mem resource. Uses managed device, so | ||
149 | * everything is undone on driver detach. Checks arguments, so you can feed | ||
150 | * it the result from e.g. platform_get_resource() directly. Returns the | ||
151 | * remapped pointer or NULL on error. Usage example: | ||
152 | * | ||
153 | * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
154 | * base = devm_request_and_ioremap(&pdev->dev, res); | ||
155 | * if (!base) | ||
156 | * return -EADDRNOTAVAIL; | ||
157 | */ | ||
158 | void __iomem *devm_request_and_ioremap(struct device *device, | ||
159 | struct resource *res) | ||
160 | { | ||
161 | void __iomem *dest_ptr; | ||
162 | |||
163 | dest_ptr = devm_ioremap_resource(device, res); | ||
164 | if (IS_ERR(dest_ptr)) | ||
165 | return NULL; | ||
166 | |||
167 | return dest_ptr; | ||
168 | } | ||
137 | EXPORT_SYMBOL(devm_request_and_ioremap); | 169 | EXPORT_SYMBOL(devm_request_and_ioremap); |
138 | 170 | ||
139 | #ifdef CONFIG_HAS_IOPORT | 171 | #ifdef CONFIG_HAS_IOPORT |
@@ -195,6 +227,7 @@ void devm_ioport_unmap(struct device *dev, void __iomem *addr) | |||
195 | devm_ioport_map_match, (void *)addr)); | 227 | devm_ioport_map_match, (void *)addr)); |
196 | } | 228 | } |
197 | EXPORT_SYMBOL(devm_ioport_unmap); | 229 | EXPORT_SYMBOL(devm_ioport_unmap); |
230 | #endif /* CONFIG_HAS_IOPORT */ | ||
198 | 231 | ||
199 | #ifdef CONFIG_PCI | 232 | #ifdef CONFIG_PCI |
200 | /* | 233 | /* |
@@ -400,4 +433,3 @@ void pcim_iounmap_regions(struct pci_dev *pdev, int mask) | |||
400 | } | 433 | } |
401 | EXPORT_SYMBOL(pcim_iounmap_regions); | 434 | EXPORT_SYMBOL(pcim_iounmap_regions); |
402 | #endif /* CONFIG_PCI */ | 435 | #endif /* CONFIG_PCI */ |
403 | #endif /* CONFIG_HAS_IOPORT */ | ||
diff --git a/lib/digsig.c b/lib/digsig.c index 8c0e62975c88..2f31e6a45f0a 100644 --- a/lib/digsig.c +++ b/lib/digsig.c | |||
@@ -30,11 +30,10 @@ | |||
30 | 30 | ||
31 | static struct crypto_shash *shash; | 31 | static struct crypto_shash *shash; |
32 | 32 | ||
33 | static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg, | 33 | static const char *pkcs_1_v1_5_decode_emsa(const unsigned char *msg, |
34 | unsigned long msglen, | 34 | unsigned long msglen, |
35 | unsigned long modulus_bitlen, | 35 | unsigned long modulus_bitlen, |
36 | unsigned char *out, | 36 | unsigned long *outlen) |
37 | unsigned long *outlen) | ||
38 | { | 37 | { |
39 | unsigned long modulus_len, ps_len, i; | 38 | unsigned long modulus_len, ps_len, i; |
40 | 39 | ||
@@ -42,11 +41,11 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg, | |||
42 | 41 | ||
43 | /* test message size */ | 42 | /* test message size */ |
44 | if ((msglen > modulus_len) || (modulus_len < 11)) | 43 | if ((msglen > modulus_len) || (modulus_len < 11)) |
45 | return -EINVAL; | 44 | return NULL; |
46 | 45 | ||
47 | /* separate encoded message */ | 46 | /* separate encoded message */ |
48 | if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1)) | 47 | if (msg[0] != 0x00 || msg[1] != 0x01) |
49 | return -EINVAL; | 48 | return NULL; |
50 | 49 | ||
51 | for (i = 2; i < modulus_len - 1; i++) | 50 | for (i = 2; i < modulus_len - 1; i++) |
52 | if (msg[i] != 0xFF) | 51 | if (msg[i] != 0xFF) |
@@ -56,19 +55,13 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg, | |||
56 | if (msg[i] != 0) | 55 | if (msg[i] != 0) |
57 | /* There was no octet with hexadecimal value 0x00 | 56 | /* There was no octet with hexadecimal value 0x00 |
58 | to separate ps from m. */ | 57 | to separate ps from m. */ |
59 | return -EINVAL; | 58 | return NULL; |
60 | 59 | ||
61 | ps_len = i - 2; | 60 | ps_len = i - 2; |
62 | 61 | ||
63 | if (*outlen < (msglen - (2 + ps_len + 1))) { | ||
64 | *outlen = msglen - (2 + ps_len + 1); | ||
65 | return -EOVERFLOW; | ||
66 | } | ||
67 | |||
68 | *outlen = (msglen - (2 + ps_len + 1)); | 62 | *outlen = (msglen - (2 + ps_len + 1)); |
69 | memcpy(out, &msg[2 + ps_len + 1], *outlen); | ||
70 | 63 | ||
71 | return 0; | 64 | return msg + 2 + ps_len + 1; |
72 | } | 65 | } |
73 | 66 | ||
74 | /* | 67 | /* |
@@ -83,7 +76,8 @@ static int digsig_verify_rsa(struct key *key, | |||
83 | unsigned long mlen, mblen; | 76 | unsigned long mlen, mblen; |
84 | unsigned nret, l; | 77 | unsigned nret, l; |
85 | int head, i; | 78 | int head, i; |
86 | unsigned char *out1 = NULL, *out2 = NULL; | 79 | unsigned char *out1 = NULL; |
80 | const char *m; | ||
87 | MPI in = NULL, res = NULL, pkey[2]; | 81 | MPI in = NULL, res = NULL, pkey[2]; |
88 | uint8_t *p, *datap, *endp; | 82 | uint8_t *p, *datap, *endp; |
89 | struct user_key_payload *ukp; | 83 | struct user_key_payload *ukp; |
@@ -120,7 +114,7 @@ static int digsig_verify_rsa(struct key *key, | |||
120 | } | 114 | } |
121 | 115 | ||
122 | mblen = mpi_get_nbits(pkey[0]); | 116 | mblen = mpi_get_nbits(pkey[0]); |
123 | mlen = (mblen + 7)/8; | 117 | mlen = DIV_ROUND_UP(mblen, 8); |
124 | 118 | ||
125 | if (mlen == 0) | 119 | if (mlen == 0) |
126 | goto err; | 120 | goto err; |
@@ -129,10 +123,6 @@ static int digsig_verify_rsa(struct key *key, | |||
129 | if (!out1) | 123 | if (!out1) |
130 | goto err; | 124 | goto err; |
131 | 125 | ||
132 | out2 = kzalloc(mlen, GFP_KERNEL); | ||
133 | if (!out2) | ||
134 | goto err; | ||
135 | |||
136 | nret = siglen; | 126 | nret = siglen; |
137 | in = mpi_read_from_buffer(sig, &nret); | 127 | in = mpi_read_from_buffer(sig, &nret); |
138 | if (!in) | 128 | if (!in) |
@@ -162,18 +152,17 @@ static int digsig_verify_rsa(struct key *key, | |||
162 | memset(out1, 0, head); | 152 | memset(out1, 0, head); |
163 | memcpy(out1 + head, p, l); | 153 | memcpy(out1 + head, p, l); |
164 | 154 | ||
165 | err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len); | 155 | kfree(p); |
166 | if (err) | 156 | |
167 | goto err; | 157 | m = pkcs_1_v1_5_decode_emsa(out1, len, mblen, &len); |
168 | 158 | ||
169 | if (len != hlen || memcmp(out2, h, hlen)) | 159 | if (!m || len != hlen || memcmp(m, h, hlen)) |
170 | err = -EINVAL; | 160 | err = -EINVAL; |
171 | 161 | ||
172 | err: | 162 | err: |
173 | mpi_free(in); | 163 | mpi_free(in); |
174 | mpi_free(res); | 164 | mpi_free(res); |
175 | kfree(out1); | 165 | kfree(out1); |
176 | kfree(out2); | ||
177 | while (--i >= 0) | 166 | while (--i >= 0) |
178 | mpi_free(pkey[i]); | 167 | mpi_free(pkey[i]); |
179 | err1: | 168 | err1: |
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index d84beb994f36..5e396accd3d0 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
@@ -45,6 +45,12 @@ enum { | |||
45 | dma_debug_coherent, | 45 | dma_debug_coherent, |
46 | }; | 46 | }; |
47 | 47 | ||
48 | enum map_err_types { | ||
49 | MAP_ERR_CHECK_NOT_APPLICABLE, | ||
50 | MAP_ERR_NOT_CHECKED, | ||
51 | MAP_ERR_CHECKED, | ||
52 | }; | ||
53 | |||
48 | #define DMA_DEBUG_STACKTRACE_ENTRIES 5 | 54 | #define DMA_DEBUG_STACKTRACE_ENTRIES 5 |
49 | 55 | ||
50 | struct dma_debug_entry { | 56 | struct dma_debug_entry { |
@@ -57,6 +63,7 @@ struct dma_debug_entry { | |||
57 | int direction; | 63 | int direction; |
58 | int sg_call_ents; | 64 | int sg_call_ents; |
59 | int sg_mapped_ents; | 65 | int sg_mapped_ents; |
66 | enum map_err_types map_err_type; | ||
60 | #ifdef CONFIG_STACKTRACE | 67 | #ifdef CONFIG_STACKTRACE |
61 | struct stack_trace stacktrace; | 68 | struct stack_trace stacktrace; |
62 | unsigned long st_entries[DMA_DEBUG_STACKTRACE_ENTRIES]; | 69 | unsigned long st_entries[DMA_DEBUG_STACKTRACE_ENTRIES]; |
@@ -114,6 +121,12 @@ static struct device_driver *current_driver __read_mostly; | |||
114 | 121 | ||
115 | static DEFINE_RWLOCK(driver_name_lock); | 122 | static DEFINE_RWLOCK(driver_name_lock); |
116 | 123 | ||
124 | static const char *const maperr2str[] = { | ||
125 | [MAP_ERR_CHECK_NOT_APPLICABLE] = "dma map error check not applicable", | ||
126 | [MAP_ERR_NOT_CHECKED] = "dma map error not checked", | ||
127 | [MAP_ERR_CHECKED] = "dma map error checked", | ||
128 | }; | ||
129 | |||
117 | static const char *type2name[4] = { "single", "page", | 130 | static const char *type2name[4] = { "single", "page", |
118 | "scather-gather", "coherent" }; | 131 | "scather-gather", "coherent" }; |
119 | 132 | ||
@@ -376,11 +389,12 @@ void debug_dma_dump_mappings(struct device *dev) | |||
376 | list_for_each_entry(entry, &bucket->list, list) { | 389 | list_for_each_entry(entry, &bucket->list, list) { |
377 | if (!dev || dev == entry->dev) { | 390 | if (!dev || dev == entry->dev) { |
378 | dev_info(entry->dev, | 391 | dev_info(entry->dev, |
379 | "%s idx %d P=%Lx D=%Lx L=%Lx %s\n", | 392 | "%s idx %d P=%Lx D=%Lx L=%Lx %s %s\n", |
380 | type2name[entry->type], idx, | 393 | type2name[entry->type], idx, |
381 | (unsigned long long)entry->paddr, | 394 | (unsigned long long)entry->paddr, |
382 | entry->dev_addr, entry->size, | 395 | entry->dev_addr, entry->size, |
383 | dir2name[entry->direction]); | 396 | dir2name[entry->direction], |
397 | maperr2str[entry->map_err_type]); | ||
384 | } | 398 | } |
385 | } | 399 | } |
386 | 400 | ||
@@ -844,16 +858,16 @@ static void check_unmap(struct dma_debug_entry *ref) | |||
844 | struct hash_bucket *bucket; | 858 | struct hash_bucket *bucket; |
845 | unsigned long flags; | 859 | unsigned long flags; |
846 | 860 | ||
847 | if (dma_mapping_error(ref->dev, ref->dev_addr)) { | ||
848 | err_printk(ref->dev, NULL, "DMA-API: device driver tries " | ||
849 | "to free an invalid DMA memory address\n"); | ||
850 | return; | ||
851 | } | ||
852 | |||
853 | bucket = get_hash_bucket(ref, &flags); | 861 | bucket = get_hash_bucket(ref, &flags); |
854 | entry = bucket_find_exact(bucket, ref); | 862 | entry = bucket_find_exact(bucket, ref); |
855 | 863 | ||
856 | if (!entry) { | 864 | if (!entry) { |
865 | if (dma_mapping_error(ref->dev, ref->dev_addr)) { | ||
866 | err_printk(ref->dev, NULL, | ||
867 | "DMA-API: device driver tries " | ||
868 | "to free an invalid DMA memory address\n"); | ||
869 | return; | ||
870 | } | ||
857 | err_printk(ref->dev, NULL, "DMA-API: device driver tries " | 871 | err_printk(ref->dev, NULL, "DMA-API: device driver tries " |
858 | "to free DMA memory it has not allocated " | 872 | "to free DMA memory it has not allocated " |
859 | "[device address=0x%016llx] [size=%llu bytes]\n", | 873 | "[device address=0x%016llx] [size=%llu bytes]\n", |
@@ -910,6 +924,15 @@ static void check_unmap(struct dma_debug_entry *ref) | |||
910 | dir2name[ref->direction]); | 924 | dir2name[ref->direction]); |
911 | } | 925 | } |
912 | 926 | ||
927 | if (entry->map_err_type == MAP_ERR_NOT_CHECKED) { | ||
928 | err_printk(ref->dev, entry, | ||
929 | "DMA-API: device driver failed to check map error" | ||
930 | "[device address=0x%016llx] [size=%llu bytes] " | ||
931 | "[mapped as %s]", | ||
932 | ref->dev_addr, ref->size, | ||
933 | type2name[entry->type]); | ||
934 | } | ||
935 | |||
913 | hash_bucket_del(entry); | 936 | hash_bucket_del(entry); |
914 | dma_entry_free(entry); | 937 | dma_entry_free(entry); |
915 | 938 | ||
@@ -1017,7 +1040,7 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, | |||
1017 | if (unlikely(global_disable)) | 1040 | if (unlikely(global_disable)) |
1018 | return; | 1041 | return; |
1019 | 1042 | ||
1020 | if (unlikely(dma_mapping_error(dev, dma_addr))) | 1043 | if (dma_mapping_error(dev, dma_addr)) |
1021 | return; | 1044 | return; |
1022 | 1045 | ||
1023 | entry = dma_entry_alloc(); | 1046 | entry = dma_entry_alloc(); |
@@ -1030,6 +1053,7 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, | |||
1030 | entry->dev_addr = dma_addr; | 1053 | entry->dev_addr = dma_addr; |
1031 | entry->size = size; | 1054 | entry->size = size; |
1032 | entry->direction = direction; | 1055 | entry->direction = direction; |
1056 | entry->map_err_type = MAP_ERR_NOT_CHECKED; | ||
1033 | 1057 | ||
1034 | if (map_single) | 1058 | if (map_single) |
1035 | entry->type = dma_debug_single; | 1059 | entry->type = dma_debug_single; |
@@ -1045,6 +1069,30 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, | |||
1045 | } | 1069 | } |
1046 | EXPORT_SYMBOL(debug_dma_map_page); | 1070 | EXPORT_SYMBOL(debug_dma_map_page); |
1047 | 1071 | ||
1072 | void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | ||
1073 | { | ||
1074 | struct dma_debug_entry ref; | ||
1075 | struct dma_debug_entry *entry; | ||
1076 | struct hash_bucket *bucket; | ||
1077 | unsigned long flags; | ||
1078 | |||
1079 | if (unlikely(global_disable)) | ||
1080 | return; | ||
1081 | |||
1082 | ref.dev = dev; | ||
1083 | ref.dev_addr = dma_addr; | ||
1084 | bucket = get_hash_bucket(&ref, &flags); | ||
1085 | entry = bucket_find_exact(bucket, &ref); | ||
1086 | |||
1087 | if (!entry) | ||
1088 | goto out; | ||
1089 | |||
1090 | entry->map_err_type = MAP_ERR_CHECKED; | ||
1091 | out: | ||
1092 | put_hash_bucket(bucket, &flags); | ||
1093 | } | ||
1094 | EXPORT_SYMBOL(debug_dma_mapping_error); | ||
1095 | |||
1048 | void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, | 1096 | void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, |
1049 | size_t size, int direction, bool map_single) | 1097 | size_t size, int direction, bool map_single) |
1050 | { | 1098 | { |
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index e7f7d993357a..5276b99ca650 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
@@ -59,16 +59,9 @@ struct ddebug_iter { | |||
59 | 59 | ||
60 | static DEFINE_MUTEX(ddebug_lock); | 60 | static DEFINE_MUTEX(ddebug_lock); |
61 | static LIST_HEAD(ddebug_tables); | 61 | static LIST_HEAD(ddebug_tables); |
62 | static int verbose = 0; | 62 | static int verbose; |
63 | module_param(verbose, int, 0644); | 63 | module_param(verbose, int, 0644); |
64 | 64 | ||
65 | /* Return the last part of a pathname */ | ||
66 | static inline const char *basename(const char *path) | ||
67 | { | ||
68 | const char *tail = strrchr(path, '/'); | ||
69 | return tail ? tail+1 : path; | ||
70 | } | ||
71 | |||
72 | /* Return the path relative to source root */ | 65 | /* Return the path relative to source root */ |
73 | static inline const char *trim_prefix(const char *path) | 66 | static inline const char *trim_prefix(const char *path) |
74 | { | 67 | { |
@@ -107,24 +100,32 @@ static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, | |||
107 | return buf; | 100 | return buf; |
108 | } | 101 | } |
109 | 102 | ||
110 | #define vpr_info(fmt, ...) \ | 103 | #define vpr_info(fmt, ...) \ |
111 | if (verbose) do { pr_info(fmt, ##__VA_ARGS__); } while (0) | ||
112 | |||
113 | #define vpr_info_dq(q, msg) \ | ||
114 | do { \ | 104 | do { \ |
115 | /* trim last char off format print */ \ | 105 | if (verbose) \ |
116 | vpr_info("%s: func=\"%s\" file=\"%s\" " \ | 106 | pr_info(fmt, ##__VA_ARGS__); \ |
117 | "module=\"%s\" format=\"%.*s\" " \ | ||
118 | "lineno=%u-%u", \ | ||
119 | msg, \ | ||
120 | q->function ? q->function : "", \ | ||
121 | q->filename ? q->filename : "", \ | ||
122 | q->module ? q->module : "", \ | ||
123 | (int)(q->format ? strlen(q->format) - 1 : 0), \ | ||
124 | q->format ? q->format : "", \ | ||
125 | q->first_lineno, q->last_lineno); \ | ||
126 | } while (0) | 107 | } while (0) |
127 | 108 | ||
109 | static void vpr_info_dq(const struct ddebug_query *query, const char *msg) | ||
110 | { | ||
111 | /* trim any trailing newlines */ | ||
112 | int fmtlen = 0; | ||
113 | |||
114 | if (query->format) { | ||
115 | fmtlen = strlen(query->format); | ||
116 | while (fmtlen && query->format[fmtlen - 1] == '\n') | ||
117 | fmtlen--; | ||
118 | } | ||
119 | |||
120 | vpr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n", | ||
121 | msg, | ||
122 | query->function ? query->function : "", | ||
123 | query->filename ? query->filename : "", | ||
124 | query->module ? query->module : "", | ||
125 | fmtlen, query->format ? query->format : "", | ||
126 | query->first_lineno, query->last_lineno); | ||
127 | } | ||
128 | |||
128 | /* | 129 | /* |
129 | * Search the tables for _ddebug's which match the given `query' and | 130 | * Search the tables for _ddebug's which match the given `query' and |
130 | * apply the `flags' and `mask' to them. Returns number of matching | 131 | * apply the `flags' and `mask' to them. Returns number of matching |
@@ -148,13 +149,13 @@ static int ddebug_change(const struct ddebug_query *query, | |||
148 | if (query->module && strcmp(query->module, dt->mod_name)) | 149 | if (query->module && strcmp(query->module, dt->mod_name)) |
149 | continue; | 150 | continue; |
150 | 151 | ||
151 | for (i = 0 ; i < dt->num_ddebugs ; i++) { | 152 | for (i = 0; i < dt->num_ddebugs; i++) { |
152 | struct _ddebug *dp = &dt->ddebugs[i]; | 153 | struct _ddebug *dp = &dt->ddebugs[i]; |
153 | 154 | ||
154 | /* match against the source filename */ | 155 | /* match against the source filename */ |
155 | if (query->filename && | 156 | if (query->filename && |
156 | strcmp(query->filename, dp->filename) && | 157 | strcmp(query->filename, dp->filename) && |
157 | strcmp(query->filename, basename(dp->filename)) && | 158 | strcmp(query->filename, kbasename(dp->filename)) && |
158 | strcmp(query->filename, trim_prefix(dp->filename))) | 159 | strcmp(query->filename, trim_prefix(dp->filename))) |
159 | continue; | 160 | continue; |
160 | 161 | ||
@@ -183,10 +184,10 @@ static int ddebug_change(const struct ddebug_query *query, | |||
183 | continue; | 184 | continue; |
184 | dp->flags = newflags; | 185 | dp->flags = newflags; |
185 | vpr_info("changed %s:%d [%s]%s =%s\n", | 186 | vpr_info("changed %s:%d [%s]%s =%s\n", |
186 | trim_prefix(dp->filename), dp->lineno, | 187 | trim_prefix(dp->filename), dp->lineno, |
187 | dt->mod_name, dp->function, | 188 | dt->mod_name, dp->function, |
188 | ddebug_describe_flags(dp, flagbuf, | 189 | ddebug_describe_flags(dp, flagbuf, |
189 | sizeof(flagbuf))); | 190 | sizeof(flagbuf))); |
190 | } | 191 | } |
191 | } | 192 | } |
192 | mutex_unlock(&ddebug_lock); | 193 | mutex_unlock(&ddebug_lock); |
@@ -220,19 +221,23 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords) | |||
220 | /* find `end' of word, whitespace separated or quoted */ | 221 | /* find `end' of word, whitespace separated or quoted */ |
221 | if (*buf == '"' || *buf == '\'') { | 222 | if (*buf == '"' || *buf == '\'') { |
222 | int quote = *buf++; | 223 | int quote = *buf++; |
223 | for (end = buf ; *end && *end != quote ; end++) | 224 | for (end = buf; *end && *end != quote; end++) |
224 | ; | 225 | ; |
225 | if (!*end) | 226 | if (!*end) { |
227 | pr_err("unclosed quote: %s\n", buf); | ||
226 | return -EINVAL; /* unclosed quote */ | 228 | return -EINVAL; /* unclosed quote */ |
229 | } | ||
227 | } else { | 230 | } else { |
228 | for (end = buf ; *end && !isspace(*end) ; end++) | 231 | for (end = buf; *end && !isspace(*end); end++) |
229 | ; | 232 | ; |
230 | BUG_ON(end == buf); | 233 | BUG_ON(end == buf); |
231 | } | 234 | } |
232 | 235 | ||
233 | /* `buf' is start of word, `end' is one past its end */ | 236 | /* `buf' is start of word, `end' is one past its end */ |
234 | if (nwords == maxwords) | 237 | if (nwords == maxwords) { |
238 | pr_err("too many words, legal max <=%d\n", maxwords); | ||
235 | return -EINVAL; /* ran out of words[] before bytes */ | 239 | return -EINVAL; /* ran out of words[] before bytes */ |
240 | } | ||
236 | if (*end) | 241 | if (*end) |
237 | *end++ = '\0'; /* terminate the word */ | 242 | *end++ = '\0'; /* terminate the word */ |
238 | words[nwords++] = buf; | 243 | words[nwords++] = buf; |
@@ -242,7 +247,7 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords) | |||
242 | if (verbose) { | 247 | if (verbose) { |
243 | int i; | 248 | int i; |
244 | pr_info("split into words:"); | 249 | pr_info("split into words:"); |
245 | for (i = 0 ; i < nwords ; i++) | 250 | for (i = 0; i < nwords; i++) |
246 | pr_cont(" \"%s\"", words[i]); | 251 | pr_cont(" \"%s\"", words[i]); |
247 | pr_cont("\n"); | 252 | pr_cont("\n"); |
248 | } | 253 | } |
@@ -264,7 +269,11 @@ static inline int parse_lineno(const char *str, unsigned int *val) | |||
264 | return 0; | 269 | return 0; |
265 | } | 270 | } |
266 | *val = simple_strtoul(str, &end, 10); | 271 | *val = simple_strtoul(str, &end, 10); |
267 | return end == NULL || end == str || *end != '\0' ? -EINVAL : 0; | 272 | if (end == NULL || end == str || *end != '\0') { |
273 | pr_err("bad line-number: %s\n", str); | ||
274 | return -EINVAL; | ||
275 | } | ||
276 | return 0; | ||
268 | } | 277 | } |
269 | 278 | ||
270 | /* | 279 | /* |
@@ -293,11 +302,11 @@ static char *unescape(char *str) | |||
293 | in += 2; | 302 | in += 2; |
294 | continue; | 303 | continue; |
295 | } else if (isodigit(in[1]) && | 304 | } else if (isodigit(in[1]) && |
296 | isodigit(in[2]) && | 305 | isodigit(in[2]) && |
297 | isodigit(in[3])) { | 306 | isodigit(in[3])) { |
298 | *out++ = ((in[1] - '0')<<6) | | 307 | *out++ = (((in[1] - '0') << 6) | |
299 | ((in[2] - '0')<<3) | | 308 | ((in[2] - '0') << 3) | |
300 | (in[3] - '0'); | 309 | (in[3] - '0')); |
301 | in += 4; | 310 | in += 4; |
302 | continue; | 311 | continue; |
303 | } | 312 | } |
@@ -315,8 +324,8 @@ static int check_set(const char **dest, char *src, char *name) | |||
315 | 324 | ||
316 | if (*dest) { | 325 | if (*dest) { |
317 | rc = -EINVAL; | 326 | rc = -EINVAL; |
318 | pr_err("match-spec:%s val:%s overridden by %s", | 327 | pr_err("match-spec:%s val:%s overridden by %s\n", |
319 | name, *dest, src); | 328 | name, *dest, src); |
320 | } | 329 | } |
321 | *dest = src; | 330 | *dest = src; |
322 | return rc; | 331 | return rc; |
@@ -344,40 +353,46 @@ static int ddebug_parse_query(char *words[], int nwords, | |||
344 | int rc; | 353 | int rc; |
345 | 354 | ||
346 | /* check we have an even number of words */ | 355 | /* check we have an even number of words */ |
347 | if (nwords % 2 != 0) | 356 | if (nwords % 2 != 0) { |
357 | pr_err("expecting pairs of match-spec <value>\n"); | ||
348 | return -EINVAL; | 358 | return -EINVAL; |
359 | } | ||
349 | memset(query, 0, sizeof(*query)); | 360 | memset(query, 0, sizeof(*query)); |
350 | 361 | ||
351 | if (modname) | 362 | if (modname) |
352 | /* support $modname.dyndbg=<multiple queries> */ | 363 | /* support $modname.dyndbg=<multiple queries> */ |
353 | query->module = modname; | 364 | query->module = modname; |
354 | 365 | ||
355 | for (i = 0 ; i < nwords ; i += 2) { | 366 | for (i = 0; i < nwords; i += 2) { |
356 | if (!strcmp(words[i], "func")) | 367 | if (!strcmp(words[i], "func")) { |
357 | rc = check_set(&query->function, words[i+1], "func"); | 368 | rc = check_set(&query->function, words[i+1], "func"); |
358 | else if (!strcmp(words[i], "file")) | 369 | } else if (!strcmp(words[i], "file")) { |
359 | rc = check_set(&query->filename, words[i+1], "file"); | 370 | rc = check_set(&query->filename, words[i+1], "file"); |
360 | else if (!strcmp(words[i], "module")) | 371 | } else if (!strcmp(words[i], "module")) { |
361 | rc = check_set(&query->module, words[i+1], "module"); | 372 | rc = check_set(&query->module, words[i+1], "module"); |
362 | else if (!strcmp(words[i], "format")) | 373 | } else if (!strcmp(words[i], "format")) { |
363 | rc = check_set(&query->format, unescape(words[i+1]), | 374 | rc = check_set(&query->format, unescape(words[i+1]), |
364 | "format"); | 375 | "format"); |
365 | else if (!strcmp(words[i], "line")) { | 376 | } else if (!strcmp(words[i], "line")) { |
366 | char *first = words[i+1]; | 377 | char *first = words[i+1]; |
367 | char *last = strchr(first, '-'); | 378 | char *last = strchr(first, '-'); |
368 | if (query->first_lineno || query->last_lineno) { | 379 | if (query->first_lineno || query->last_lineno) { |
369 | pr_err("match-spec:line given 2 times\n"); | 380 | pr_err("match-spec: line used 2x\n"); |
370 | return -EINVAL; | 381 | return -EINVAL; |
371 | } | 382 | } |
372 | if (last) | 383 | if (last) |
373 | *last++ = '\0'; | 384 | *last++ = '\0'; |
374 | if (parse_lineno(first, &query->first_lineno) < 0) | 385 | if (parse_lineno(first, &query->first_lineno) < 0) { |
386 | pr_err("line-number is <0\n"); | ||
375 | return -EINVAL; | 387 | return -EINVAL; |
388 | } | ||
376 | if (last) { | 389 | if (last) { |
377 | /* range <first>-<last> */ | 390 | /* range <first>-<last> */ |
378 | if (parse_lineno(last, &query->last_lineno) | 391 | if (parse_lineno(last, &query->last_lineno) |
379 | < query->first_lineno) { | 392 | < query->first_lineno) { |
380 | pr_err("last-line < 1st-line\n"); | 393 | pr_err("last-line:%d < 1st-line:%d\n", |
394 | query->last_lineno, | ||
395 | query->first_lineno); | ||
381 | return -EINVAL; | 396 | return -EINVAL; |
382 | } | 397 | } |
383 | } else { | 398 | } else { |
@@ -413,19 +428,22 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
413 | op = *str++; | 428 | op = *str++; |
414 | break; | 429 | break; |
415 | default: | 430 | default: |
431 | pr_err("bad flag-op %c, at start of %s\n", *str, str); | ||
416 | return -EINVAL; | 432 | return -EINVAL; |
417 | } | 433 | } |
418 | vpr_info("op='%c'\n", op); | 434 | vpr_info("op='%c'\n", op); |
419 | 435 | ||
420 | for ( ; *str ; ++str) { | 436 | for (; *str ; ++str) { |
421 | for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { | 437 | for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { |
422 | if (*str == opt_array[i].opt_char) { | 438 | if (*str == opt_array[i].opt_char) { |
423 | flags |= opt_array[i].flag; | 439 | flags |= opt_array[i].flag; |
424 | break; | 440 | break; |
425 | } | 441 | } |
426 | } | 442 | } |
427 | if (i < 0) | 443 | if (i < 0) { |
444 | pr_err("unknown flag '%c' in \"%s\"\n", *str, str); | ||
428 | return -EINVAL; | 445 | return -EINVAL; |
446 | } | ||
429 | } | 447 | } |
430 | vpr_info("flags=0x%x\n", flags); | 448 | vpr_info("flags=0x%x\n", flags); |
431 | 449 | ||
@@ -457,16 +475,22 @@ static int ddebug_exec_query(char *query_string, const char *modname) | |||
457 | char *words[MAXWORDS]; | 475 | char *words[MAXWORDS]; |
458 | 476 | ||
459 | nwords = ddebug_tokenize(query_string, words, MAXWORDS); | 477 | nwords = ddebug_tokenize(query_string, words, MAXWORDS); |
460 | if (nwords <= 0) | 478 | if (nwords <= 0) { |
479 | pr_err("tokenize failed\n"); | ||
461 | return -EINVAL; | 480 | return -EINVAL; |
462 | if (ddebug_parse_query(words, nwords-1, &query, modname)) | 481 | } |
482 | /* check flags 1st (last arg) so query is pairs of spec,val */ | ||
483 | if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) { | ||
484 | pr_err("flags parse failed\n"); | ||
463 | return -EINVAL; | 485 | return -EINVAL; |
464 | if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) | 486 | } |
487 | if (ddebug_parse_query(words, nwords-1, &query, modname)) { | ||
488 | pr_err("query parse failed\n"); | ||
465 | return -EINVAL; | 489 | return -EINVAL; |
466 | 490 | } | |
467 | /* actually go and implement the change */ | 491 | /* actually go and implement the change */ |
468 | nfound = ddebug_change(&query, flags, mask); | 492 | nfound = ddebug_change(&query, flags, mask); |
469 | vpr_info_dq((&query), (nfound) ? "applied" : "no-match"); | 493 | vpr_info_dq(&query, nfound ? "applied" : "no-match"); |
470 | 494 | ||
471 | return nfound; | 495 | return nfound; |
472 | } | 496 | } |
@@ -495,8 +519,9 @@ static int ddebug_exec_queries(char *query, const char *modname) | |||
495 | if (rc < 0) { | 519 | if (rc < 0) { |
496 | errs++; | 520 | errs++; |
497 | exitcode = rc; | 521 | exitcode = rc; |
498 | } else | 522 | } else { |
499 | nfound += rc; | 523 | nfound += rc; |
524 | } | ||
500 | i++; | 525 | i++; |
501 | } | 526 | } |
502 | vpr_info("processed %d queries, with %d matches, %d errs\n", | 527 | vpr_info("processed %d queries, with %d matches, %d errs\n", |
@@ -772,7 +797,7 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos) | |||
772 | struct _ddebug *dp; | 797 | struct _ddebug *dp; |
773 | 798 | ||
774 | vpr_info("called m=%p p=%p *pos=%lld\n", | 799 | vpr_info("called m=%p p=%p *pos=%lld\n", |
775 | m, p, (unsigned long long)*pos); | 800 | m, p, (unsigned long long)*pos); |
776 | 801 | ||
777 | if (p == SEQ_START_TOKEN) | 802 | if (p == SEQ_START_TOKEN) |
778 | dp = ddebug_iter_first(iter); | 803 | dp = ddebug_iter_first(iter); |
@@ -798,14 +823,14 @@ static int ddebug_proc_show(struct seq_file *m, void *p) | |||
798 | 823 | ||
799 | if (p == SEQ_START_TOKEN) { | 824 | if (p == SEQ_START_TOKEN) { |
800 | seq_puts(m, | 825 | seq_puts(m, |
801 | "# filename:lineno [module]function flags format\n"); | 826 | "# filename:lineno [module]function flags format\n"); |
802 | return 0; | 827 | return 0; |
803 | } | 828 | } |
804 | 829 | ||
805 | seq_printf(m, "%s:%u [%s]%s =%s \"", | 830 | seq_printf(m, "%s:%u [%s]%s =%s \"", |
806 | trim_prefix(dp->filename), dp->lineno, | 831 | trim_prefix(dp->filename), dp->lineno, |
807 | iter->table->mod_name, dp->function, | 832 | iter->table->mod_name, dp->function, |
808 | ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf))); | 833 | ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf))); |
809 | seq_escape(m, dp->format, "\t\r\n\""); | 834 | seq_escape(m, dp->format, "\t\r\n\""); |
810 | seq_puts(m, "\"\n"); | 835 | seq_puts(m, "\"\n"); |
811 | 836 | ||
@@ -852,7 +877,7 @@ static int ddebug_proc_open(struct inode *inode, struct file *file) | |||
852 | kfree(iter); | 877 | kfree(iter); |
853 | return err; | 878 | return err; |
854 | } | 879 | } |
855 | ((struct seq_file *) file->private_data)->private = iter; | 880 | ((struct seq_file *)file->private_data)->private = iter; |
856 | return 0; | 881 | return 0; |
857 | } | 882 | } |
858 | 883 | ||
@@ -1009,8 +1034,7 @@ static int __init dynamic_debug_init(void) | |||
1009 | int verbose_bytes = 0; | 1034 | int verbose_bytes = 0; |
1010 | 1035 | ||
1011 | if (__start___verbose == __stop___verbose) { | 1036 | if (__start___verbose == __stop___verbose) { |
1012 | pr_warn("_ddebug table is empty in a " | 1037 | pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n"); |
1013 | "CONFIG_DYNAMIC_DEBUG build"); | ||
1014 | return 1; | 1038 | return 1; |
1015 | } | 1039 | } |
1016 | iter = __start___verbose; | 1040 | iter = __start___verbose; |
@@ -1037,18 +1061,16 @@ static int __init dynamic_debug_init(void) | |||
1037 | goto out_err; | 1061 | goto out_err; |
1038 | 1062 | ||
1039 | ddebug_init_success = 1; | 1063 | ddebug_init_success = 1; |
1040 | vpr_info("%d modules, %d entries and %d bytes in ddebug tables," | 1064 | vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in (readonly) verbose section\n", |
1041 | " %d bytes in (readonly) verbose section\n", | 1065 | modct, entries, (int)(modct * sizeof(struct ddebug_table)), |
1042 | modct, entries, (int)( modct * sizeof(struct ddebug_table)), | 1066 | verbose_bytes + (int)(__stop___verbose - __start___verbose)); |
1043 | verbose_bytes + (int)(__stop___verbose - __start___verbose)); | ||
1044 | 1067 | ||
1045 | /* apply ddebug_query boot param, dont unload tables on err */ | 1068 | /* apply ddebug_query boot param, dont unload tables on err */ |
1046 | if (ddebug_setup_string[0] != '\0') { | 1069 | if (ddebug_setup_string[0] != '\0') { |
1047 | pr_warn("ddebug_query param name is deprecated," | 1070 | pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n"); |
1048 | " change it to dyndbg\n"); | ||
1049 | ret = ddebug_exec_queries(ddebug_setup_string, NULL); | 1071 | ret = ddebug_exec_queries(ddebug_setup_string, NULL); |
1050 | if (ret < 0) | 1072 | if (ret < 0) |
1051 | pr_warn("Invalid ddebug boot param %s", | 1073 | pr_warn("Invalid ddebug boot param %s\n", |
1052 | ddebug_setup_string); | 1074 | ddebug_setup_string); |
1053 | else | 1075 | else |
1054 | pr_info("%d changes by ddebug_query\n", ret); | 1076 | pr_info("%d changes by ddebug_query\n", ret); |
diff --git a/lib/earlycpio.c b/lib/earlycpio.c new file mode 100644 index 000000000000..8078ef49cb79 --- /dev/null +++ b/lib/earlycpio.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* ----------------------------------------------------------------------- * | ||
2 | * | ||
3 | * Copyright 2012 Intel Corporation; author H. Peter Anvin | ||
4 | * | ||
5 | * This file is part of the Linux kernel, and is made available | ||
6 | * under the terms of the GNU General Public License version 2, as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | * | ||
14 | * ----------------------------------------------------------------------- */ | ||
15 | |||
16 | /* | ||
17 | * earlycpio.c | ||
18 | * | ||
19 | * Find a specific cpio member; must precede any compressed content. | ||
20 | * This is used to locate data items in the initramfs used by the | ||
21 | * kernel itself during early boot (before the main initramfs is | ||
22 | * decompressed.) It is the responsibility of the initramfs creator | ||
23 | * to ensure that these items are uncompressed at the head of the | ||
24 | * blob. Depending on the boot loader or package tool that may be a | ||
25 | * separate file or part of the same file. | ||
26 | */ | ||
27 | |||
28 | #include <linux/earlycpio.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/string.h> | ||
31 | |||
32 | enum cpio_fields { | ||
33 | C_MAGIC, | ||
34 | C_INO, | ||
35 | C_MODE, | ||
36 | C_UID, | ||
37 | C_GID, | ||
38 | C_NLINK, | ||
39 | C_MTIME, | ||
40 | C_FILESIZE, | ||
41 | C_MAJ, | ||
42 | C_MIN, | ||
43 | C_RMAJ, | ||
44 | C_RMIN, | ||
45 | C_NAMESIZE, | ||
46 | C_CHKSUM, | ||
47 | C_NFIELDS | ||
48 | }; | ||
49 | |||
50 | /** | ||
51 | * cpio_data find_cpio_data - Search for files in an uncompressed cpio | ||
52 | * @path: The directory to search for, including a slash at the end | ||
53 | * @data: Pointer to the the cpio archive or a header inside | ||
54 | * @len: Remaining length of the cpio based on data pointer | ||
55 | * @offset: When a matching file is found, this is the offset to the | ||
56 | * beginning of the cpio. It can be used to iterate through | ||
57 | * the cpio to find all files inside of a directory path | ||
58 | * | ||
59 | * @return: struct cpio_data containing the address, length and | ||
60 | * filename (with the directory path cut off) of the found file. | ||
61 | * If you search for a filename and not for files in a directory, | ||
62 | * pass the absolute path of the filename in the cpio and make sure | ||
63 | * the match returned an empty filename string. | ||
64 | */ | ||
65 | |||
66 | struct cpio_data __cpuinit find_cpio_data(const char *path, void *data, | ||
67 | size_t len, long *offset) | ||
68 | { | ||
69 | const size_t cpio_header_len = 8*C_NFIELDS - 2; | ||
70 | struct cpio_data cd = { NULL, 0, "" }; | ||
71 | const char *p, *dptr, *nptr; | ||
72 | unsigned int ch[C_NFIELDS], *chp, v; | ||
73 | unsigned char c, x; | ||
74 | size_t mypathsize = strlen(path); | ||
75 | int i, j; | ||
76 | |||
77 | p = data; | ||
78 | |||
79 | while (len > cpio_header_len) { | ||
80 | if (!*p) { | ||
81 | /* All cpio headers need to be 4-byte aligned */ | ||
82 | p += 4; | ||
83 | len -= 4; | ||
84 | continue; | ||
85 | } | ||
86 | |||
87 | j = 6; /* The magic field is only 6 characters */ | ||
88 | chp = ch; | ||
89 | for (i = C_NFIELDS; i; i--) { | ||
90 | v = 0; | ||
91 | while (j--) { | ||
92 | v <<= 4; | ||
93 | c = *p++; | ||
94 | |||
95 | x = c - '0'; | ||
96 | if (x < 10) { | ||
97 | v += x; | ||
98 | continue; | ||
99 | } | ||
100 | |||
101 | x = (c | 0x20) - 'a'; | ||
102 | if (x < 6) { | ||
103 | v += x + 10; | ||
104 | continue; | ||
105 | } | ||
106 | |||
107 | goto quit; /* Invalid hexadecimal */ | ||
108 | } | ||
109 | *chp++ = v; | ||
110 | j = 8; /* All other fields are 8 characters */ | ||
111 | } | ||
112 | |||
113 | if ((ch[C_MAGIC] - 0x070701) > 1) | ||
114 | goto quit; /* Invalid magic */ | ||
115 | |||
116 | len -= cpio_header_len; | ||
117 | |||
118 | dptr = PTR_ALIGN(p + ch[C_NAMESIZE], 4); | ||
119 | nptr = PTR_ALIGN(dptr + ch[C_FILESIZE], 4); | ||
120 | |||
121 | if (nptr > p + len || dptr < p || nptr < dptr) | ||
122 | goto quit; /* Buffer overrun */ | ||
123 | |||
124 | if ((ch[C_MODE] & 0170000) == 0100000 && | ||
125 | ch[C_NAMESIZE] >= mypathsize && | ||
126 | !memcmp(p, path, mypathsize)) { | ||
127 | *offset = (long)nptr - (long)data; | ||
128 | if (ch[C_NAMESIZE] - mypathsize >= MAX_CPIO_FILE_NAME) { | ||
129 | pr_warn( | ||
130 | "File %s exceeding MAX_CPIO_FILE_NAME [%d]\n", | ||
131 | p, MAX_CPIO_FILE_NAME); | ||
132 | } | ||
133 | strlcpy(cd.name, p + mypathsize, MAX_CPIO_FILE_NAME); | ||
134 | |||
135 | cd.data = (void *)dptr; | ||
136 | cd.size = ch[C_FILESIZE]; | ||
137 | return cd; /* Found it! */ | ||
138 | } | ||
139 | len -= (nptr - p); | ||
140 | p = nptr; | ||
141 | } | ||
142 | |||
143 | quit: | ||
144 | return cd; | ||
145 | } | ||
diff --git a/lib/hexdump.c b/lib/hexdump.c index 6540d657dca4..3f0494c9d57a 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c | |||
@@ -227,6 +227,7 @@ void print_hex_dump(const char *level, const char *prefix_str, int prefix_type, | |||
227 | } | 227 | } |
228 | EXPORT_SYMBOL(print_hex_dump); | 228 | EXPORT_SYMBOL(print_hex_dump); |
229 | 229 | ||
230 | #if !defined(CONFIG_DYNAMIC_DEBUG) | ||
230 | /** | 231 | /** |
231 | * print_hex_dump_bytes - shorthand form of print_hex_dump() with default params | 232 | * print_hex_dump_bytes - shorthand form of print_hex_dump() with default params |
232 | * @prefix_str: string to prefix each line with; | 233 | * @prefix_str: string to prefix each line with; |
@@ -246,4 +247,5 @@ void print_hex_dump_bytes(const char *prefix_str, int prefix_type, | |||
246 | buf, len, true); | 247 | buf, len, true); |
247 | } | 248 | } |
248 | EXPORT_SYMBOL(print_hex_dump_bytes); | 249 | EXPORT_SYMBOL(print_hex_dump_bytes); |
249 | #endif | 250 | #endif /* !defined(CONFIG_DYNAMIC_DEBUG) */ |
251 | #endif /* defined(CONFIG_PRINTK) */ | ||
@@ -35,10 +35,41 @@ | |||
35 | #include <linux/string.h> | 35 | #include <linux/string.h> |
36 | #include <linux/idr.h> | 36 | #include <linux/idr.h> |
37 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
38 | #include <linux/percpu.h> | ||
39 | #include <linux/hardirq.h> | ||
40 | |||
41 | #define MAX_IDR_SHIFT (sizeof(int) * 8 - 1) | ||
42 | #define MAX_IDR_BIT (1U << MAX_IDR_SHIFT) | ||
43 | |||
44 | /* Leave the possibility of an incomplete final layer */ | ||
45 | #define MAX_IDR_LEVEL ((MAX_IDR_SHIFT + IDR_BITS - 1) / IDR_BITS) | ||
46 | |||
47 | /* Number of id_layer structs to leave in free list */ | ||
48 | #define MAX_IDR_FREE (MAX_IDR_LEVEL * 2) | ||
38 | 49 | ||
39 | static struct kmem_cache *idr_layer_cache; | 50 | static struct kmem_cache *idr_layer_cache; |
51 | static DEFINE_PER_CPU(struct idr_layer *, idr_preload_head); | ||
52 | static DEFINE_PER_CPU(int, idr_preload_cnt); | ||
40 | static DEFINE_SPINLOCK(simple_ida_lock); | 53 | static DEFINE_SPINLOCK(simple_ida_lock); |
41 | 54 | ||
55 | /* the maximum ID which can be allocated given idr->layers */ | ||
56 | static int idr_max(int layers) | ||
57 | { | ||
58 | int bits = min_t(int, layers * IDR_BITS, MAX_IDR_SHIFT); | ||
59 | |||
60 | return (1 << bits) - 1; | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * Prefix mask for an idr_layer at @layer. For layer 0, the prefix mask is | ||
65 | * all bits except for the lower IDR_BITS. For layer 1, 2 * IDR_BITS, and | ||
66 | * so on. | ||
67 | */ | ||
68 | static int idr_layer_prefix_mask(int layer) | ||
69 | { | ||
70 | return ~idr_max(layer + 1); | ||
71 | } | ||
72 | |||
42 | static struct idr_layer *get_from_free_list(struct idr *idp) | 73 | static struct idr_layer *get_from_free_list(struct idr *idp) |
43 | { | 74 | { |
44 | struct idr_layer *p; | 75 | struct idr_layer *p; |
@@ -54,6 +85,62 @@ static struct idr_layer *get_from_free_list(struct idr *idp) | |||
54 | return(p); | 85 | return(p); |
55 | } | 86 | } |
56 | 87 | ||
88 | /** | ||
89 | * idr_layer_alloc - allocate a new idr_layer | ||
90 | * @gfp_mask: allocation mask | ||
91 | * @layer_idr: optional idr to allocate from | ||
92 | * | ||
93 | * If @layer_idr is %NULL, directly allocate one using @gfp_mask or fetch | ||
94 | * one from the per-cpu preload buffer. If @layer_idr is not %NULL, fetch | ||
95 | * an idr_layer from @idr->id_free. | ||
96 | * | ||
97 | * @layer_idr is to maintain backward compatibility with the old alloc | ||
98 | * interface - idr_pre_get() and idr_get_new*() - and will be removed | ||
99 | * together with per-pool preload buffer. | ||
100 | */ | ||
101 | static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr) | ||
102 | { | ||
103 | struct idr_layer *new; | ||
104 | |||
105 | /* this is the old path, bypass to get_from_free_list() */ | ||
106 | if (layer_idr) | ||
107 | return get_from_free_list(layer_idr); | ||
108 | |||
109 | /* | ||
110 | * Try to allocate directly from kmem_cache. We want to try this | ||
111 | * before preload buffer; otherwise, non-preloading idr_alloc() | ||
112 | * users will end up taking advantage of preloading ones. As the | ||
113 | * following is allowed to fail for preloaded cases, suppress | ||
114 | * warning this time. | ||
115 | */ | ||
116 | new = kmem_cache_zalloc(idr_layer_cache, gfp_mask | __GFP_NOWARN); | ||
117 | if (new) | ||
118 | return new; | ||
119 | |||
120 | /* | ||
121 | * Try to fetch one from the per-cpu preload buffer if in process | ||
122 | * context. See idr_preload() for details. | ||
123 | */ | ||
124 | if (!in_interrupt()) { | ||
125 | preempt_disable(); | ||
126 | new = __this_cpu_read(idr_preload_head); | ||
127 | if (new) { | ||
128 | __this_cpu_write(idr_preload_head, new->ary[0]); | ||
129 | __this_cpu_dec(idr_preload_cnt); | ||
130 | new->ary[0] = NULL; | ||
131 | } | ||
132 | preempt_enable(); | ||
133 | if (new) | ||
134 | return new; | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * Both failed. Try kmem_cache again w/o adding __GFP_NOWARN so | ||
139 | * that memory allocation failure warning is printed as intended. | ||
140 | */ | ||
141 | return kmem_cache_zalloc(idr_layer_cache, gfp_mask); | ||
142 | } | ||
143 | |||
57 | static void idr_layer_rcu_free(struct rcu_head *head) | 144 | static void idr_layer_rcu_free(struct rcu_head *head) |
58 | { | 145 | { |
59 | struct idr_layer *layer; | 146 | struct idr_layer *layer; |
@@ -62,8 +149,10 @@ static void idr_layer_rcu_free(struct rcu_head *head) | |||
62 | kmem_cache_free(idr_layer_cache, layer); | 149 | kmem_cache_free(idr_layer_cache, layer); |
63 | } | 150 | } |
64 | 151 | ||
65 | static inline void free_layer(struct idr_layer *p) | 152 | static inline void free_layer(struct idr *idr, struct idr_layer *p) |
66 | { | 153 | { |
154 | if (idr->hint && idr->hint == p) | ||
155 | RCU_INIT_POINTER(idr->hint, NULL); | ||
67 | call_rcu(&p->rcu_head, idr_layer_rcu_free); | 156 | call_rcu(&p->rcu_head, idr_layer_rcu_free); |
68 | } | 157 | } |
69 | 158 | ||
@@ -92,35 +181,22 @@ static void idr_mark_full(struct idr_layer **pa, int id) | |||
92 | struct idr_layer *p = pa[0]; | 181 | struct idr_layer *p = pa[0]; |
93 | int l = 0; | 182 | int l = 0; |
94 | 183 | ||
95 | __set_bit(id & IDR_MASK, &p->bitmap); | 184 | __set_bit(id & IDR_MASK, p->bitmap); |
96 | /* | 185 | /* |
97 | * If this layer is full mark the bit in the layer above to | 186 | * If this layer is full mark the bit in the layer above to |
98 | * show that this part of the radix tree is full. This may | 187 | * show that this part of the radix tree is full. This may |
99 | * complete the layer above and require walking up the radix | 188 | * complete the layer above and require walking up the radix |
100 | * tree. | 189 | * tree. |
101 | */ | 190 | */ |
102 | while (p->bitmap == IDR_FULL) { | 191 | while (bitmap_full(p->bitmap, IDR_SIZE)) { |
103 | if (!(p = pa[++l])) | 192 | if (!(p = pa[++l])) |
104 | break; | 193 | break; |
105 | id = id >> IDR_BITS; | 194 | id = id >> IDR_BITS; |
106 | __set_bit((id & IDR_MASK), &p->bitmap); | 195 | __set_bit((id & IDR_MASK), p->bitmap); |
107 | } | 196 | } |
108 | } | 197 | } |
109 | 198 | ||
110 | /** | 199 | int __idr_pre_get(struct idr *idp, gfp_t gfp_mask) |
111 | * idr_pre_get - reserve resources for idr allocation | ||
112 | * @idp: idr handle | ||
113 | * @gfp_mask: memory allocation flags | ||
114 | * | ||
115 | * This function should be called prior to calling the idr_get_new* functions. | ||
116 | * It preallocates enough memory to satisfy the worst possible allocation. The | ||
117 | * caller should pass in GFP_KERNEL if possible. This of course requires that | ||
118 | * no spinning locks be held. | ||
119 | * | ||
120 | * If the system is REALLY out of memory this function returns %0, | ||
121 | * otherwise %1. | ||
122 | */ | ||
123 | int idr_pre_get(struct idr *idp, gfp_t gfp_mask) | ||
124 | { | 200 | { |
125 | while (idp->id_free_cnt < MAX_IDR_FREE) { | 201 | while (idp->id_free_cnt < MAX_IDR_FREE) { |
126 | struct idr_layer *new; | 202 | struct idr_layer *new; |
@@ -131,14 +207,30 @@ int idr_pre_get(struct idr *idp, gfp_t gfp_mask) | |||
131 | } | 207 | } |
132 | return 1; | 208 | return 1; |
133 | } | 209 | } |
134 | EXPORT_SYMBOL(idr_pre_get); | 210 | EXPORT_SYMBOL(__idr_pre_get); |
135 | 211 | ||
136 | static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa) | 212 | /** |
213 | * sub_alloc - try to allocate an id without growing the tree depth | ||
214 | * @idp: idr handle | ||
215 | * @starting_id: id to start search at | ||
216 | * @pa: idr_layer[MAX_IDR_LEVEL] used as backtrack buffer | ||
217 | * @gfp_mask: allocation mask for idr_layer_alloc() | ||
218 | * @layer_idr: optional idr passed to idr_layer_alloc() | ||
219 | * | ||
220 | * Allocate an id in range [@starting_id, INT_MAX] from @idp without | ||
221 | * growing its depth. Returns | ||
222 | * | ||
223 | * the allocated id >= 0 if successful, | ||
224 | * -EAGAIN if the tree needs to grow for allocation to succeed, | ||
225 | * -ENOSPC if the id space is exhausted, | ||
226 | * -ENOMEM if more idr_layers need to be allocated. | ||
227 | */ | ||
228 | static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa, | ||
229 | gfp_t gfp_mask, struct idr *layer_idr) | ||
137 | { | 230 | { |
138 | int n, m, sh; | 231 | int n, m, sh; |
139 | struct idr_layer *p, *new; | 232 | struct idr_layer *p, *new; |
140 | int l, id, oid; | 233 | int l, id, oid; |
141 | unsigned long bm; | ||
142 | 234 | ||
143 | id = *starting_id; | 235 | id = *starting_id; |
144 | restart: | 236 | restart: |
@@ -150,8 +242,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa) | |||
150 | * We run around this while until we reach the leaf node... | 242 | * We run around this while until we reach the leaf node... |
151 | */ | 243 | */ |
152 | n = (id >> (IDR_BITS*l)) & IDR_MASK; | 244 | n = (id >> (IDR_BITS*l)) & IDR_MASK; |
153 | bm = ~p->bitmap; | 245 | m = find_next_zero_bit(p->bitmap, IDR_SIZE, n); |
154 | m = find_next_bit(&bm, IDR_SIZE, n); | ||
155 | if (m == IDR_SIZE) { | 246 | if (m == IDR_SIZE) { |
156 | /* no space available go back to previous layer. */ | 247 | /* no space available go back to previous layer. */ |
157 | l++; | 248 | l++; |
@@ -161,7 +252,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa) | |||
161 | /* if already at the top layer, we need to grow */ | 252 | /* if already at the top layer, we need to grow */ |
162 | if (id >= 1 << (idp->layers * IDR_BITS)) { | 253 | if (id >= 1 << (idp->layers * IDR_BITS)) { |
163 | *starting_id = id; | 254 | *starting_id = id; |
164 | return IDR_NEED_TO_GROW; | 255 | return -EAGAIN; |
165 | } | 256 | } |
166 | p = pa[l]; | 257 | p = pa[l]; |
167 | BUG_ON(!p); | 258 | BUG_ON(!p); |
@@ -180,17 +271,18 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa) | |||
180 | id = ((id >> sh) ^ n ^ m) << sh; | 271 | id = ((id >> sh) ^ n ^ m) << sh; |
181 | } | 272 | } |
182 | if ((id >= MAX_IDR_BIT) || (id < 0)) | 273 | if ((id >= MAX_IDR_BIT) || (id < 0)) |
183 | return IDR_NOMORE_SPACE; | 274 | return -ENOSPC; |
184 | if (l == 0) | 275 | if (l == 0) |
185 | break; | 276 | break; |
186 | /* | 277 | /* |
187 | * Create the layer below if it is missing. | 278 | * Create the layer below if it is missing. |
188 | */ | 279 | */ |
189 | if (!p->ary[m]) { | 280 | if (!p->ary[m]) { |
190 | new = get_from_free_list(idp); | 281 | new = idr_layer_alloc(gfp_mask, layer_idr); |
191 | if (!new) | 282 | if (!new) |
192 | return -1; | 283 | return -ENOMEM; |
193 | new->layer = l-1; | 284 | new->layer = l-1; |
285 | new->prefix = id & idr_layer_prefix_mask(new->layer); | ||
194 | rcu_assign_pointer(p->ary[m], new); | 286 | rcu_assign_pointer(p->ary[m], new); |
195 | p->count++; | 287 | p->count++; |
196 | } | 288 | } |
@@ -203,7 +295,8 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa) | |||
203 | } | 295 | } |
204 | 296 | ||
205 | static int idr_get_empty_slot(struct idr *idp, int starting_id, | 297 | static int idr_get_empty_slot(struct idr *idp, int starting_id, |
206 | struct idr_layer **pa) | 298 | struct idr_layer **pa, gfp_t gfp_mask, |
299 | struct idr *layer_idr) | ||
207 | { | 300 | { |
208 | struct idr_layer *p, *new; | 301 | struct idr_layer *p, *new; |
209 | int layers, v, id; | 302 | int layers, v, id; |
@@ -214,8 +307,8 @@ build_up: | |||
214 | p = idp->top; | 307 | p = idp->top; |
215 | layers = idp->layers; | 308 | layers = idp->layers; |
216 | if (unlikely(!p)) { | 309 | if (unlikely(!p)) { |
217 | if (!(p = get_from_free_list(idp))) | 310 | if (!(p = idr_layer_alloc(gfp_mask, layer_idr))) |
218 | return -1; | 311 | return -ENOMEM; |
219 | p->layer = 0; | 312 | p->layer = 0; |
220 | layers = 1; | 313 | layers = 1; |
221 | } | 314 | } |
@@ -223,7 +316,7 @@ build_up: | |||
223 | * Add a new layer to the top of the tree if the requested | 316 | * Add a new layer to the top of the tree if the requested |
224 | * id is larger than the currently allocated space. | 317 | * id is larger than the currently allocated space. |
225 | */ | 318 | */ |
226 | while ((layers < (MAX_IDR_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) { | 319 | while (id > idr_max(layers)) { |
227 | layers++; | 320 | layers++; |
228 | if (!p->count) { | 321 | if (!p->count) { |
229 | /* special case: if the tree is currently empty, | 322 | /* special case: if the tree is currently empty, |
@@ -231,9 +324,10 @@ build_up: | |||
231 | * upwards. | 324 | * upwards. |
232 | */ | 325 | */ |
233 | p->layer++; | 326 | p->layer++; |
327 | WARN_ON_ONCE(p->prefix); | ||
234 | continue; | 328 | continue; |
235 | } | 329 | } |
236 | if (!(new = get_from_free_list(idp))) { | 330 | if (!(new = idr_layer_alloc(gfp_mask, layer_idr))) { |
237 | /* | 331 | /* |
238 | * The allocation failed. If we built part of | 332 | * The allocation failed. If we built part of |
239 | * the structure tear it down. | 333 | * the structure tear it down. |
@@ -242,110 +336,164 @@ build_up: | |||
242 | for (new = p; p && p != idp->top; new = p) { | 336 | for (new = p; p && p != idp->top; new = p) { |
243 | p = p->ary[0]; | 337 | p = p->ary[0]; |
244 | new->ary[0] = NULL; | 338 | new->ary[0] = NULL; |
245 | new->bitmap = new->count = 0; | 339 | new->count = 0; |
340 | bitmap_clear(new->bitmap, 0, IDR_SIZE); | ||
246 | __move_to_free_list(idp, new); | 341 | __move_to_free_list(idp, new); |
247 | } | 342 | } |
248 | spin_unlock_irqrestore(&idp->lock, flags); | 343 | spin_unlock_irqrestore(&idp->lock, flags); |
249 | return -1; | 344 | return -ENOMEM; |
250 | } | 345 | } |
251 | new->ary[0] = p; | 346 | new->ary[0] = p; |
252 | new->count = 1; | 347 | new->count = 1; |
253 | new->layer = layers-1; | 348 | new->layer = layers-1; |
254 | if (p->bitmap == IDR_FULL) | 349 | new->prefix = id & idr_layer_prefix_mask(new->layer); |
255 | __set_bit(0, &new->bitmap); | 350 | if (bitmap_full(p->bitmap, IDR_SIZE)) |
351 | __set_bit(0, new->bitmap); | ||
256 | p = new; | 352 | p = new; |
257 | } | 353 | } |
258 | rcu_assign_pointer(idp->top, p); | 354 | rcu_assign_pointer(idp->top, p); |
259 | idp->layers = layers; | 355 | idp->layers = layers; |
260 | v = sub_alloc(idp, &id, pa); | 356 | v = sub_alloc(idp, &id, pa, gfp_mask, layer_idr); |
261 | if (v == IDR_NEED_TO_GROW) | 357 | if (v == -EAGAIN) |
262 | goto build_up; | 358 | goto build_up; |
263 | return(v); | 359 | return(v); |
264 | } | 360 | } |
265 | 361 | ||
266 | static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id) | 362 | /* |
363 | * @id and @pa are from a successful allocation from idr_get_empty_slot(). | ||
364 | * Install the user pointer @ptr and mark the slot full. | ||
365 | */ | ||
366 | static void idr_fill_slot(struct idr *idr, void *ptr, int id, | ||
367 | struct idr_layer **pa) | ||
267 | { | 368 | { |
268 | struct idr_layer *pa[MAX_IDR_LEVEL]; | 369 | /* update hint used for lookup, cleared from free_layer() */ |
269 | int id; | 370 | rcu_assign_pointer(idr->hint, pa[0]); |
270 | 371 | ||
271 | id = idr_get_empty_slot(idp, starting_id, pa); | 372 | rcu_assign_pointer(pa[0]->ary[id & IDR_MASK], (struct idr_layer *)ptr); |
272 | if (id >= 0) { | 373 | pa[0]->count++; |
273 | /* | 374 | idr_mark_full(pa, id); |
274 | * Successfully found an empty slot. Install the user | 375 | } |
275 | * pointer and mark the slot full. | ||
276 | */ | ||
277 | rcu_assign_pointer(pa[0]->ary[id & IDR_MASK], | ||
278 | (struct idr_layer *)ptr); | ||
279 | pa[0]->count++; | ||
280 | idr_mark_full(pa, id); | ||
281 | } | ||
282 | 376 | ||
283 | return id; | 377 | int __idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id) |
378 | { | ||
379 | struct idr_layer *pa[MAX_IDR_LEVEL + 1]; | ||
380 | int rv; | ||
381 | |||
382 | rv = idr_get_empty_slot(idp, starting_id, pa, 0, idp); | ||
383 | if (rv < 0) | ||
384 | return rv == -ENOMEM ? -EAGAIN : rv; | ||
385 | |||
386 | idr_fill_slot(idp, ptr, rv, pa); | ||
387 | *id = rv; | ||
388 | return 0; | ||
284 | } | 389 | } |
390 | EXPORT_SYMBOL(__idr_get_new_above); | ||
285 | 391 | ||
286 | /** | 392 | /** |
287 | * idr_get_new_above - allocate new idr entry above or equal to a start id | 393 | * idr_preload - preload for idr_alloc() |
288 | * @idp: idr handle | 394 | * @gfp_mask: allocation mask to use for preloading |
289 | * @ptr: pointer you want associated with the id | 395 | * |
290 | * @starting_id: id to start search at | 396 | * Preload per-cpu layer buffer for idr_alloc(). Can only be used from |
291 | * @id: pointer to the allocated handle | 397 | * process context and each idr_preload() invocation should be matched with |
398 | * idr_preload_end(). Note that preemption is disabled while preloaded. | ||
292 | * | 399 | * |
293 | * This is the allocate id function. It should be called with any | 400 | * The first idr_alloc() in the preloaded section can be treated as if it |
294 | * required locks. | 401 | * were invoked with @gfp_mask used for preloading. This allows using more |
402 | * permissive allocation masks for idrs protected by spinlocks. | ||
295 | * | 403 | * |
296 | * If allocation from IDR's private freelist fails, idr_get_new_above() will | 404 | * For example, if idr_alloc() below fails, the failure can be treated as |
297 | * return %-EAGAIN. The caller should retry the idr_pre_get() call to refill | 405 | * if idr_alloc() were called with GFP_KERNEL rather than GFP_NOWAIT. |
298 | * IDR's preallocation and then retry the idr_get_new_above() call. | ||
299 | * | 406 | * |
300 | * If the idr is full idr_get_new_above() will return %-ENOSPC. | 407 | * idr_preload(GFP_KERNEL); |
408 | * spin_lock(lock); | ||
301 | * | 409 | * |
302 | * @id returns a value in the range @starting_id ... %0x7fffffff | 410 | * id = idr_alloc(idr, ptr, start, end, GFP_NOWAIT); |
411 | * | ||
412 | * spin_unlock(lock); | ||
413 | * idr_preload_end(); | ||
414 | * if (id < 0) | ||
415 | * error; | ||
303 | */ | 416 | */ |
304 | int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id) | 417 | void idr_preload(gfp_t gfp_mask) |
305 | { | 418 | { |
306 | int rv; | 419 | /* |
420 | * Consuming preload buffer from non-process context breaks preload | ||
421 | * allocation guarantee. Disallow usage from those contexts. | ||
422 | */ | ||
423 | WARN_ON_ONCE(in_interrupt()); | ||
424 | might_sleep_if(gfp_mask & __GFP_WAIT); | ||
425 | |||
426 | preempt_disable(); | ||
307 | 427 | ||
308 | rv = idr_get_new_above_int(idp, ptr, starting_id); | ||
309 | /* | 428 | /* |
310 | * This is a cheap hack until the IDR code can be fixed to | 429 | * idr_alloc() is likely to succeed w/o full idr_layer buffer and |
311 | * return proper error values. | 430 | * return value from idr_alloc() needs to be checked for failure |
431 | * anyway. Silently give up if allocation fails. The caller can | ||
432 | * treat failures from idr_alloc() as if idr_alloc() were called | ||
433 | * with @gfp_mask which should be enough. | ||
312 | */ | 434 | */ |
313 | if (rv < 0) | 435 | while (__this_cpu_read(idr_preload_cnt) < MAX_IDR_FREE) { |
314 | return _idr_rc_to_errno(rv); | 436 | struct idr_layer *new; |
315 | *id = rv; | 437 | |
316 | return 0; | 438 | preempt_enable(); |
439 | new = kmem_cache_zalloc(idr_layer_cache, gfp_mask); | ||
440 | preempt_disable(); | ||
441 | if (!new) | ||
442 | break; | ||
443 | |||
444 | /* link the new one to per-cpu preload list */ | ||
445 | new->ary[0] = __this_cpu_read(idr_preload_head); | ||
446 | __this_cpu_write(idr_preload_head, new); | ||
447 | __this_cpu_inc(idr_preload_cnt); | ||
448 | } | ||
317 | } | 449 | } |
318 | EXPORT_SYMBOL(idr_get_new_above); | 450 | EXPORT_SYMBOL(idr_preload); |
319 | 451 | ||
320 | /** | 452 | /** |
321 | * idr_get_new - allocate new idr entry | 453 | * idr_alloc - allocate new idr entry |
322 | * @idp: idr handle | 454 | * @idr: the (initialized) idr |
323 | * @ptr: pointer you want associated with the id | 455 | * @ptr: pointer to be associated with the new id |
324 | * @id: pointer to the allocated handle | 456 | * @start: the minimum id (inclusive) |
457 | * @end: the maximum id (exclusive, <= 0 for max) | ||
458 | * @gfp_mask: memory allocation flags | ||
325 | * | 459 | * |
326 | * If allocation from IDR's private freelist fails, idr_get_new_above() will | 460 | * Allocate an id in [start, end) and associate it with @ptr. If no ID is |
327 | * return %-EAGAIN. The caller should retry the idr_pre_get() call to refill | 461 | * available in the specified range, returns -ENOSPC. On memory allocation |
328 | * IDR's preallocation and then retry the idr_get_new_above() call. | 462 | * failure, returns -ENOMEM. |
329 | * | 463 | * |
330 | * If the idr is full idr_get_new_above() will return %-ENOSPC. | 464 | * Note that @end is treated as max when <= 0. This is to always allow |
465 | * using @start + N as @end as long as N is inside integer range. | ||
331 | * | 466 | * |
332 | * @id returns a value in the range %0 ... %0x7fffffff | 467 | * The user is responsible for exclusively synchronizing all operations |
468 | * which may modify @idr. However, read-only accesses such as idr_find() | ||
469 | * or iteration can be performed under RCU read lock provided the user | ||
470 | * destroys @ptr in RCU-safe way after removal from idr. | ||
333 | */ | 471 | */ |
334 | int idr_get_new(struct idr *idp, void *ptr, int *id) | 472 | int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask) |
335 | { | 473 | { |
336 | int rv; | 474 | int max = end > 0 ? end - 1 : INT_MAX; /* inclusive upper limit */ |
475 | struct idr_layer *pa[MAX_IDR_LEVEL + 1]; | ||
476 | int id; | ||
337 | 477 | ||
338 | rv = idr_get_new_above_int(idp, ptr, 0); | 478 | might_sleep_if(gfp_mask & __GFP_WAIT); |
339 | /* | 479 | |
340 | * This is a cheap hack until the IDR code can be fixed to | 480 | /* sanity checks */ |
341 | * return proper error values. | 481 | if (WARN_ON_ONCE(start < 0)) |
342 | */ | 482 | return -EINVAL; |
343 | if (rv < 0) | 483 | if (unlikely(max < start)) |
344 | return _idr_rc_to_errno(rv); | 484 | return -ENOSPC; |
345 | *id = rv; | 485 | |
346 | return 0; | 486 | /* allocate id */ |
487 | id = idr_get_empty_slot(idr, start, pa, gfp_mask, NULL); | ||
488 | if (unlikely(id < 0)) | ||
489 | return id; | ||
490 | if (unlikely(id > max)) | ||
491 | return -ENOSPC; | ||
492 | |||
493 | idr_fill_slot(idr, ptr, id, pa); | ||
494 | return id; | ||
347 | } | 495 | } |
348 | EXPORT_SYMBOL(idr_get_new); | 496 | EXPORT_SYMBOL_GPL(idr_alloc); |
349 | 497 | ||
350 | static void idr_remove_warning(int id) | 498 | static void idr_remove_warning(int id) |
351 | { | 499 | { |
@@ -357,7 +505,7 @@ static void idr_remove_warning(int id) | |||
357 | static void sub_remove(struct idr *idp, int shift, int id) | 505 | static void sub_remove(struct idr *idp, int shift, int id) |
358 | { | 506 | { |
359 | struct idr_layer *p = idp->top; | 507 | struct idr_layer *p = idp->top; |
360 | struct idr_layer **pa[MAX_IDR_LEVEL]; | 508 | struct idr_layer **pa[MAX_IDR_LEVEL + 1]; |
361 | struct idr_layer ***paa = &pa[0]; | 509 | struct idr_layer ***paa = &pa[0]; |
362 | struct idr_layer *to_free; | 510 | struct idr_layer *to_free; |
363 | int n; | 511 | int n; |
@@ -367,26 +515,26 @@ static void sub_remove(struct idr *idp, int shift, int id) | |||
367 | 515 | ||
368 | while ((shift > 0) && p) { | 516 | while ((shift > 0) && p) { |
369 | n = (id >> shift) & IDR_MASK; | 517 | n = (id >> shift) & IDR_MASK; |
370 | __clear_bit(n, &p->bitmap); | 518 | __clear_bit(n, p->bitmap); |
371 | *++paa = &p->ary[n]; | 519 | *++paa = &p->ary[n]; |
372 | p = p->ary[n]; | 520 | p = p->ary[n]; |
373 | shift -= IDR_BITS; | 521 | shift -= IDR_BITS; |
374 | } | 522 | } |
375 | n = id & IDR_MASK; | 523 | n = id & IDR_MASK; |
376 | if (likely(p != NULL && test_bit(n, &p->bitmap))){ | 524 | if (likely(p != NULL && test_bit(n, p->bitmap))) { |
377 | __clear_bit(n, &p->bitmap); | 525 | __clear_bit(n, p->bitmap); |
378 | rcu_assign_pointer(p->ary[n], NULL); | 526 | rcu_assign_pointer(p->ary[n], NULL); |
379 | to_free = NULL; | 527 | to_free = NULL; |
380 | while(*paa && ! --((**paa)->count)){ | 528 | while(*paa && ! --((**paa)->count)){ |
381 | if (to_free) | 529 | if (to_free) |
382 | free_layer(to_free); | 530 | free_layer(idp, to_free); |
383 | to_free = **paa; | 531 | to_free = **paa; |
384 | **paa-- = NULL; | 532 | **paa-- = NULL; |
385 | } | 533 | } |
386 | if (!*paa) | 534 | if (!*paa) |
387 | idp->layers = 0; | 535 | idp->layers = 0; |
388 | if (to_free) | 536 | if (to_free) |
389 | free_layer(to_free); | 537 | free_layer(idp, to_free); |
390 | } else | 538 | } else |
391 | idr_remove_warning(id); | 539 | idr_remove_warning(id); |
392 | } | 540 | } |
@@ -401,8 +549,8 @@ void idr_remove(struct idr *idp, int id) | |||
401 | struct idr_layer *p; | 549 | struct idr_layer *p; |
402 | struct idr_layer *to_free; | 550 | struct idr_layer *to_free; |
403 | 551 | ||
404 | /* Mask off upper bits we don't use for the search. */ | 552 | if (id < 0) |
405 | id &= MAX_IDR_MASK; | 553 | return; |
406 | 554 | ||
407 | sub_remove(idp, (idp->layers - 1) * IDR_BITS, id); | 555 | sub_remove(idp, (idp->layers - 1) * IDR_BITS, id); |
408 | if (idp->top && idp->top->count == 1 && (idp->layers > 1) && | 556 | if (idp->top && idp->top->count == 1 && (idp->layers > 1) && |
@@ -417,8 +565,9 @@ void idr_remove(struct idr *idp, int id) | |||
417 | p = idp->top->ary[0]; | 565 | p = idp->top->ary[0]; |
418 | rcu_assign_pointer(idp->top, p); | 566 | rcu_assign_pointer(idp->top, p); |
419 | --idp->layers; | 567 | --idp->layers; |
420 | to_free->bitmap = to_free->count = 0; | 568 | to_free->count = 0; |
421 | free_layer(to_free); | 569 | bitmap_clear(to_free->bitmap, 0, IDR_SIZE); |
570 | free_layer(idp, to_free); | ||
422 | } | 571 | } |
423 | while (idp->id_free_cnt >= MAX_IDR_FREE) { | 572 | while (idp->id_free_cnt >= MAX_IDR_FREE) { |
424 | p = get_from_free_list(idp); | 573 | p = get_from_free_list(idp); |
@@ -433,34 +582,21 @@ void idr_remove(struct idr *idp, int id) | |||
433 | } | 582 | } |
434 | EXPORT_SYMBOL(idr_remove); | 583 | EXPORT_SYMBOL(idr_remove); |
435 | 584 | ||
436 | /** | 585 | void __idr_remove_all(struct idr *idp) |
437 | * idr_remove_all - remove all ids from the given idr tree | ||
438 | * @idp: idr handle | ||
439 | * | ||
440 | * idr_destroy() only frees up unused, cached idp_layers, but this | ||
441 | * function will remove all id mappings and leave all idp_layers | ||
442 | * unused. | ||
443 | * | ||
444 | * A typical clean-up sequence for objects stored in an idr tree will | ||
445 | * use idr_for_each() to free all objects, if necessay, then | ||
446 | * idr_remove_all() to remove all ids, and idr_destroy() to free | ||
447 | * up the cached idr_layers. | ||
448 | */ | ||
449 | void idr_remove_all(struct idr *idp) | ||
450 | { | 586 | { |
451 | int n, id, max; | 587 | int n, id, max; |
452 | int bt_mask; | 588 | int bt_mask; |
453 | struct idr_layer *p; | 589 | struct idr_layer *p; |
454 | struct idr_layer *pa[MAX_IDR_LEVEL]; | 590 | struct idr_layer *pa[MAX_IDR_LEVEL + 1]; |
455 | struct idr_layer **paa = &pa[0]; | 591 | struct idr_layer **paa = &pa[0]; |
456 | 592 | ||
457 | n = idp->layers * IDR_BITS; | 593 | n = idp->layers * IDR_BITS; |
458 | p = idp->top; | 594 | p = idp->top; |
459 | rcu_assign_pointer(idp->top, NULL); | 595 | rcu_assign_pointer(idp->top, NULL); |
460 | max = 1 << n; | 596 | max = idr_max(idp->layers); |
461 | 597 | ||
462 | id = 0; | 598 | id = 0; |
463 | while (id < max) { | 599 | while (id >= 0 && id <= max) { |
464 | while (n > IDR_BITS && p) { | 600 | while (n > IDR_BITS && p) { |
465 | n -= IDR_BITS; | 601 | n -= IDR_BITS; |
466 | *paa++ = p; | 602 | *paa++ = p; |
@@ -472,21 +608,32 @@ void idr_remove_all(struct idr *idp) | |||
472 | /* Get the highest bit that the above add changed from 0->1. */ | 608 | /* Get the highest bit that the above add changed from 0->1. */ |
473 | while (n < fls(id ^ bt_mask)) { | 609 | while (n < fls(id ^ bt_mask)) { |
474 | if (p) | 610 | if (p) |
475 | free_layer(p); | 611 | free_layer(idp, p); |
476 | n += IDR_BITS; | 612 | n += IDR_BITS; |
477 | p = *--paa; | 613 | p = *--paa; |
478 | } | 614 | } |
479 | } | 615 | } |
480 | idp->layers = 0; | 616 | idp->layers = 0; |
481 | } | 617 | } |
482 | EXPORT_SYMBOL(idr_remove_all); | 618 | EXPORT_SYMBOL(__idr_remove_all); |
483 | 619 | ||
484 | /** | 620 | /** |
485 | * idr_destroy - release all cached layers within an idr tree | 621 | * idr_destroy - release all cached layers within an idr tree |
486 | * @idp: idr handle | 622 | * @idp: idr handle |
623 | * | ||
624 | * Free all id mappings and all idp_layers. After this function, @idp is | ||
625 | * completely unused and can be freed / recycled. The caller is | ||
626 | * responsible for ensuring that no one else accesses @idp during or after | ||
627 | * idr_destroy(). | ||
628 | * | ||
629 | * A typical clean-up sequence for objects stored in an idr tree will use | ||
630 | * idr_for_each() to free all objects, if necessay, then idr_destroy() to | ||
631 | * free up the id mappings and cached idr_layers. | ||
487 | */ | 632 | */ |
488 | void idr_destroy(struct idr *idp) | 633 | void idr_destroy(struct idr *idp) |
489 | { | 634 | { |
635 | __idr_remove_all(idp); | ||
636 | |||
490 | while (idp->id_free_cnt) { | 637 | while (idp->id_free_cnt) { |
491 | struct idr_layer *p = get_from_free_list(idp); | 638 | struct idr_layer *p = get_from_free_list(idp); |
492 | kmem_cache_free(idr_layer_cache, p); | 639 | kmem_cache_free(idr_layer_cache, p); |
@@ -494,32 +641,20 @@ void idr_destroy(struct idr *idp) | |||
494 | } | 641 | } |
495 | EXPORT_SYMBOL(idr_destroy); | 642 | EXPORT_SYMBOL(idr_destroy); |
496 | 643 | ||
497 | /** | 644 | void *idr_find_slowpath(struct idr *idp, int id) |
498 | * idr_find - return pointer for given id | ||
499 | * @idp: idr handle | ||
500 | * @id: lookup key | ||
501 | * | ||
502 | * Return the pointer given the id it has been registered with. A %NULL | ||
503 | * return indicates that @id is not valid or you passed %NULL in | ||
504 | * idr_get_new(). | ||
505 | * | ||
506 | * This function can be called under rcu_read_lock(), given that the leaf | ||
507 | * pointers lifetimes are correctly managed. | ||
508 | */ | ||
509 | void *idr_find(struct idr *idp, int id) | ||
510 | { | 645 | { |
511 | int n; | 646 | int n; |
512 | struct idr_layer *p; | 647 | struct idr_layer *p; |
513 | 648 | ||
649 | if (id < 0) | ||
650 | return NULL; | ||
651 | |||
514 | p = rcu_dereference_raw(idp->top); | 652 | p = rcu_dereference_raw(idp->top); |
515 | if (!p) | 653 | if (!p) |
516 | return NULL; | 654 | return NULL; |
517 | n = (p->layer+1) * IDR_BITS; | 655 | n = (p->layer+1) * IDR_BITS; |
518 | 656 | ||
519 | /* Mask off upper bits we don't use for the search. */ | 657 | if (id > idr_max(p->layer + 1)) |
520 | id &= MAX_IDR_MASK; | ||
521 | |||
522 | if (id >= (1 << n)) | ||
523 | return NULL; | 658 | return NULL; |
524 | BUG_ON(n == 0); | 659 | BUG_ON(n == 0); |
525 | 660 | ||
@@ -530,7 +665,7 @@ void *idr_find(struct idr *idp, int id) | |||
530 | } | 665 | } |
531 | return((void *)p); | 666 | return((void *)p); |
532 | } | 667 | } |
533 | EXPORT_SYMBOL(idr_find); | 668 | EXPORT_SYMBOL(idr_find_slowpath); |
534 | 669 | ||
535 | /** | 670 | /** |
536 | * idr_for_each - iterate through all stored pointers | 671 | * idr_for_each - iterate through all stored pointers |
@@ -555,15 +690,15 @@ int idr_for_each(struct idr *idp, | |||
555 | { | 690 | { |
556 | int n, id, max, error = 0; | 691 | int n, id, max, error = 0; |
557 | struct idr_layer *p; | 692 | struct idr_layer *p; |
558 | struct idr_layer *pa[MAX_IDR_LEVEL]; | 693 | struct idr_layer *pa[MAX_IDR_LEVEL + 1]; |
559 | struct idr_layer **paa = &pa[0]; | 694 | struct idr_layer **paa = &pa[0]; |
560 | 695 | ||
561 | n = idp->layers * IDR_BITS; | 696 | n = idp->layers * IDR_BITS; |
562 | p = rcu_dereference_raw(idp->top); | 697 | p = rcu_dereference_raw(idp->top); |
563 | max = 1 << n; | 698 | max = idr_max(idp->layers); |
564 | 699 | ||
565 | id = 0; | 700 | id = 0; |
566 | while (id < max) { | 701 | while (id >= 0 && id <= max) { |
567 | while (n > 0 && p) { | 702 | while (n > 0 && p) { |
568 | n -= IDR_BITS; | 703 | n -= IDR_BITS; |
569 | *paa++ = p; | 704 | *paa++ = p; |
@@ -601,7 +736,7 @@ EXPORT_SYMBOL(idr_for_each); | |||
601 | */ | 736 | */ |
602 | void *idr_get_next(struct idr *idp, int *nextidp) | 737 | void *idr_get_next(struct idr *idp, int *nextidp) |
603 | { | 738 | { |
604 | struct idr_layer *p, *pa[MAX_IDR_LEVEL]; | 739 | struct idr_layer *p, *pa[MAX_IDR_LEVEL + 1]; |
605 | struct idr_layer **paa = &pa[0]; | 740 | struct idr_layer **paa = &pa[0]; |
606 | int id = *nextidp; | 741 | int id = *nextidp; |
607 | int n, max; | 742 | int n, max; |
@@ -611,9 +746,9 @@ void *idr_get_next(struct idr *idp, int *nextidp) | |||
611 | if (!p) | 746 | if (!p) |
612 | return NULL; | 747 | return NULL; |
613 | n = (p->layer + 1) * IDR_BITS; | 748 | n = (p->layer + 1) * IDR_BITS; |
614 | max = 1 << n; | 749 | max = idr_max(p->layer + 1); |
615 | 750 | ||
616 | while (id < max) { | 751 | while (id >= 0 && id <= max) { |
617 | while (n > 0 && p) { | 752 | while (n > 0 && p) { |
618 | n -= IDR_BITS; | 753 | n -= IDR_BITS; |
619 | *paa++ = p; | 754 | *paa++ = p; |
@@ -625,7 +760,14 @@ void *idr_get_next(struct idr *idp, int *nextidp) | |||
625 | return p; | 760 | return p; |
626 | } | 761 | } |
627 | 762 | ||
628 | id += 1 << n; | 763 | /* |
764 | * Proceed to the next layer at the current level. Unlike | ||
765 | * idr_for_each(), @id isn't guaranteed to be aligned to | ||
766 | * layer boundary at this point and adding 1 << n may | ||
767 | * incorrectly skip IDs. Make sure we jump to the | ||
768 | * beginning of the next layer using round_up(). | ||
769 | */ | ||
770 | id = round_up(id + 1, 1 << n); | ||
629 | while (n < fls(id)) { | 771 | while (n < fls(id)) { |
630 | n += IDR_BITS; | 772 | n += IDR_BITS; |
631 | p = *--paa; | 773 | p = *--paa; |
@@ -653,14 +795,15 @@ void *idr_replace(struct idr *idp, void *ptr, int id) | |||
653 | int n; | 795 | int n; |
654 | struct idr_layer *p, *old_p; | 796 | struct idr_layer *p, *old_p; |
655 | 797 | ||
798 | if (id < 0) | ||
799 | return ERR_PTR(-EINVAL); | ||
800 | |||
656 | p = idp->top; | 801 | p = idp->top; |
657 | if (!p) | 802 | if (!p) |
658 | return ERR_PTR(-EINVAL); | 803 | return ERR_PTR(-EINVAL); |
659 | 804 | ||
660 | n = (p->layer+1) * IDR_BITS; | 805 | n = (p->layer+1) * IDR_BITS; |
661 | 806 | ||
662 | id &= MAX_IDR_MASK; | ||
663 | |||
664 | if (id >= (1 << n)) | 807 | if (id >= (1 << n)) |
665 | return ERR_PTR(-EINVAL); | 808 | return ERR_PTR(-EINVAL); |
666 | 809 | ||
@@ -671,7 +814,7 @@ void *idr_replace(struct idr *idp, void *ptr, int id) | |||
671 | } | 814 | } |
672 | 815 | ||
673 | n = id & IDR_MASK; | 816 | n = id & IDR_MASK; |
674 | if (unlikely(p == NULL || !test_bit(n, &p->bitmap))) | 817 | if (unlikely(p == NULL || !test_bit(n, p->bitmap))) |
675 | return ERR_PTR(-ENOENT); | 818 | return ERR_PTR(-ENOENT); |
676 | 819 | ||
677 | old_p = p->ary[n]; | 820 | old_p = p->ary[n]; |
@@ -745,7 +888,7 @@ static void free_bitmap(struct ida *ida, struct ida_bitmap *bitmap) | |||
745 | int ida_pre_get(struct ida *ida, gfp_t gfp_mask) | 888 | int ida_pre_get(struct ida *ida, gfp_t gfp_mask) |
746 | { | 889 | { |
747 | /* allocate idr_layers */ | 890 | /* allocate idr_layers */ |
748 | if (!idr_pre_get(&ida->idr, gfp_mask)) | 891 | if (!__idr_pre_get(&ida->idr, gfp_mask)) |
749 | return 0; | 892 | return 0; |
750 | 893 | ||
751 | /* allocate free_bitmap */ | 894 | /* allocate free_bitmap */ |
@@ -780,7 +923,7 @@ EXPORT_SYMBOL(ida_pre_get); | |||
780 | */ | 923 | */ |
781 | int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) | 924 | int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) |
782 | { | 925 | { |
783 | struct idr_layer *pa[MAX_IDR_LEVEL]; | 926 | struct idr_layer *pa[MAX_IDR_LEVEL + 1]; |
784 | struct ida_bitmap *bitmap; | 927 | struct ida_bitmap *bitmap; |
785 | unsigned long flags; | 928 | unsigned long flags; |
786 | int idr_id = starting_id / IDA_BITMAP_BITS; | 929 | int idr_id = starting_id / IDA_BITMAP_BITS; |
@@ -789,9 +932,9 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) | |||
789 | 932 | ||
790 | restart: | 933 | restart: |
791 | /* get vacant slot */ | 934 | /* get vacant slot */ |
792 | t = idr_get_empty_slot(&ida->idr, idr_id, pa); | 935 | t = idr_get_empty_slot(&ida->idr, idr_id, pa, 0, &ida->idr); |
793 | if (t < 0) | 936 | if (t < 0) |
794 | return _idr_rc_to_errno(t); | 937 | return t == -ENOMEM ? -EAGAIN : t; |
795 | 938 | ||
796 | if (t * IDA_BITMAP_BITS >= MAX_IDR_BIT) | 939 | if (t * IDA_BITMAP_BITS >= MAX_IDR_BIT) |
797 | return -ENOSPC; | 940 | return -ENOSPC; |
@@ -852,25 +995,6 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) | |||
852 | EXPORT_SYMBOL(ida_get_new_above); | 995 | EXPORT_SYMBOL(ida_get_new_above); |
853 | 996 | ||
854 | /** | 997 | /** |
855 | * ida_get_new - allocate new ID | ||
856 | * @ida: idr handle | ||
857 | * @p_id: pointer to the allocated handle | ||
858 | * | ||
859 | * Allocate new ID. It should be called with any required locks. | ||
860 | * | ||
861 | * If memory is required, it will return %-EAGAIN, you should unlock | ||
862 | * and go back to the idr_pre_get() call. If the idr is full, it will | ||
863 | * return %-ENOSPC. | ||
864 | * | ||
865 | * @p_id returns a value in the range %0 ... %0x7fffffff. | ||
866 | */ | ||
867 | int ida_get_new(struct ida *ida, int *p_id) | ||
868 | { | ||
869 | return ida_get_new_above(ida, 0, p_id); | ||
870 | } | ||
871 | EXPORT_SYMBOL(ida_get_new); | ||
872 | |||
873 | /** | ||
874 | * ida_remove - remove the given ID | 998 | * ida_remove - remove the given ID |
875 | * @ida: ida handle | 999 | * @ida: ida handle |
876 | * @id: ID to free | 1000 | * @id: ID to free |
@@ -887,7 +1011,7 @@ void ida_remove(struct ida *ida, int id) | |||
887 | /* clear full bits while looking up the leaf idr_layer */ | 1011 | /* clear full bits while looking up the leaf idr_layer */ |
888 | while ((shift > 0) && p) { | 1012 | while ((shift > 0) && p) { |
889 | n = (idr_id >> shift) & IDR_MASK; | 1013 | n = (idr_id >> shift) & IDR_MASK; |
890 | __clear_bit(n, &p->bitmap); | 1014 | __clear_bit(n, p->bitmap); |
891 | p = p->ary[n]; | 1015 | p = p->ary[n]; |
892 | shift -= IDR_BITS; | 1016 | shift -= IDR_BITS; |
893 | } | 1017 | } |
@@ -896,7 +1020,7 @@ void ida_remove(struct ida *ida, int id) | |||
896 | goto err; | 1020 | goto err; |
897 | 1021 | ||
898 | n = idr_id & IDR_MASK; | 1022 | n = idr_id & IDR_MASK; |
899 | __clear_bit(n, &p->bitmap); | 1023 | __clear_bit(n, p->bitmap); |
900 | 1024 | ||
901 | bitmap = (void *)p->ary[n]; | 1025 | bitmap = (void *)p->ary[n]; |
902 | if (!test_bit(offset, bitmap->bitmap)) | 1026 | if (!test_bit(offset, bitmap->bitmap)) |
@@ -905,7 +1029,7 @@ void ida_remove(struct ida *ida, int id) | |||
905 | /* update bitmap and remove it if empty */ | 1029 | /* update bitmap and remove it if empty */ |
906 | __clear_bit(offset, bitmap->bitmap); | 1030 | __clear_bit(offset, bitmap->bitmap); |
907 | if (--bitmap->nr_busy == 0) { | 1031 | if (--bitmap->nr_busy == 0) { |
908 | __set_bit(n, &p->bitmap); /* to please idr_remove() */ | 1032 | __set_bit(n, p->bitmap); /* to please idr_remove() */ |
909 | idr_remove(&ida->idr, idr_id); | 1033 | idr_remove(&ida->idr, idr_id); |
910 | free_bitmap(ida, bitmap); | 1034 | free_bitmap(ida, bitmap); |
911 | } | 1035 | } |
diff --git a/lib/interval_tree_test_main.c b/lib/interval_tree_test_main.c index b25903987f7a..245900b98c8e 100644 --- a/lib/interval_tree_test_main.c +++ b/lib/interval_tree_test_main.c | |||
@@ -30,7 +30,8 @@ static void init(void) | |||
30 | { | 30 | { |
31 | int i; | 31 | int i; |
32 | for (i = 0; i < NODES; i++) { | 32 | for (i = 0; i < NODES; i++) { |
33 | u32 a = prandom32(&rnd), b = prandom32(&rnd); | 33 | u32 a = prandom_u32_state(&rnd); |
34 | u32 b = prandom_u32_state(&rnd); | ||
34 | if (a <= b) { | 35 | if (a <= b) { |
35 | nodes[i].start = a; | 36 | nodes[i].start = a; |
36 | nodes[i].last = b; | 37 | nodes[i].last = b; |
@@ -40,7 +41,7 @@ static void init(void) | |||
40 | } | 41 | } |
41 | } | 42 | } |
42 | for (i = 0; i < SEARCHES; i++) | 43 | for (i = 0; i < SEARCHES; i++) |
43 | queries[i] = prandom32(&rnd); | 44 | queries[i] = prandom_u32_state(&rnd); |
44 | } | 45 | } |
45 | 46 | ||
46 | static int interval_tree_test_init(void) | 47 | static int interval_tree_test_init(void) |
@@ -51,7 +52,7 @@ static int interval_tree_test_init(void) | |||
51 | 52 | ||
52 | printk(KERN_ALERT "interval tree insert/remove"); | 53 | printk(KERN_ALERT "interval tree insert/remove"); |
53 | 54 | ||
54 | prandom32_seed(&rnd, 3141592653589793238ULL); | 55 | prandom_seed_state(&rnd, 3141592653589793238ULL); |
55 | init(); | 56 | init(); |
56 | 57 | ||
57 | time1 = get_cycles(); | 58 | time1 = get_cycles(); |
diff --git a/lib/kfifo.c b/lib/kfifo.c new file mode 100644 index 000000000000..7b7f83027b7b --- /dev/null +++ b/lib/kfifo.c | |||
@@ -0,0 +1,607 @@ | |||
1 | /* | ||
2 | * A generic kernel FIFO implementation | ||
3 | * | ||
4 | * Copyright (C) 2009/2010 Stefani Seibold <stefani@seibold.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/export.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/log2.h> | ||
27 | #include <linux/uaccess.h> | ||
28 | #include <linux/kfifo.h> | ||
29 | |||
30 | /* | ||
31 | * internal helper to calculate the unused elements in a fifo | ||
32 | */ | ||
33 | static inline unsigned int kfifo_unused(struct __kfifo *fifo) | ||
34 | { | ||
35 | return (fifo->mask + 1) - (fifo->in - fifo->out); | ||
36 | } | ||
37 | |||
38 | int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, | ||
39 | size_t esize, gfp_t gfp_mask) | ||
40 | { | ||
41 | /* | ||
42 | * round down to the next power of 2, since our 'let the indices | ||
43 | * wrap' technique works only in this case. | ||
44 | */ | ||
45 | size = roundup_pow_of_two(size); | ||
46 | |||
47 | fifo->in = 0; | ||
48 | fifo->out = 0; | ||
49 | fifo->esize = esize; | ||
50 | |||
51 | if (size < 2) { | ||
52 | fifo->data = NULL; | ||
53 | fifo->mask = 0; | ||
54 | return -EINVAL; | ||
55 | } | ||
56 | |||
57 | fifo->data = kmalloc(size * esize, gfp_mask); | ||
58 | |||
59 | if (!fifo->data) { | ||
60 | fifo->mask = 0; | ||
61 | return -ENOMEM; | ||
62 | } | ||
63 | fifo->mask = size - 1; | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | EXPORT_SYMBOL(__kfifo_alloc); | ||
68 | |||
69 | void __kfifo_free(struct __kfifo *fifo) | ||
70 | { | ||
71 | kfree(fifo->data); | ||
72 | fifo->in = 0; | ||
73 | fifo->out = 0; | ||
74 | fifo->esize = 0; | ||
75 | fifo->data = NULL; | ||
76 | fifo->mask = 0; | ||
77 | } | ||
78 | EXPORT_SYMBOL(__kfifo_free); | ||
79 | |||
80 | int __kfifo_init(struct __kfifo *fifo, void *buffer, | ||
81 | unsigned int size, size_t esize) | ||
82 | { | ||
83 | size /= esize; | ||
84 | |||
85 | size = roundup_pow_of_two(size); | ||
86 | |||
87 | fifo->in = 0; | ||
88 | fifo->out = 0; | ||
89 | fifo->esize = esize; | ||
90 | fifo->data = buffer; | ||
91 | |||
92 | if (size < 2) { | ||
93 | fifo->mask = 0; | ||
94 | return -EINVAL; | ||
95 | } | ||
96 | fifo->mask = size - 1; | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | EXPORT_SYMBOL(__kfifo_init); | ||
101 | |||
102 | static void kfifo_copy_in(struct __kfifo *fifo, const void *src, | ||
103 | unsigned int len, unsigned int off) | ||
104 | { | ||
105 | unsigned int size = fifo->mask + 1; | ||
106 | unsigned int esize = fifo->esize; | ||
107 | unsigned int l; | ||
108 | |||
109 | off &= fifo->mask; | ||
110 | if (esize != 1) { | ||
111 | off *= esize; | ||
112 | size *= esize; | ||
113 | len *= esize; | ||
114 | } | ||
115 | l = min(len, size - off); | ||
116 | |||
117 | memcpy(fifo->data + off, src, l); | ||
118 | memcpy(fifo->data, src + l, len - l); | ||
119 | /* | ||
120 | * make sure that the data in the fifo is up to date before | ||
121 | * incrementing the fifo->in index counter | ||
122 | */ | ||
123 | smp_wmb(); | ||
124 | } | ||
125 | |||
126 | unsigned int __kfifo_in(struct __kfifo *fifo, | ||
127 | const void *buf, unsigned int len) | ||
128 | { | ||
129 | unsigned int l; | ||
130 | |||
131 | l = kfifo_unused(fifo); | ||
132 | if (len > l) | ||
133 | len = l; | ||
134 | |||
135 | kfifo_copy_in(fifo, buf, len, fifo->in); | ||
136 | fifo->in += len; | ||
137 | return len; | ||
138 | } | ||
139 | EXPORT_SYMBOL(__kfifo_in); | ||
140 | |||
141 | static void kfifo_copy_out(struct __kfifo *fifo, void *dst, | ||
142 | unsigned int len, unsigned int off) | ||
143 | { | ||
144 | unsigned int size = fifo->mask + 1; | ||
145 | unsigned int esize = fifo->esize; | ||
146 | unsigned int l; | ||
147 | |||
148 | off &= fifo->mask; | ||
149 | if (esize != 1) { | ||
150 | off *= esize; | ||
151 | size *= esize; | ||
152 | len *= esize; | ||
153 | } | ||
154 | l = min(len, size - off); | ||
155 | |||
156 | memcpy(dst, fifo->data + off, l); | ||
157 | memcpy(dst + l, fifo->data, len - l); | ||
158 | /* | ||
159 | * make sure that the data is copied before | ||
160 | * incrementing the fifo->out index counter | ||
161 | */ | ||
162 | smp_wmb(); | ||
163 | } | ||
164 | |||
165 | unsigned int __kfifo_out_peek(struct __kfifo *fifo, | ||
166 | void *buf, unsigned int len) | ||
167 | { | ||
168 | unsigned int l; | ||
169 | |||
170 | l = fifo->in - fifo->out; | ||
171 | if (len > l) | ||
172 | len = l; | ||
173 | |||
174 | kfifo_copy_out(fifo, buf, len, fifo->out); | ||
175 | return len; | ||
176 | } | ||
177 | EXPORT_SYMBOL(__kfifo_out_peek); | ||
178 | |||
179 | unsigned int __kfifo_out(struct __kfifo *fifo, | ||
180 | void *buf, unsigned int len) | ||
181 | { | ||
182 | len = __kfifo_out_peek(fifo, buf, len); | ||
183 | fifo->out += len; | ||
184 | return len; | ||
185 | } | ||
186 | EXPORT_SYMBOL(__kfifo_out); | ||
187 | |||
188 | static unsigned long kfifo_copy_from_user(struct __kfifo *fifo, | ||
189 | const void __user *from, unsigned int len, unsigned int off, | ||
190 | unsigned int *copied) | ||
191 | { | ||
192 | unsigned int size = fifo->mask + 1; | ||
193 | unsigned int esize = fifo->esize; | ||
194 | unsigned int l; | ||
195 | unsigned long ret; | ||
196 | |||
197 | off &= fifo->mask; | ||
198 | if (esize != 1) { | ||
199 | off *= esize; | ||
200 | size *= esize; | ||
201 | len *= esize; | ||
202 | } | ||
203 | l = min(len, size - off); | ||
204 | |||
205 | ret = copy_from_user(fifo->data + off, from, l); | ||
206 | if (unlikely(ret)) | ||
207 | ret = DIV_ROUND_UP(ret + len - l, esize); | ||
208 | else { | ||
209 | ret = copy_from_user(fifo->data, from + l, len - l); | ||
210 | if (unlikely(ret)) | ||
211 | ret = DIV_ROUND_UP(ret, esize); | ||
212 | } | ||
213 | /* | ||
214 | * make sure that the data in the fifo is up to date before | ||
215 | * incrementing the fifo->in index counter | ||
216 | */ | ||
217 | smp_wmb(); | ||
218 | *copied = len - ret; | ||
219 | /* return the number of elements which are not copied */ | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | int __kfifo_from_user(struct __kfifo *fifo, const void __user *from, | ||
224 | unsigned long len, unsigned int *copied) | ||
225 | { | ||
226 | unsigned int l; | ||
227 | unsigned long ret; | ||
228 | unsigned int esize = fifo->esize; | ||
229 | int err; | ||
230 | |||
231 | if (esize != 1) | ||
232 | len /= esize; | ||
233 | |||
234 | l = kfifo_unused(fifo); | ||
235 | if (len > l) | ||
236 | len = l; | ||
237 | |||
238 | ret = kfifo_copy_from_user(fifo, from, len, fifo->in, copied); | ||
239 | if (unlikely(ret)) { | ||
240 | len -= ret; | ||
241 | err = -EFAULT; | ||
242 | } else | ||
243 | err = 0; | ||
244 | fifo->in += len; | ||
245 | return err; | ||
246 | } | ||
247 | EXPORT_SYMBOL(__kfifo_from_user); | ||
248 | |||
249 | static unsigned long kfifo_copy_to_user(struct __kfifo *fifo, void __user *to, | ||
250 | unsigned int len, unsigned int off, unsigned int *copied) | ||
251 | { | ||
252 | unsigned int l; | ||
253 | unsigned long ret; | ||
254 | unsigned int size = fifo->mask + 1; | ||
255 | unsigned int esize = fifo->esize; | ||
256 | |||
257 | off &= fifo->mask; | ||
258 | if (esize != 1) { | ||
259 | off *= esize; | ||
260 | size *= esize; | ||
261 | len *= esize; | ||
262 | } | ||
263 | l = min(len, size - off); | ||
264 | |||
265 | ret = copy_to_user(to, fifo->data + off, l); | ||
266 | if (unlikely(ret)) | ||
267 | ret = DIV_ROUND_UP(ret + len - l, esize); | ||
268 | else { | ||
269 | ret = copy_to_user(to + l, fifo->data, len - l); | ||
270 | if (unlikely(ret)) | ||
271 | ret = DIV_ROUND_UP(ret, esize); | ||
272 | } | ||
273 | /* | ||
274 | * make sure that the data is copied before | ||
275 | * incrementing the fifo->out index counter | ||
276 | */ | ||
277 | smp_wmb(); | ||
278 | *copied = len - ret; | ||
279 | /* return the number of elements which are not copied */ | ||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | int __kfifo_to_user(struct __kfifo *fifo, void __user *to, | ||
284 | unsigned long len, unsigned int *copied) | ||
285 | { | ||
286 | unsigned int l; | ||
287 | unsigned long ret; | ||
288 | unsigned int esize = fifo->esize; | ||
289 | int err; | ||
290 | |||
291 | if (esize != 1) | ||
292 | len /= esize; | ||
293 | |||
294 | l = fifo->in - fifo->out; | ||
295 | if (len > l) | ||
296 | len = l; | ||
297 | ret = kfifo_copy_to_user(fifo, to, len, fifo->out, copied); | ||
298 | if (unlikely(ret)) { | ||
299 | len -= ret; | ||
300 | err = -EFAULT; | ||
301 | } else | ||
302 | err = 0; | ||
303 | fifo->out += len; | ||
304 | return err; | ||
305 | } | ||
306 | EXPORT_SYMBOL(__kfifo_to_user); | ||
307 | |||
308 | static int setup_sgl_buf(struct scatterlist *sgl, void *buf, | ||
309 | int nents, unsigned int len) | ||
310 | { | ||
311 | int n; | ||
312 | unsigned int l; | ||
313 | unsigned int off; | ||
314 | struct page *page; | ||
315 | |||
316 | if (!nents) | ||
317 | return 0; | ||
318 | |||
319 | if (!len) | ||
320 | return 0; | ||
321 | |||
322 | n = 0; | ||
323 | page = virt_to_page(buf); | ||
324 | off = offset_in_page(buf); | ||
325 | l = 0; | ||
326 | |||
327 | while (len >= l + PAGE_SIZE - off) { | ||
328 | struct page *npage; | ||
329 | |||
330 | l += PAGE_SIZE; | ||
331 | buf += PAGE_SIZE; | ||
332 | npage = virt_to_page(buf); | ||
333 | if (page_to_phys(page) != page_to_phys(npage) - l) { | ||
334 | sg_set_page(sgl, page, l - off, off); | ||
335 | sgl = sg_next(sgl); | ||
336 | if (++n == nents || sgl == NULL) | ||
337 | return n; | ||
338 | page = npage; | ||
339 | len -= l - off; | ||
340 | l = off = 0; | ||
341 | } | ||
342 | } | ||
343 | sg_set_page(sgl, page, len, off); | ||
344 | return n + 1; | ||
345 | } | ||
346 | |||
347 | static unsigned int setup_sgl(struct __kfifo *fifo, struct scatterlist *sgl, | ||
348 | int nents, unsigned int len, unsigned int off) | ||
349 | { | ||
350 | unsigned int size = fifo->mask + 1; | ||
351 | unsigned int esize = fifo->esize; | ||
352 | unsigned int l; | ||
353 | unsigned int n; | ||
354 | |||
355 | off &= fifo->mask; | ||
356 | if (esize != 1) { | ||
357 | off *= esize; | ||
358 | size *= esize; | ||
359 | len *= esize; | ||
360 | } | ||
361 | l = min(len, size - off); | ||
362 | |||
363 | n = setup_sgl_buf(sgl, fifo->data + off, nents, l); | ||
364 | n += setup_sgl_buf(sgl + n, fifo->data, nents - n, len - l); | ||
365 | |||
366 | return n; | ||
367 | } | ||
368 | |||
369 | unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo, | ||
370 | struct scatterlist *sgl, int nents, unsigned int len) | ||
371 | { | ||
372 | unsigned int l; | ||
373 | |||
374 | l = kfifo_unused(fifo); | ||
375 | if (len > l) | ||
376 | len = l; | ||
377 | |||
378 | return setup_sgl(fifo, sgl, nents, len, fifo->in); | ||
379 | } | ||
380 | EXPORT_SYMBOL(__kfifo_dma_in_prepare); | ||
381 | |||
382 | unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo, | ||
383 | struct scatterlist *sgl, int nents, unsigned int len) | ||
384 | { | ||
385 | unsigned int l; | ||
386 | |||
387 | l = fifo->in - fifo->out; | ||
388 | if (len > l) | ||
389 | len = l; | ||
390 | |||
391 | return setup_sgl(fifo, sgl, nents, len, fifo->out); | ||
392 | } | ||
393 | EXPORT_SYMBOL(__kfifo_dma_out_prepare); | ||
394 | |||
395 | unsigned int __kfifo_max_r(unsigned int len, size_t recsize) | ||
396 | { | ||
397 | unsigned int max = (1 << (recsize << 3)) - 1; | ||
398 | |||
399 | if (len > max) | ||
400 | return max; | ||
401 | return len; | ||
402 | } | ||
403 | EXPORT_SYMBOL(__kfifo_max_r); | ||
404 | |||
405 | #define __KFIFO_PEEK(data, out, mask) \ | ||
406 | ((data)[(out) & (mask)]) | ||
407 | /* | ||
408 | * __kfifo_peek_n internal helper function for determinate the length of | ||
409 | * the next record in the fifo | ||
410 | */ | ||
411 | static unsigned int __kfifo_peek_n(struct __kfifo *fifo, size_t recsize) | ||
412 | { | ||
413 | unsigned int l; | ||
414 | unsigned int mask = fifo->mask; | ||
415 | unsigned char *data = fifo->data; | ||
416 | |||
417 | l = __KFIFO_PEEK(data, fifo->out, mask); | ||
418 | |||
419 | if (--recsize) | ||
420 | l |= __KFIFO_PEEK(data, fifo->out + 1, mask) << 8; | ||
421 | |||
422 | return l; | ||
423 | } | ||
424 | |||
425 | #define __KFIFO_POKE(data, in, mask, val) \ | ||
426 | ( \ | ||
427 | (data)[(in) & (mask)] = (unsigned char)(val) \ | ||
428 | ) | ||
429 | |||
430 | /* | ||
431 | * __kfifo_poke_n internal helper function for storeing the length of | ||
432 | * the record into the fifo | ||
433 | */ | ||
434 | static void __kfifo_poke_n(struct __kfifo *fifo, unsigned int n, size_t recsize) | ||
435 | { | ||
436 | unsigned int mask = fifo->mask; | ||
437 | unsigned char *data = fifo->data; | ||
438 | |||
439 | __KFIFO_POKE(data, fifo->in, mask, n); | ||
440 | |||
441 | if (recsize > 1) | ||
442 | __KFIFO_POKE(data, fifo->in + 1, mask, n >> 8); | ||
443 | } | ||
444 | |||
445 | unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize) | ||
446 | { | ||
447 | return __kfifo_peek_n(fifo, recsize); | ||
448 | } | ||
449 | EXPORT_SYMBOL(__kfifo_len_r); | ||
450 | |||
451 | unsigned int __kfifo_in_r(struct __kfifo *fifo, const void *buf, | ||
452 | unsigned int len, size_t recsize) | ||
453 | { | ||
454 | if (len + recsize > kfifo_unused(fifo)) | ||
455 | return 0; | ||
456 | |||
457 | __kfifo_poke_n(fifo, len, recsize); | ||
458 | |||
459 | kfifo_copy_in(fifo, buf, len, fifo->in + recsize); | ||
460 | fifo->in += len + recsize; | ||
461 | return len; | ||
462 | } | ||
463 | EXPORT_SYMBOL(__kfifo_in_r); | ||
464 | |||
465 | static unsigned int kfifo_out_copy_r(struct __kfifo *fifo, | ||
466 | void *buf, unsigned int len, size_t recsize, unsigned int *n) | ||
467 | { | ||
468 | *n = __kfifo_peek_n(fifo, recsize); | ||
469 | |||
470 | if (len > *n) | ||
471 | len = *n; | ||
472 | |||
473 | kfifo_copy_out(fifo, buf, len, fifo->out + recsize); | ||
474 | return len; | ||
475 | } | ||
476 | |||
477 | unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, void *buf, | ||
478 | unsigned int len, size_t recsize) | ||
479 | { | ||
480 | unsigned int n; | ||
481 | |||
482 | if (fifo->in == fifo->out) | ||
483 | return 0; | ||
484 | |||
485 | return kfifo_out_copy_r(fifo, buf, len, recsize, &n); | ||
486 | } | ||
487 | EXPORT_SYMBOL(__kfifo_out_peek_r); | ||
488 | |||
489 | unsigned int __kfifo_out_r(struct __kfifo *fifo, void *buf, | ||
490 | unsigned int len, size_t recsize) | ||
491 | { | ||
492 | unsigned int n; | ||
493 | |||
494 | if (fifo->in == fifo->out) | ||
495 | return 0; | ||
496 | |||
497 | len = kfifo_out_copy_r(fifo, buf, len, recsize, &n); | ||
498 | fifo->out += n + recsize; | ||
499 | return len; | ||
500 | } | ||
501 | EXPORT_SYMBOL(__kfifo_out_r); | ||
502 | |||
503 | void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize) | ||
504 | { | ||
505 | unsigned int n; | ||
506 | |||
507 | n = __kfifo_peek_n(fifo, recsize); | ||
508 | fifo->out += n + recsize; | ||
509 | } | ||
510 | EXPORT_SYMBOL(__kfifo_skip_r); | ||
511 | |||
512 | int __kfifo_from_user_r(struct __kfifo *fifo, const void __user *from, | ||
513 | unsigned long len, unsigned int *copied, size_t recsize) | ||
514 | { | ||
515 | unsigned long ret; | ||
516 | |||
517 | len = __kfifo_max_r(len, recsize); | ||
518 | |||
519 | if (len + recsize > kfifo_unused(fifo)) { | ||
520 | *copied = 0; | ||
521 | return 0; | ||
522 | } | ||
523 | |||
524 | __kfifo_poke_n(fifo, len, recsize); | ||
525 | |||
526 | ret = kfifo_copy_from_user(fifo, from, len, fifo->in + recsize, copied); | ||
527 | if (unlikely(ret)) { | ||
528 | *copied = 0; | ||
529 | return -EFAULT; | ||
530 | } | ||
531 | fifo->in += len + recsize; | ||
532 | return 0; | ||
533 | } | ||
534 | EXPORT_SYMBOL(__kfifo_from_user_r); | ||
535 | |||
536 | int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to, | ||
537 | unsigned long len, unsigned int *copied, size_t recsize) | ||
538 | { | ||
539 | unsigned long ret; | ||
540 | unsigned int n; | ||
541 | |||
542 | if (fifo->in == fifo->out) { | ||
543 | *copied = 0; | ||
544 | return 0; | ||
545 | } | ||
546 | |||
547 | n = __kfifo_peek_n(fifo, recsize); | ||
548 | if (len > n) | ||
549 | len = n; | ||
550 | |||
551 | ret = kfifo_copy_to_user(fifo, to, len, fifo->out + recsize, copied); | ||
552 | if (unlikely(ret)) { | ||
553 | *copied = 0; | ||
554 | return -EFAULT; | ||
555 | } | ||
556 | fifo->out += n + recsize; | ||
557 | return 0; | ||
558 | } | ||
559 | EXPORT_SYMBOL(__kfifo_to_user_r); | ||
560 | |||
561 | unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo, | ||
562 | struct scatterlist *sgl, int nents, unsigned int len, size_t recsize) | ||
563 | { | ||
564 | if (!nents) | ||
565 | BUG(); | ||
566 | |||
567 | len = __kfifo_max_r(len, recsize); | ||
568 | |||
569 | if (len + recsize > kfifo_unused(fifo)) | ||
570 | return 0; | ||
571 | |||
572 | return setup_sgl(fifo, sgl, nents, len, fifo->in + recsize); | ||
573 | } | ||
574 | EXPORT_SYMBOL(__kfifo_dma_in_prepare_r); | ||
575 | |||
576 | void __kfifo_dma_in_finish_r(struct __kfifo *fifo, | ||
577 | unsigned int len, size_t recsize) | ||
578 | { | ||
579 | len = __kfifo_max_r(len, recsize); | ||
580 | __kfifo_poke_n(fifo, len, recsize); | ||
581 | fifo->in += len + recsize; | ||
582 | } | ||
583 | EXPORT_SYMBOL(__kfifo_dma_in_finish_r); | ||
584 | |||
585 | unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo, | ||
586 | struct scatterlist *sgl, int nents, unsigned int len, size_t recsize) | ||
587 | { | ||
588 | if (!nents) | ||
589 | BUG(); | ||
590 | |||
591 | len = __kfifo_max_r(len, recsize); | ||
592 | |||
593 | if (len + recsize > fifo->in - fifo->out) | ||
594 | return 0; | ||
595 | |||
596 | return setup_sgl(fifo, sgl, nents, len, fifo->out + recsize); | ||
597 | } | ||
598 | EXPORT_SYMBOL(__kfifo_dma_out_prepare_r); | ||
599 | |||
600 | void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize) | ||
601 | { | ||
602 | unsigned int len; | ||
603 | |||
604 | len = __kfifo_peek_n(fifo, recsize); | ||
605 | fifo->out += len + recsize; | ||
606 | } | ||
607 | EXPORT_SYMBOL(__kfifo_dma_out_finish_r); | ||
diff --git a/lib/kstrtox.c b/lib/kstrtox.c index c3615eab0cc3..f78ae0c0c4e2 100644 --- a/lib/kstrtox.c +++ b/lib/kstrtox.c | |||
@@ -104,6 +104,22 @@ static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res) | |||
104 | return 0; | 104 | return 0; |
105 | } | 105 | } |
106 | 106 | ||
107 | /** | ||
108 | * kstrtoull - convert a string to an unsigned long long | ||
109 | * @s: The start of the string. The string must be null-terminated, and may also | ||
110 | * include a single newline before its terminating null. The first character | ||
111 | * may also be a plus sign, but not a minus sign. | ||
112 | * @base: The number base to use. The maximum supported base is 16. If base is | ||
113 | * given as 0, then the base of the string is automatically detected with the | ||
114 | * conventional semantics - If it begins with 0x the number will be parsed as a | ||
115 | * hexadecimal (case insensitive), if it otherwise begins with 0, it will be | ||
116 | * parsed as an octal number. Otherwise it will be parsed as a decimal. | ||
117 | * @res: Where to write the result of the conversion on success. | ||
118 | * | ||
119 | * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. | ||
120 | * Used as a replacement for the obsolete simple_strtoull. Return code must | ||
121 | * be checked. | ||
122 | */ | ||
107 | int kstrtoull(const char *s, unsigned int base, unsigned long long *res) | 123 | int kstrtoull(const char *s, unsigned int base, unsigned long long *res) |
108 | { | 124 | { |
109 | if (s[0] == '+') | 125 | if (s[0] == '+') |
@@ -112,6 +128,22 @@ int kstrtoull(const char *s, unsigned int base, unsigned long long *res) | |||
112 | } | 128 | } |
113 | EXPORT_SYMBOL(kstrtoull); | 129 | EXPORT_SYMBOL(kstrtoull); |
114 | 130 | ||
131 | /** | ||
132 | * kstrtoll - convert a string to a long long | ||
133 | * @s: The start of the string. The string must be null-terminated, and may also | ||
134 | * include a single newline before its terminating null. The first character | ||
135 | * may also be a plus sign or a minus sign. | ||
136 | * @base: The number base to use. The maximum supported base is 16. If base is | ||
137 | * given as 0, then the base of the string is automatically detected with the | ||
138 | * conventional semantics - If it begins with 0x the number will be parsed as a | ||
139 | * hexadecimal (case insensitive), if it otherwise begins with 0, it will be | ||
140 | * parsed as an octal number. Otherwise it will be parsed as a decimal. | ||
141 | * @res: Where to write the result of the conversion on success. | ||
142 | * | ||
143 | * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. | ||
144 | * Used as a replacement for the obsolete simple_strtoull. Return code must | ||
145 | * be checked. | ||
146 | */ | ||
115 | int kstrtoll(const char *s, unsigned int base, long long *res) | 147 | int kstrtoll(const char *s, unsigned int base, long long *res) |
116 | { | 148 | { |
117 | unsigned long long tmp; | 149 | unsigned long long tmp; |
@@ -168,6 +200,22 @@ int _kstrtol(const char *s, unsigned int base, long *res) | |||
168 | } | 200 | } |
169 | EXPORT_SYMBOL(_kstrtol); | 201 | EXPORT_SYMBOL(_kstrtol); |
170 | 202 | ||
203 | /** | ||
204 | * kstrtouint - convert a string to an unsigned int | ||
205 | * @s: The start of the string. The string must be null-terminated, and may also | ||
206 | * include a single newline before its terminating null. The first character | ||
207 | * may also be a plus sign, but not a minus sign. | ||
208 | * @base: The number base to use. The maximum supported base is 16. If base is | ||
209 | * given as 0, then the base of the string is automatically detected with the | ||
210 | * conventional semantics - If it begins with 0x the number will be parsed as a | ||
211 | * hexadecimal (case insensitive), if it otherwise begins with 0, it will be | ||
212 | * parsed as an octal number. Otherwise it will be parsed as a decimal. | ||
213 | * @res: Where to write the result of the conversion on success. | ||
214 | * | ||
215 | * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. | ||
216 | * Used as a replacement for the obsolete simple_strtoull. Return code must | ||
217 | * be checked. | ||
218 | */ | ||
171 | int kstrtouint(const char *s, unsigned int base, unsigned int *res) | 219 | int kstrtouint(const char *s, unsigned int base, unsigned int *res) |
172 | { | 220 | { |
173 | unsigned long long tmp; | 221 | unsigned long long tmp; |
@@ -183,6 +231,22 @@ int kstrtouint(const char *s, unsigned int base, unsigned int *res) | |||
183 | } | 231 | } |
184 | EXPORT_SYMBOL(kstrtouint); | 232 | EXPORT_SYMBOL(kstrtouint); |
185 | 233 | ||
234 | /** | ||
235 | * kstrtoint - convert a string to an int | ||
236 | * @s: The start of the string. The string must be null-terminated, and may also | ||
237 | * include a single newline before its terminating null. The first character | ||
238 | * may also be a plus sign or a minus sign. | ||
239 | * @base: The number base to use. The maximum supported base is 16. If base is | ||
240 | * given as 0, then the base of the string is automatically detected with the | ||
241 | * conventional semantics - If it begins with 0x the number will be parsed as a | ||
242 | * hexadecimal (case insensitive), if it otherwise begins with 0, it will be | ||
243 | * parsed as an octal number. Otherwise it will be parsed as a decimal. | ||
244 | * @res: Where to write the result of the conversion on success. | ||
245 | * | ||
246 | * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. | ||
247 | * Used as a replacement for the obsolete simple_strtoull. Return code must | ||
248 | * be checked. | ||
249 | */ | ||
186 | int kstrtoint(const char *s, unsigned int base, int *res) | 250 | int kstrtoint(const char *s, unsigned int base, int *res) |
187 | { | 251 | { |
188 | long long tmp; | 252 | long long tmp; |
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index 7aae0f2a5e0a..c3eb261a7df3 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c | |||
@@ -47,10 +47,10 @@ __setup("debug_locks_verbose=", setup_debug_locks_verbose); | |||
47 | * Normal standalone locks, for the circular and irq-context | 47 | * Normal standalone locks, for the circular and irq-context |
48 | * dependency tests: | 48 | * dependency tests: |
49 | */ | 49 | */ |
50 | static DEFINE_SPINLOCK(lock_A); | 50 | static DEFINE_RAW_SPINLOCK(lock_A); |
51 | static DEFINE_SPINLOCK(lock_B); | 51 | static DEFINE_RAW_SPINLOCK(lock_B); |
52 | static DEFINE_SPINLOCK(lock_C); | 52 | static DEFINE_RAW_SPINLOCK(lock_C); |
53 | static DEFINE_SPINLOCK(lock_D); | 53 | static DEFINE_RAW_SPINLOCK(lock_D); |
54 | 54 | ||
55 | static DEFINE_RWLOCK(rwlock_A); | 55 | static DEFINE_RWLOCK(rwlock_A); |
56 | static DEFINE_RWLOCK(rwlock_B); | 56 | static DEFINE_RWLOCK(rwlock_B); |
@@ -73,12 +73,12 @@ static DECLARE_RWSEM(rwsem_D); | |||
73 | * but X* and Y* are different classes. We do this so that | 73 | * but X* and Y* are different classes. We do this so that |
74 | * we do not trigger a real lockup: | 74 | * we do not trigger a real lockup: |
75 | */ | 75 | */ |
76 | static DEFINE_SPINLOCK(lock_X1); | 76 | static DEFINE_RAW_SPINLOCK(lock_X1); |
77 | static DEFINE_SPINLOCK(lock_X2); | 77 | static DEFINE_RAW_SPINLOCK(lock_X2); |
78 | static DEFINE_SPINLOCK(lock_Y1); | 78 | static DEFINE_RAW_SPINLOCK(lock_Y1); |
79 | static DEFINE_SPINLOCK(lock_Y2); | 79 | static DEFINE_RAW_SPINLOCK(lock_Y2); |
80 | static DEFINE_SPINLOCK(lock_Z1); | 80 | static DEFINE_RAW_SPINLOCK(lock_Z1); |
81 | static DEFINE_SPINLOCK(lock_Z2); | 81 | static DEFINE_RAW_SPINLOCK(lock_Z2); |
82 | 82 | ||
83 | static DEFINE_RWLOCK(rwlock_X1); | 83 | static DEFINE_RWLOCK(rwlock_X1); |
84 | static DEFINE_RWLOCK(rwlock_X2); | 84 | static DEFINE_RWLOCK(rwlock_X2); |
@@ -107,10 +107,10 @@ static DECLARE_RWSEM(rwsem_Z2); | |||
107 | */ | 107 | */ |
108 | #define INIT_CLASS_FUNC(class) \ | 108 | #define INIT_CLASS_FUNC(class) \ |
109 | static noinline void \ | 109 | static noinline void \ |
110 | init_class_##class(spinlock_t *lock, rwlock_t *rwlock, struct mutex *mutex, \ | 110 | init_class_##class(raw_spinlock_t *lock, rwlock_t *rwlock, \ |
111 | struct rw_semaphore *rwsem) \ | 111 | struct mutex *mutex, struct rw_semaphore *rwsem)\ |
112 | { \ | 112 | { \ |
113 | spin_lock_init(lock); \ | 113 | raw_spin_lock_init(lock); \ |
114 | rwlock_init(rwlock); \ | 114 | rwlock_init(rwlock); \ |
115 | mutex_init(mutex); \ | 115 | mutex_init(mutex); \ |
116 | init_rwsem(rwsem); \ | 116 | init_rwsem(rwsem); \ |
@@ -168,10 +168,10 @@ static void init_shared_classes(void) | |||
168 | * Shortcuts for lock/unlock API variants, to keep | 168 | * Shortcuts for lock/unlock API variants, to keep |
169 | * the testcases compact: | 169 | * the testcases compact: |
170 | */ | 170 | */ |
171 | #define L(x) spin_lock(&lock_##x) | 171 | #define L(x) raw_spin_lock(&lock_##x) |
172 | #define U(x) spin_unlock(&lock_##x) | 172 | #define U(x) raw_spin_unlock(&lock_##x) |
173 | #define LU(x) L(x); U(x) | 173 | #define LU(x) L(x); U(x) |
174 | #define SI(x) spin_lock_init(&lock_##x) | 174 | #define SI(x) raw_spin_lock_init(&lock_##x) |
175 | 175 | ||
176 | #define WL(x) write_lock(&rwlock_##x) | 176 | #define WL(x) write_lock(&rwlock_##x) |
177 | #define WU(x) write_unlock(&rwlock_##x) | 177 | #define WU(x) write_unlock(&rwlock_##x) |
@@ -911,7 +911,7 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft) | |||
911 | 911 | ||
912 | #define I2(x) \ | 912 | #define I2(x) \ |
913 | do { \ | 913 | do { \ |
914 | spin_lock_init(&lock_##x); \ | 914 | raw_spin_lock_init(&lock_##x); \ |
915 | rwlock_init(&rwlock_##x); \ | 915 | rwlock_init(&rwlock_##x); \ |
916 | mutex_init(&mutex_##x); \ | 916 | mutex_init(&mutex_##x); \ |
917 | init_rwsem(&rwsem_##x); \ | 917 | init_rwsem(&rwsem_##x); \ |
diff --git a/lib/lru_cache.c b/lib/lru_cache.c index a07e7268d7ed..8335d39d2ccd 100644 --- a/lib/lru_cache.c +++ b/lib/lru_cache.c | |||
@@ -44,8 +44,8 @@ MODULE_LICENSE("GPL"); | |||
44 | } while (0) | 44 | } while (0) |
45 | 45 | ||
46 | #define RETURN(x...) do { \ | 46 | #define RETURN(x...) do { \ |
47 | clear_bit(__LC_PARANOIA, &lc->flags); \ | 47 | clear_bit_unlock(__LC_PARANOIA, &lc->flags); \ |
48 | smp_mb__after_clear_bit(); return x ; } while (0) | 48 | return x ; } while (0) |
49 | 49 | ||
50 | /* BUG() if e is not one of the elements tracked by lc */ | 50 | /* BUG() if e is not one of the elements tracked by lc */ |
51 | #define PARANOIA_LC_ELEMENT(lc, e) do { \ | 51 | #define PARANOIA_LC_ELEMENT(lc, e) do { \ |
@@ -55,9 +55,40 @@ MODULE_LICENSE("GPL"); | |||
55 | BUG_ON(i >= lc_->nr_elements); \ | 55 | BUG_ON(i >= lc_->nr_elements); \ |
56 | BUG_ON(lc_->lc_element[i] != e_); } while (0) | 56 | BUG_ON(lc_->lc_element[i] != e_); } while (0) |
57 | 57 | ||
58 | |||
59 | /* We need to atomically | ||
60 | * - try to grab the lock (set LC_LOCKED) | ||
61 | * - only if there is no pending transaction | ||
62 | * (neither LC_DIRTY nor LC_STARVING is set) | ||
63 | * Because of PARANOIA_ENTRY() above abusing lc->flags as well, | ||
64 | * it is not sufficient to just say | ||
65 | * return 0 == cmpxchg(&lc->flags, 0, LC_LOCKED); | ||
66 | */ | ||
67 | int lc_try_lock(struct lru_cache *lc) | ||
68 | { | ||
69 | unsigned long val; | ||
70 | do { | ||
71 | val = cmpxchg(&lc->flags, 0, LC_LOCKED); | ||
72 | } while (unlikely (val == LC_PARANOIA)); | ||
73 | /* Spin until no-one is inside a PARANOIA_ENTRY()/RETURN() section. */ | ||
74 | return 0 == val; | ||
75 | #if 0 | ||
76 | /* Alternative approach, spin in case someone enters or leaves a | ||
77 | * PARANOIA_ENTRY()/RETURN() section. */ | ||
78 | unsigned long old, new, val; | ||
79 | do { | ||
80 | old = lc->flags & LC_PARANOIA; | ||
81 | new = old | LC_LOCKED; | ||
82 | val = cmpxchg(&lc->flags, old, new); | ||
83 | } while (unlikely (val == (old ^ LC_PARANOIA))); | ||
84 | return old == val; | ||
85 | #endif | ||
86 | } | ||
87 | |||
58 | /** | 88 | /** |
59 | * lc_create - prepares to track objects in an active set | 89 | * lc_create - prepares to track objects in an active set |
60 | * @name: descriptive name only used in lc_seq_printf_stats and lc_seq_dump_details | 90 | * @name: descriptive name only used in lc_seq_printf_stats and lc_seq_dump_details |
91 | * @max_pending_changes: maximum changes to accumulate until a transaction is required | ||
61 | * @e_count: number of elements allowed to be active simultaneously | 92 | * @e_count: number of elements allowed to be active simultaneously |
62 | * @e_size: size of the tracked objects | 93 | * @e_size: size of the tracked objects |
63 | * @e_off: offset to the &struct lc_element member in a tracked object | 94 | * @e_off: offset to the &struct lc_element member in a tracked object |
@@ -66,6 +97,7 @@ MODULE_LICENSE("GPL"); | |||
66 | * or NULL on (allocation) failure. | 97 | * or NULL on (allocation) failure. |
67 | */ | 98 | */ |
68 | struct lru_cache *lc_create(const char *name, struct kmem_cache *cache, | 99 | struct lru_cache *lc_create(const char *name, struct kmem_cache *cache, |
100 | unsigned max_pending_changes, | ||
69 | unsigned e_count, size_t e_size, size_t e_off) | 101 | unsigned e_count, size_t e_size, size_t e_off) |
70 | { | 102 | { |
71 | struct hlist_head *slot = NULL; | 103 | struct hlist_head *slot = NULL; |
@@ -98,12 +130,13 @@ struct lru_cache *lc_create(const char *name, struct kmem_cache *cache, | |||
98 | INIT_LIST_HEAD(&lc->in_use); | 130 | INIT_LIST_HEAD(&lc->in_use); |
99 | INIT_LIST_HEAD(&lc->lru); | 131 | INIT_LIST_HEAD(&lc->lru); |
100 | INIT_LIST_HEAD(&lc->free); | 132 | INIT_LIST_HEAD(&lc->free); |
133 | INIT_LIST_HEAD(&lc->to_be_changed); | ||
101 | 134 | ||
102 | lc->name = name; | 135 | lc->name = name; |
103 | lc->element_size = e_size; | 136 | lc->element_size = e_size; |
104 | lc->element_off = e_off; | 137 | lc->element_off = e_off; |
105 | lc->nr_elements = e_count; | 138 | lc->nr_elements = e_count; |
106 | lc->new_number = LC_FREE; | 139 | lc->max_pending_changes = max_pending_changes; |
107 | lc->lc_cache = cache; | 140 | lc->lc_cache = cache; |
108 | lc->lc_element = element; | 141 | lc->lc_element = element; |
109 | lc->lc_slot = slot; | 142 | lc->lc_slot = slot; |
@@ -117,6 +150,7 @@ struct lru_cache *lc_create(const char *name, struct kmem_cache *cache, | |||
117 | e = p + e_off; | 150 | e = p + e_off; |
118 | e->lc_index = i; | 151 | e->lc_index = i; |
119 | e->lc_number = LC_FREE; | 152 | e->lc_number = LC_FREE; |
153 | e->lc_new_number = LC_FREE; | ||
120 | list_add(&e->list, &lc->free); | 154 | list_add(&e->list, &lc->free); |
121 | element[i] = e; | 155 | element[i] = e; |
122 | } | 156 | } |
@@ -175,15 +209,15 @@ void lc_reset(struct lru_cache *lc) | |||
175 | INIT_LIST_HEAD(&lc->in_use); | 209 | INIT_LIST_HEAD(&lc->in_use); |
176 | INIT_LIST_HEAD(&lc->lru); | 210 | INIT_LIST_HEAD(&lc->lru); |
177 | INIT_LIST_HEAD(&lc->free); | 211 | INIT_LIST_HEAD(&lc->free); |
212 | INIT_LIST_HEAD(&lc->to_be_changed); | ||
178 | lc->used = 0; | 213 | lc->used = 0; |
179 | lc->hits = 0; | 214 | lc->hits = 0; |
180 | lc->misses = 0; | 215 | lc->misses = 0; |
181 | lc->starving = 0; | 216 | lc->starving = 0; |
182 | lc->dirty = 0; | 217 | lc->locked = 0; |
183 | lc->changed = 0; | 218 | lc->changed = 0; |
219 | lc->pending_changes = 0; | ||
184 | lc->flags = 0; | 220 | lc->flags = 0; |
185 | lc->changing_element = NULL; | ||
186 | lc->new_number = LC_FREE; | ||
187 | memset(lc->lc_slot, 0, sizeof(struct hlist_head) * lc->nr_elements); | 221 | memset(lc->lc_slot, 0, sizeof(struct hlist_head) * lc->nr_elements); |
188 | 222 | ||
189 | for (i = 0; i < lc->nr_elements; i++) { | 223 | for (i = 0; i < lc->nr_elements; i++) { |
@@ -194,6 +228,7 @@ void lc_reset(struct lru_cache *lc) | |||
194 | /* re-init it */ | 228 | /* re-init it */ |
195 | e->lc_index = i; | 229 | e->lc_index = i; |
196 | e->lc_number = LC_FREE; | 230 | e->lc_number = LC_FREE; |
231 | e->lc_new_number = LC_FREE; | ||
197 | list_add(&e->list, &lc->free); | 232 | list_add(&e->list, &lc->free); |
198 | } | 233 | } |
199 | } | 234 | } |
@@ -208,14 +243,14 @@ size_t lc_seq_printf_stats(struct seq_file *seq, struct lru_cache *lc) | |||
208 | /* NOTE: | 243 | /* NOTE: |
209 | * total calls to lc_get are | 244 | * total calls to lc_get are |
210 | * (starving + hits + misses) | 245 | * (starving + hits + misses) |
211 | * misses include "dirty" count (update from an other thread in | 246 | * misses include "locked" count (update from an other thread in |
212 | * progress) and "changed", when this in fact lead to an successful | 247 | * progress) and "changed", when this in fact lead to an successful |
213 | * update of the cache. | 248 | * update of the cache. |
214 | */ | 249 | */ |
215 | return seq_printf(seq, "\t%s: used:%u/%u " | 250 | return seq_printf(seq, "\t%s: used:%u/%u " |
216 | "hits:%lu misses:%lu starving:%lu dirty:%lu changed:%lu\n", | 251 | "hits:%lu misses:%lu starving:%lu locked:%lu changed:%lu\n", |
217 | lc->name, lc->used, lc->nr_elements, | 252 | lc->name, lc->used, lc->nr_elements, |
218 | lc->hits, lc->misses, lc->starving, lc->dirty, lc->changed); | 253 | lc->hits, lc->misses, lc->starving, lc->locked, lc->changed); |
219 | } | 254 | } |
220 | 255 | ||
221 | static struct hlist_head *lc_hash_slot(struct lru_cache *lc, unsigned int enr) | 256 | static struct hlist_head *lc_hash_slot(struct lru_cache *lc, unsigned int enr) |
@@ -224,6 +259,26 @@ static struct hlist_head *lc_hash_slot(struct lru_cache *lc, unsigned int enr) | |||
224 | } | 259 | } |
225 | 260 | ||
226 | 261 | ||
262 | static struct lc_element *__lc_find(struct lru_cache *lc, unsigned int enr, | ||
263 | bool include_changing) | ||
264 | { | ||
265 | struct lc_element *e; | ||
266 | |||
267 | BUG_ON(!lc); | ||
268 | BUG_ON(!lc->nr_elements); | ||
269 | hlist_for_each_entry(e, lc_hash_slot(lc, enr), colision) { | ||
270 | /* "about to be changed" elements, pending transaction commit, | ||
271 | * are hashed by their "new number". "Normal" elements have | ||
272 | * lc_number == lc_new_number. */ | ||
273 | if (e->lc_new_number != enr) | ||
274 | continue; | ||
275 | if (e->lc_new_number == e->lc_number || include_changing) | ||
276 | return e; | ||
277 | break; | ||
278 | } | ||
279 | return NULL; | ||
280 | } | ||
281 | |||
227 | /** | 282 | /** |
228 | * lc_find - find element by label, if present in the hash table | 283 | * lc_find - find element by label, if present in the hash table |
229 | * @lc: The lru_cache object | 284 | * @lc: The lru_cache object |
@@ -232,38 +287,28 @@ static struct hlist_head *lc_hash_slot(struct lru_cache *lc, unsigned int enr) | |||
232 | * Returns the pointer to an element, if the element with the requested | 287 | * Returns the pointer to an element, if the element with the requested |
233 | * "label" or element number is present in the hash table, | 288 | * "label" or element number is present in the hash table, |
234 | * or NULL if not found. Does not change the refcnt. | 289 | * or NULL if not found. Does not change the refcnt. |
290 | * Ignores elements that are "about to be used", i.e. not yet in the active | ||
291 | * set, but still pending transaction commit. | ||
235 | */ | 292 | */ |
236 | struct lc_element *lc_find(struct lru_cache *lc, unsigned int enr) | 293 | struct lc_element *lc_find(struct lru_cache *lc, unsigned int enr) |
237 | { | 294 | { |
238 | struct hlist_node *n; | 295 | return __lc_find(lc, enr, 0); |
239 | struct lc_element *e; | ||
240 | |||
241 | BUG_ON(!lc); | ||
242 | BUG_ON(!lc->nr_elements); | ||
243 | hlist_for_each_entry(e, n, lc_hash_slot(lc, enr), colision) { | ||
244 | if (e->lc_number == enr) | ||
245 | return e; | ||
246 | } | ||
247 | return NULL; | ||
248 | } | 296 | } |
249 | 297 | ||
250 | /* returned element will be "recycled" immediately */ | 298 | /** |
251 | static struct lc_element *lc_evict(struct lru_cache *lc) | 299 | * lc_is_used - find element by label |
300 | * @lc: The lru_cache object | ||
301 | * @enr: element number | ||
302 | * | ||
303 | * Returns true, if the element with the requested "label" or element number is | ||
304 | * present in the hash table, and is used (refcnt > 0). | ||
305 | * Also finds elements that are not _currently_ used but only "about to be | ||
306 | * used", i.e. on the "to_be_changed" list, pending transaction commit. | ||
307 | */ | ||
308 | bool lc_is_used(struct lru_cache *lc, unsigned int enr) | ||
252 | { | 309 | { |
253 | struct list_head *n; | 310 | struct lc_element *e = __lc_find(lc, enr, 1); |
254 | struct lc_element *e; | 311 | return e && e->refcnt; |
255 | |||
256 | if (list_empty(&lc->lru)) | ||
257 | return NULL; | ||
258 | |||
259 | n = lc->lru.prev; | ||
260 | e = list_entry(n, struct lc_element, list); | ||
261 | |||
262 | PARANOIA_LC_ELEMENT(lc, e); | ||
263 | |||
264 | list_del(&e->list); | ||
265 | hlist_del(&e->colision); | ||
266 | return e; | ||
267 | } | 312 | } |
268 | 313 | ||
269 | /** | 314 | /** |
@@ -280,22 +325,34 @@ void lc_del(struct lru_cache *lc, struct lc_element *e) | |||
280 | PARANOIA_LC_ELEMENT(lc, e); | 325 | PARANOIA_LC_ELEMENT(lc, e); |
281 | BUG_ON(e->refcnt); | 326 | BUG_ON(e->refcnt); |
282 | 327 | ||
283 | e->lc_number = LC_FREE; | 328 | e->lc_number = e->lc_new_number = LC_FREE; |
284 | hlist_del_init(&e->colision); | 329 | hlist_del_init(&e->colision); |
285 | list_move(&e->list, &lc->free); | 330 | list_move(&e->list, &lc->free); |
286 | RETURN(); | 331 | RETURN(); |
287 | } | 332 | } |
288 | 333 | ||
289 | static struct lc_element *lc_get_unused_element(struct lru_cache *lc) | 334 | static struct lc_element *lc_prepare_for_change(struct lru_cache *lc, unsigned new_number) |
290 | { | 335 | { |
291 | struct list_head *n; | 336 | struct list_head *n; |
337 | struct lc_element *e; | ||
338 | |||
339 | if (!list_empty(&lc->free)) | ||
340 | n = lc->free.next; | ||
341 | else if (!list_empty(&lc->lru)) | ||
342 | n = lc->lru.prev; | ||
343 | else | ||
344 | return NULL; | ||
292 | 345 | ||
293 | if (list_empty(&lc->free)) | 346 | e = list_entry(n, struct lc_element, list); |
294 | return lc_evict(lc); | 347 | PARANOIA_LC_ELEMENT(lc, e); |
295 | 348 | ||
296 | n = lc->free.next; | 349 | e->lc_new_number = new_number; |
297 | list_del(n); | 350 | if (!hlist_unhashed(&e->colision)) |
298 | return list_entry(n, struct lc_element, list); | 351 | __hlist_del(&e->colision); |
352 | hlist_add_head(&e->colision, lc_hash_slot(lc, new_number)); | ||
353 | list_move(&e->list, &lc->to_be_changed); | ||
354 | |||
355 | return e; | ||
299 | } | 356 | } |
300 | 357 | ||
301 | static int lc_unused_element_available(struct lru_cache *lc) | 358 | static int lc_unused_element_available(struct lru_cache *lc) |
@@ -308,45 +365,7 @@ static int lc_unused_element_available(struct lru_cache *lc) | |||
308 | return 0; | 365 | return 0; |
309 | } | 366 | } |
310 | 367 | ||
311 | 368 | static struct lc_element *__lc_get(struct lru_cache *lc, unsigned int enr, bool may_change) | |
312 | /** | ||
313 | * lc_get - get element by label, maybe change the active set | ||
314 | * @lc: the lru cache to operate on | ||
315 | * @enr: the label to look up | ||
316 | * | ||
317 | * Finds an element in the cache, increases its usage count, | ||
318 | * "touches" and returns it. | ||
319 | * | ||
320 | * In case the requested number is not present, it needs to be added to the | ||
321 | * cache. Therefore it is possible that an other element becomes evicted from | ||
322 | * the cache. In either case, the user is notified so he is able to e.g. keep | ||
323 | * a persistent log of the cache changes, and therefore the objects in use. | ||
324 | * | ||
325 | * Return values: | ||
326 | * NULL | ||
327 | * The cache was marked %LC_STARVING, | ||
328 | * or the requested label was not in the active set | ||
329 | * and a changing transaction is still pending (@lc was marked %LC_DIRTY). | ||
330 | * Or no unused or free element could be recycled (@lc will be marked as | ||
331 | * %LC_STARVING, blocking further lc_get() operations). | ||
332 | * | ||
333 | * pointer to the element with the REQUESTED element number. | ||
334 | * In this case, it can be used right away | ||
335 | * | ||
336 | * pointer to an UNUSED element with some different element number, | ||
337 | * where that different number may also be %LC_FREE. | ||
338 | * | ||
339 | * In this case, the cache is marked %LC_DIRTY (blocking further changes), | ||
340 | * and the returned element pointer is removed from the lru list and | ||
341 | * hash collision chains. The user now should do whatever housekeeping | ||
342 | * is necessary. | ||
343 | * Then he must call lc_changed(lc,element_pointer), to finish | ||
344 | * the change. | ||
345 | * | ||
346 | * NOTE: The user needs to check the lc_number on EACH use, so he recognizes | ||
347 | * any cache set change. | ||
348 | */ | ||
349 | struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr) | ||
350 | { | 369 | { |
351 | struct lc_element *e; | 370 | struct lc_element *e; |
352 | 371 | ||
@@ -356,8 +375,12 @@ struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr) | |||
356 | RETURN(NULL); | 375 | RETURN(NULL); |
357 | } | 376 | } |
358 | 377 | ||
359 | e = lc_find(lc, enr); | 378 | e = __lc_find(lc, enr, 1); |
360 | if (e) { | 379 | /* if lc_new_number != lc_number, |
380 | * this enr is currently being pulled in already, | ||
381 | * and will be available once the pending transaction | ||
382 | * has been committed. */ | ||
383 | if (e && e->lc_new_number == e->lc_number) { | ||
361 | ++lc->hits; | 384 | ++lc->hits; |
362 | if (e->refcnt++ == 0) | 385 | if (e->refcnt++ == 0) |
363 | lc->used++; | 386 | lc->used++; |
@@ -366,6 +389,26 @@ struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr) | |||
366 | } | 389 | } |
367 | 390 | ||
368 | ++lc->misses; | 391 | ++lc->misses; |
392 | if (!may_change) | ||
393 | RETURN(NULL); | ||
394 | |||
395 | /* It has been found above, but on the "to_be_changed" list, not yet | ||
396 | * committed. Don't pull it in twice, wait for the transaction, then | ||
397 | * try again */ | ||
398 | if (e) | ||
399 | RETURN(NULL); | ||
400 | |||
401 | /* To avoid races with lc_try_lock(), first, mark us dirty | ||
402 | * (using test_and_set_bit, as it implies memory barriers), ... */ | ||
403 | test_and_set_bit(__LC_DIRTY, &lc->flags); | ||
404 | |||
405 | /* ... only then check if it is locked anyways. If lc_unlock clears | ||
406 | * the dirty bit again, that's not a problem, we will come here again. | ||
407 | */ | ||
408 | if (test_bit(__LC_LOCKED, &lc->flags)) { | ||
409 | ++lc->locked; | ||
410 | RETURN(NULL); | ||
411 | } | ||
369 | 412 | ||
370 | /* In case there is nothing available and we can not kick out | 413 | /* In case there is nothing available and we can not kick out |
371 | * the LRU element, we have to wait ... | 414 | * the LRU element, we have to wait ... |
@@ -375,71 +418,109 @@ struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr) | |||
375 | RETURN(NULL); | 418 | RETURN(NULL); |
376 | } | 419 | } |
377 | 420 | ||
378 | /* it was not present in the active set. | 421 | /* It was not present in the active set. We are going to recycle an |
379 | * we are going to recycle an unused (or even "free") element. | 422 | * unused (or even "free") element, but we won't accumulate more than |
380 | * user may need to commit a transaction to record that change. | 423 | * max_pending_changes changes. */ |
381 | * we serialize on flags & TF_DIRTY */ | 424 | if (lc->pending_changes >= lc->max_pending_changes) |
382 | if (test_and_set_bit(__LC_DIRTY, &lc->flags)) { | ||
383 | ++lc->dirty; | ||
384 | RETURN(NULL); | 425 | RETURN(NULL); |
385 | } | ||
386 | 426 | ||
387 | e = lc_get_unused_element(lc); | 427 | e = lc_prepare_for_change(lc, enr); |
388 | BUG_ON(!e); | 428 | BUG_ON(!e); |
389 | 429 | ||
390 | clear_bit(__LC_STARVING, &lc->flags); | 430 | clear_bit(__LC_STARVING, &lc->flags); |
391 | BUG_ON(++e->refcnt != 1); | 431 | BUG_ON(++e->refcnt != 1); |
392 | lc->used++; | 432 | lc->used++; |
393 | 433 | lc->pending_changes++; | |
394 | lc->changing_element = e; | ||
395 | lc->new_number = enr; | ||
396 | 434 | ||
397 | RETURN(e); | 435 | RETURN(e); |
398 | } | 436 | } |
399 | 437 | ||
400 | /* similar to lc_get, | 438 | /** |
401 | * but only gets a new reference on an existing element. | 439 | * lc_get - get element by label, maybe change the active set |
402 | * you either get the requested element, or NULL. | 440 | * @lc: the lru cache to operate on |
403 | * will be consolidated into one function. | 441 | * @enr: the label to look up |
442 | * | ||
443 | * Finds an element in the cache, increases its usage count, | ||
444 | * "touches" and returns it. | ||
445 | * | ||
446 | * In case the requested number is not present, it needs to be added to the | ||
447 | * cache. Therefore it is possible that an other element becomes evicted from | ||
448 | * the cache. In either case, the user is notified so he is able to e.g. keep | ||
449 | * a persistent log of the cache changes, and therefore the objects in use. | ||
450 | * | ||
451 | * Return values: | ||
452 | * NULL | ||
453 | * The cache was marked %LC_STARVING, | ||
454 | * or the requested label was not in the active set | ||
455 | * and a changing transaction is still pending (@lc was marked %LC_DIRTY). | ||
456 | * Or no unused or free element could be recycled (@lc will be marked as | ||
457 | * %LC_STARVING, blocking further lc_get() operations). | ||
458 | * | ||
459 | * pointer to the element with the REQUESTED element number. | ||
460 | * In this case, it can be used right away | ||
461 | * | ||
462 | * pointer to an UNUSED element with some different element number, | ||
463 | * where that different number may also be %LC_FREE. | ||
464 | * | ||
465 | * In this case, the cache is marked %LC_DIRTY, | ||
466 | * so lc_try_lock() will no longer succeed. | ||
467 | * The returned element pointer is moved to the "to_be_changed" list, | ||
468 | * and registered with the new element number on the hash collision chains, | ||
469 | * so it is possible to pick it up from lc_is_used(). | ||
470 | * Up to "max_pending_changes" (see lc_create()) can be accumulated. | ||
471 | * The user now should do whatever housekeeping is necessary, | ||
472 | * typically serialize on lc_try_lock_for_transaction(), then call | ||
473 | * lc_committed(lc) and lc_unlock(), to finish the change. | ||
474 | * | ||
475 | * NOTE: The user needs to check the lc_number on EACH use, so he recognizes | ||
476 | * any cache set change. | ||
404 | */ | 477 | */ |
405 | struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr) | 478 | struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr) |
406 | { | 479 | { |
407 | struct lc_element *e; | 480 | return __lc_get(lc, enr, 1); |
408 | 481 | } | |
409 | PARANOIA_ENTRY(); | ||
410 | if (lc->flags & LC_STARVING) { | ||
411 | ++lc->starving; | ||
412 | RETURN(NULL); | ||
413 | } | ||
414 | 482 | ||
415 | e = lc_find(lc, enr); | 483 | /** |
416 | if (e) { | 484 | * lc_try_get - get element by label, if present; do not change the active set |
417 | ++lc->hits; | 485 | * @lc: the lru cache to operate on |
418 | if (e->refcnt++ == 0) | 486 | * @enr: the label to look up |
419 | lc->used++; | 487 | * |
420 | list_move(&e->list, &lc->in_use); /* Not evictable... */ | 488 | * Finds an element in the cache, increases its usage count, |
421 | } | 489 | * "touches" and returns it. |
422 | RETURN(e); | 490 | * |
491 | * Return values: | ||
492 | * NULL | ||
493 | * The cache was marked %LC_STARVING, | ||
494 | * or the requested label was not in the active set | ||
495 | * | ||
496 | * pointer to the element with the REQUESTED element number. | ||
497 | * In this case, it can be used right away | ||
498 | */ | ||
499 | struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr) | ||
500 | { | ||
501 | return __lc_get(lc, enr, 0); | ||
423 | } | 502 | } |
424 | 503 | ||
425 | /** | 504 | /** |
426 | * lc_changed - tell @lc that the change has been recorded | 505 | * lc_committed - tell @lc that pending changes have been recorded |
427 | * @lc: the lru cache to operate on | 506 | * @lc: the lru cache to operate on |
428 | * @e: the element pending label change | 507 | * |
508 | * User is expected to serialize on explicit lc_try_lock_for_transaction() | ||
509 | * before the transaction is started, and later needs to lc_unlock() explicitly | ||
510 | * as well. | ||
429 | */ | 511 | */ |
430 | void lc_changed(struct lru_cache *lc, struct lc_element *e) | 512 | void lc_committed(struct lru_cache *lc) |
431 | { | 513 | { |
514 | struct lc_element *e, *tmp; | ||
515 | |||
432 | PARANOIA_ENTRY(); | 516 | PARANOIA_ENTRY(); |
433 | BUG_ON(e != lc->changing_element); | 517 | list_for_each_entry_safe(e, tmp, &lc->to_be_changed, list) { |
434 | PARANOIA_LC_ELEMENT(lc, e); | 518 | /* count number of changes, not number of transactions */ |
435 | ++lc->changed; | 519 | ++lc->changed; |
436 | e->lc_number = lc->new_number; | 520 | e->lc_number = e->lc_new_number; |
437 | list_add(&e->list, &lc->in_use); | 521 | list_move(&e->list, &lc->in_use); |
438 | hlist_add_head(&e->colision, lc_hash_slot(lc, lc->new_number)); | 522 | } |
439 | lc->changing_element = NULL; | 523 | lc->pending_changes = 0; |
440 | lc->new_number = LC_FREE; | ||
441 | clear_bit(__LC_DIRTY, &lc->flags); | ||
442 | smp_mb__after_clear_bit(); | ||
443 | RETURN(); | 524 | RETURN(); |
444 | } | 525 | } |
445 | 526 | ||
@@ -458,13 +539,12 @@ unsigned int lc_put(struct lru_cache *lc, struct lc_element *e) | |||
458 | PARANOIA_ENTRY(); | 539 | PARANOIA_ENTRY(); |
459 | PARANOIA_LC_ELEMENT(lc, e); | 540 | PARANOIA_LC_ELEMENT(lc, e); |
460 | BUG_ON(e->refcnt == 0); | 541 | BUG_ON(e->refcnt == 0); |
461 | BUG_ON(e == lc->changing_element); | 542 | BUG_ON(e->lc_number != e->lc_new_number); |
462 | if (--e->refcnt == 0) { | 543 | if (--e->refcnt == 0) { |
463 | /* move it to the front of LRU. */ | 544 | /* move it to the front of LRU. */ |
464 | list_move(&e->list, &lc->lru); | 545 | list_move(&e->list, &lc->lru); |
465 | lc->used--; | 546 | lc->used--; |
466 | clear_bit(__LC_STARVING, &lc->flags); | 547 | clear_bit_unlock(__LC_STARVING, &lc->flags); |
467 | smp_mb__after_clear_bit(); | ||
468 | } | 548 | } |
469 | RETURN(e->refcnt); | 549 | RETURN(e->refcnt); |
470 | } | 550 | } |
@@ -504,16 +584,24 @@ unsigned int lc_index_of(struct lru_cache *lc, struct lc_element *e) | |||
504 | void lc_set(struct lru_cache *lc, unsigned int enr, int index) | 584 | void lc_set(struct lru_cache *lc, unsigned int enr, int index) |
505 | { | 585 | { |
506 | struct lc_element *e; | 586 | struct lc_element *e; |
587 | struct list_head *lh; | ||
507 | 588 | ||
508 | if (index < 0 || index >= lc->nr_elements) | 589 | if (index < 0 || index >= lc->nr_elements) |
509 | return; | 590 | return; |
510 | 591 | ||
511 | e = lc_element_by_index(lc, index); | 592 | e = lc_element_by_index(lc, index); |
512 | e->lc_number = enr; | 593 | BUG_ON(e->lc_number != e->lc_new_number); |
594 | BUG_ON(e->refcnt != 0); | ||
513 | 595 | ||
596 | e->lc_number = e->lc_new_number = enr; | ||
514 | hlist_del_init(&e->colision); | 597 | hlist_del_init(&e->colision); |
515 | hlist_add_head(&e->colision, lc_hash_slot(lc, enr)); | 598 | if (enr == LC_FREE) |
516 | list_move(&e->list, e->refcnt ? &lc->in_use : &lc->lru); | 599 | lh = &lc->free; |
600 | else { | ||
601 | hlist_add_head(&e->colision, lc_hash_slot(lc, enr)); | ||
602 | lh = &lc->lru; | ||
603 | } | ||
604 | list_move(&e->list, lh); | ||
517 | } | 605 | } |
518 | 606 | ||
519 | /** | 607 | /** |
@@ -553,8 +641,10 @@ EXPORT_SYMBOL(lc_try_get); | |||
553 | EXPORT_SYMBOL(lc_find); | 641 | EXPORT_SYMBOL(lc_find); |
554 | EXPORT_SYMBOL(lc_get); | 642 | EXPORT_SYMBOL(lc_get); |
555 | EXPORT_SYMBOL(lc_put); | 643 | EXPORT_SYMBOL(lc_put); |
556 | EXPORT_SYMBOL(lc_changed); | 644 | EXPORT_SYMBOL(lc_committed); |
557 | EXPORT_SYMBOL(lc_element_by_index); | 645 | EXPORT_SYMBOL(lc_element_by_index); |
558 | EXPORT_SYMBOL(lc_index_of); | 646 | EXPORT_SYMBOL(lc_index_of); |
559 | EXPORT_SYMBOL(lc_seq_printf_stats); | 647 | EXPORT_SYMBOL(lc_seq_printf_stats); |
560 | EXPORT_SYMBOL(lc_seq_dump_details); | 648 | EXPORT_SYMBOL(lc_seq_dump_details); |
649 | EXPORT_SYMBOL(lc_try_lock); | ||
650 | EXPORT_SYMBOL(lc_is_used); | ||
diff --git a/lib/lzo/Makefile b/lib/lzo/Makefile index e764116ea12d..f0f7d7ca2b83 100644 --- a/lib/lzo/Makefile +++ b/lib/lzo/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | lzo_compress-objs := lzo1x_compress.o | 1 | lzo_compress-objs := lzo1x_compress.o |
2 | lzo_decompress-objs := lzo1x_decompress.o | 2 | lzo_decompress-objs := lzo1x_decompress_safe.o |
3 | 3 | ||
4 | obj-$(CONFIG_LZO_COMPRESS) += lzo_compress.o | 4 | obj-$(CONFIG_LZO_COMPRESS) += lzo_compress.o |
5 | obj-$(CONFIG_LZO_DECOMPRESS) += lzo_decompress.o | 5 | obj-$(CONFIG_LZO_DECOMPRESS) += lzo_decompress.o |
diff --git a/lib/lzo/lzo1x_compress.c b/lib/lzo/lzo1x_compress.c index a6040990a62e..236eb21167b5 100644 --- a/lib/lzo/lzo1x_compress.c +++ b/lib/lzo/lzo1x_compress.c | |||
@@ -1,194 +1,243 @@ | |||
1 | /* | 1 | /* |
2 | * LZO1X Compressor from MiniLZO | 2 | * LZO1X Compressor from LZO |
3 | * | 3 | * |
4 | * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com> | 4 | * Copyright (C) 1996-2012 Markus F.X.J. Oberhumer <markus@oberhumer.com> |
5 | * | 5 | * |
6 | * The full LZO package can be found at: | 6 | * The full LZO package can be found at: |
7 | * http://www.oberhumer.com/opensource/lzo/ | 7 | * http://www.oberhumer.com/opensource/lzo/ |
8 | * | 8 | * |
9 | * Changed for kernel use by: | 9 | * Changed for Linux kernel use by: |
10 | * Nitin Gupta <nitingupta910@gmail.com> | 10 | * Nitin Gupta <nitingupta910@gmail.com> |
11 | * Richard Purdie <rpurdie@openedhand.com> | 11 | * Richard Purdie <rpurdie@openedhand.com> |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/lzo.h> | ||
17 | #include <asm/unaligned.h> | 16 | #include <asm/unaligned.h> |
17 | #include <linux/lzo.h> | ||
18 | #include "lzodefs.h" | 18 | #include "lzodefs.h" |
19 | 19 | ||
20 | static noinline size_t | 20 | static noinline size_t |
21 | _lzo1x_1_do_compress(const unsigned char *in, size_t in_len, | 21 | lzo1x_1_do_compress(const unsigned char *in, size_t in_len, |
22 | unsigned char *out, size_t *out_len, void *wrkmem) | 22 | unsigned char *out, size_t *out_len, |
23 | size_t ti, void *wrkmem) | ||
23 | { | 24 | { |
25 | const unsigned char *ip; | ||
26 | unsigned char *op; | ||
24 | const unsigned char * const in_end = in + in_len; | 27 | const unsigned char * const in_end = in + in_len; |
25 | const unsigned char * const ip_end = in + in_len - M2_MAX_LEN - 5; | 28 | const unsigned char * const ip_end = in + in_len - 20; |
26 | const unsigned char ** const dict = wrkmem; | 29 | const unsigned char *ii; |
27 | const unsigned char *ip = in, *ii = ip; | 30 | lzo_dict_t * const dict = (lzo_dict_t *) wrkmem; |
28 | const unsigned char *end, *m, *m_pos; | ||
29 | size_t m_off, m_len, dindex; | ||
30 | unsigned char *op = out; | ||
31 | 31 | ||
32 | ip += 4; | 32 | op = out; |
33 | ip = in; | ||
34 | ii = ip; | ||
35 | ip += ti < 4 ? 4 - ti : 0; | ||
33 | 36 | ||
34 | for (;;) { | 37 | for (;;) { |
35 | dindex = ((size_t)(0x21 * DX3(ip, 5, 5, 6)) >> 5) & D_MASK; | 38 | const unsigned char *m_pos; |
36 | m_pos = dict[dindex]; | 39 | size_t t, m_len, m_off; |
37 | 40 | u32 dv; | |
38 | if (m_pos < in) | ||
39 | goto literal; | ||
40 | |||
41 | if (ip == m_pos || ((size_t)(ip - m_pos) > M4_MAX_OFFSET)) | ||
42 | goto literal; | ||
43 | |||
44 | m_off = ip - m_pos; | ||
45 | if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) | ||
46 | goto try_match; | ||
47 | |||
48 | dindex = (dindex & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f); | ||
49 | m_pos = dict[dindex]; | ||
50 | |||
51 | if (m_pos < in) | ||
52 | goto literal; | ||
53 | |||
54 | if (ip == m_pos || ((size_t)(ip - m_pos) > M4_MAX_OFFSET)) | ||
55 | goto literal; | ||
56 | |||
57 | m_off = ip - m_pos; | ||
58 | if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) | ||
59 | goto try_match; | ||
60 | |||
61 | goto literal; | ||
62 | |||
63 | try_match: | ||
64 | if (get_unaligned((const unsigned short *)m_pos) | ||
65 | == get_unaligned((const unsigned short *)ip)) { | ||
66 | if (likely(m_pos[2] == ip[2])) | ||
67 | goto match; | ||
68 | } | ||
69 | |||
70 | literal: | 41 | literal: |
71 | dict[dindex] = ip; | 42 | ip += 1 + ((ip - ii) >> 5); |
72 | ++ip; | 43 | next: |
73 | if (unlikely(ip >= ip_end)) | 44 | if (unlikely(ip >= ip_end)) |
74 | break; | 45 | break; |
75 | continue; | 46 | dv = get_unaligned_le32(ip); |
76 | 47 | t = ((dv * 0x1824429d) >> (32 - D_BITS)) & D_MASK; | |
77 | match: | 48 | m_pos = in + dict[t]; |
78 | dict[dindex] = ip; | 49 | dict[t] = (lzo_dict_t) (ip - in); |
79 | if (ip != ii) { | 50 | if (unlikely(dv != get_unaligned_le32(m_pos))) |
80 | size_t t = ip - ii; | 51 | goto literal; |
81 | 52 | ||
53 | ii -= ti; | ||
54 | ti = 0; | ||
55 | t = ip - ii; | ||
56 | if (t != 0) { | ||
82 | if (t <= 3) { | 57 | if (t <= 3) { |
83 | op[-2] |= t; | 58 | op[-2] |= t; |
84 | } else if (t <= 18) { | 59 | COPY4(op, ii); |
60 | op += t; | ||
61 | } else if (t <= 16) { | ||
85 | *op++ = (t - 3); | 62 | *op++ = (t - 3); |
63 | COPY8(op, ii); | ||
64 | COPY8(op + 8, ii + 8); | ||
65 | op += t; | ||
86 | } else { | 66 | } else { |
87 | size_t tt = t - 18; | 67 | if (t <= 18) { |
88 | 68 | *op++ = (t - 3); | |
89 | *op++ = 0; | 69 | } else { |
90 | while (tt > 255) { | 70 | size_t tt = t - 18; |
91 | tt -= 255; | ||
92 | *op++ = 0; | 71 | *op++ = 0; |
72 | while (unlikely(tt > 255)) { | ||
73 | tt -= 255; | ||
74 | *op++ = 0; | ||
75 | } | ||
76 | *op++ = tt; | ||
93 | } | 77 | } |
94 | *op++ = tt; | 78 | do { |
79 | COPY8(op, ii); | ||
80 | COPY8(op + 8, ii + 8); | ||
81 | op += 16; | ||
82 | ii += 16; | ||
83 | t -= 16; | ||
84 | } while (t >= 16); | ||
85 | if (t > 0) do { | ||
86 | *op++ = *ii++; | ||
87 | } while (--t > 0); | ||
95 | } | 88 | } |
96 | do { | ||
97 | *op++ = *ii++; | ||
98 | } while (--t > 0); | ||
99 | } | 89 | } |
100 | 90 | ||
101 | ip += 3; | 91 | m_len = 4; |
102 | if (m_pos[3] != *ip++ || m_pos[4] != *ip++ | 92 | { |
103 | || m_pos[5] != *ip++ || m_pos[6] != *ip++ | 93 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && defined(LZO_USE_CTZ64) |
104 | || m_pos[7] != *ip++ || m_pos[8] != *ip++) { | 94 | u64 v; |
105 | --ip; | 95 | v = get_unaligned((const u64 *) (ip + m_len)) ^ |
106 | m_len = ip - ii; | 96 | get_unaligned((const u64 *) (m_pos + m_len)); |
97 | if (unlikely(v == 0)) { | ||
98 | do { | ||
99 | m_len += 8; | ||
100 | v = get_unaligned((const u64 *) (ip + m_len)) ^ | ||
101 | get_unaligned((const u64 *) (m_pos + m_len)); | ||
102 | if (unlikely(ip + m_len >= ip_end)) | ||
103 | goto m_len_done; | ||
104 | } while (v == 0); | ||
105 | } | ||
106 | # if defined(__LITTLE_ENDIAN) | ||
107 | m_len += (unsigned) __builtin_ctzll(v) / 8; | ||
108 | # elif defined(__BIG_ENDIAN) | ||
109 | m_len += (unsigned) __builtin_clzll(v) / 8; | ||
110 | # else | ||
111 | # error "missing endian definition" | ||
112 | # endif | ||
113 | #elif defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && defined(LZO_USE_CTZ32) | ||
114 | u32 v; | ||
115 | v = get_unaligned((const u32 *) (ip + m_len)) ^ | ||
116 | get_unaligned((const u32 *) (m_pos + m_len)); | ||
117 | if (unlikely(v == 0)) { | ||
118 | do { | ||
119 | m_len += 4; | ||
120 | v = get_unaligned((const u32 *) (ip + m_len)) ^ | ||
121 | get_unaligned((const u32 *) (m_pos + m_len)); | ||
122 | if (v != 0) | ||
123 | break; | ||
124 | m_len += 4; | ||
125 | v = get_unaligned((const u32 *) (ip + m_len)) ^ | ||
126 | get_unaligned((const u32 *) (m_pos + m_len)); | ||
127 | if (unlikely(ip + m_len >= ip_end)) | ||
128 | goto m_len_done; | ||
129 | } while (v == 0); | ||
130 | } | ||
131 | # if defined(__LITTLE_ENDIAN) | ||
132 | m_len += (unsigned) __builtin_ctz(v) / 8; | ||
133 | # elif defined(__BIG_ENDIAN) | ||
134 | m_len += (unsigned) __builtin_clz(v) / 8; | ||
135 | # else | ||
136 | # error "missing endian definition" | ||
137 | # endif | ||
138 | #else | ||
139 | if (unlikely(ip[m_len] == m_pos[m_len])) { | ||
140 | do { | ||
141 | m_len += 1; | ||
142 | if (ip[m_len] != m_pos[m_len]) | ||
143 | break; | ||
144 | m_len += 1; | ||
145 | if (ip[m_len] != m_pos[m_len]) | ||
146 | break; | ||
147 | m_len += 1; | ||
148 | if (ip[m_len] != m_pos[m_len]) | ||
149 | break; | ||
150 | m_len += 1; | ||
151 | if (ip[m_len] != m_pos[m_len]) | ||
152 | break; | ||
153 | m_len += 1; | ||
154 | if (ip[m_len] != m_pos[m_len]) | ||
155 | break; | ||
156 | m_len += 1; | ||
157 | if (ip[m_len] != m_pos[m_len]) | ||
158 | break; | ||
159 | m_len += 1; | ||
160 | if (ip[m_len] != m_pos[m_len]) | ||
161 | break; | ||
162 | m_len += 1; | ||
163 | if (unlikely(ip + m_len >= ip_end)) | ||
164 | goto m_len_done; | ||
165 | } while (ip[m_len] == m_pos[m_len]); | ||
166 | } | ||
167 | #endif | ||
168 | } | ||
169 | m_len_done: | ||
107 | 170 | ||
108 | if (m_off <= M2_MAX_OFFSET) { | 171 | m_off = ip - m_pos; |
109 | m_off -= 1; | 172 | ip += m_len; |
110 | *op++ = (((m_len - 1) << 5) | 173 | ii = ip; |
111 | | ((m_off & 7) << 2)); | 174 | if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) { |
112 | *op++ = (m_off >> 3); | 175 | m_off -= 1; |
113 | } else if (m_off <= M3_MAX_OFFSET) { | 176 | *op++ = (((m_len - 1) << 5) | ((m_off & 7) << 2)); |
114 | m_off -= 1; | 177 | *op++ = (m_off >> 3); |
178 | } else if (m_off <= M3_MAX_OFFSET) { | ||
179 | m_off -= 1; | ||
180 | if (m_len <= M3_MAX_LEN) | ||
115 | *op++ = (M3_MARKER | (m_len - 2)); | 181 | *op++ = (M3_MARKER | (m_len - 2)); |
116 | goto m3_m4_offset; | 182 | else { |
117 | } else { | 183 | m_len -= M3_MAX_LEN; |
118 | m_off -= 0x4000; | 184 | *op++ = M3_MARKER | 0; |
119 | 185 | while (unlikely(m_len > 255)) { | |
120 | *op++ = (M4_MARKER | ((m_off & 0x4000) >> 11) | 186 | m_len -= 255; |
121 | | (m_len - 2)); | 187 | *op++ = 0; |
122 | goto m3_m4_offset; | 188 | } |
189 | *op++ = (m_len); | ||
123 | } | 190 | } |
191 | *op++ = (m_off << 2); | ||
192 | *op++ = (m_off >> 6); | ||
124 | } else { | 193 | } else { |
125 | end = in_end; | 194 | m_off -= 0x4000; |
126 | m = m_pos + M2_MAX_LEN + 1; | 195 | if (m_len <= M4_MAX_LEN) |
127 | 196 | *op++ = (M4_MARKER | ((m_off >> 11) & 8) | |
128 | while (ip < end && *m == *ip) { | ||
129 | m++; | ||
130 | ip++; | ||
131 | } | ||
132 | m_len = ip - ii; | ||
133 | |||
134 | if (m_off <= M3_MAX_OFFSET) { | ||
135 | m_off -= 1; | ||
136 | if (m_len <= 33) { | ||
137 | *op++ = (M3_MARKER | (m_len - 2)); | ||
138 | } else { | ||
139 | m_len -= 33; | ||
140 | *op++ = M3_MARKER | 0; | ||
141 | goto m3_m4_len; | ||
142 | } | ||
143 | } else { | ||
144 | m_off -= 0x4000; | ||
145 | if (m_len <= M4_MAX_LEN) { | ||
146 | *op++ = (M4_MARKER | ||
147 | | ((m_off & 0x4000) >> 11) | ||
148 | | (m_len - 2)); | 197 | | (m_len - 2)); |
149 | } else { | 198 | else { |
150 | m_len -= M4_MAX_LEN; | 199 | m_len -= M4_MAX_LEN; |
151 | *op++ = (M4_MARKER | 200 | *op++ = (M4_MARKER | ((m_off >> 11) & 8)); |
152 | | ((m_off & 0x4000) >> 11)); | 201 | while (unlikely(m_len > 255)) { |
153 | m3_m4_len: | 202 | m_len -= 255; |
154 | while (m_len > 255) { | 203 | *op++ = 0; |
155 | m_len -= 255; | ||
156 | *op++ = 0; | ||
157 | } | ||
158 | |||
159 | *op++ = (m_len); | ||
160 | } | 204 | } |
205 | *op++ = (m_len); | ||
161 | } | 206 | } |
162 | m3_m4_offset: | 207 | *op++ = (m_off << 2); |
163 | *op++ = ((m_off & 63) << 2); | ||
164 | *op++ = (m_off >> 6); | 208 | *op++ = (m_off >> 6); |
165 | } | 209 | } |
166 | 210 | goto next; | |
167 | ii = ip; | ||
168 | if (unlikely(ip >= ip_end)) | ||
169 | break; | ||
170 | } | 211 | } |
171 | |||
172 | *out_len = op - out; | 212 | *out_len = op - out; |
173 | return in_end - ii; | 213 | return in_end - (ii - ti); |
174 | } | 214 | } |
175 | 215 | ||
176 | int lzo1x_1_compress(const unsigned char *in, size_t in_len, unsigned char *out, | 216 | int lzo1x_1_compress(const unsigned char *in, size_t in_len, |
177 | size_t *out_len, void *wrkmem) | 217 | unsigned char *out, size_t *out_len, |
218 | void *wrkmem) | ||
178 | { | 219 | { |
179 | const unsigned char *ii; | 220 | const unsigned char *ip = in; |
180 | unsigned char *op = out; | 221 | unsigned char *op = out; |
181 | size_t t; | 222 | size_t l = in_len; |
223 | size_t t = 0; | ||
182 | 224 | ||
183 | if (unlikely(in_len <= M2_MAX_LEN + 5)) { | 225 | while (l > 20) { |
184 | t = in_len; | 226 | size_t ll = l <= (M4_MAX_OFFSET + 1) ? l : (M4_MAX_OFFSET + 1); |
185 | } else { | 227 | uintptr_t ll_end = (uintptr_t) ip + ll; |
186 | t = _lzo1x_1_do_compress(in, in_len, op, out_len, wrkmem); | 228 | if ((ll_end + ((t + ll) >> 5)) <= ll_end) |
229 | break; | ||
230 | BUILD_BUG_ON(D_SIZE * sizeof(lzo_dict_t) > LZO1X_1_MEM_COMPRESS); | ||
231 | memset(wrkmem, 0, D_SIZE * sizeof(lzo_dict_t)); | ||
232 | t = lzo1x_1_do_compress(ip, ll, op, out_len, t, wrkmem); | ||
233 | ip += ll; | ||
187 | op += *out_len; | 234 | op += *out_len; |
235 | l -= ll; | ||
188 | } | 236 | } |
237 | t += l; | ||
189 | 238 | ||
190 | if (t > 0) { | 239 | if (t > 0) { |
191 | ii = in + in_len - t; | 240 | const unsigned char *ii = in + in_len - t; |
192 | 241 | ||
193 | if (op == out && t <= 238) { | 242 | if (op == out && t <= 238) { |
194 | *op++ = (17 + t); | 243 | *op++ = (17 + t); |
@@ -198,16 +247,21 @@ int lzo1x_1_compress(const unsigned char *in, size_t in_len, unsigned char *out, | |||
198 | *op++ = (t - 3); | 247 | *op++ = (t - 3); |
199 | } else { | 248 | } else { |
200 | size_t tt = t - 18; | 249 | size_t tt = t - 18; |
201 | |||
202 | *op++ = 0; | 250 | *op++ = 0; |
203 | while (tt > 255) { | 251 | while (tt > 255) { |
204 | tt -= 255; | 252 | tt -= 255; |
205 | *op++ = 0; | 253 | *op++ = 0; |
206 | } | 254 | } |
207 | |||
208 | *op++ = tt; | 255 | *op++ = tt; |
209 | } | 256 | } |
210 | do { | 257 | if (t >= 16) do { |
258 | COPY8(op, ii); | ||
259 | COPY8(op + 8, ii + 8); | ||
260 | op += 16; | ||
261 | ii += 16; | ||
262 | t -= 16; | ||
263 | } while (t >= 16); | ||
264 | if (t > 0) do { | ||
211 | *op++ = *ii++; | 265 | *op++ = *ii++; |
212 | } while (--t > 0); | 266 | } while (--t > 0); |
213 | } | 267 | } |
@@ -223,4 +277,3 @@ EXPORT_SYMBOL_GPL(lzo1x_1_compress); | |||
223 | 277 | ||
224 | MODULE_LICENSE("GPL"); | 278 | MODULE_LICENSE("GPL"); |
225 | MODULE_DESCRIPTION("LZO1X-1 Compressor"); | 279 | MODULE_DESCRIPTION("LZO1X-1 Compressor"); |
226 | |||
diff --git a/lib/lzo/lzo1x_decompress.c b/lib/lzo/lzo1x_decompress.c deleted file mode 100644 index f2fd09850223..000000000000 --- a/lib/lzo/lzo1x_decompress.c +++ /dev/null | |||
@@ -1,255 +0,0 @@ | |||
1 | /* | ||
2 | * LZO1X Decompressor from MiniLZO | ||
3 | * | ||
4 | * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com> | ||
5 | * | ||
6 | * The full LZO package can be found at: | ||
7 | * http://www.oberhumer.com/opensource/lzo/ | ||
8 | * | ||
9 | * Changed for kernel use by: | ||
10 | * Nitin Gupta <nitingupta910@gmail.com> | ||
11 | * Richard Purdie <rpurdie@openedhand.com> | ||
12 | */ | ||
13 | |||
14 | #ifndef STATIC | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #endif | ||
18 | |||
19 | #include <asm/unaligned.h> | ||
20 | #include <linux/lzo.h> | ||
21 | #include "lzodefs.h" | ||
22 | |||
23 | #define HAVE_IP(x, ip_end, ip) ((size_t)(ip_end - ip) < (x)) | ||
24 | #define HAVE_OP(x, op_end, op) ((size_t)(op_end - op) < (x)) | ||
25 | #define HAVE_LB(m_pos, out, op) (m_pos < out || m_pos >= op) | ||
26 | |||
27 | #define COPY4(dst, src) \ | ||
28 | put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst)) | ||
29 | |||
30 | int lzo1x_decompress_safe(const unsigned char *in, size_t in_len, | ||
31 | unsigned char *out, size_t *out_len) | ||
32 | { | ||
33 | const unsigned char * const ip_end = in + in_len; | ||
34 | unsigned char * const op_end = out + *out_len; | ||
35 | const unsigned char *ip = in, *m_pos; | ||
36 | unsigned char *op = out; | ||
37 | size_t t; | ||
38 | |||
39 | *out_len = 0; | ||
40 | |||
41 | if (*ip > 17) { | ||
42 | t = *ip++ - 17; | ||
43 | if (t < 4) | ||
44 | goto match_next; | ||
45 | if (HAVE_OP(t, op_end, op)) | ||
46 | goto output_overrun; | ||
47 | if (HAVE_IP(t + 1, ip_end, ip)) | ||
48 | goto input_overrun; | ||
49 | do { | ||
50 | *op++ = *ip++; | ||
51 | } while (--t > 0); | ||
52 | goto first_literal_run; | ||
53 | } | ||
54 | |||
55 | while ((ip < ip_end)) { | ||
56 | t = *ip++; | ||
57 | if (t >= 16) | ||
58 | goto match; | ||
59 | if (t == 0) { | ||
60 | if (HAVE_IP(1, ip_end, ip)) | ||
61 | goto input_overrun; | ||
62 | while (*ip == 0) { | ||
63 | t += 255; | ||
64 | ip++; | ||
65 | if (HAVE_IP(1, ip_end, ip)) | ||
66 | goto input_overrun; | ||
67 | } | ||
68 | t += 15 + *ip++; | ||
69 | } | ||
70 | if (HAVE_OP(t + 3, op_end, op)) | ||
71 | goto output_overrun; | ||
72 | if (HAVE_IP(t + 4, ip_end, ip)) | ||
73 | goto input_overrun; | ||
74 | |||
75 | COPY4(op, ip); | ||
76 | op += 4; | ||
77 | ip += 4; | ||
78 | if (--t > 0) { | ||
79 | if (t >= 4) { | ||
80 | do { | ||
81 | COPY4(op, ip); | ||
82 | op += 4; | ||
83 | ip += 4; | ||
84 | t -= 4; | ||
85 | } while (t >= 4); | ||
86 | if (t > 0) { | ||
87 | do { | ||
88 | *op++ = *ip++; | ||
89 | } while (--t > 0); | ||
90 | } | ||
91 | } else { | ||
92 | do { | ||
93 | *op++ = *ip++; | ||
94 | } while (--t > 0); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | first_literal_run: | ||
99 | t = *ip++; | ||
100 | if (t >= 16) | ||
101 | goto match; | ||
102 | m_pos = op - (1 + M2_MAX_OFFSET); | ||
103 | m_pos -= t >> 2; | ||
104 | m_pos -= *ip++ << 2; | ||
105 | |||
106 | if (HAVE_LB(m_pos, out, op)) | ||
107 | goto lookbehind_overrun; | ||
108 | |||
109 | if (HAVE_OP(3, op_end, op)) | ||
110 | goto output_overrun; | ||
111 | *op++ = *m_pos++; | ||
112 | *op++ = *m_pos++; | ||
113 | *op++ = *m_pos; | ||
114 | |||
115 | goto match_done; | ||
116 | |||
117 | do { | ||
118 | match: | ||
119 | if (t >= 64) { | ||
120 | m_pos = op - 1; | ||
121 | m_pos -= (t >> 2) & 7; | ||
122 | m_pos -= *ip++ << 3; | ||
123 | t = (t >> 5) - 1; | ||
124 | if (HAVE_LB(m_pos, out, op)) | ||
125 | goto lookbehind_overrun; | ||
126 | if (HAVE_OP(t + 3 - 1, op_end, op)) | ||
127 | goto output_overrun; | ||
128 | goto copy_match; | ||
129 | } else if (t >= 32) { | ||
130 | t &= 31; | ||
131 | if (t == 0) { | ||
132 | if (HAVE_IP(1, ip_end, ip)) | ||
133 | goto input_overrun; | ||
134 | while (*ip == 0) { | ||
135 | t += 255; | ||
136 | ip++; | ||
137 | if (HAVE_IP(1, ip_end, ip)) | ||
138 | goto input_overrun; | ||
139 | } | ||
140 | t += 31 + *ip++; | ||
141 | } | ||
142 | m_pos = op - 1; | ||
143 | m_pos -= get_unaligned_le16(ip) >> 2; | ||
144 | ip += 2; | ||
145 | } else if (t >= 16) { | ||
146 | m_pos = op; | ||
147 | m_pos -= (t & 8) << 11; | ||
148 | |||
149 | t &= 7; | ||
150 | if (t == 0) { | ||
151 | if (HAVE_IP(1, ip_end, ip)) | ||
152 | goto input_overrun; | ||
153 | while (*ip == 0) { | ||
154 | t += 255; | ||
155 | ip++; | ||
156 | if (HAVE_IP(1, ip_end, ip)) | ||
157 | goto input_overrun; | ||
158 | } | ||
159 | t += 7 + *ip++; | ||
160 | } | ||
161 | m_pos -= get_unaligned_le16(ip) >> 2; | ||
162 | ip += 2; | ||
163 | if (m_pos == op) | ||
164 | goto eof_found; | ||
165 | m_pos -= 0x4000; | ||
166 | } else { | ||
167 | m_pos = op - 1; | ||
168 | m_pos -= t >> 2; | ||
169 | m_pos -= *ip++ << 2; | ||
170 | |||
171 | if (HAVE_LB(m_pos, out, op)) | ||
172 | goto lookbehind_overrun; | ||
173 | if (HAVE_OP(2, op_end, op)) | ||
174 | goto output_overrun; | ||
175 | |||
176 | *op++ = *m_pos++; | ||
177 | *op++ = *m_pos; | ||
178 | goto match_done; | ||
179 | } | ||
180 | |||
181 | if (HAVE_LB(m_pos, out, op)) | ||
182 | goto lookbehind_overrun; | ||
183 | if (HAVE_OP(t + 3 - 1, op_end, op)) | ||
184 | goto output_overrun; | ||
185 | |||
186 | if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) { | ||
187 | COPY4(op, m_pos); | ||
188 | op += 4; | ||
189 | m_pos += 4; | ||
190 | t -= 4 - (3 - 1); | ||
191 | do { | ||
192 | COPY4(op, m_pos); | ||
193 | op += 4; | ||
194 | m_pos += 4; | ||
195 | t -= 4; | ||
196 | } while (t >= 4); | ||
197 | if (t > 0) | ||
198 | do { | ||
199 | *op++ = *m_pos++; | ||
200 | } while (--t > 0); | ||
201 | } else { | ||
202 | copy_match: | ||
203 | *op++ = *m_pos++; | ||
204 | *op++ = *m_pos++; | ||
205 | do { | ||
206 | *op++ = *m_pos++; | ||
207 | } while (--t > 0); | ||
208 | } | ||
209 | match_done: | ||
210 | t = ip[-2] & 3; | ||
211 | if (t == 0) | ||
212 | break; | ||
213 | match_next: | ||
214 | if (HAVE_OP(t, op_end, op)) | ||
215 | goto output_overrun; | ||
216 | if (HAVE_IP(t + 1, ip_end, ip)) | ||
217 | goto input_overrun; | ||
218 | |||
219 | *op++ = *ip++; | ||
220 | if (t > 1) { | ||
221 | *op++ = *ip++; | ||
222 | if (t > 2) | ||
223 | *op++ = *ip++; | ||
224 | } | ||
225 | |||
226 | t = *ip++; | ||
227 | } while (ip < ip_end); | ||
228 | } | ||
229 | |||
230 | *out_len = op - out; | ||
231 | return LZO_E_EOF_NOT_FOUND; | ||
232 | |||
233 | eof_found: | ||
234 | *out_len = op - out; | ||
235 | return (ip == ip_end ? LZO_E_OK : | ||
236 | (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); | ||
237 | input_overrun: | ||
238 | *out_len = op - out; | ||
239 | return LZO_E_INPUT_OVERRUN; | ||
240 | |||
241 | output_overrun: | ||
242 | *out_len = op - out; | ||
243 | return LZO_E_OUTPUT_OVERRUN; | ||
244 | |||
245 | lookbehind_overrun: | ||
246 | *out_len = op - out; | ||
247 | return LZO_E_LOOKBEHIND_OVERRUN; | ||
248 | } | ||
249 | #ifndef STATIC | ||
250 | EXPORT_SYMBOL_GPL(lzo1x_decompress_safe); | ||
251 | |||
252 | MODULE_LICENSE("GPL"); | ||
253 | MODULE_DESCRIPTION("LZO1X Decompressor"); | ||
254 | |||
255 | #endif | ||
diff --git a/lib/lzo/lzo1x_decompress_safe.c b/lib/lzo/lzo1x_decompress_safe.c new file mode 100644 index 000000000000..569985d522d5 --- /dev/null +++ b/lib/lzo/lzo1x_decompress_safe.c | |||
@@ -0,0 +1,237 @@ | |||
1 | /* | ||
2 | * LZO1X Decompressor from LZO | ||
3 | * | ||
4 | * Copyright (C) 1996-2012 Markus F.X.J. Oberhumer <markus@oberhumer.com> | ||
5 | * | ||
6 | * The full LZO package can be found at: | ||
7 | * http://www.oberhumer.com/opensource/lzo/ | ||
8 | * | ||
9 | * Changed for Linux kernel use by: | ||
10 | * Nitin Gupta <nitingupta910@gmail.com> | ||
11 | * Richard Purdie <rpurdie@openedhand.com> | ||
12 | */ | ||
13 | |||
14 | #ifndef STATIC | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #endif | ||
18 | #include <asm/unaligned.h> | ||
19 | #include <linux/lzo.h> | ||
20 | #include "lzodefs.h" | ||
21 | |||
22 | #define HAVE_IP(x) ((size_t)(ip_end - ip) >= (size_t)(x)) | ||
23 | #define HAVE_OP(x) ((size_t)(op_end - op) >= (size_t)(x)) | ||
24 | #define NEED_IP(x) if (!HAVE_IP(x)) goto input_overrun | ||
25 | #define NEED_OP(x) if (!HAVE_OP(x)) goto output_overrun | ||
26 | #define TEST_LB(m_pos) if ((m_pos) < out) goto lookbehind_overrun | ||
27 | |||
28 | int lzo1x_decompress_safe(const unsigned char *in, size_t in_len, | ||
29 | unsigned char *out, size_t *out_len) | ||
30 | { | ||
31 | unsigned char *op; | ||
32 | const unsigned char *ip; | ||
33 | size_t t, next; | ||
34 | size_t state = 0; | ||
35 | const unsigned char *m_pos; | ||
36 | const unsigned char * const ip_end = in + in_len; | ||
37 | unsigned char * const op_end = out + *out_len; | ||
38 | |||
39 | op = out; | ||
40 | ip = in; | ||
41 | |||
42 | if (unlikely(in_len < 3)) | ||
43 | goto input_overrun; | ||
44 | if (*ip > 17) { | ||
45 | t = *ip++ - 17; | ||
46 | if (t < 4) { | ||
47 | next = t; | ||
48 | goto match_next; | ||
49 | } | ||
50 | goto copy_literal_run; | ||
51 | } | ||
52 | |||
53 | for (;;) { | ||
54 | t = *ip++; | ||
55 | if (t < 16) { | ||
56 | if (likely(state == 0)) { | ||
57 | if (unlikely(t == 0)) { | ||
58 | while (unlikely(*ip == 0)) { | ||
59 | t += 255; | ||
60 | ip++; | ||
61 | NEED_IP(1); | ||
62 | } | ||
63 | t += 15 + *ip++; | ||
64 | } | ||
65 | t += 3; | ||
66 | copy_literal_run: | ||
67 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) | ||
68 | if (likely(HAVE_IP(t + 15) && HAVE_OP(t + 15))) { | ||
69 | const unsigned char *ie = ip + t; | ||
70 | unsigned char *oe = op + t; | ||
71 | do { | ||
72 | COPY8(op, ip); | ||
73 | op += 8; | ||
74 | ip += 8; | ||
75 | COPY8(op, ip); | ||
76 | op += 8; | ||
77 | ip += 8; | ||
78 | } while (ip < ie); | ||
79 | ip = ie; | ||
80 | op = oe; | ||
81 | } else | ||
82 | #endif | ||
83 | { | ||
84 | NEED_OP(t); | ||
85 | NEED_IP(t + 3); | ||
86 | do { | ||
87 | *op++ = *ip++; | ||
88 | } while (--t > 0); | ||
89 | } | ||
90 | state = 4; | ||
91 | continue; | ||
92 | } else if (state != 4) { | ||
93 | next = t & 3; | ||
94 | m_pos = op - 1; | ||
95 | m_pos -= t >> 2; | ||
96 | m_pos -= *ip++ << 2; | ||
97 | TEST_LB(m_pos); | ||
98 | NEED_OP(2); | ||
99 | op[0] = m_pos[0]; | ||
100 | op[1] = m_pos[1]; | ||
101 | op += 2; | ||
102 | goto match_next; | ||
103 | } else { | ||
104 | next = t & 3; | ||
105 | m_pos = op - (1 + M2_MAX_OFFSET); | ||
106 | m_pos -= t >> 2; | ||
107 | m_pos -= *ip++ << 2; | ||
108 | t = 3; | ||
109 | } | ||
110 | } else if (t >= 64) { | ||
111 | next = t & 3; | ||
112 | m_pos = op - 1; | ||
113 | m_pos -= (t >> 2) & 7; | ||
114 | m_pos -= *ip++ << 3; | ||
115 | t = (t >> 5) - 1 + (3 - 1); | ||
116 | } else if (t >= 32) { | ||
117 | t = (t & 31) + (3 - 1); | ||
118 | if (unlikely(t == 2)) { | ||
119 | while (unlikely(*ip == 0)) { | ||
120 | t += 255; | ||
121 | ip++; | ||
122 | NEED_IP(1); | ||
123 | } | ||
124 | t += 31 + *ip++; | ||
125 | NEED_IP(2); | ||
126 | } | ||
127 | m_pos = op - 1; | ||
128 | next = get_unaligned_le16(ip); | ||
129 | ip += 2; | ||
130 | m_pos -= next >> 2; | ||
131 | next &= 3; | ||
132 | } else { | ||
133 | m_pos = op; | ||
134 | m_pos -= (t & 8) << 11; | ||
135 | t = (t & 7) + (3 - 1); | ||
136 | if (unlikely(t == 2)) { | ||
137 | while (unlikely(*ip == 0)) { | ||
138 | t += 255; | ||
139 | ip++; | ||
140 | NEED_IP(1); | ||
141 | } | ||
142 | t += 7 + *ip++; | ||
143 | NEED_IP(2); | ||
144 | } | ||
145 | next = get_unaligned_le16(ip); | ||
146 | ip += 2; | ||
147 | m_pos -= next >> 2; | ||
148 | next &= 3; | ||
149 | if (m_pos == op) | ||
150 | goto eof_found; | ||
151 | m_pos -= 0x4000; | ||
152 | } | ||
153 | TEST_LB(m_pos); | ||
154 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) | ||
155 | if (op - m_pos >= 8) { | ||
156 | unsigned char *oe = op + t; | ||
157 | if (likely(HAVE_OP(t + 15))) { | ||
158 | do { | ||
159 | COPY8(op, m_pos); | ||
160 | op += 8; | ||
161 | m_pos += 8; | ||
162 | COPY8(op, m_pos); | ||
163 | op += 8; | ||
164 | m_pos += 8; | ||
165 | } while (op < oe); | ||
166 | op = oe; | ||
167 | if (HAVE_IP(6)) { | ||
168 | state = next; | ||
169 | COPY4(op, ip); | ||
170 | op += next; | ||
171 | ip += next; | ||
172 | continue; | ||
173 | } | ||
174 | } else { | ||
175 | NEED_OP(t); | ||
176 | do { | ||
177 | *op++ = *m_pos++; | ||
178 | } while (op < oe); | ||
179 | } | ||
180 | } else | ||
181 | #endif | ||
182 | { | ||
183 | unsigned char *oe = op + t; | ||
184 | NEED_OP(t); | ||
185 | op[0] = m_pos[0]; | ||
186 | op[1] = m_pos[1]; | ||
187 | op += 2; | ||
188 | m_pos += 2; | ||
189 | do { | ||
190 | *op++ = *m_pos++; | ||
191 | } while (op < oe); | ||
192 | } | ||
193 | match_next: | ||
194 | state = next; | ||
195 | t = next; | ||
196 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) | ||
197 | if (likely(HAVE_IP(6) && HAVE_OP(4))) { | ||
198 | COPY4(op, ip); | ||
199 | op += t; | ||
200 | ip += t; | ||
201 | } else | ||
202 | #endif | ||
203 | { | ||
204 | NEED_IP(t + 3); | ||
205 | NEED_OP(t); | ||
206 | while (t > 0) { | ||
207 | *op++ = *ip++; | ||
208 | t--; | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | |||
213 | eof_found: | ||
214 | *out_len = op - out; | ||
215 | return (t != 3 ? LZO_E_ERROR : | ||
216 | ip == ip_end ? LZO_E_OK : | ||
217 | ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN); | ||
218 | |||
219 | input_overrun: | ||
220 | *out_len = op - out; | ||
221 | return LZO_E_INPUT_OVERRUN; | ||
222 | |||
223 | output_overrun: | ||
224 | *out_len = op - out; | ||
225 | return LZO_E_OUTPUT_OVERRUN; | ||
226 | |||
227 | lookbehind_overrun: | ||
228 | *out_len = op - out; | ||
229 | return LZO_E_LOOKBEHIND_OVERRUN; | ||
230 | } | ||
231 | #ifndef STATIC | ||
232 | EXPORT_SYMBOL_GPL(lzo1x_decompress_safe); | ||
233 | |||
234 | MODULE_LICENSE("GPL"); | ||
235 | MODULE_DESCRIPTION("LZO1X Decompressor"); | ||
236 | |||
237 | #endif | ||
diff --git a/lib/lzo/lzodefs.h b/lib/lzo/lzodefs.h index b6d482c492ef..6710b83ce72e 100644 --- a/lib/lzo/lzodefs.h +++ b/lib/lzo/lzodefs.h | |||
@@ -1,19 +1,37 @@ | |||
1 | /* | 1 | /* |
2 | * lzodefs.h -- architecture, OS and compiler specific defines | 2 | * lzodefs.h -- architecture, OS and compiler specific defines |
3 | * | 3 | * |
4 | * Copyright (C) 1996-2005 Markus F.X.J. Oberhumer <markus@oberhumer.com> | 4 | * Copyright (C) 1996-2012 Markus F.X.J. Oberhumer <markus@oberhumer.com> |
5 | * | 5 | * |
6 | * The full LZO package can be found at: | 6 | * The full LZO package can be found at: |
7 | * http://www.oberhumer.com/opensource/lzo/ | 7 | * http://www.oberhumer.com/opensource/lzo/ |
8 | * | 8 | * |
9 | * Changed for kernel use by: | 9 | * Changed for Linux kernel use by: |
10 | * Nitin Gupta <nitingupta910@gmail.com> | 10 | * Nitin Gupta <nitingupta910@gmail.com> |
11 | * Richard Purdie <rpurdie@openedhand.com> | 11 | * Richard Purdie <rpurdie@openedhand.com> |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define LZO_VERSION 0x2020 | 14 | |
15 | #define LZO_VERSION_STRING "2.02" | 15 | #define COPY4(dst, src) \ |
16 | #define LZO_VERSION_DATE "Oct 17 2005" | 16 | put_unaligned(get_unaligned((const u32 *)(src)), (u32 *)(dst)) |
17 | #if defined(__x86_64__) | ||
18 | #define COPY8(dst, src) \ | ||
19 | put_unaligned(get_unaligned((const u64 *)(src)), (u64 *)(dst)) | ||
20 | #else | ||
21 | #define COPY8(dst, src) \ | ||
22 | COPY4(dst, src); COPY4((dst) + 4, (src) + 4) | ||
23 | #endif | ||
24 | |||
25 | #if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) | ||
26 | #error "conflicting endian definitions" | ||
27 | #elif defined(__x86_64__) | ||
28 | #define LZO_USE_CTZ64 1 | ||
29 | #define LZO_USE_CTZ32 1 | ||
30 | #elif defined(__i386__) || defined(__powerpc__) | ||
31 | #define LZO_USE_CTZ32 1 | ||
32 | #elif defined(__arm__) && (__LINUX_ARM_ARCH__ >= 5) | ||
33 | #define LZO_USE_CTZ32 1 | ||
34 | #endif | ||
17 | 35 | ||
18 | #define M1_MAX_OFFSET 0x0400 | 36 | #define M1_MAX_OFFSET 0x0400 |
19 | #define M2_MAX_OFFSET 0x0800 | 37 | #define M2_MAX_OFFSET 0x0800 |
@@ -34,10 +52,8 @@ | |||
34 | #define M3_MARKER 32 | 52 | #define M3_MARKER 32 |
35 | #define M4_MARKER 16 | 53 | #define M4_MARKER 16 |
36 | 54 | ||
37 | #define D_BITS 14 | 55 | #define lzo_dict_t unsigned short |
38 | #define D_MASK ((1u << D_BITS) - 1) | 56 | #define D_BITS 13 |
57 | #define D_SIZE (1u << D_BITS) | ||
58 | #define D_MASK (D_SIZE - 1) | ||
39 | #define D_HIGH ((D_MASK >> 1) + 1) | 59 | #define D_HIGH ((D_MASK >> 1) + 1) |
40 | |||
41 | #define DX2(p, s1, s2) (((((size_t)((p)[2]) << (s2)) ^ (p)[1]) \ | ||
42 | << (s1)) ^ (p)[0]) | ||
43 | #define DX3(p, s1, s2, s3) ((DX2((p)+1, s2, s3) << (s1)) ^ (p)[0]) | ||
diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h index 678ce4f1e124..095ab157a521 100644 --- a/lib/mpi/longlong.h +++ b/lib/mpi/longlong.h | |||
@@ -641,7 +641,14 @@ do { \ | |||
641 | ************** MIPS ***************** | 641 | ************** MIPS ***************** |
642 | ***************************************/ | 642 | ***************************************/ |
643 | #if defined(__mips__) && W_TYPE_SIZE == 32 | 643 | #if defined(__mips__) && W_TYPE_SIZE == 32 |
644 | #if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 | 644 | #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 |
645 | #define umul_ppmm(w1, w0, u, v) \ | ||
646 | do { \ | ||
647 | UDItype __ll = (UDItype)(u) * (v); \ | ||
648 | w1 = __ll >> 32; \ | ||
649 | w0 = __ll; \ | ||
650 | } while (0) | ||
651 | #elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 | ||
645 | #define umul_ppmm(w1, w0, u, v) \ | 652 | #define umul_ppmm(w1, w0, u, v) \ |
646 | __asm__ ("multu %2,%3" \ | 653 | __asm__ ("multu %2,%3" \ |
647 | : "=l" ((USItype)(w0)), \ | 654 | : "=l" ((USItype)(w0)), \ |
@@ -666,7 +673,15 @@ do { \ | |||
666 | ************** MIPS/64 ************** | 673 | ************** MIPS/64 ************** |
667 | ***************************************/ | 674 | ***************************************/ |
668 | #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 | 675 | #if (defined(__mips) && __mips >= 3) && W_TYPE_SIZE == 64 |
669 | #if __GNUC__ > 2 || __GNUC_MINOR__ >= 7 | 676 | #if __GNUC__ >= 4 && __GNUC_MINOR__ >= 4 |
677 | #define umul_ppmm(w1, w0, u, v) \ | ||
678 | do { \ | ||
679 | typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ | ||
680 | __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \ | ||
681 | w1 = __ll >> 64; \ | ||
682 | w0 = __ll; \ | ||
683 | } while (0) | ||
684 | #elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 | ||
670 | #define umul_ppmm(w1, w0, u, v) \ | 685 | #define umul_ppmm(w1, w0, u, v) \ |
671 | __asm__ ("dmultu %2,%3" \ | 686 | __asm__ ("dmultu %2,%3" \ |
672 | : "=l" ((UDItype)(w0)), \ | 687 | : "=l" ((UDItype)(w0)), \ |
diff --git a/lib/mpi/mpi-internal.h b/lib/mpi/mpi-internal.h index 77adcf6bc257..60cf765628e9 100644 --- a/lib/mpi/mpi-internal.h +++ b/lib/mpi/mpi-internal.h | |||
@@ -65,10 +65,6 @@ | |||
65 | typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */ | 65 | typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */ |
66 | typedef int mpi_size_t; /* (must be a signed type) */ | 66 | typedef int mpi_size_t; /* (must be a signed type) */ |
67 | 67 | ||
68 | #define ABS(x) (x >= 0 ? x : -x) | ||
69 | #define MIN(l, o) ((l) < (o) ? (l) : (o)) | ||
70 | #define MAX(h, i) ((h) > (i) ? (h) : (i)) | ||
71 | |||
72 | static inline int RESIZE_IF_NEEDED(MPI a, unsigned b) | 68 | static inline int RESIZE_IF_NEEDED(MPI a, unsigned b) |
73 | { | 69 | { |
74 | if (a->alloced < b) | 70 | if (a->alloced < b) |
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c index 3962b7f7fe3f..5f9c44cdf1f5 100644 --- a/lib/mpi/mpicoder.c +++ b/lib/mpi/mpicoder.c | |||
@@ -52,7 +52,7 @@ MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes) | |||
52 | else | 52 | else |
53 | nbits = 0; | 53 | nbits = 0; |
54 | 54 | ||
55 | nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; | 55 | nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); |
56 | val = mpi_alloc(nlimbs); | 56 | val = mpi_alloc(nlimbs); |
57 | if (!val) | 57 | if (!val) |
58 | return NULL; | 58 | return NULL; |
@@ -96,8 +96,8 @@ MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread) | |||
96 | buffer += 2; | 96 | buffer += 2; |
97 | nread = 2; | 97 | nread = 2; |
98 | 98 | ||
99 | nbytes = (nbits + 7) / 8; | 99 | nbytes = DIV_ROUND_UP(nbits, 8); |
100 | nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; | 100 | nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); |
101 | val = mpi_alloc(nlimbs); | 101 | val = mpi_alloc(nlimbs); |
102 | if (!val) | 102 | if (!val) |
103 | return NULL; | 103 | return NULL; |
@@ -193,7 +193,7 @@ int mpi_set_buffer(MPI a, const void *xbuffer, unsigned nbytes, int sign) | |||
193 | int nlimbs; | 193 | int nlimbs; |
194 | int i; | 194 | int i; |
195 | 195 | ||
196 | nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; | 196 | nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB); |
197 | if (RESIZE_IF_NEEDED(a, nlimbs) < 0) | 197 | if (RESIZE_IF_NEEDED(a, nlimbs) < 0) |
198 | return -ENOMEM; | 198 | return -ENOMEM; |
199 | a->sign = sign; | 199 | a->sign = sign; |
diff --git a/lib/pSeries-reconfig-notifier-error-inject.c b/lib/of-reconfig-notifier-error-inject.c index 7f7c98dcd5c4..8dc79861758a 100644 --- a/lib/pSeries-reconfig-notifier-error-inject.c +++ b/lib/of-reconfig-notifier-error-inject.c | |||
@@ -1,20 +1,20 @@ | |||
1 | #include <linux/kernel.h> | 1 | #include <linux/kernel.h> |
2 | #include <linux/module.h> | 2 | #include <linux/module.h> |
3 | 3 | #include <linux/of.h> | |
4 | #include <asm/pSeries_reconfig.h> | ||
5 | 4 | ||
6 | #include "notifier-error-inject.h" | 5 | #include "notifier-error-inject.h" |
7 | 6 | ||
8 | static int priority; | 7 | static int priority; |
9 | module_param(priority, int, 0); | 8 | module_param(priority, int, 0); |
10 | MODULE_PARM_DESC(priority, "specify pSeries reconfig notifier priority"); | 9 | MODULE_PARM_DESC(priority, "specify OF reconfig notifier priority"); |
11 | 10 | ||
12 | static struct notifier_err_inject reconfig_err_inject = { | 11 | static struct notifier_err_inject reconfig_err_inject = { |
13 | .actions = { | 12 | .actions = { |
14 | { NOTIFIER_ERR_INJECT_ACTION(PSERIES_RECONFIG_ADD) }, | 13 | { NOTIFIER_ERR_INJECT_ACTION(OF_RECONFIG_ATTACH_NODE) }, |
15 | { NOTIFIER_ERR_INJECT_ACTION(PSERIES_RECONFIG_REMOVE) }, | 14 | { NOTIFIER_ERR_INJECT_ACTION(OF_RECONFIG_DETACH_NODE) }, |
16 | { NOTIFIER_ERR_INJECT_ACTION(PSERIES_DRCONF_MEM_ADD) }, | 15 | { NOTIFIER_ERR_INJECT_ACTION(OF_RECONFIG_ADD_PROPERTY) }, |
17 | { NOTIFIER_ERR_INJECT_ACTION(PSERIES_DRCONF_MEM_REMOVE) }, | 16 | { NOTIFIER_ERR_INJECT_ACTION(OF_RECONFIG_REMOVE_PROPERTY) }, |
17 | { NOTIFIER_ERR_INJECT_ACTION(OF_RECONFIG_UPDATE_PROPERTY) }, | ||
18 | {} | 18 | {} |
19 | } | 19 | } |
20 | }; | 20 | }; |
@@ -25,12 +25,12 @@ static int err_inject_init(void) | |||
25 | { | 25 | { |
26 | int err; | 26 | int err; |
27 | 27 | ||
28 | dir = notifier_err_inject_init("pSeries-reconfig", | 28 | dir = notifier_err_inject_init("OF-reconfig", |
29 | notifier_err_inject_dir, &reconfig_err_inject, priority); | 29 | notifier_err_inject_dir, &reconfig_err_inject, priority); |
30 | if (IS_ERR(dir)) | 30 | if (IS_ERR(dir)) |
31 | return PTR_ERR(dir); | 31 | return PTR_ERR(dir); |
32 | 32 | ||
33 | err = pSeries_reconfig_notifier_register(&reconfig_err_inject.nb); | 33 | err = of_reconfig_notifier_register(&reconfig_err_inject.nb); |
34 | if (err) | 34 | if (err) |
35 | debugfs_remove_recursive(dir); | 35 | debugfs_remove_recursive(dir); |
36 | 36 | ||
@@ -39,13 +39,13 @@ static int err_inject_init(void) | |||
39 | 39 | ||
40 | static void err_inject_exit(void) | 40 | static void err_inject_exit(void) |
41 | { | 41 | { |
42 | pSeries_reconfig_notifier_unregister(&reconfig_err_inject.nb); | 42 | of_reconfig_notifier_unregister(&reconfig_err_inject.nb); |
43 | debugfs_remove_recursive(dir); | 43 | debugfs_remove_recursive(dir); |
44 | } | 44 | } |
45 | 45 | ||
46 | module_init(err_inject_init); | 46 | module_init(err_inject_init); |
47 | module_exit(err_inject_exit); | 47 | module_exit(err_inject_exit); |
48 | 48 | ||
49 | MODULE_DESCRIPTION("pSeries reconfig notifier error injection module"); | 49 | MODULE_DESCRIPTION("OF reconfig notifier error injection module"); |
50 | MODULE_LICENSE("GPL"); | 50 | MODULE_LICENSE("GPL"); |
51 | MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>"); | 51 | MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>"); |
diff --git a/lib/parser.c b/lib/parser.c index 52cfa69f73df..807b2aaa33fa 100644 --- a/lib/parser.c +++ b/lib/parser.c | |||
@@ -157,7 +157,7 @@ static int match_number(substring_t *s, int *result, int base) | |||
157 | * | 157 | * |
158 | * Description: Attempts to parse the &substring_t @s as a decimal integer. On | 158 | * Description: Attempts to parse the &substring_t @s as a decimal integer. On |
159 | * success, sets @result to the integer represented by the string and returns 0. | 159 | * success, sets @result to the integer represented by the string and returns 0. |
160 | * Returns either -ENOMEM or -EINVAL on failure. | 160 | * Returns -ENOMEM, -EINVAL, or -ERANGE on failure. |
161 | */ | 161 | */ |
162 | int match_int(substring_t *s, int *result) | 162 | int match_int(substring_t *s, int *result) |
163 | { | 163 | { |
@@ -171,7 +171,7 @@ int match_int(substring_t *s, int *result) | |||
171 | * | 171 | * |
172 | * Description: Attempts to parse the &substring_t @s as an octal integer. On | 172 | * Description: Attempts to parse the &substring_t @s as an octal integer. On |
173 | * success, sets @result to the integer represented by the string and returns | 173 | * success, sets @result to the integer represented by the string and returns |
174 | * 0. Returns either -ENOMEM or -EINVAL on failure. | 174 | * 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. |
175 | */ | 175 | */ |
176 | int match_octal(substring_t *s, int *result) | 176 | int match_octal(substring_t *s, int *result) |
177 | { | 177 | { |
@@ -185,7 +185,7 @@ int match_octal(substring_t *s, int *result) | |||
185 | * | 185 | * |
186 | * Description: Attempts to parse the &substring_t @s as a hexadecimal integer. | 186 | * Description: Attempts to parse the &substring_t @s as a hexadecimal integer. |
187 | * On success, sets @result to the integer represented by the string and | 187 | * On success, sets @result to the integer represented by the string and |
188 | * returns 0. Returns either -ENOMEM or -EINVAL on failure. | 188 | * returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. |
189 | */ | 189 | */ |
190 | int match_hex(substring_t *s, int *result) | 190 | int match_hex(substring_t *s, int *result) |
191 | { | 191 | { |
diff --git a/lib/percpu-rwsem.c b/lib/percpu-rwsem.c new file mode 100644 index 000000000000..652a8ee8efe9 --- /dev/null +++ b/lib/percpu-rwsem.c | |||
@@ -0,0 +1,165 @@ | |||
1 | #include <linux/atomic.h> | ||
2 | #include <linux/rwsem.h> | ||
3 | #include <linux/percpu.h> | ||
4 | #include <linux/wait.h> | ||
5 | #include <linux/lockdep.h> | ||
6 | #include <linux/percpu-rwsem.h> | ||
7 | #include <linux/rcupdate.h> | ||
8 | #include <linux/sched.h> | ||
9 | #include <linux/errno.h> | ||
10 | |||
11 | int __percpu_init_rwsem(struct percpu_rw_semaphore *brw, | ||
12 | const char *name, struct lock_class_key *rwsem_key) | ||
13 | { | ||
14 | brw->fast_read_ctr = alloc_percpu(int); | ||
15 | if (unlikely(!brw->fast_read_ctr)) | ||
16 | return -ENOMEM; | ||
17 | |||
18 | /* ->rw_sem represents the whole percpu_rw_semaphore for lockdep */ | ||
19 | __init_rwsem(&brw->rw_sem, name, rwsem_key); | ||
20 | atomic_set(&brw->write_ctr, 0); | ||
21 | atomic_set(&brw->slow_read_ctr, 0); | ||
22 | init_waitqueue_head(&brw->write_waitq); | ||
23 | return 0; | ||
24 | } | ||
25 | |||
26 | void percpu_free_rwsem(struct percpu_rw_semaphore *brw) | ||
27 | { | ||
28 | free_percpu(brw->fast_read_ctr); | ||
29 | brw->fast_read_ctr = NULL; /* catch use after free bugs */ | ||
30 | } | ||
31 | |||
32 | /* | ||
33 | * This is the fast-path for down_read/up_read, it only needs to ensure | ||
34 | * there is no pending writer (atomic_read(write_ctr) == 0) and inc/dec the | ||
35 | * fast per-cpu counter. The writer uses synchronize_sched_expedited() to | ||
36 | * serialize with the preempt-disabled section below. | ||
37 | * | ||
38 | * The nontrivial part is that we should guarantee acquire/release semantics | ||
39 | * in case when | ||
40 | * | ||
41 | * R_W: down_write() comes after up_read(), the writer should see all | ||
42 | * changes done by the reader | ||
43 | * or | ||
44 | * W_R: down_read() comes after up_write(), the reader should see all | ||
45 | * changes done by the writer | ||
46 | * | ||
47 | * If this helper fails the callers rely on the normal rw_semaphore and | ||
48 | * atomic_dec_and_test(), so in this case we have the necessary barriers. | ||
49 | * | ||
50 | * But if it succeeds we do not have any barriers, atomic_read(write_ctr) or | ||
51 | * __this_cpu_add() below can be reordered with any LOAD/STORE done by the | ||
52 | * reader inside the critical section. See the comments in down_write and | ||
53 | * up_write below. | ||
54 | */ | ||
55 | static bool update_fast_ctr(struct percpu_rw_semaphore *brw, unsigned int val) | ||
56 | { | ||
57 | bool success = false; | ||
58 | |||
59 | preempt_disable(); | ||
60 | if (likely(!atomic_read(&brw->write_ctr))) { | ||
61 | __this_cpu_add(*brw->fast_read_ctr, val); | ||
62 | success = true; | ||
63 | } | ||
64 | preempt_enable(); | ||
65 | |||
66 | return success; | ||
67 | } | ||
68 | |||
69 | /* | ||
70 | * Like the normal down_read() this is not recursive, the writer can | ||
71 | * come after the first percpu_down_read() and create the deadlock. | ||
72 | * | ||
73 | * Note: returns with lock_is_held(brw->rw_sem) == T for lockdep, | ||
74 | * percpu_up_read() does rwsem_release(). This pairs with the usage | ||
75 | * of ->rw_sem in percpu_down/up_write(). | ||
76 | */ | ||
77 | void percpu_down_read(struct percpu_rw_semaphore *brw) | ||
78 | { | ||
79 | might_sleep(); | ||
80 | if (likely(update_fast_ctr(brw, +1))) { | ||
81 | rwsem_acquire_read(&brw->rw_sem.dep_map, 0, 0, _RET_IP_); | ||
82 | return; | ||
83 | } | ||
84 | |||
85 | down_read(&brw->rw_sem); | ||
86 | atomic_inc(&brw->slow_read_ctr); | ||
87 | /* avoid up_read()->rwsem_release() */ | ||
88 | __up_read(&brw->rw_sem); | ||
89 | } | ||
90 | |||
91 | void percpu_up_read(struct percpu_rw_semaphore *brw) | ||
92 | { | ||
93 | rwsem_release(&brw->rw_sem.dep_map, 1, _RET_IP_); | ||
94 | |||
95 | if (likely(update_fast_ctr(brw, -1))) | ||
96 | return; | ||
97 | |||
98 | /* false-positive is possible but harmless */ | ||
99 | if (atomic_dec_and_test(&brw->slow_read_ctr)) | ||
100 | wake_up_all(&brw->write_waitq); | ||
101 | } | ||
102 | |||
103 | static int clear_fast_ctr(struct percpu_rw_semaphore *brw) | ||
104 | { | ||
105 | unsigned int sum = 0; | ||
106 | int cpu; | ||
107 | |||
108 | for_each_possible_cpu(cpu) { | ||
109 | sum += per_cpu(*brw->fast_read_ctr, cpu); | ||
110 | per_cpu(*brw->fast_read_ctr, cpu) = 0; | ||
111 | } | ||
112 | |||
113 | return sum; | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * A writer increments ->write_ctr to force the readers to switch to the | ||
118 | * slow mode, note the atomic_read() check in update_fast_ctr(). | ||
119 | * | ||
120 | * After that the readers can only inc/dec the slow ->slow_read_ctr counter, | ||
121 | * ->fast_read_ctr is stable. Once the writer moves its sum into the slow | ||
122 | * counter it represents the number of active readers. | ||
123 | * | ||
124 | * Finally the writer takes ->rw_sem for writing and blocks the new readers, | ||
125 | * then waits until the slow counter becomes zero. | ||
126 | */ | ||
127 | void percpu_down_write(struct percpu_rw_semaphore *brw) | ||
128 | { | ||
129 | /* tell update_fast_ctr() there is a pending writer */ | ||
130 | atomic_inc(&brw->write_ctr); | ||
131 | /* | ||
132 | * 1. Ensures that write_ctr != 0 is visible to any down_read/up_read | ||
133 | * so that update_fast_ctr() can't succeed. | ||
134 | * | ||
135 | * 2. Ensures we see the result of every previous this_cpu_add() in | ||
136 | * update_fast_ctr(). | ||
137 | * | ||
138 | * 3. Ensures that if any reader has exited its critical section via | ||
139 | * fast-path, it executes a full memory barrier before we return. | ||
140 | * See R_W case in the comment above update_fast_ctr(). | ||
141 | */ | ||
142 | synchronize_sched_expedited(); | ||
143 | |||
144 | /* exclude other writers, and block the new readers completely */ | ||
145 | down_write(&brw->rw_sem); | ||
146 | |||
147 | /* nobody can use fast_read_ctr, move its sum into slow_read_ctr */ | ||
148 | atomic_add(clear_fast_ctr(brw), &brw->slow_read_ctr); | ||
149 | |||
150 | /* wait for all readers to complete their percpu_up_read() */ | ||
151 | wait_event(brw->write_waitq, !atomic_read(&brw->slow_read_ctr)); | ||
152 | } | ||
153 | |||
154 | void percpu_up_write(struct percpu_rw_semaphore *brw) | ||
155 | { | ||
156 | /* release the lock, but the readers can't use the fast-path */ | ||
157 | up_write(&brw->rw_sem); | ||
158 | /* | ||
159 | * Insert the barrier before the next fast-path in down_read, | ||
160 | * see W_R case in the comment above update_fast_ctr(). | ||
161 | */ | ||
162 | synchronize_sched_expedited(); | ||
163 | /* the last writer unblocks update_fast_ctr() */ | ||
164 | atomic_dec(&brw->write_ctr); | ||
165 | } | ||
diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile index de06dfe165b8..9f7c184725d7 100644 --- a/lib/raid6/Makefile +++ b/lib/raid6/Makefile | |||
@@ -1,8 +1,11 @@ | |||
1 | obj-$(CONFIG_RAID6_PQ) += raid6_pq.o | 1 | obj-$(CONFIG_RAID6_PQ) += raid6_pq.o |
2 | 2 | ||
3 | raid6_pq-y += algos.o recov.o recov_ssse3.o tables.o int1.o int2.o int4.o \ | 3 | raid6_pq-y += algos.o recov.o tables.o int1.o int2.o int4.o \ |
4 | int8.o int16.o int32.o altivec1.o altivec2.o altivec4.o \ | 4 | int8.o int16.o int32.o |
5 | altivec8.o mmx.o sse1.o sse2.o | 5 | |
6 | raid6_pq-$(CONFIG_X86) += recov_ssse3.o recov_avx2.o mmx.o sse1.o sse2.o avx2.o | ||
7 | raid6_pq-$(CONFIG_ALTIVEC) += altivec1.o altivec2.o altivec4.o altivec8.o | ||
8 | |||
6 | hostprogs-y += mktables | 9 | hostprogs-y += mktables |
7 | 10 | ||
8 | quiet_cmd_unroll = UNROLL $@ | 11 | quiet_cmd_unroll = UNROLL $@ |
diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c index 589f5f50ad2e..6d7316fe9f30 100644 --- a/lib/raid6/algos.c +++ b/lib/raid6/algos.c | |||
@@ -45,11 +45,20 @@ const struct raid6_calls * const raid6_algos[] = { | |||
45 | &raid6_sse1x2, | 45 | &raid6_sse1x2, |
46 | &raid6_sse2x1, | 46 | &raid6_sse2x1, |
47 | &raid6_sse2x2, | 47 | &raid6_sse2x2, |
48 | #ifdef CONFIG_AS_AVX2 | ||
49 | &raid6_avx2x1, | ||
50 | &raid6_avx2x2, | ||
51 | #endif | ||
48 | #endif | 52 | #endif |
49 | #if defined(__x86_64__) && !defined(__arch_um__) | 53 | #if defined(__x86_64__) && !defined(__arch_um__) |
50 | &raid6_sse2x1, | 54 | &raid6_sse2x1, |
51 | &raid6_sse2x2, | 55 | &raid6_sse2x2, |
52 | &raid6_sse2x4, | 56 | &raid6_sse2x4, |
57 | #ifdef CONFIG_AS_AVX2 | ||
58 | &raid6_avx2x1, | ||
59 | &raid6_avx2x2, | ||
60 | &raid6_avx2x4, | ||
61 | #endif | ||
53 | #endif | 62 | #endif |
54 | #ifdef CONFIG_ALTIVEC | 63 | #ifdef CONFIG_ALTIVEC |
55 | &raid6_altivec1, | 64 | &raid6_altivec1, |
@@ -72,6 +81,9 @@ EXPORT_SYMBOL_GPL(raid6_datap_recov); | |||
72 | 81 | ||
73 | const struct raid6_recov_calls *const raid6_recov_algos[] = { | 82 | const struct raid6_recov_calls *const raid6_recov_algos[] = { |
74 | #if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__) | 83 | #if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__) |
84 | #ifdef CONFIG_AS_AVX2 | ||
85 | &raid6_recov_avx2, | ||
86 | #endif | ||
75 | &raid6_recov_ssse3, | 87 | &raid6_recov_ssse3, |
76 | #endif | 88 | #endif |
77 | &raid6_recov_intx1, | 89 | &raid6_recov_intx1, |
diff --git a/lib/raid6/altivec.uc b/lib/raid6/altivec.uc index b71012b756f4..7cc12b532e95 100644 --- a/lib/raid6/altivec.uc +++ b/lib/raid6/altivec.uc | |||
@@ -24,13 +24,10 @@ | |||
24 | 24 | ||
25 | #include <linux/raid/pq.h> | 25 | #include <linux/raid/pq.h> |
26 | 26 | ||
27 | #ifdef CONFIG_ALTIVEC | ||
28 | |||
29 | #include <altivec.h> | 27 | #include <altivec.h> |
30 | #ifdef __KERNEL__ | 28 | #ifdef __KERNEL__ |
31 | # include <asm/cputable.h> | 29 | # include <asm/cputable.h> |
32 | # include <asm/switch_to.h> | 30 | # include <asm/switch_to.h> |
33 | #endif | ||
34 | 31 | ||
35 | /* | 32 | /* |
36 | * This is the C data type to use. We use a vector of | 33 | * This is the C data type to use. We use a vector of |
diff --git a/lib/raid6/avx2.c b/lib/raid6/avx2.c new file mode 100644 index 000000000000..bc3b1dd436eb --- /dev/null +++ b/lib/raid6/avx2.c | |||
@@ -0,0 +1,251 @@ | |||
1 | /* -*- linux-c -*- ------------------------------------------------------- * | ||
2 | * | ||
3 | * Copyright (C) 2012 Intel Corporation | ||
4 | * Author: Yuanhan Liu <yuanhan.liu@linux.intel.com> | ||
5 | * | ||
6 | * Based on sse2.c: Copyright 2002 H. Peter Anvin - All Rights Reserved | ||
7 | * | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation, Inc., 53 Temple Place Ste 330, | ||
12 | * Boston MA 02111-1307, USA; either version 2 of the License, or | ||
13 | * (at your option) any later version; incorporated herein by reference. | ||
14 | * | ||
15 | * ----------------------------------------------------------------------- */ | ||
16 | |||
17 | /* | ||
18 | * AVX2 implementation of RAID-6 syndrome functions | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifdef CONFIG_AS_AVX2 | ||
23 | |||
24 | #include <linux/raid/pq.h> | ||
25 | #include "x86.h" | ||
26 | |||
27 | static const struct raid6_avx2_constants { | ||
28 | u64 x1d[4]; | ||
29 | } raid6_avx2_constants __aligned(32) = { | ||
30 | { 0x1d1d1d1d1d1d1d1dULL, 0x1d1d1d1d1d1d1d1dULL, | ||
31 | 0x1d1d1d1d1d1d1d1dULL, 0x1d1d1d1d1d1d1d1dULL,}, | ||
32 | }; | ||
33 | |||
34 | static int raid6_have_avx2(void) | ||
35 | { | ||
36 | return boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_AVX); | ||
37 | } | ||
38 | |||
39 | /* | ||
40 | * Plain AVX2 implementation | ||
41 | */ | ||
42 | static void raid6_avx21_gen_syndrome(int disks, size_t bytes, void **ptrs) | ||
43 | { | ||
44 | u8 **dptr = (u8 **)ptrs; | ||
45 | u8 *p, *q; | ||
46 | int d, z, z0; | ||
47 | |||
48 | z0 = disks - 3; /* Highest data disk */ | ||
49 | p = dptr[z0+1]; /* XOR parity */ | ||
50 | q = dptr[z0+2]; /* RS syndrome */ | ||
51 | |||
52 | kernel_fpu_begin(); | ||
53 | |||
54 | asm volatile("vmovdqa %0,%%ymm0" : : "m" (raid6_avx2_constants.x1d[0])); | ||
55 | asm volatile("vpxor %ymm3,%ymm3,%ymm3"); /* Zero temp */ | ||
56 | |||
57 | for (d = 0; d < bytes; d += 32) { | ||
58 | asm volatile("prefetchnta %0" : : "m" (dptr[z0][d])); | ||
59 | asm volatile("vmovdqa %0,%%ymm2" : : "m" (dptr[z0][d]));/* P[0] */ | ||
60 | asm volatile("prefetchnta %0" : : "m" (dptr[z0-1][d])); | ||
61 | asm volatile("vmovdqa %ymm2,%ymm4");/* Q[0] */ | ||
62 | asm volatile("vmovdqa %0,%%ymm6" : : "m" (dptr[z0-1][d])); | ||
63 | for (z = z0-2; z >= 0; z--) { | ||
64 | asm volatile("prefetchnta %0" : : "m" (dptr[z][d])); | ||
65 | asm volatile("vpcmpgtb %ymm4,%ymm3,%ymm5"); | ||
66 | asm volatile("vpaddb %ymm4,%ymm4,%ymm4"); | ||
67 | asm volatile("vpand %ymm0,%ymm5,%ymm5"); | ||
68 | asm volatile("vpxor %ymm5,%ymm4,%ymm4"); | ||
69 | asm volatile("vpxor %ymm6,%ymm2,%ymm2"); | ||
70 | asm volatile("vpxor %ymm6,%ymm4,%ymm4"); | ||
71 | asm volatile("vmovdqa %0,%%ymm6" : : "m" (dptr[z][d])); | ||
72 | } | ||
73 | asm volatile("vpcmpgtb %ymm4,%ymm3,%ymm5"); | ||
74 | asm volatile("vpaddb %ymm4,%ymm4,%ymm4"); | ||
75 | asm volatile("vpand %ymm0,%ymm5,%ymm5"); | ||
76 | asm volatile("vpxor %ymm5,%ymm4,%ymm4"); | ||
77 | asm volatile("vpxor %ymm6,%ymm2,%ymm2"); | ||
78 | asm volatile("vpxor %ymm6,%ymm4,%ymm4"); | ||
79 | |||
80 | asm volatile("vmovntdq %%ymm2,%0" : "=m" (p[d])); | ||
81 | asm volatile("vpxor %ymm2,%ymm2,%ymm2"); | ||
82 | asm volatile("vmovntdq %%ymm4,%0" : "=m" (q[d])); | ||
83 | asm volatile("vpxor %ymm4,%ymm4,%ymm4"); | ||
84 | } | ||
85 | |||
86 | asm volatile("sfence" : : : "memory"); | ||
87 | kernel_fpu_end(); | ||
88 | } | ||
89 | |||
90 | const struct raid6_calls raid6_avx2x1 = { | ||
91 | raid6_avx21_gen_syndrome, | ||
92 | raid6_have_avx2, | ||
93 | "avx2x1", | ||
94 | 1 /* Has cache hints */ | ||
95 | }; | ||
96 | |||
97 | /* | ||
98 | * Unrolled-by-2 AVX2 implementation | ||
99 | */ | ||
100 | static void raid6_avx22_gen_syndrome(int disks, size_t bytes, void **ptrs) | ||
101 | { | ||
102 | u8 **dptr = (u8 **)ptrs; | ||
103 | u8 *p, *q; | ||
104 | int d, z, z0; | ||
105 | |||
106 | z0 = disks - 3; /* Highest data disk */ | ||
107 | p = dptr[z0+1]; /* XOR parity */ | ||
108 | q = dptr[z0+2]; /* RS syndrome */ | ||
109 | |||
110 | kernel_fpu_begin(); | ||
111 | |||
112 | asm volatile("vmovdqa %0,%%ymm0" : : "m" (raid6_avx2_constants.x1d[0])); | ||
113 | asm volatile("vpxor %ymm1,%ymm1,%ymm1"); /* Zero temp */ | ||
114 | |||
115 | /* We uniformly assume a single prefetch covers at least 32 bytes */ | ||
116 | for (d = 0; d < bytes; d += 64) { | ||
117 | asm volatile("prefetchnta %0" : : "m" (dptr[z0][d])); | ||
118 | asm volatile("prefetchnta %0" : : "m" (dptr[z0][d+32])); | ||
119 | asm volatile("vmovdqa %0,%%ymm2" : : "m" (dptr[z0][d]));/* P[0] */ | ||
120 | asm volatile("vmovdqa %0,%%ymm3" : : "m" (dptr[z0][d+32]));/* P[1] */ | ||
121 | asm volatile("vmovdqa %ymm2,%ymm4"); /* Q[0] */ | ||
122 | asm volatile("vmovdqa %ymm3,%ymm6"); /* Q[1] */ | ||
123 | for (z = z0-1; z >= 0; z--) { | ||
124 | asm volatile("prefetchnta %0" : : "m" (dptr[z][d])); | ||
125 | asm volatile("prefetchnta %0" : : "m" (dptr[z][d+32])); | ||
126 | asm volatile("vpcmpgtb %ymm4,%ymm1,%ymm5"); | ||
127 | asm volatile("vpcmpgtb %ymm6,%ymm1,%ymm7"); | ||
128 | asm volatile("vpaddb %ymm4,%ymm4,%ymm4"); | ||
129 | asm volatile("vpaddb %ymm6,%ymm6,%ymm6"); | ||
130 | asm volatile("vpand %ymm0,%ymm5,%ymm5"); | ||
131 | asm volatile("vpand %ymm0,%ymm7,%ymm7"); | ||
132 | asm volatile("vpxor %ymm5,%ymm4,%ymm4"); | ||
133 | asm volatile("vpxor %ymm7,%ymm6,%ymm6"); | ||
134 | asm volatile("vmovdqa %0,%%ymm5" : : "m" (dptr[z][d])); | ||
135 | asm volatile("vmovdqa %0,%%ymm7" : : "m" (dptr[z][d+32])); | ||
136 | asm volatile("vpxor %ymm5,%ymm2,%ymm2"); | ||
137 | asm volatile("vpxor %ymm7,%ymm3,%ymm3"); | ||
138 | asm volatile("vpxor %ymm5,%ymm4,%ymm4"); | ||
139 | asm volatile("vpxor %ymm7,%ymm6,%ymm6"); | ||
140 | } | ||
141 | asm volatile("vmovntdq %%ymm2,%0" : "=m" (p[d])); | ||
142 | asm volatile("vmovntdq %%ymm3,%0" : "=m" (p[d+32])); | ||
143 | asm volatile("vmovntdq %%ymm4,%0" : "=m" (q[d])); | ||
144 | asm volatile("vmovntdq %%ymm6,%0" : "=m" (q[d+32])); | ||
145 | } | ||
146 | |||
147 | asm volatile("sfence" : : : "memory"); | ||
148 | kernel_fpu_end(); | ||
149 | } | ||
150 | |||
151 | const struct raid6_calls raid6_avx2x2 = { | ||
152 | raid6_avx22_gen_syndrome, | ||
153 | raid6_have_avx2, | ||
154 | "avx2x2", | ||
155 | 1 /* Has cache hints */ | ||
156 | }; | ||
157 | |||
158 | #ifdef CONFIG_X86_64 | ||
159 | |||
160 | /* | ||
161 | * Unrolled-by-4 AVX2 implementation | ||
162 | */ | ||
163 | static void raid6_avx24_gen_syndrome(int disks, size_t bytes, void **ptrs) | ||
164 | { | ||
165 | u8 **dptr = (u8 **)ptrs; | ||
166 | u8 *p, *q; | ||
167 | int d, z, z0; | ||
168 | |||
169 | z0 = disks - 3; /* Highest data disk */ | ||
170 | p = dptr[z0+1]; /* XOR parity */ | ||
171 | q = dptr[z0+2]; /* RS syndrome */ | ||
172 | |||
173 | kernel_fpu_begin(); | ||
174 | |||
175 | asm volatile("vmovdqa %0,%%ymm0" : : "m" (raid6_avx2_constants.x1d[0])); | ||
176 | asm volatile("vpxor %ymm1,%ymm1,%ymm1"); /* Zero temp */ | ||
177 | asm volatile("vpxor %ymm2,%ymm2,%ymm2"); /* P[0] */ | ||
178 | asm volatile("vpxor %ymm3,%ymm3,%ymm3"); /* P[1] */ | ||
179 | asm volatile("vpxor %ymm4,%ymm4,%ymm4"); /* Q[0] */ | ||
180 | asm volatile("vpxor %ymm6,%ymm6,%ymm6"); /* Q[1] */ | ||
181 | asm volatile("vpxor %ymm10,%ymm10,%ymm10"); /* P[2] */ | ||
182 | asm volatile("vpxor %ymm11,%ymm11,%ymm11"); /* P[3] */ | ||
183 | asm volatile("vpxor %ymm12,%ymm12,%ymm12"); /* Q[2] */ | ||
184 | asm volatile("vpxor %ymm14,%ymm14,%ymm14"); /* Q[3] */ | ||
185 | |||
186 | for (d = 0; d < bytes; d += 128) { | ||
187 | for (z = z0; z >= 0; z--) { | ||
188 | asm volatile("prefetchnta %0" : : "m" (dptr[z][d])); | ||
189 | asm volatile("prefetchnta %0" : : "m" (dptr[z][d+32])); | ||
190 | asm volatile("prefetchnta %0" : : "m" (dptr[z][d+64])); | ||
191 | asm volatile("prefetchnta %0" : : "m" (dptr[z][d+96])); | ||
192 | asm volatile("vpcmpgtb %ymm4,%ymm1,%ymm5"); | ||
193 | asm volatile("vpcmpgtb %ymm6,%ymm1,%ymm7"); | ||
194 | asm volatile("vpcmpgtb %ymm12,%ymm1,%ymm13"); | ||
195 | asm volatile("vpcmpgtb %ymm14,%ymm1,%ymm15"); | ||
196 | asm volatile("vpaddb %ymm4,%ymm4,%ymm4"); | ||
197 | asm volatile("vpaddb %ymm6,%ymm6,%ymm6"); | ||
198 | asm volatile("vpaddb %ymm12,%ymm12,%ymm12"); | ||
199 | asm volatile("vpaddb %ymm14,%ymm14,%ymm14"); | ||
200 | asm volatile("vpand %ymm0,%ymm5,%ymm5"); | ||
201 | asm volatile("vpand %ymm0,%ymm7,%ymm7"); | ||
202 | asm volatile("vpand %ymm0,%ymm13,%ymm13"); | ||
203 | asm volatile("vpand %ymm0,%ymm15,%ymm15"); | ||
204 | asm volatile("vpxor %ymm5,%ymm4,%ymm4"); | ||
205 | asm volatile("vpxor %ymm7,%ymm6,%ymm6"); | ||
206 | asm volatile("vpxor %ymm13,%ymm12,%ymm12"); | ||
207 | asm volatile("vpxor %ymm15,%ymm14,%ymm14"); | ||
208 | asm volatile("vmovdqa %0,%%ymm5" : : "m" (dptr[z][d])); | ||
209 | asm volatile("vmovdqa %0,%%ymm7" : : "m" (dptr[z][d+32])); | ||
210 | asm volatile("vmovdqa %0,%%ymm13" : : "m" (dptr[z][d+64])); | ||
211 | asm volatile("vmovdqa %0,%%ymm15" : : "m" (dptr[z][d+96])); | ||
212 | asm volatile("vpxor %ymm5,%ymm2,%ymm2"); | ||
213 | asm volatile("vpxor %ymm7,%ymm3,%ymm3"); | ||
214 | asm volatile("vpxor %ymm13,%ymm10,%ymm10"); | ||
215 | asm volatile("vpxor %ymm15,%ymm11,%ymm11"); | ||
216 | asm volatile("vpxor %ymm5,%ymm4,%ymm4"); | ||
217 | asm volatile("vpxor %ymm7,%ymm6,%ymm6"); | ||
218 | asm volatile("vpxor %ymm13,%ymm12,%ymm12"); | ||
219 | asm volatile("vpxor %ymm15,%ymm14,%ymm14"); | ||
220 | } | ||
221 | asm volatile("vmovntdq %%ymm2,%0" : "=m" (p[d])); | ||
222 | asm volatile("vpxor %ymm2,%ymm2,%ymm2"); | ||
223 | asm volatile("vmovntdq %%ymm3,%0" : "=m" (p[d+32])); | ||
224 | asm volatile("vpxor %ymm3,%ymm3,%ymm3"); | ||
225 | asm volatile("vmovntdq %%ymm10,%0" : "=m" (p[d+64])); | ||
226 | asm volatile("vpxor %ymm10,%ymm10,%ymm10"); | ||
227 | asm volatile("vmovntdq %%ymm11,%0" : "=m" (p[d+96])); | ||
228 | asm volatile("vpxor %ymm11,%ymm11,%ymm11"); | ||
229 | asm volatile("vmovntdq %%ymm4,%0" : "=m" (q[d])); | ||
230 | asm volatile("vpxor %ymm4,%ymm4,%ymm4"); | ||
231 | asm volatile("vmovntdq %%ymm6,%0" : "=m" (q[d+32])); | ||
232 | asm volatile("vpxor %ymm6,%ymm6,%ymm6"); | ||
233 | asm volatile("vmovntdq %%ymm12,%0" : "=m" (q[d+64])); | ||
234 | asm volatile("vpxor %ymm12,%ymm12,%ymm12"); | ||
235 | asm volatile("vmovntdq %%ymm14,%0" : "=m" (q[d+96])); | ||
236 | asm volatile("vpxor %ymm14,%ymm14,%ymm14"); | ||
237 | } | ||
238 | |||
239 | asm volatile("sfence" : : : "memory"); | ||
240 | kernel_fpu_end(); | ||
241 | } | ||
242 | |||
243 | const struct raid6_calls raid6_avx2x4 = { | ||
244 | raid6_avx24_gen_syndrome, | ||
245 | raid6_have_avx2, | ||
246 | "avx2x4", | ||
247 | 1 /* Has cache hints */ | ||
248 | }; | ||
249 | #endif | ||
250 | |||
251 | #endif /* CONFIG_AS_AVX2 */ | ||
diff --git a/lib/raid6/mmx.c b/lib/raid6/mmx.c index 279347f23094..590c71c9e200 100644 --- a/lib/raid6/mmx.c +++ b/lib/raid6/mmx.c | |||
@@ -16,7 +16,7 @@ | |||
16 | * MMX implementation of RAID-6 syndrome functions | 16 | * MMX implementation of RAID-6 syndrome functions |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #if defined(__i386__) && !defined(__arch_um__) | 19 | #ifdef CONFIG_X86_32 |
20 | 20 | ||
21 | #include <linux/raid/pq.h> | 21 | #include <linux/raid/pq.h> |
22 | #include "x86.h" | 22 | #include "x86.h" |
diff --git a/lib/raid6/recov_avx2.c b/lib/raid6/recov_avx2.c new file mode 100644 index 000000000000..e1eea433a493 --- /dev/null +++ b/lib/raid6/recov_avx2.c | |||
@@ -0,0 +1,323 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Intel Corporation | ||
3 | * Author: Jim Kukunas <james.t.kukunas@linux.intel.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; version 2 | ||
8 | * of the License. | ||
9 | */ | ||
10 | |||
11 | #if CONFIG_AS_AVX2 | ||
12 | |||
13 | #include <linux/raid/pq.h> | ||
14 | #include "x86.h" | ||
15 | |||
16 | static int raid6_has_avx2(void) | ||
17 | { | ||
18 | return boot_cpu_has(X86_FEATURE_AVX2) && | ||
19 | boot_cpu_has(X86_FEATURE_AVX); | ||
20 | } | ||
21 | |||
22 | static void raid6_2data_recov_avx2(int disks, size_t bytes, int faila, | ||
23 | int failb, void **ptrs) | ||
24 | { | ||
25 | u8 *p, *q, *dp, *dq; | ||
26 | const u8 *pbmul; /* P multiplier table for B data */ | ||
27 | const u8 *qmul; /* Q multiplier table (for both) */ | ||
28 | const u8 x0f = 0x0f; | ||
29 | |||
30 | p = (u8 *)ptrs[disks-2]; | ||
31 | q = (u8 *)ptrs[disks-1]; | ||
32 | |||
33 | /* Compute syndrome with zero for the missing data pages | ||
34 | Use the dead data pages as temporary storage for | ||
35 | delta p and delta q */ | ||
36 | dp = (u8 *)ptrs[faila]; | ||
37 | ptrs[faila] = (void *)raid6_empty_zero_page; | ||
38 | ptrs[disks-2] = dp; | ||
39 | dq = (u8 *)ptrs[failb]; | ||
40 | ptrs[failb] = (void *)raid6_empty_zero_page; | ||
41 | ptrs[disks-1] = dq; | ||
42 | |||
43 | raid6_call.gen_syndrome(disks, bytes, ptrs); | ||
44 | |||
45 | /* Restore pointer table */ | ||
46 | ptrs[faila] = dp; | ||
47 | ptrs[failb] = dq; | ||
48 | ptrs[disks-2] = p; | ||
49 | ptrs[disks-1] = q; | ||
50 | |||
51 | /* Now, pick the proper data tables */ | ||
52 | pbmul = raid6_vgfmul[raid6_gfexi[failb-faila]]; | ||
53 | qmul = raid6_vgfmul[raid6_gfinv[raid6_gfexp[faila] ^ | ||
54 | raid6_gfexp[failb]]]; | ||
55 | |||
56 | kernel_fpu_begin(); | ||
57 | |||
58 | /* ymm0 = x0f[16] */ | ||
59 | asm volatile("vpbroadcastb %0, %%ymm7" : : "m" (x0f)); | ||
60 | |||
61 | while (bytes) { | ||
62 | #ifdef CONFIG_X86_64 | ||
63 | asm volatile("vmovdqa %0, %%ymm1" : : "m" (q[0])); | ||
64 | asm volatile("vmovdqa %0, %%ymm9" : : "m" (q[32])); | ||
65 | asm volatile("vmovdqa %0, %%ymm0" : : "m" (p[0])); | ||
66 | asm volatile("vmovdqa %0, %%ymm8" : : "m" (p[32])); | ||
67 | asm volatile("vpxor %0, %%ymm1, %%ymm1" : : "m" (dq[0])); | ||
68 | asm volatile("vpxor %0, %%ymm9, %%ymm9" : : "m" (dq[32])); | ||
69 | asm volatile("vpxor %0, %%ymm0, %%ymm0" : : "m" (dp[0])); | ||
70 | asm volatile("vpxor %0, %%ymm8, %%ymm8" : : "m" (dp[32])); | ||
71 | |||
72 | /* | ||
73 | * 1 = dq[0] ^ q[0] | ||
74 | * 9 = dq[32] ^ q[32] | ||
75 | * 0 = dp[0] ^ p[0] | ||
76 | * 8 = dp[32] ^ p[32] | ||
77 | */ | ||
78 | |||
79 | asm volatile("vbroadcasti128 %0, %%ymm4" : : "m" (qmul[0])); | ||
80 | asm volatile("vbroadcasti128 %0, %%ymm5" : : "m" (qmul[16])); | ||
81 | |||
82 | asm volatile("vpsraw $4, %ymm1, %ymm3"); | ||
83 | asm volatile("vpsraw $4, %ymm9, %ymm12"); | ||
84 | asm volatile("vpand %ymm7, %ymm1, %ymm1"); | ||
85 | asm volatile("vpand %ymm7, %ymm9, %ymm9"); | ||
86 | asm volatile("vpand %ymm7, %ymm3, %ymm3"); | ||
87 | asm volatile("vpand %ymm7, %ymm12, %ymm12"); | ||
88 | asm volatile("vpshufb %ymm9, %ymm4, %ymm14"); | ||
89 | asm volatile("vpshufb %ymm1, %ymm4, %ymm4"); | ||
90 | asm volatile("vpshufb %ymm12, %ymm5, %ymm15"); | ||
91 | asm volatile("vpshufb %ymm3, %ymm5, %ymm5"); | ||
92 | asm volatile("vpxor %ymm14, %ymm15, %ymm15"); | ||
93 | asm volatile("vpxor %ymm4, %ymm5, %ymm5"); | ||
94 | |||
95 | /* | ||
96 | * 5 = qx[0] | ||
97 | * 15 = qx[32] | ||
98 | */ | ||
99 | |||
100 | asm volatile("vbroadcasti128 %0, %%ymm4" : : "m" (pbmul[0])); | ||
101 | asm volatile("vbroadcasti128 %0, %%ymm1" : : "m" (pbmul[16])); | ||
102 | asm volatile("vpsraw $4, %ymm0, %ymm2"); | ||
103 | asm volatile("vpsraw $4, %ymm8, %ymm6"); | ||
104 | asm volatile("vpand %ymm7, %ymm0, %ymm3"); | ||
105 | asm volatile("vpand %ymm7, %ymm8, %ymm14"); | ||
106 | asm volatile("vpand %ymm7, %ymm2, %ymm2"); | ||
107 | asm volatile("vpand %ymm7, %ymm6, %ymm6"); | ||
108 | asm volatile("vpshufb %ymm14, %ymm4, %ymm12"); | ||
109 | asm volatile("vpshufb %ymm3, %ymm4, %ymm4"); | ||
110 | asm volatile("vpshufb %ymm6, %ymm1, %ymm13"); | ||
111 | asm volatile("vpshufb %ymm2, %ymm1, %ymm1"); | ||
112 | asm volatile("vpxor %ymm4, %ymm1, %ymm1"); | ||
113 | asm volatile("vpxor %ymm12, %ymm13, %ymm13"); | ||
114 | |||
115 | /* | ||
116 | * 1 = pbmul[px[0]] | ||
117 | * 13 = pbmul[px[32]] | ||
118 | */ | ||
119 | asm volatile("vpxor %ymm5, %ymm1, %ymm1"); | ||
120 | asm volatile("vpxor %ymm15, %ymm13, %ymm13"); | ||
121 | |||
122 | /* | ||
123 | * 1 = db = DQ | ||
124 | * 13 = db[32] = DQ[32] | ||
125 | */ | ||
126 | asm volatile("vmovdqa %%ymm1, %0" : "=m" (dq[0])); | ||
127 | asm volatile("vmovdqa %%ymm13,%0" : "=m" (dq[32])); | ||
128 | asm volatile("vpxor %ymm1, %ymm0, %ymm0"); | ||
129 | asm volatile("vpxor %ymm13, %ymm8, %ymm8"); | ||
130 | |||
131 | asm volatile("vmovdqa %%ymm0, %0" : "=m" (dp[0])); | ||
132 | asm volatile("vmovdqa %%ymm8, %0" : "=m" (dp[32])); | ||
133 | |||
134 | bytes -= 64; | ||
135 | p += 64; | ||
136 | q += 64; | ||
137 | dp += 64; | ||
138 | dq += 64; | ||
139 | #else | ||
140 | asm volatile("vmovdqa %0, %%ymm1" : : "m" (*q)); | ||
141 | asm volatile("vmovdqa %0, %%ymm0" : : "m" (*p)); | ||
142 | asm volatile("vpxor %0, %%ymm1, %%ymm1" : : "m" (*dq)); | ||
143 | asm volatile("vpxor %0, %%ymm0, %%ymm0" : : "m" (*dp)); | ||
144 | |||
145 | /* 1 = dq ^ q; 0 = dp ^ p */ | ||
146 | |||
147 | asm volatile("vbroadcasti128 %0, %%ymm4" : : "m" (qmul[0])); | ||
148 | asm volatile("vbroadcasti128 %0, %%ymm5" : : "m" (qmul[16])); | ||
149 | |||
150 | /* | ||
151 | * 1 = dq ^ q | ||
152 | * 3 = dq ^ p >> 4 | ||
153 | */ | ||
154 | asm volatile("vpsraw $4, %ymm1, %ymm3"); | ||
155 | asm volatile("vpand %ymm7, %ymm1, %ymm1"); | ||
156 | asm volatile("vpand %ymm7, %ymm3, %ymm3"); | ||
157 | asm volatile("vpshufb %ymm1, %ymm4, %ymm4"); | ||
158 | asm volatile("vpshufb %ymm3, %ymm5, %ymm5"); | ||
159 | asm volatile("vpxor %ymm4, %ymm5, %ymm5"); | ||
160 | |||
161 | /* 5 = qx */ | ||
162 | |||
163 | asm volatile("vbroadcasti128 %0, %%ymm4" : : "m" (pbmul[0])); | ||
164 | asm volatile("vbroadcasti128 %0, %%ymm1" : : "m" (pbmul[16])); | ||
165 | |||
166 | asm volatile("vpsraw $4, %ymm0, %ymm2"); | ||
167 | asm volatile("vpand %ymm7, %ymm0, %ymm3"); | ||
168 | asm volatile("vpand %ymm7, %ymm2, %ymm2"); | ||
169 | asm volatile("vpshufb %ymm3, %ymm4, %ymm4"); | ||
170 | asm volatile("vpshufb %ymm2, %ymm1, %ymm1"); | ||
171 | asm volatile("vpxor %ymm4, %ymm1, %ymm1"); | ||
172 | |||
173 | /* 1 = pbmul[px] */ | ||
174 | asm volatile("vpxor %ymm5, %ymm1, %ymm1"); | ||
175 | /* 1 = db = DQ */ | ||
176 | asm volatile("vmovdqa %%ymm1, %0" : "=m" (dq[0])); | ||
177 | |||
178 | asm volatile("vpxor %ymm1, %ymm0, %ymm0"); | ||
179 | asm volatile("vmovdqa %%ymm0, %0" : "=m" (dp[0])); | ||
180 | |||
181 | bytes -= 32; | ||
182 | p += 32; | ||
183 | q += 32; | ||
184 | dp += 32; | ||
185 | dq += 32; | ||
186 | #endif | ||
187 | } | ||
188 | |||
189 | kernel_fpu_end(); | ||
190 | } | ||
191 | |||
192 | static void raid6_datap_recov_avx2(int disks, size_t bytes, int faila, | ||
193 | void **ptrs) | ||
194 | { | ||
195 | u8 *p, *q, *dq; | ||
196 | const u8 *qmul; /* Q multiplier table */ | ||
197 | const u8 x0f = 0x0f; | ||
198 | |||
199 | p = (u8 *)ptrs[disks-2]; | ||
200 | q = (u8 *)ptrs[disks-1]; | ||
201 | |||
202 | /* Compute syndrome with zero for the missing data page | ||
203 | Use the dead data page as temporary storage for delta q */ | ||
204 | dq = (u8 *)ptrs[faila]; | ||
205 | ptrs[faila] = (void *)raid6_empty_zero_page; | ||
206 | ptrs[disks-1] = dq; | ||
207 | |||
208 | raid6_call.gen_syndrome(disks, bytes, ptrs); | ||
209 | |||
210 | /* Restore pointer table */ | ||
211 | ptrs[faila] = dq; | ||
212 | ptrs[disks-1] = q; | ||
213 | |||
214 | /* Now, pick the proper data tables */ | ||
215 | qmul = raid6_vgfmul[raid6_gfinv[raid6_gfexp[faila]]]; | ||
216 | |||
217 | kernel_fpu_begin(); | ||
218 | |||
219 | asm volatile("vpbroadcastb %0, %%ymm7" : : "m" (x0f)); | ||
220 | |||
221 | while (bytes) { | ||
222 | #ifdef CONFIG_X86_64 | ||
223 | asm volatile("vmovdqa %0, %%ymm3" : : "m" (dq[0])); | ||
224 | asm volatile("vmovdqa %0, %%ymm8" : : "m" (dq[32])); | ||
225 | asm volatile("vpxor %0, %%ymm3, %%ymm3" : : "m" (q[0])); | ||
226 | asm volatile("vpxor %0, %%ymm8, %%ymm8" : : "m" (q[32])); | ||
227 | |||
228 | /* | ||
229 | * 3 = q[0] ^ dq[0] | ||
230 | * 8 = q[32] ^ dq[32] | ||
231 | */ | ||
232 | asm volatile("vbroadcasti128 %0, %%ymm0" : : "m" (qmul[0])); | ||
233 | asm volatile("vmovapd %ymm0, %ymm13"); | ||
234 | asm volatile("vbroadcasti128 %0, %%ymm1" : : "m" (qmul[16])); | ||
235 | asm volatile("vmovapd %ymm1, %ymm14"); | ||
236 | |||
237 | asm volatile("vpsraw $4, %ymm3, %ymm6"); | ||
238 | asm volatile("vpsraw $4, %ymm8, %ymm12"); | ||
239 | asm volatile("vpand %ymm7, %ymm3, %ymm3"); | ||
240 | asm volatile("vpand %ymm7, %ymm8, %ymm8"); | ||
241 | asm volatile("vpand %ymm7, %ymm6, %ymm6"); | ||
242 | asm volatile("vpand %ymm7, %ymm12, %ymm12"); | ||
243 | asm volatile("vpshufb %ymm3, %ymm0, %ymm0"); | ||
244 | asm volatile("vpshufb %ymm8, %ymm13, %ymm13"); | ||
245 | asm volatile("vpshufb %ymm6, %ymm1, %ymm1"); | ||
246 | asm volatile("vpshufb %ymm12, %ymm14, %ymm14"); | ||
247 | asm volatile("vpxor %ymm0, %ymm1, %ymm1"); | ||
248 | asm volatile("vpxor %ymm13, %ymm14, %ymm14"); | ||
249 | |||
250 | /* | ||
251 | * 1 = qmul[q[0] ^ dq[0]] | ||
252 | * 14 = qmul[q[32] ^ dq[32]] | ||
253 | */ | ||
254 | asm volatile("vmovdqa %0, %%ymm2" : : "m" (p[0])); | ||
255 | asm volatile("vmovdqa %0, %%ymm12" : : "m" (p[32])); | ||
256 | asm volatile("vpxor %ymm1, %ymm2, %ymm2"); | ||
257 | asm volatile("vpxor %ymm14, %ymm12, %ymm12"); | ||
258 | |||
259 | /* | ||
260 | * 2 = p[0] ^ qmul[q[0] ^ dq[0]] | ||
261 | * 12 = p[32] ^ qmul[q[32] ^ dq[32]] | ||
262 | */ | ||
263 | |||
264 | asm volatile("vmovdqa %%ymm1, %0" : "=m" (dq[0])); | ||
265 | asm volatile("vmovdqa %%ymm14, %0" : "=m" (dq[32])); | ||
266 | asm volatile("vmovdqa %%ymm2, %0" : "=m" (p[0])); | ||
267 | asm volatile("vmovdqa %%ymm12,%0" : "=m" (p[32])); | ||
268 | |||
269 | bytes -= 64; | ||
270 | p += 64; | ||
271 | q += 64; | ||
272 | dq += 64; | ||
273 | #else | ||
274 | asm volatile("vmovdqa %0, %%ymm3" : : "m" (dq[0])); | ||
275 | asm volatile("vpxor %0, %%ymm3, %%ymm3" : : "m" (q[0])); | ||
276 | |||
277 | /* 3 = q ^ dq */ | ||
278 | |||
279 | asm volatile("vbroadcasti128 %0, %%ymm0" : : "m" (qmul[0])); | ||
280 | asm volatile("vbroadcasti128 %0, %%ymm1" : : "m" (qmul[16])); | ||
281 | |||
282 | asm volatile("vpsraw $4, %ymm3, %ymm6"); | ||
283 | asm volatile("vpand %ymm7, %ymm3, %ymm3"); | ||
284 | asm volatile("vpand %ymm7, %ymm6, %ymm6"); | ||
285 | asm volatile("vpshufb %ymm3, %ymm0, %ymm0"); | ||
286 | asm volatile("vpshufb %ymm6, %ymm1, %ymm1"); | ||
287 | asm volatile("vpxor %ymm0, %ymm1, %ymm1"); | ||
288 | |||
289 | /* 1 = qmul[q ^ dq] */ | ||
290 | |||
291 | asm volatile("vmovdqa %0, %%ymm2" : : "m" (p[0])); | ||
292 | asm volatile("vpxor %ymm1, %ymm2, %ymm2"); | ||
293 | |||
294 | /* 2 = p ^ qmul[q ^ dq] */ | ||
295 | |||
296 | asm volatile("vmovdqa %%ymm1, %0" : "=m" (dq[0])); | ||
297 | asm volatile("vmovdqa %%ymm2, %0" : "=m" (p[0])); | ||
298 | |||
299 | bytes -= 32; | ||
300 | p += 32; | ||
301 | q += 32; | ||
302 | dq += 32; | ||
303 | #endif | ||
304 | } | ||
305 | |||
306 | kernel_fpu_end(); | ||
307 | } | ||
308 | |||
309 | const struct raid6_recov_calls raid6_recov_avx2 = { | ||
310 | .data2 = raid6_2data_recov_avx2, | ||
311 | .datap = raid6_datap_recov_avx2, | ||
312 | .valid = raid6_has_avx2, | ||
313 | #ifdef CONFIG_X86_64 | ||
314 | .name = "avx2x2", | ||
315 | #else | ||
316 | .name = "avx2x1", | ||
317 | #endif | ||
318 | .priority = 2, | ||
319 | }; | ||
320 | |||
321 | #else | ||
322 | #warning "your version of binutils lacks AVX2 support" | ||
323 | #endif | ||
diff --git a/lib/raid6/recov_ssse3.c b/lib/raid6/recov_ssse3.c index ecb710c0b4d9..a9168328f03b 100644 --- a/lib/raid6/recov_ssse3.c +++ b/lib/raid6/recov_ssse3.c | |||
@@ -7,8 +7,6 @@ | |||
7 | * of the License. | 7 | * of the License. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__) | ||
11 | |||
12 | #include <linux/raid/pq.h> | 10 | #include <linux/raid/pq.h> |
13 | #include "x86.h" | 11 | #include "x86.h" |
14 | 12 | ||
@@ -332,5 +330,3 @@ const struct raid6_recov_calls raid6_recov_ssse3 = { | |||
332 | #endif | 330 | #endif |
333 | .priority = 1, | 331 | .priority = 1, |
334 | }; | 332 | }; |
335 | |||
336 | #endif | ||
diff --git a/lib/raid6/sse1.c b/lib/raid6/sse1.c index 10dd91948c07..f76297139445 100644 --- a/lib/raid6/sse1.c +++ b/lib/raid6/sse1.c | |||
@@ -21,7 +21,7 @@ | |||
21 | * worthwhile as a separate implementation. | 21 | * worthwhile as a separate implementation. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #if defined(__i386__) && !defined(__arch_um__) | 24 | #ifdef CONFIG_X86_32 |
25 | 25 | ||
26 | #include <linux/raid/pq.h> | 26 | #include <linux/raid/pq.h> |
27 | #include "x86.h" | 27 | #include "x86.h" |
diff --git a/lib/raid6/sse2.c b/lib/raid6/sse2.c index bc2d57daa589..85b82c85f28e 100644 --- a/lib/raid6/sse2.c +++ b/lib/raid6/sse2.c | |||
@@ -17,8 +17,6 @@ | |||
17 | * | 17 | * |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__) | ||
21 | |||
22 | #include <linux/raid/pq.h> | 20 | #include <linux/raid/pq.h> |
23 | #include "x86.h" | 21 | #include "x86.h" |
24 | 22 | ||
@@ -159,9 +157,7 @@ const struct raid6_calls raid6_sse2x2 = { | |||
159 | 1 /* Has cache hints */ | 157 | 1 /* Has cache hints */ |
160 | }; | 158 | }; |
161 | 159 | ||
162 | #endif | 160 | #ifdef CONFIG_X86_64 |
163 | |||
164 | #if defined(__x86_64__) && !defined(__arch_um__) | ||
165 | 161 | ||
166 | /* | 162 | /* |
167 | * Unrolled-by-4 SSE2 implementation | 163 | * Unrolled-by-4 SSE2 implementation |
@@ -259,4 +255,4 @@ const struct raid6_calls raid6_sse2x4 = { | |||
259 | 1 /* Has cache hints */ | 255 | 1 /* Has cache hints */ |
260 | }; | 256 | }; |
261 | 257 | ||
262 | #endif | 258 | #endif /* CONFIG_X86_64 */ |
diff --git a/lib/raid6/test/Makefile b/lib/raid6/test/Makefile index c76151d94764..087332dbf8aa 100644 --- a/lib/raid6/test/Makefile +++ b/lib/raid6/test/Makefile | |||
@@ -10,6 +10,31 @@ LD = ld | |||
10 | AWK = awk -f | 10 | AWK = awk -f |
11 | AR = ar | 11 | AR = ar |
12 | RANLIB = ranlib | 12 | RANLIB = ranlib |
13 | OBJS = int1.o int2.o int4.o int8.o int16.o int32.o recov.o algos.o tables.o | ||
14 | |||
15 | ARCH := $(shell uname -m 2>/dev/null | sed -e /s/i.86/i386/) | ||
16 | ifeq ($(ARCH),i386) | ||
17 | CFLAGS += -DCONFIG_X86_32 | ||
18 | IS_X86 = yes | ||
19 | endif | ||
20 | ifeq ($(ARCH),x86_64) | ||
21 | CFLAGS += -DCONFIG_X86_64 | ||
22 | IS_X86 = yes | ||
23 | endif | ||
24 | |||
25 | ifeq ($(IS_X86),yes) | ||
26 | OBJS += mmx.o sse1.o sse2.o avx2.o recov_ssse3.o recov_avx2.o | ||
27 | CFLAGS += $(shell echo "vpbroadcastb %xmm0, %ymm1" | \ | ||
28 | gcc -c -x assembler - >&/dev/null && \ | ||
29 | rm ./-.o && echo -DCONFIG_AS_AVX2=1) | ||
30 | else | ||
31 | HAS_ALTIVEC := $(shell echo -e '\#include <altivec.h>\nvector int a;' |\ | ||
32 | gcc -c -x c - >&/dev/null && \ | ||
33 | rm ./-.o && echo yes) | ||
34 | ifeq ($(HAS_ALTIVEC),yes) | ||
35 | OBJS += altivec1.o altivec2.o altivec4.o altivec8.o | ||
36 | endif | ||
37 | endif | ||
13 | 38 | ||
14 | .c.o: | 39 | .c.o: |
15 | $(CC) $(CFLAGS) -c -o $@ $< | 40 | $(CC) $(CFLAGS) -c -o $@ $< |
@@ -22,9 +47,7 @@ RANLIB = ranlib | |||
22 | 47 | ||
23 | all: raid6.a raid6test | 48 | all: raid6.a raid6test |
24 | 49 | ||
25 | raid6.a: int1.o int2.o int4.o int8.o int16.o int32.o mmx.o sse1.o sse2.o \ | 50 | raid6.a: $(OBJS) |
26 | altivec1.o altivec2.o altivec4.o altivec8.o recov.o recov_ssse3.o algos.o \ | ||
27 | tables.o | ||
28 | rm -f $@ | 51 | rm -f $@ |
29 | $(AR) cq $@ $^ | 52 | $(AR) cq $@ $^ |
30 | $(RANLIB) $@ | 53 | $(RANLIB) $@ |
diff --git a/lib/raid6/x86.h b/lib/raid6/x86.h index d55d63232c55..b7595484a815 100644 --- a/lib/raid6/x86.h +++ b/lib/raid6/x86.h | |||
@@ -45,19 +45,23 @@ static inline void kernel_fpu_end(void) | |||
45 | #define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ | 45 | #define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ |
46 | #define X86_FEATURE_SSSE3 (4*32+ 9) /* Supplemental SSE-3 */ | 46 | #define X86_FEATURE_SSSE3 (4*32+ 9) /* Supplemental SSE-3 */ |
47 | #define X86_FEATURE_AVX (4*32+28) /* Advanced Vector Extensions */ | 47 | #define X86_FEATURE_AVX (4*32+28) /* Advanced Vector Extensions */ |
48 | #define X86_FEATURE_AVX2 (9*32+ 5) /* AVX2 instructions */ | ||
48 | #define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ | 49 | #define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */ |
49 | 50 | ||
50 | /* Should work well enough on modern CPUs for testing */ | 51 | /* Should work well enough on modern CPUs for testing */ |
51 | static inline int boot_cpu_has(int flag) | 52 | static inline int boot_cpu_has(int flag) |
52 | { | 53 | { |
53 | u32 eax = (flag & 0x20) ? 0x80000001 : 1; | 54 | u32 eax, ebx, ecx, edx; |
54 | u32 ecx, edx; | 55 | |
56 | eax = (flag & 0x100) ? 7 : | ||
57 | (flag & 0x20) ? 0x80000001 : 1; | ||
58 | ecx = 0; | ||
55 | 59 | ||
56 | asm volatile("cpuid" | 60 | asm volatile("cpuid" |
57 | : "+a" (eax), "=d" (edx), "=c" (ecx) | 61 | : "+a" (eax), "=b" (ebx), "=d" (edx), "+c" (ecx)); |
58 | : : "ebx"); | ||
59 | 62 | ||
60 | return ((flag & 0x80 ? ecx : edx) >> (flag & 31)) & 1; | 63 | return ((flag & 0x100 ? ebx : |
64 | (flag & 0x80) ? ecx : edx) >> (flag & 31)) & 1; | ||
61 | } | 65 | } |
62 | 66 | ||
63 | #endif /* ndef __KERNEL__ */ | 67 | #endif /* ndef __KERNEL__ */ |
diff --git a/lib/random32.c b/lib/random32.c index 938bde5876ac..52280d5526be 100644 --- a/lib/random32.c +++ b/lib/random32.c | |||
@@ -42,13 +42,13 @@ | |||
42 | static DEFINE_PER_CPU(struct rnd_state, net_rand_state); | 42 | static DEFINE_PER_CPU(struct rnd_state, net_rand_state); |
43 | 43 | ||
44 | /** | 44 | /** |
45 | * prandom32 - seeded pseudo-random number generator. | 45 | * prandom_u32_state - seeded pseudo-random number generator. |
46 | * @state: pointer to state structure holding seeded state. | 46 | * @state: pointer to state structure holding seeded state. |
47 | * | 47 | * |
48 | * This is used for pseudo-randomness with no outside seeding. | 48 | * This is used for pseudo-randomness with no outside seeding. |
49 | * For more random results, use random32(). | 49 | * For more random results, use prandom_u32(). |
50 | */ | 50 | */ |
51 | u32 prandom32(struct rnd_state *state) | 51 | u32 prandom_u32_state(struct rnd_state *state) |
52 | { | 52 | { |
53 | #define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b) | 53 | #define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b) |
54 | 54 | ||
@@ -58,32 +58,81 @@ u32 prandom32(struct rnd_state *state) | |||
58 | 58 | ||
59 | return (state->s1 ^ state->s2 ^ state->s3); | 59 | return (state->s1 ^ state->s2 ^ state->s3); |
60 | } | 60 | } |
61 | EXPORT_SYMBOL(prandom32); | 61 | EXPORT_SYMBOL(prandom_u32_state); |
62 | 62 | ||
63 | /** | 63 | /** |
64 | * random32 - pseudo random number generator | 64 | * prandom_u32 - pseudo random number generator |
65 | * | 65 | * |
66 | * A 32 bit pseudo-random number is generated using a fast | 66 | * A 32 bit pseudo-random number is generated using a fast |
67 | * algorithm suitable for simulation. This algorithm is NOT | 67 | * algorithm suitable for simulation. This algorithm is NOT |
68 | * considered safe for cryptographic use. | 68 | * considered safe for cryptographic use. |
69 | */ | 69 | */ |
70 | u32 random32(void) | 70 | u32 prandom_u32(void) |
71 | { | 71 | { |
72 | unsigned long r; | 72 | unsigned long r; |
73 | struct rnd_state *state = &get_cpu_var(net_rand_state); | 73 | struct rnd_state *state = &get_cpu_var(net_rand_state); |
74 | r = prandom32(state); | 74 | r = prandom_u32_state(state); |
75 | put_cpu_var(state); | 75 | put_cpu_var(state); |
76 | return r; | 76 | return r; |
77 | } | 77 | } |
78 | EXPORT_SYMBOL(random32); | 78 | EXPORT_SYMBOL(prandom_u32); |
79 | |||
80 | /* | ||
81 | * prandom_bytes_state - get the requested number of pseudo-random bytes | ||
82 | * | ||
83 | * @state: pointer to state structure holding seeded state. | ||
84 | * @buf: where to copy the pseudo-random bytes to | ||
85 | * @bytes: the requested number of bytes | ||
86 | * | ||
87 | * This is used for pseudo-randomness with no outside seeding. | ||
88 | * For more random results, use prandom_bytes(). | ||
89 | */ | ||
90 | void prandom_bytes_state(struct rnd_state *state, void *buf, int bytes) | ||
91 | { | ||
92 | unsigned char *p = buf; | ||
93 | int i; | ||
94 | |||
95 | for (i = 0; i < round_down(bytes, sizeof(u32)); i += sizeof(u32)) { | ||
96 | u32 random = prandom_u32_state(state); | ||
97 | int j; | ||
98 | |||
99 | for (j = 0; j < sizeof(u32); j++) { | ||
100 | p[i + j] = random; | ||
101 | random >>= BITS_PER_BYTE; | ||
102 | } | ||
103 | } | ||
104 | if (i < bytes) { | ||
105 | u32 random = prandom_u32_state(state); | ||
106 | |||
107 | for (; i < bytes; i++) { | ||
108 | p[i] = random; | ||
109 | random >>= BITS_PER_BYTE; | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | EXPORT_SYMBOL(prandom_bytes_state); | ||
114 | |||
115 | /** | ||
116 | * prandom_bytes - get the requested number of pseudo-random bytes | ||
117 | * @buf: where to copy the pseudo-random bytes to | ||
118 | * @bytes: the requested number of bytes | ||
119 | */ | ||
120 | void prandom_bytes(void *buf, int bytes) | ||
121 | { | ||
122 | struct rnd_state *state = &get_cpu_var(net_rand_state); | ||
123 | |||
124 | prandom_bytes_state(state, buf, bytes); | ||
125 | put_cpu_var(state); | ||
126 | } | ||
127 | EXPORT_SYMBOL(prandom_bytes); | ||
79 | 128 | ||
80 | /** | 129 | /** |
81 | * srandom32 - add entropy to pseudo random number generator | 130 | * prandom_seed - add entropy to pseudo random number generator |
82 | * @seed: seed value | 131 | * @seed: seed value |
83 | * | 132 | * |
84 | * Add some additional seeding to the random32() pool. | 133 | * Add some additional seeding to the prandom pool. |
85 | */ | 134 | */ |
86 | void srandom32(u32 entropy) | 135 | void prandom_seed(u32 entropy) |
87 | { | 136 | { |
88 | int i; | 137 | int i; |
89 | /* | 138 | /* |
@@ -95,13 +144,13 @@ void srandom32(u32 entropy) | |||
95 | state->s1 = __seed(state->s1 ^ entropy, 1); | 144 | state->s1 = __seed(state->s1 ^ entropy, 1); |
96 | } | 145 | } |
97 | } | 146 | } |
98 | EXPORT_SYMBOL(srandom32); | 147 | EXPORT_SYMBOL(prandom_seed); |
99 | 148 | ||
100 | /* | 149 | /* |
101 | * Generate some initially weak seeding values to allow | 150 | * Generate some initially weak seeding values to allow |
102 | * to start the random32() engine. | 151 | * to start the prandom_u32() engine. |
103 | */ | 152 | */ |
104 | static int __init random32_init(void) | 153 | static int __init prandom_init(void) |
105 | { | 154 | { |
106 | int i; | 155 | int i; |
107 | 156 | ||
@@ -114,22 +163,22 @@ static int __init random32_init(void) | |||
114 | state->s3 = __seed(LCG(state->s2), 15); | 163 | state->s3 = __seed(LCG(state->s2), 15); |
115 | 164 | ||
116 | /* "warm it up" */ | 165 | /* "warm it up" */ |
117 | prandom32(state); | 166 | prandom_u32_state(state); |
118 | prandom32(state); | 167 | prandom_u32_state(state); |
119 | prandom32(state); | 168 | prandom_u32_state(state); |
120 | prandom32(state); | 169 | prandom_u32_state(state); |
121 | prandom32(state); | 170 | prandom_u32_state(state); |
122 | prandom32(state); | 171 | prandom_u32_state(state); |
123 | } | 172 | } |
124 | return 0; | 173 | return 0; |
125 | } | 174 | } |
126 | core_initcall(random32_init); | 175 | core_initcall(prandom_init); |
127 | 176 | ||
128 | /* | 177 | /* |
129 | * Generate better values after random number generator | 178 | * Generate better values after random number generator |
130 | * is fully initialized. | 179 | * is fully initialized. |
131 | */ | 180 | */ |
132 | static int __init random32_reseed(void) | 181 | static int __init prandom_reseed(void) |
133 | { | 182 | { |
134 | int i; | 183 | int i; |
135 | 184 | ||
@@ -143,8 +192,8 @@ static int __init random32_reseed(void) | |||
143 | state->s3 = __seed(seeds[2], 15); | 192 | state->s3 = __seed(seeds[2], 15); |
144 | 193 | ||
145 | /* mix it in */ | 194 | /* mix it in */ |
146 | prandom32(state); | 195 | prandom_u32_state(state); |
147 | } | 196 | } |
148 | return 0; | 197 | return 0; |
149 | } | 198 | } |
150 | late_initcall(random32_reseed); | 199 | late_initcall(prandom_reseed); |
diff --git a/lib/rbtree.c b/lib/rbtree.c index 4f56a11d67fa..c0e31fe2fabf 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c | |||
@@ -194,8 +194,12 @@ __rb_insert(struct rb_node *node, struct rb_root *root, | |||
194 | } | 194 | } |
195 | } | 195 | } |
196 | 196 | ||
197 | __always_inline void | 197 | /* |
198 | __rb_erase_color(struct rb_node *parent, struct rb_root *root, | 198 | * Inline version for rb_erase() use - we want to be able to inline |
199 | * and eliminate the dummy_rotate callback there | ||
200 | */ | ||
201 | static __always_inline void | ||
202 | ____rb_erase_color(struct rb_node *parent, struct rb_root *root, | ||
199 | void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) | 203 | void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) |
200 | { | 204 | { |
201 | struct rb_node *node = NULL, *sibling, *tmp1, *tmp2; | 205 | struct rb_node *node = NULL, *sibling, *tmp1, *tmp2; |
@@ -355,6 +359,13 @@ __rb_erase_color(struct rb_node *parent, struct rb_root *root, | |||
355 | } | 359 | } |
356 | } | 360 | } |
357 | } | 361 | } |
362 | |||
363 | /* Non-inline version for rb_erase_augmented() use */ | ||
364 | void __rb_erase_color(struct rb_node *parent, struct rb_root *root, | ||
365 | void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) | ||
366 | { | ||
367 | ____rb_erase_color(parent, root, augment_rotate); | ||
368 | } | ||
358 | EXPORT_SYMBOL(__rb_erase_color); | 369 | EXPORT_SYMBOL(__rb_erase_color); |
359 | 370 | ||
360 | /* | 371 | /* |
@@ -380,7 +391,10 @@ EXPORT_SYMBOL(rb_insert_color); | |||
380 | 391 | ||
381 | void rb_erase(struct rb_node *node, struct rb_root *root) | 392 | void rb_erase(struct rb_node *node, struct rb_root *root) |
382 | { | 393 | { |
383 | rb_erase_augmented(node, root, &dummy_callbacks); | 394 | struct rb_node *rebalance; |
395 | rebalance = __rb_erase_augmented(node, root, &dummy_callbacks); | ||
396 | if (rebalance) | ||
397 | ____rb_erase_color(rebalance, root, dummy_rotate); | ||
384 | } | 398 | } |
385 | EXPORT_SYMBOL(rb_erase); | 399 | EXPORT_SYMBOL(rb_erase); |
386 | 400 | ||
diff --git a/lib/rbtree_test.c b/lib/rbtree_test.c index 268b23951fec..af38aedbd874 100644 --- a/lib/rbtree_test.c +++ b/lib/rbtree_test.c | |||
@@ -96,8 +96,8 @@ static void init(void) | |||
96 | { | 96 | { |
97 | int i; | 97 | int i; |
98 | for (i = 0; i < NODES; i++) { | 98 | for (i = 0; i < NODES; i++) { |
99 | nodes[i].key = prandom32(&rnd); | 99 | nodes[i].key = prandom_u32_state(&rnd); |
100 | nodes[i].val = prandom32(&rnd); | 100 | nodes[i].val = prandom_u32_state(&rnd); |
101 | } | 101 | } |
102 | } | 102 | } |
103 | 103 | ||
@@ -118,7 +118,7 @@ static void check(int nr_nodes) | |||
118 | { | 118 | { |
119 | struct rb_node *rb; | 119 | struct rb_node *rb; |
120 | int count = 0; | 120 | int count = 0; |
121 | int blacks; | 121 | int blacks = 0; |
122 | u32 prev_key = 0; | 122 | u32 prev_key = 0; |
123 | 123 | ||
124 | for (rb = rb_first(&root); rb; rb = rb_next(rb)) { | 124 | for (rb = rb_first(&root); rb; rb = rb_next(rb)) { |
@@ -155,7 +155,7 @@ static int rbtree_test_init(void) | |||
155 | 155 | ||
156 | printk(KERN_ALERT "rbtree testing"); | 156 | printk(KERN_ALERT "rbtree testing"); |
157 | 157 | ||
158 | prandom32_seed(&rnd, 3141592653589793238ULL); | 158 | prandom_seed_state(&rnd, 3141592653589793238ULL); |
159 | init(); | 159 | init(); |
160 | 160 | ||
161 | time1 = get_cycles(); | 161 | time1 = get_cycles(); |
diff --git a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c index 7e0d6a58fc83..7542afbb22b3 100644 --- a/lib/rwsem-spinlock.c +++ b/lib/rwsem-spinlock.c | |||
@@ -73,20 +73,13 @@ __rwsem_do_wake(struct rw_semaphore *sem, int wakewrite) | |||
73 | goto dont_wake_writers; | 73 | goto dont_wake_writers; |
74 | } | 74 | } |
75 | 75 | ||
76 | /* if we are allowed to wake writers try to grant a single write lock | 76 | /* |
77 | * if there's a writer at the front of the queue | 77 | * as we support write lock stealing, we can't set sem->activity |
78 | * - we leave the 'waiting count' incremented to signify potential | 78 | * to -1 here to indicate we get the lock. Instead, we wake it up |
79 | * contention | 79 | * to let it go get it again. |
80 | */ | 80 | */ |
81 | if (waiter->flags & RWSEM_WAITING_FOR_WRITE) { | 81 | if (waiter->flags & RWSEM_WAITING_FOR_WRITE) { |
82 | sem->activity = -1; | 82 | wake_up_process(waiter->task); |
83 | list_del(&waiter->list); | ||
84 | tsk = waiter->task; | ||
85 | /* Don't touch waiter after ->task has been NULLed */ | ||
86 | smp_mb(); | ||
87 | waiter->task = NULL; | ||
88 | wake_up_process(tsk); | ||
89 | put_task_struct(tsk); | ||
90 | goto out; | 83 | goto out; |
91 | } | 84 | } |
92 | 85 | ||
@@ -121,18 +114,10 @@ static inline struct rw_semaphore * | |||
121 | __rwsem_wake_one_writer(struct rw_semaphore *sem) | 114 | __rwsem_wake_one_writer(struct rw_semaphore *sem) |
122 | { | 115 | { |
123 | struct rwsem_waiter *waiter; | 116 | struct rwsem_waiter *waiter; |
124 | struct task_struct *tsk; | ||
125 | |||
126 | sem->activity = -1; | ||
127 | 117 | ||
128 | waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list); | 118 | waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list); |
129 | list_del(&waiter->list); | 119 | wake_up_process(waiter->task); |
130 | 120 | ||
131 | tsk = waiter->task; | ||
132 | smp_mb(); | ||
133 | waiter->task = NULL; | ||
134 | wake_up_process(tsk); | ||
135 | put_task_struct(tsk); | ||
136 | return sem; | 121 | return sem; |
137 | } | 122 | } |
138 | 123 | ||
@@ -204,7 +189,6 @@ int __down_read_trylock(struct rw_semaphore *sem) | |||
204 | 189 | ||
205 | /* | 190 | /* |
206 | * get a write lock on the semaphore | 191 | * get a write lock on the semaphore |
207 | * - we increment the waiting count anyway to indicate an exclusive lock | ||
208 | */ | 192 | */ |
209 | void __sched __down_write_nested(struct rw_semaphore *sem, int subclass) | 193 | void __sched __down_write_nested(struct rw_semaphore *sem, int subclass) |
210 | { | 194 | { |
@@ -214,37 +198,32 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass) | |||
214 | 198 | ||
215 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | 199 | raw_spin_lock_irqsave(&sem->wait_lock, flags); |
216 | 200 | ||
217 | if (sem->activity == 0 && list_empty(&sem->wait_list)) { | ||
218 | /* granted */ | ||
219 | sem->activity = -1; | ||
220 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
221 | goto out; | ||
222 | } | ||
223 | |||
224 | tsk = current; | ||
225 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||
226 | |||
227 | /* set up my own style of waitqueue */ | 201 | /* set up my own style of waitqueue */ |
202 | tsk = current; | ||
228 | waiter.task = tsk; | 203 | waiter.task = tsk; |
229 | waiter.flags = RWSEM_WAITING_FOR_WRITE; | 204 | waiter.flags = RWSEM_WAITING_FOR_WRITE; |
230 | get_task_struct(tsk); | ||
231 | |||
232 | list_add_tail(&waiter.list, &sem->wait_list); | 205 | list_add_tail(&waiter.list, &sem->wait_list); |
233 | 206 | ||
234 | /* we don't need to touch the semaphore struct anymore */ | 207 | /* wait for someone to release the lock */ |
235 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
236 | |||
237 | /* wait to be given the lock */ | ||
238 | for (;;) { | 208 | for (;;) { |
239 | if (!waiter.task) | 209 | /* |
210 | * That is the key to support write lock stealing: allows the | ||
211 | * task already on CPU to get the lock soon rather than put | ||
212 | * itself into sleep and waiting for system woke it or someone | ||
213 | * else in the head of the wait list up. | ||
214 | */ | ||
215 | if (sem->activity == 0) | ||
240 | break; | 216 | break; |
241 | schedule(); | ||
242 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 217 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); |
218 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); | ||
219 | schedule(); | ||
220 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | ||
243 | } | 221 | } |
222 | /* got the lock */ | ||
223 | sem->activity = -1; | ||
224 | list_del(&waiter.list); | ||
244 | 225 | ||
245 | tsk->state = TASK_RUNNING; | 226 | raw_spin_unlock_irqrestore(&sem->wait_lock, flags); |
246 | out: | ||
247 | ; | ||
248 | } | 227 | } |
249 | 228 | ||
250 | void __sched __down_write(struct rw_semaphore *sem) | 229 | void __sched __down_write(struct rw_semaphore *sem) |
@@ -262,8 +241,8 @@ int __down_write_trylock(struct rw_semaphore *sem) | |||
262 | 241 | ||
263 | raw_spin_lock_irqsave(&sem->wait_lock, flags); | 242 | raw_spin_lock_irqsave(&sem->wait_lock, flags); |
264 | 243 | ||
265 | if (sem->activity == 0 && list_empty(&sem->wait_list)) { | 244 | if (sem->activity == 0) { |
266 | /* granted */ | 245 | /* got the lock */ |
267 | sem->activity = -1; | 246 | sem->activity = -1; |
268 | ret = 1; | 247 | ret = 1; |
269 | } | 248 | } |
diff --git a/lib/rwsem.c b/lib/rwsem.c index 8337e1b9bb8d..ad5e0df16ab4 100644 --- a/lib/rwsem.c +++ b/lib/rwsem.c | |||
@@ -2,6 +2,8 @@ | |||
2 | * | 2 | * |
3 | * Written by David Howells (dhowells@redhat.com). | 3 | * Written by David Howells (dhowells@redhat.com). |
4 | * Derived from arch/i386/kernel/semaphore.c | 4 | * Derived from arch/i386/kernel/semaphore.c |
5 | * | ||
6 | * Writer lock-stealing by Alex Shi <alex.shi@intel.com> | ||
5 | */ | 7 | */ |
6 | #include <linux/rwsem.h> | 8 | #include <linux/rwsem.h> |
7 | #include <linux/sched.h> | 9 | #include <linux/sched.h> |
@@ -60,7 +62,7 @@ __rwsem_do_wake(struct rw_semaphore *sem, int wake_type) | |||
60 | struct rwsem_waiter *waiter; | 62 | struct rwsem_waiter *waiter; |
61 | struct task_struct *tsk; | 63 | struct task_struct *tsk; |
62 | struct list_head *next; | 64 | struct list_head *next; |
63 | signed long oldcount, woken, loop, adjustment; | 65 | signed long woken, loop, adjustment; |
64 | 66 | ||
65 | waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list); | 67 | waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list); |
66 | if (!(waiter->flags & RWSEM_WAITING_FOR_WRITE)) | 68 | if (!(waiter->flags & RWSEM_WAITING_FOR_WRITE)) |
@@ -72,30 +74,8 @@ __rwsem_do_wake(struct rw_semaphore *sem, int wake_type) | |||
72 | */ | 74 | */ |
73 | goto out; | 75 | goto out; |
74 | 76 | ||
75 | /* There's a writer at the front of the queue - try to grant it the | 77 | /* Wake up the writing waiter and let the task grab the sem: */ |
76 | * write lock. However, we only wake this writer if we can transition | 78 | wake_up_process(waiter->task); |
77 | * the active part of the count from 0 -> 1 | ||
78 | */ | ||
79 | adjustment = RWSEM_ACTIVE_WRITE_BIAS; | ||
80 | if (waiter->list.next == &sem->wait_list) | ||
81 | adjustment -= RWSEM_WAITING_BIAS; | ||
82 | |||
83 | try_again_write: | ||
84 | oldcount = rwsem_atomic_update(adjustment, sem) - adjustment; | ||
85 | if (oldcount & RWSEM_ACTIVE_MASK) | ||
86 | /* Someone grabbed the sem already */ | ||
87 | goto undo_write; | ||
88 | |||
89 | /* We must be careful not to touch 'waiter' after we set ->task = NULL. | ||
90 | * It is an allocated on the waiter's stack and may become invalid at | ||
91 | * any time after that point (due to a wakeup from another source). | ||
92 | */ | ||
93 | list_del(&waiter->list); | ||
94 | tsk = waiter->task; | ||
95 | smp_mb(); | ||
96 | waiter->task = NULL; | ||
97 | wake_up_process(tsk); | ||
98 | put_task_struct(tsk); | ||
99 | goto out; | 79 | goto out; |
100 | 80 | ||
101 | readers_only: | 81 | readers_only: |
@@ -157,12 +137,40 @@ __rwsem_do_wake(struct rw_semaphore *sem, int wake_type) | |||
157 | 137 | ||
158 | out: | 138 | out: |
159 | return sem; | 139 | return sem; |
140 | } | ||
141 | |||
142 | /* Try to get write sem, caller holds sem->wait_lock: */ | ||
143 | static int try_get_writer_sem(struct rw_semaphore *sem, | ||
144 | struct rwsem_waiter *waiter) | ||
145 | { | ||
146 | struct rwsem_waiter *fwaiter; | ||
147 | long oldcount, adjustment; | ||
160 | 148 | ||
161 | /* undo the change to the active count, but check for a transition | 149 | /* only steal when first waiter is writing */ |
162 | * 1->0 */ | 150 | fwaiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list); |
163 | undo_write: | 151 | if (!(fwaiter->flags & RWSEM_WAITING_FOR_WRITE)) |
152 | return 0; | ||
153 | |||
154 | adjustment = RWSEM_ACTIVE_WRITE_BIAS; | ||
155 | /* Only one waiter in the queue: */ | ||
156 | if (fwaiter == waiter && waiter->list.next == &sem->wait_list) | ||
157 | adjustment -= RWSEM_WAITING_BIAS; | ||
158 | |||
159 | try_again_write: | ||
160 | oldcount = rwsem_atomic_update(adjustment, sem) - adjustment; | ||
161 | if (!(oldcount & RWSEM_ACTIVE_MASK)) { | ||
162 | /* No active lock: */ | ||
163 | struct task_struct *tsk = waiter->task; | ||
164 | |||
165 | list_del(&waiter->list); | ||
166 | smp_mb(); | ||
167 | put_task_struct(tsk); | ||
168 | tsk->state = TASK_RUNNING; | ||
169 | return 1; | ||
170 | } | ||
171 | /* some one grabbed the sem already */ | ||
164 | if (rwsem_atomic_update(-adjustment, sem) & RWSEM_ACTIVE_MASK) | 172 | if (rwsem_atomic_update(-adjustment, sem) & RWSEM_ACTIVE_MASK) |
165 | goto out; | 173 | return 0; |
166 | goto try_again_write; | 174 | goto try_again_write; |
167 | } | 175 | } |
168 | 176 | ||
@@ -210,6 +218,15 @@ rwsem_down_failed_common(struct rw_semaphore *sem, | |||
210 | for (;;) { | 218 | for (;;) { |
211 | if (!waiter.task) | 219 | if (!waiter.task) |
212 | break; | 220 | break; |
221 | |||
222 | raw_spin_lock_irq(&sem->wait_lock); | ||
223 | /* Try to get the writer sem, may steal from the head writer: */ | ||
224 | if (flags == RWSEM_WAITING_FOR_WRITE) | ||
225 | if (try_get_writer_sem(sem, &waiter)) { | ||
226 | raw_spin_unlock_irq(&sem->wait_lock); | ||
227 | return sem; | ||
228 | } | ||
229 | raw_spin_unlock_irq(&sem->wait_lock); | ||
213 | schedule(); | 230 | schedule(); |
214 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 231 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); |
215 | } | 232 | } |
diff --git a/lib/scatterlist.c b/lib/scatterlist.c index 3675452b23ca..b83c144d731f 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c | |||
@@ -248,7 +248,8 @@ int __sg_alloc_table(struct sg_table *table, unsigned int nents, | |||
248 | unsigned int left; | 248 | unsigned int left; |
249 | 249 | ||
250 | #ifndef ARCH_HAS_SG_CHAIN | 250 | #ifndef ARCH_HAS_SG_CHAIN |
251 | BUG_ON(nents > max_ents); | 251 | if (WARN_ON_ONCE(nents > max_ents)) |
252 | return -EINVAL; | ||
252 | #endif | 253 | #endif |
253 | 254 | ||
254 | memset(table, 0, sizeof(*table)); | 255 | memset(table, 0, sizeof(*table)); |
@@ -393,6 +394,44 @@ int sg_alloc_table_from_pages(struct sg_table *sgt, | |||
393 | } | 394 | } |
394 | EXPORT_SYMBOL(sg_alloc_table_from_pages); | 395 | EXPORT_SYMBOL(sg_alloc_table_from_pages); |
395 | 396 | ||
397 | void __sg_page_iter_start(struct sg_page_iter *piter, | ||
398 | struct scatterlist *sglist, unsigned int nents, | ||
399 | unsigned long pgoffset) | ||
400 | { | ||
401 | piter->__pg_advance = 0; | ||
402 | piter->__nents = nents; | ||
403 | |||
404 | piter->page = NULL; | ||
405 | piter->sg = sglist; | ||
406 | piter->sg_pgoffset = pgoffset; | ||
407 | } | ||
408 | EXPORT_SYMBOL(__sg_page_iter_start); | ||
409 | |||
410 | static int sg_page_count(struct scatterlist *sg) | ||
411 | { | ||
412 | return PAGE_ALIGN(sg->offset + sg->length) >> PAGE_SHIFT; | ||
413 | } | ||
414 | |||
415 | bool __sg_page_iter_next(struct sg_page_iter *piter) | ||
416 | { | ||
417 | if (!piter->__nents || !piter->sg) | ||
418 | return false; | ||
419 | |||
420 | piter->sg_pgoffset += piter->__pg_advance; | ||
421 | piter->__pg_advance = 1; | ||
422 | |||
423 | while (piter->sg_pgoffset >= sg_page_count(piter->sg)) { | ||
424 | piter->sg_pgoffset -= sg_page_count(piter->sg); | ||
425 | piter->sg = sg_next(piter->sg); | ||
426 | if (!--piter->__nents || !piter->sg) | ||
427 | return false; | ||
428 | } | ||
429 | piter->page = nth_page(sg_page(piter->sg), piter->sg_pgoffset); | ||
430 | |||
431 | return true; | ||
432 | } | ||
433 | EXPORT_SYMBOL(__sg_page_iter_next); | ||
434 | |||
396 | /** | 435 | /** |
397 | * sg_miter_start - start mapping iteration over a sg list | 436 | * sg_miter_start - start mapping iteration over a sg list |
398 | * @miter: sg mapping iter to be started | 437 | * @miter: sg mapping iter to be started |
@@ -410,9 +449,7 @@ void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl, | |||
410 | { | 449 | { |
411 | memset(miter, 0, sizeof(struct sg_mapping_iter)); | 450 | memset(miter, 0, sizeof(struct sg_mapping_iter)); |
412 | 451 | ||
413 | miter->__sg = sgl; | 452 | __sg_page_iter_start(&miter->piter, sgl, nents, 0); |
414 | miter->__nents = nents; | ||
415 | miter->__offset = 0; | ||
416 | WARN_ON(!(flags & (SG_MITER_TO_SG | SG_MITER_FROM_SG))); | 453 | WARN_ON(!(flags & (SG_MITER_TO_SG | SG_MITER_FROM_SG))); |
417 | miter->__flags = flags; | 454 | miter->__flags = flags; |
418 | } | 455 | } |
@@ -437,36 +474,35 @@ EXPORT_SYMBOL(sg_miter_start); | |||
437 | */ | 474 | */ |
438 | bool sg_miter_next(struct sg_mapping_iter *miter) | 475 | bool sg_miter_next(struct sg_mapping_iter *miter) |
439 | { | 476 | { |
440 | unsigned int off, len; | ||
441 | |||
442 | /* check for end and drop resources from the last iteration */ | ||
443 | if (!miter->__nents) | ||
444 | return false; | ||
445 | |||
446 | sg_miter_stop(miter); | 477 | sg_miter_stop(miter); |
447 | 478 | ||
448 | /* get to the next sg if necessary. __offset is adjusted by stop */ | 479 | /* |
449 | while (miter->__offset == miter->__sg->length) { | 480 | * Get to the next page if necessary. |
450 | if (--miter->__nents) { | 481 | * __remaining, __offset is adjusted by sg_miter_stop |
451 | miter->__sg = sg_next(miter->__sg); | 482 | */ |
452 | miter->__offset = 0; | 483 | if (!miter->__remaining) { |
453 | } else | 484 | struct scatterlist *sg; |
485 | unsigned long pgoffset; | ||
486 | |||
487 | if (!__sg_page_iter_next(&miter->piter)) | ||
454 | return false; | 488 | return false; |
455 | } | ||
456 | 489 | ||
457 | /* map the next page */ | 490 | sg = miter->piter.sg; |
458 | off = miter->__sg->offset + miter->__offset; | 491 | pgoffset = miter->piter.sg_pgoffset; |
459 | len = miter->__sg->length - miter->__offset; | ||
460 | 492 | ||
461 | miter->page = nth_page(sg_page(miter->__sg), off >> PAGE_SHIFT); | 493 | miter->__offset = pgoffset ? 0 : sg->offset; |
462 | off &= ~PAGE_MASK; | 494 | miter->__remaining = sg->offset + sg->length - |
463 | miter->length = min_t(unsigned int, len, PAGE_SIZE - off); | 495 | (pgoffset << PAGE_SHIFT) - miter->__offset; |
464 | miter->consumed = miter->length; | 496 | miter->__remaining = min_t(unsigned long, miter->__remaining, |
497 | PAGE_SIZE - miter->__offset); | ||
498 | } | ||
499 | miter->page = miter->piter.page; | ||
500 | miter->consumed = miter->length = miter->__remaining; | ||
465 | 501 | ||
466 | if (miter->__flags & SG_MITER_ATOMIC) | 502 | if (miter->__flags & SG_MITER_ATOMIC) |
467 | miter->addr = kmap_atomic(miter->page) + off; | 503 | miter->addr = kmap_atomic(miter->page) + miter->__offset; |
468 | else | 504 | else |
469 | miter->addr = kmap(miter->page) + off; | 505 | miter->addr = kmap(miter->page) + miter->__offset; |
470 | 506 | ||
471 | return true; | 507 | return true; |
472 | } | 508 | } |
@@ -493,6 +529,7 @@ void sg_miter_stop(struct sg_mapping_iter *miter) | |||
493 | /* drop resources from the last iteration */ | 529 | /* drop resources from the last iteration */ |
494 | if (miter->addr) { | 530 | if (miter->addr) { |
495 | miter->__offset += miter->consumed; | 531 | miter->__offset += miter->consumed; |
532 | miter->__remaining -= miter->consumed; | ||
496 | 533 | ||
497 | if (miter->__flags & SG_MITER_TO_SG) | 534 | if (miter->__flags & SG_MITER_TO_SG) |
498 | flush_kernel_dcache_page(miter->page); | 535 | flush_kernel_dcache_page(miter->page); |
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index f114bf6a8e13..bfe02b8fc55b 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
@@ -57,7 +57,7 @@ int swiotlb_force; | |||
57 | * swiotlb_tbl_sync_single_*, to see if the memory was in fact allocated by this | 57 | * swiotlb_tbl_sync_single_*, to see if the memory was in fact allocated by this |
58 | * API. | 58 | * API. |
59 | */ | 59 | */ |
60 | static char *io_tlb_start, *io_tlb_end; | 60 | static phys_addr_t io_tlb_start, io_tlb_end; |
61 | 61 | ||
62 | /* | 62 | /* |
63 | * The number of IO TLB blocks (in groups of 64) between io_tlb_start and | 63 | * The number of IO TLB blocks (in groups of 64) between io_tlb_start and |
@@ -70,7 +70,7 @@ static unsigned long io_tlb_nslabs; | |||
70 | */ | 70 | */ |
71 | static unsigned long io_tlb_overflow = 32*1024; | 71 | static unsigned long io_tlb_overflow = 32*1024; |
72 | 72 | ||
73 | static void *io_tlb_overflow_buffer; | 73 | static phys_addr_t io_tlb_overflow_buffer; |
74 | 74 | ||
75 | /* | 75 | /* |
76 | * This is a free list describing the number of free entries available from | 76 | * This is a free list describing the number of free entries available from |
@@ -122,30 +122,49 @@ static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, | |||
122 | return phys_to_dma(hwdev, virt_to_phys(address)); | 122 | return phys_to_dma(hwdev, virt_to_phys(address)); |
123 | } | 123 | } |
124 | 124 | ||
125 | static bool no_iotlb_memory; | ||
126 | |||
125 | void swiotlb_print_info(void) | 127 | void swiotlb_print_info(void) |
126 | { | 128 | { |
127 | unsigned long bytes = io_tlb_nslabs << IO_TLB_SHIFT; | 129 | unsigned long bytes = io_tlb_nslabs << IO_TLB_SHIFT; |
128 | phys_addr_t pstart, pend; | 130 | unsigned char *vstart, *vend; |
131 | |||
132 | if (no_iotlb_memory) { | ||
133 | pr_warn("software IO TLB: No low mem\n"); | ||
134 | return; | ||
135 | } | ||
129 | 136 | ||
130 | pstart = virt_to_phys(io_tlb_start); | 137 | vstart = phys_to_virt(io_tlb_start); |
131 | pend = virt_to_phys(io_tlb_end); | 138 | vend = phys_to_virt(io_tlb_end); |
132 | 139 | ||
133 | printk(KERN_INFO "software IO TLB [mem %#010llx-%#010llx] (%luMB) mapped at [%p-%p]\n", | 140 | printk(KERN_INFO "software IO TLB [mem %#010llx-%#010llx] (%luMB) mapped at [%p-%p]\n", |
134 | (unsigned long long)pstart, (unsigned long long)pend - 1, | 141 | (unsigned long long)io_tlb_start, |
135 | bytes >> 20, io_tlb_start, io_tlb_end - 1); | 142 | (unsigned long long)io_tlb_end, |
143 | bytes >> 20, vstart, vend - 1); | ||
136 | } | 144 | } |
137 | 145 | ||
138 | void __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) | 146 | int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) |
139 | { | 147 | { |
148 | void *v_overflow_buffer; | ||
140 | unsigned long i, bytes; | 149 | unsigned long i, bytes; |
141 | 150 | ||
142 | bytes = nslabs << IO_TLB_SHIFT; | 151 | bytes = nslabs << IO_TLB_SHIFT; |
143 | 152 | ||
144 | io_tlb_nslabs = nslabs; | 153 | io_tlb_nslabs = nslabs; |
145 | io_tlb_start = tlb; | 154 | io_tlb_start = __pa(tlb); |
146 | io_tlb_end = io_tlb_start + bytes; | 155 | io_tlb_end = io_tlb_start + bytes; |
147 | 156 | ||
148 | /* | 157 | /* |
158 | * Get the overflow emergency buffer | ||
159 | */ | ||
160 | v_overflow_buffer = alloc_bootmem_low_pages_nopanic( | ||
161 | PAGE_ALIGN(io_tlb_overflow)); | ||
162 | if (!v_overflow_buffer) | ||
163 | return -ENOMEM; | ||
164 | |||
165 | io_tlb_overflow_buffer = __pa(v_overflow_buffer); | ||
166 | |||
167 | /* | ||
149 | * Allocate and initialize the free list array. This array is used | 168 | * Allocate and initialize the free list array. This array is used |
150 | * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE | 169 | * to find contiguous free memory regions of size up to IO_TLB_SEGSIZE |
151 | * between io_tlb_start and io_tlb_end. | 170 | * between io_tlb_start and io_tlb_end. |
@@ -156,23 +175,22 @@ void __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) | |||
156 | io_tlb_index = 0; | 175 | io_tlb_index = 0; |
157 | io_tlb_orig_addr = alloc_bootmem_pages(PAGE_ALIGN(io_tlb_nslabs * sizeof(phys_addr_t))); | 176 | io_tlb_orig_addr = alloc_bootmem_pages(PAGE_ALIGN(io_tlb_nslabs * sizeof(phys_addr_t))); |
158 | 177 | ||
159 | /* | ||
160 | * Get the overflow emergency buffer | ||
161 | */ | ||
162 | io_tlb_overflow_buffer = alloc_bootmem_low_pages(PAGE_ALIGN(io_tlb_overflow)); | ||
163 | if (!io_tlb_overflow_buffer) | ||
164 | panic("Cannot allocate SWIOTLB overflow buffer!\n"); | ||
165 | if (verbose) | 178 | if (verbose) |
166 | swiotlb_print_info(); | 179 | swiotlb_print_info(); |
180 | |||
181 | return 0; | ||
167 | } | 182 | } |
168 | 183 | ||
169 | /* | 184 | /* |
170 | * Statically reserve bounce buffer space and initialize bounce buffer data | 185 | * Statically reserve bounce buffer space and initialize bounce buffer data |
171 | * structures for the software IO TLB used to implement the DMA API. | 186 | * structures for the software IO TLB used to implement the DMA API. |
172 | */ | 187 | */ |
173 | static void __init | 188 | void __init |
174 | swiotlb_init_with_default_size(size_t default_size, int verbose) | 189 | swiotlb_init(int verbose) |
175 | { | 190 | { |
191 | /* default to 64MB */ | ||
192 | size_t default_size = 64UL<<20; | ||
193 | unsigned char *vstart; | ||
176 | unsigned long bytes; | 194 | unsigned long bytes; |
177 | 195 | ||
178 | if (!io_tlb_nslabs) { | 196 | if (!io_tlb_nslabs) { |
@@ -182,20 +200,16 @@ swiotlb_init_with_default_size(size_t default_size, int verbose) | |||
182 | 200 | ||
183 | bytes = io_tlb_nslabs << IO_TLB_SHIFT; | 201 | bytes = io_tlb_nslabs << IO_TLB_SHIFT; |
184 | 202 | ||
185 | /* | 203 | /* Get IO TLB memory from the low pages */ |
186 | * Get IO TLB memory from the low pages | 204 | vstart = alloc_bootmem_low_pages_nopanic(PAGE_ALIGN(bytes)); |
187 | */ | 205 | if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, verbose)) |
188 | io_tlb_start = alloc_bootmem_low_pages(PAGE_ALIGN(bytes)); | 206 | return; |
189 | if (!io_tlb_start) | ||
190 | panic("Cannot allocate SWIOTLB buffer"); | ||
191 | |||
192 | swiotlb_init_with_tbl(io_tlb_start, io_tlb_nslabs, verbose); | ||
193 | } | ||
194 | 207 | ||
195 | void __init | 208 | if (io_tlb_start) |
196 | swiotlb_init(int verbose) | 209 | free_bootmem(io_tlb_start, |
197 | { | 210 | PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); |
198 | swiotlb_init_with_default_size(64 * (1<<20), verbose); /* default to 64MB */ | 211 | pr_warn("Cannot allocate SWIOTLB buffer"); |
212 | no_iotlb_memory = true; | ||
199 | } | 213 | } |
200 | 214 | ||
201 | /* | 215 | /* |
@@ -207,6 +221,7 @@ int | |||
207 | swiotlb_late_init_with_default_size(size_t default_size) | 221 | swiotlb_late_init_with_default_size(size_t default_size) |
208 | { | 222 | { |
209 | unsigned long bytes, req_nslabs = io_tlb_nslabs; | 223 | unsigned long bytes, req_nslabs = io_tlb_nslabs; |
224 | unsigned char *vstart = NULL; | ||
210 | unsigned int order; | 225 | unsigned int order; |
211 | int rc = 0; | 226 | int rc = 0; |
212 | 227 | ||
@@ -223,14 +238,14 @@ swiotlb_late_init_with_default_size(size_t default_size) | |||
223 | bytes = io_tlb_nslabs << IO_TLB_SHIFT; | 238 | bytes = io_tlb_nslabs << IO_TLB_SHIFT; |
224 | 239 | ||
225 | while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) { | 240 | while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) { |
226 | io_tlb_start = (void *)__get_free_pages(GFP_DMA | __GFP_NOWARN, | 241 | vstart = (void *)__get_free_pages(GFP_DMA | __GFP_NOWARN, |
227 | order); | 242 | order); |
228 | if (io_tlb_start) | 243 | if (vstart) |
229 | break; | 244 | break; |
230 | order--; | 245 | order--; |
231 | } | 246 | } |
232 | 247 | ||
233 | if (!io_tlb_start) { | 248 | if (!vstart) { |
234 | io_tlb_nslabs = req_nslabs; | 249 | io_tlb_nslabs = req_nslabs; |
235 | return -ENOMEM; | 250 | return -ENOMEM; |
236 | } | 251 | } |
@@ -239,9 +254,9 @@ swiotlb_late_init_with_default_size(size_t default_size) | |||
239 | "for software IO TLB\n", (PAGE_SIZE << order) >> 20); | 254 | "for software IO TLB\n", (PAGE_SIZE << order) >> 20); |
240 | io_tlb_nslabs = SLABS_PER_PAGE << order; | 255 | io_tlb_nslabs = SLABS_PER_PAGE << order; |
241 | } | 256 | } |
242 | rc = swiotlb_late_init_with_tbl(io_tlb_start, io_tlb_nslabs); | 257 | rc = swiotlb_late_init_with_tbl(vstart, io_tlb_nslabs); |
243 | if (rc) | 258 | if (rc) |
244 | free_pages((unsigned long)io_tlb_start, order); | 259 | free_pages((unsigned long)vstart, order); |
245 | return rc; | 260 | return rc; |
246 | } | 261 | } |
247 | 262 | ||
@@ -249,14 +264,25 @@ int | |||
249 | swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) | 264 | swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) |
250 | { | 265 | { |
251 | unsigned long i, bytes; | 266 | unsigned long i, bytes; |
267 | unsigned char *v_overflow_buffer; | ||
252 | 268 | ||
253 | bytes = nslabs << IO_TLB_SHIFT; | 269 | bytes = nslabs << IO_TLB_SHIFT; |
254 | 270 | ||
255 | io_tlb_nslabs = nslabs; | 271 | io_tlb_nslabs = nslabs; |
256 | io_tlb_start = tlb; | 272 | io_tlb_start = virt_to_phys(tlb); |
257 | io_tlb_end = io_tlb_start + bytes; | 273 | io_tlb_end = io_tlb_start + bytes; |
258 | 274 | ||
259 | memset(io_tlb_start, 0, bytes); | 275 | memset(tlb, 0, bytes); |
276 | |||
277 | /* | ||
278 | * Get the overflow emergency buffer | ||
279 | */ | ||
280 | v_overflow_buffer = (void *)__get_free_pages(GFP_DMA, | ||
281 | get_order(io_tlb_overflow)); | ||
282 | if (!v_overflow_buffer) | ||
283 | goto cleanup2; | ||
284 | |||
285 | io_tlb_overflow_buffer = virt_to_phys(v_overflow_buffer); | ||
260 | 286 | ||
261 | /* | 287 | /* |
262 | * Allocate and initialize the free list array. This array is used | 288 | * Allocate and initialize the free list array. This array is used |
@@ -266,7 +292,7 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) | |||
266 | io_tlb_list = (unsigned int *)__get_free_pages(GFP_KERNEL, | 292 | io_tlb_list = (unsigned int *)__get_free_pages(GFP_KERNEL, |
267 | get_order(io_tlb_nslabs * sizeof(int))); | 293 | get_order(io_tlb_nslabs * sizeof(int))); |
268 | if (!io_tlb_list) | 294 | if (!io_tlb_list) |
269 | goto cleanup2; | 295 | goto cleanup3; |
270 | 296 | ||
271 | for (i = 0; i < io_tlb_nslabs; i++) | 297 | for (i = 0; i < io_tlb_nslabs; i++) |
272 | io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); | 298 | io_tlb_list[i] = IO_TLB_SEGSIZE - OFFSET(i, IO_TLB_SEGSIZE); |
@@ -277,18 +303,10 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) | |||
277 | get_order(io_tlb_nslabs * | 303 | get_order(io_tlb_nslabs * |
278 | sizeof(phys_addr_t))); | 304 | sizeof(phys_addr_t))); |
279 | if (!io_tlb_orig_addr) | 305 | if (!io_tlb_orig_addr) |
280 | goto cleanup3; | 306 | goto cleanup4; |
281 | 307 | ||
282 | memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(phys_addr_t)); | 308 | memset(io_tlb_orig_addr, 0, io_tlb_nslabs * sizeof(phys_addr_t)); |
283 | 309 | ||
284 | /* | ||
285 | * Get the overflow emergency buffer | ||
286 | */ | ||
287 | io_tlb_overflow_buffer = (void *)__get_free_pages(GFP_DMA, | ||
288 | get_order(io_tlb_overflow)); | ||
289 | if (!io_tlb_overflow_buffer) | ||
290 | goto cleanup4; | ||
291 | |||
292 | swiotlb_print_info(); | 310 | swiotlb_print_info(); |
293 | 311 | ||
294 | late_alloc = 1; | 312 | late_alloc = 1; |
@@ -296,42 +314,42 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) | |||
296 | return 0; | 314 | return 0; |
297 | 315 | ||
298 | cleanup4: | 316 | cleanup4: |
299 | free_pages((unsigned long)io_tlb_orig_addr, | ||
300 | get_order(io_tlb_nslabs * sizeof(phys_addr_t))); | ||
301 | io_tlb_orig_addr = NULL; | ||
302 | cleanup3: | ||
303 | free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs * | 317 | free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs * |
304 | sizeof(int))); | 318 | sizeof(int))); |
305 | io_tlb_list = NULL; | 319 | io_tlb_list = NULL; |
320 | cleanup3: | ||
321 | free_pages((unsigned long)v_overflow_buffer, | ||
322 | get_order(io_tlb_overflow)); | ||
323 | io_tlb_overflow_buffer = 0; | ||
306 | cleanup2: | 324 | cleanup2: |
307 | io_tlb_end = NULL; | 325 | io_tlb_end = 0; |
308 | io_tlb_start = NULL; | 326 | io_tlb_start = 0; |
309 | io_tlb_nslabs = 0; | 327 | io_tlb_nslabs = 0; |
310 | return -ENOMEM; | 328 | return -ENOMEM; |
311 | } | 329 | } |
312 | 330 | ||
313 | void __init swiotlb_free(void) | 331 | void __init swiotlb_free(void) |
314 | { | 332 | { |
315 | if (!io_tlb_overflow_buffer) | 333 | if (!io_tlb_orig_addr) |
316 | return; | 334 | return; |
317 | 335 | ||
318 | if (late_alloc) { | 336 | if (late_alloc) { |
319 | free_pages((unsigned long)io_tlb_overflow_buffer, | 337 | free_pages((unsigned long)phys_to_virt(io_tlb_overflow_buffer), |
320 | get_order(io_tlb_overflow)); | 338 | get_order(io_tlb_overflow)); |
321 | free_pages((unsigned long)io_tlb_orig_addr, | 339 | free_pages((unsigned long)io_tlb_orig_addr, |
322 | get_order(io_tlb_nslabs * sizeof(phys_addr_t))); | 340 | get_order(io_tlb_nslabs * sizeof(phys_addr_t))); |
323 | free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs * | 341 | free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs * |
324 | sizeof(int))); | 342 | sizeof(int))); |
325 | free_pages((unsigned long)io_tlb_start, | 343 | free_pages((unsigned long)phys_to_virt(io_tlb_start), |
326 | get_order(io_tlb_nslabs << IO_TLB_SHIFT)); | 344 | get_order(io_tlb_nslabs << IO_TLB_SHIFT)); |
327 | } else { | 345 | } else { |
328 | free_bootmem_late(__pa(io_tlb_overflow_buffer), | 346 | free_bootmem_late(io_tlb_overflow_buffer, |
329 | PAGE_ALIGN(io_tlb_overflow)); | 347 | PAGE_ALIGN(io_tlb_overflow)); |
330 | free_bootmem_late(__pa(io_tlb_orig_addr), | 348 | free_bootmem_late(__pa(io_tlb_orig_addr), |
331 | PAGE_ALIGN(io_tlb_nslabs * sizeof(phys_addr_t))); | 349 | PAGE_ALIGN(io_tlb_nslabs * sizeof(phys_addr_t))); |
332 | free_bootmem_late(__pa(io_tlb_list), | 350 | free_bootmem_late(__pa(io_tlb_list), |
333 | PAGE_ALIGN(io_tlb_nslabs * sizeof(int))); | 351 | PAGE_ALIGN(io_tlb_nslabs * sizeof(int))); |
334 | free_bootmem_late(__pa(io_tlb_start), | 352 | free_bootmem_late(io_tlb_start, |
335 | PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); | 353 | PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); |
336 | } | 354 | } |
337 | io_tlb_nslabs = 0; | 355 | io_tlb_nslabs = 0; |
@@ -339,21 +357,21 @@ void __init swiotlb_free(void) | |||
339 | 357 | ||
340 | static int is_swiotlb_buffer(phys_addr_t paddr) | 358 | static int is_swiotlb_buffer(phys_addr_t paddr) |
341 | { | 359 | { |
342 | return paddr >= virt_to_phys(io_tlb_start) && | 360 | return paddr >= io_tlb_start && paddr < io_tlb_end; |
343 | paddr < virt_to_phys(io_tlb_end); | ||
344 | } | 361 | } |
345 | 362 | ||
346 | /* | 363 | /* |
347 | * Bounce: copy the swiotlb buffer back to the original dma location | 364 | * Bounce: copy the swiotlb buffer back to the original dma location |
348 | */ | 365 | */ |
349 | void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size, | 366 | static void swiotlb_bounce(phys_addr_t orig_addr, phys_addr_t tlb_addr, |
350 | enum dma_data_direction dir) | 367 | size_t size, enum dma_data_direction dir) |
351 | { | 368 | { |
352 | unsigned long pfn = PFN_DOWN(phys); | 369 | unsigned long pfn = PFN_DOWN(orig_addr); |
370 | unsigned char *vaddr = phys_to_virt(tlb_addr); | ||
353 | 371 | ||
354 | if (PageHighMem(pfn_to_page(pfn))) { | 372 | if (PageHighMem(pfn_to_page(pfn))) { |
355 | /* The buffer does not have a mapping. Map it in and copy */ | 373 | /* The buffer does not have a mapping. Map it in and copy */ |
356 | unsigned int offset = phys & ~PAGE_MASK; | 374 | unsigned int offset = orig_addr & ~PAGE_MASK; |
357 | char *buffer; | 375 | char *buffer; |
358 | unsigned int sz = 0; | 376 | unsigned int sz = 0; |
359 | unsigned long flags; | 377 | unsigned long flags; |
@@ -364,38 +382,40 @@ void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size, | |||
364 | local_irq_save(flags); | 382 | local_irq_save(flags); |
365 | buffer = kmap_atomic(pfn_to_page(pfn)); | 383 | buffer = kmap_atomic(pfn_to_page(pfn)); |
366 | if (dir == DMA_TO_DEVICE) | 384 | if (dir == DMA_TO_DEVICE) |
367 | memcpy(dma_addr, buffer + offset, sz); | 385 | memcpy(vaddr, buffer + offset, sz); |
368 | else | 386 | else |
369 | memcpy(buffer + offset, dma_addr, sz); | 387 | memcpy(buffer + offset, vaddr, sz); |
370 | kunmap_atomic(buffer); | 388 | kunmap_atomic(buffer); |
371 | local_irq_restore(flags); | 389 | local_irq_restore(flags); |
372 | 390 | ||
373 | size -= sz; | 391 | size -= sz; |
374 | pfn++; | 392 | pfn++; |
375 | dma_addr += sz; | 393 | vaddr += sz; |
376 | offset = 0; | 394 | offset = 0; |
377 | } | 395 | } |
396 | } else if (dir == DMA_TO_DEVICE) { | ||
397 | memcpy(vaddr, phys_to_virt(orig_addr), size); | ||
378 | } else { | 398 | } else { |
379 | if (dir == DMA_TO_DEVICE) | 399 | memcpy(phys_to_virt(orig_addr), vaddr, size); |
380 | memcpy(dma_addr, phys_to_virt(phys), size); | ||
381 | else | ||
382 | memcpy(phys_to_virt(phys), dma_addr, size); | ||
383 | } | 400 | } |
384 | } | 401 | } |
385 | EXPORT_SYMBOL_GPL(swiotlb_bounce); | ||
386 | 402 | ||
387 | void *swiotlb_tbl_map_single(struct device *hwdev, dma_addr_t tbl_dma_addr, | 403 | phys_addr_t swiotlb_tbl_map_single(struct device *hwdev, |
388 | phys_addr_t phys, size_t size, | 404 | dma_addr_t tbl_dma_addr, |
389 | enum dma_data_direction dir) | 405 | phys_addr_t orig_addr, size_t size, |
406 | enum dma_data_direction dir) | ||
390 | { | 407 | { |
391 | unsigned long flags; | 408 | unsigned long flags; |
392 | char *dma_addr; | 409 | phys_addr_t tlb_addr; |
393 | unsigned int nslots, stride, index, wrap; | 410 | unsigned int nslots, stride, index, wrap; |
394 | int i; | 411 | int i; |
395 | unsigned long mask; | 412 | unsigned long mask; |
396 | unsigned long offset_slots; | 413 | unsigned long offset_slots; |
397 | unsigned long max_slots; | 414 | unsigned long max_slots; |
398 | 415 | ||
416 | if (no_iotlb_memory) | ||
417 | panic("Can not allocate SWIOTLB buffer earlier and can't now provide you with the DMA bounce buffer"); | ||
418 | |||
399 | mask = dma_get_seg_boundary(hwdev); | 419 | mask = dma_get_seg_boundary(hwdev); |
400 | 420 | ||
401 | tbl_dma_addr &= mask; | 421 | tbl_dma_addr &= mask; |
@@ -453,7 +473,7 @@ void *swiotlb_tbl_map_single(struct device *hwdev, dma_addr_t tbl_dma_addr, | |||
453 | io_tlb_list[i] = 0; | 473 | io_tlb_list[i] = 0; |
454 | for (i = index - 1; (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE - 1) && io_tlb_list[i]; i--) | 474 | for (i = index - 1; (OFFSET(i, IO_TLB_SEGSIZE) != IO_TLB_SEGSIZE - 1) && io_tlb_list[i]; i--) |
455 | io_tlb_list[i] = ++count; | 475 | io_tlb_list[i] = ++count; |
456 | dma_addr = io_tlb_start + (index << IO_TLB_SHIFT); | 476 | tlb_addr = io_tlb_start + (index << IO_TLB_SHIFT); |
457 | 477 | ||
458 | /* | 478 | /* |
459 | * Update the indices to avoid searching in the next | 479 | * Update the indices to avoid searching in the next |
@@ -471,7 +491,7 @@ void *swiotlb_tbl_map_single(struct device *hwdev, dma_addr_t tbl_dma_addr, | |||
471 | 491 | ||
472 | not_found: | 492 | not_found: |
473 | spin_unlock_irqrestore(&io_tlb_lock, flags); | 493 | spin_unlock_irqrestore(&io_tlb_lock, flags); |
474 | return NULL; | 494 | return SWIOTLB_MAP_ERROR; |
475 | found: | 495 | found: |
476 | spin_unlock_irqrestore(&io_tlb_lock, flags); | 496 | spin_unlock_irqrestore(&io_tlb_lock, flags); |
477 | 497 | ||
@@ -481,11 +501,11 @@ found: | |||
481 | * needed. | 501 | * needed. |
482 | */ | 502 | */ |
483 | for (i = 0; i < nslots; i++) | 503 | for (i = 0; i < nslots; i++) |
484 | io_tlb_orig_addr[index+i] = phys + (i << IO_TLB_SHIFT); | 504 | io_tlb_orig_addr[index+i] = orig_addr + (i << IO_TLB_SHIFT); |
485 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) | 505 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) |
486 | swiotlb_bounce(phys, dma_addr, size, DMA_TO_DEVICE); | 506 | swiotlb_bounce(orig_addr, tlb_addr, size, DMA_TO_DEVICE); |
487 | 507 | ||
488 | return dma_addr; | 508 | return tlb_addr; |
489 | } | 509 | } |
490 | EXPORT_SYMBOL_GPL(swiotlb_tbl_map_single); | 510 | EXPORT_SYMBOL_GPL(swiotlb_tbl_map_single); |
491 | 511 | ||
@@ -493,11 +513,10 @@ EXPORT_SYMBOL_GPL(swiotlb_tbl_map_single); | |||
493 | * Allocates bounce buffer and returns its kernel virtual address. | 513 | * Allocates bounce buffer and returns its kernel virtual address. |
494 | */ | 514 | */ |
495 | 515 | ||
496 | static void * | 516 | phys_addr_t map_single(struct device *hwdev, phys_addr_t phys, size_t size, |
497 | map_single(struct device *hwdev, phys_addr_t phys, size_t size, | 517 | enum dma_data_direction dir) |
498 | enum dma_data_direction dir) | ||
499 | { | 518 | { |
500 | dma_addr_t start_dma_addr = swiotlb_virt_to_bus(hwdev, io_tlb_start); | 519 | dma_addr_t start_dma_addr = phys_to_dma(hwdev, io_tlb_start); |
501 | 520 | ||
502 | return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size, dir); | 521 | return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size, dir); |
503 | } | 522 | } |
@@ -505,20 +524,19 @@ map_single(struct device *hwdev, phys_addr_t phys, size_t size, | |||
505 | /* | 524 | /* |
506 | * dma_addr is the kernel virtual address of the bounce buffer to unmap. | 525 | * dma_addr is the kernel virtual address of the bounce buffer to unmap. |
507 | */ | 526 | */ |
508 | void | 527 | void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr, |
509 | swiotlb_tbl_unmap_single(struct device *hwdev, char *dma_addr, size_t size, | 528 | size_t size, enum dma_data_direction dir) |
510 | enum dma_data_direction dir) | ||
511 | { | 529 | { |
512 | unsigned long flags; | 530 | unsigned long flags; |
513 | int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; | 531 | int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; |
514 | int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; | 532 | int index = (tlb_addr - io_tlb_start) >> IO_TLB_SHIFT; |
515 | phys_addr_t phys = io_tlb_orig_addr[index]; | 533 | phys_addr_t orig_addr = io_tlb_orig_addr[index]; |
516 | 534 | ||
517 | /* | 535 | /* |
518 | * First, sync the memory before unmapping the entry | 536 | * First, sync the memory before unmapping the entry |
519 | */ | 537 | */ |
520 | if (phys && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) | 538 | if (orig_addr && ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL))) |
521 | swiotlb_bounce(phys, dma_addr, size, DMA_FROM_DEVICE); | 539 | swiotlb_bounce(orig_addr, tlb_addr, size, DMA_FROM_DEVICE); |
522 | 540 | ||
523 | /* | 541 | /* |
524 | * Return the buffer to the free list by setting the corresponding | 542 | * Return the buffer to the free list by setting the corresponding |
@@ -547,26 +565,27 @@ swiotlb_tbl_unmap_single(struct device *hwdev, char *dma_addr, size_t size, | |||
547 | } | 565 | } |
548 | EXPORT_SYMBOL_GPL(swiotlb_tbl_unmap_single); | 566 | EXPORT_SYMBOL_GPL(swiotlb_tbl_unmap_single); |
549 | 567 | ||
550 | void | 568 | void swiotlb_tbl_sync_single(struct device *hwdev, phys_addr_t tlb_addr, |
551 | swiotlb_tbl_sync_single(struct device *hwdev, char *dma_addr, size_t size, | 569 | size_t size, enum dma_data_direction dir, |
552 | enum dma_data_direction dir, | 570 | enum dma_sync_target target) |
553 | enum dma_sync_target target) | ||
554 | { | 571 | { |
555 | int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT; | 572 | int index = (tlb_addr - io_tlb_start) >> IO_TLB_SHIFT; |
556 | phys_addr_t phys = io_tlb_orig_addr[index]; | 573 | phys_addr_t orig_addr = io_tlb_orig_addr[index]; |
557 | 574 | ||
558 | phys += ((unsigned long)dma_addr & ((1 << IO_TLB_SHIFT) - 1)); | 575 | orig_addr += (unsigned long)tlb_addr & ((1 << IO_TLB_SHIFT) - 1); |
559 | 576 | ||
560 | switch (target) { | 577 | switch (target) { |
561 | case SYNC_FOR_CPU: | 578 | case SYNC_FOR_CPU: |
562 | if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) | 579 | if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) |
563 | swiotlb_bounce(phys, dma_addr, size, DMA_FROM_DEVICE); | 580 | swiotlb_bounce(orig_addr, tlb_addr, |
581 | size, DMA_FROM_DEVICE); | ||
564 | else | 582 | else |
565 | BUG_ON(dir != DMA_TO_DEVICE); | 583 | BUG_ON(dir != DMA_TO_DEVICE); |
566 | break; | 584 | break; |
567 | case SYNC_FOR_DEVICE: | 585 | case SYNC_FOR_DEVICE: |
568 | if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) | 586 | if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) |
569 | swiotlb_bounce(phys, dma_addr, size, DMA_TO_DEVICE); | 587 | swiotlb_bounce(orig_addr, tlb_addr, |
588 | size, DMA_TO_DEVICE); | ||
570 | else | 589 | else |
571 | BUG_ON(dir != DMA_FROM_DEVICE); | 590 | BUG_ON(dir != DMA_FROM_DEVICE); |
572 | break; | 591 | break; |
@@ -589,12 +608,15 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
589 | dma_mask = hwdev->coherent_dma_mask; | 608 | dma_mask = hwdev->coherent_dma_mask; |
590 | 609 | ||
591 | ret = (void *)__get_free_pages(flags, order); | 610 | ret = (void *)__get_free_pages(flags, order); |
592 | if (ret && swiotlb_virt_to_bus(hwdev, ret) + size - 1 > dma_mask) { | 611 | if (ret) { |
593 | /* | 612 | dev_addr = swiotlb_virt_to_bus(hwdev, ret); |
594 | * The allocated memory isn't reachable by the device. | 613 | if (dev_addr + size - 1 > dma_mask) { |
595 | */ | 614 | /* |
596 | free_pages((unsigned long) ret, order); | 615 | * The allocated memory isn't reachable by the device. |
597 | ret = NULL; | 616 | */ |
617 | free_pages((unsigned long) ret, order); | ||
618 | ret = NULL; | ||
619 | } | ||
598 | } | 620 | } |
599 | if (!ret) { | 621 | if (!ret) { |
600 | /* | 622 | /* |
@@ -602,25 +624,29 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
602 | * GFP_DMA memory; fall back on map_single(), which | 624 | * GFP_DMA memory; fall back on map_single(), which |
603 | * will grab memory from the lowest available address range. | 625 | * will grab memory from the lowest available address range. |
604 | */ | 626 | */ |
605 | ret = map_single(hwdev, 0, size, DMA_FROM_DEVICE); | 627 | phys_addr_t paddr = map_single(hwdev, 0, size, DMA_FROM_DEVICE); |
606 | if (!ret) | 628 | if (paddr == SWIOTLB_MAP_ERROR) |
607 | return NULL; | 629 | return NULL; |
608 | } | ||
609 | 630 | ||
610 | memset(ret, 0, size); | 631 | ret = phys_to_virt(paddr); |
611 | dev_addr = swiotlb_virt_to_bus(hwdev, ret); | 632 | dev_addr = phys_to_dma(hwdev, paddr); |
612 | 633 | ||
613 | /* Confirm address can be DMA'd by device */ | 634 | /* Confirm address can be DMA'd by device */ |
614 | if (dev_addr + size - 1 > dma_mask) { | 635 | if (dev_addr + size - 1 > dma_mask) { |
615 | printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n", | 636 | printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n", |
616 | (unsigned long long)dma_mask, | 637 | (unsigned long long)dma_mask, |
617 | (unsigned long long)dev_addr); | 638 | (unsigned long long)dev_addr); |
618 | 639 | ||
619 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ | 640 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ |
620 | swiotlb_tbl_unmap_single(hwdev, ret, size, DMA_TO_DEVICE); | 641 | swiotlb_tbl_unmap_single(hwdev, paddr, |
621 | return NULL; | 642 | size, DMA_TO_DEVICE); |
643 | return NULL; | ||
644 | } | ||
622 | } | 645 | } |
646 | |||
623 | *dma_handle = dev_addr; | 647 | *dma_handle = dev_addr; |
648 | memset(ret, 0, size); | ||
649 | |||
624 | return ret; | 650 | return ret; |
625 | } | 651 | } |
626 | EXPORT_SYMBOL(swiotlb_alloc_coherent); | 652 | EXPORT_SYMBOL(swiotlb_alloc_coherent); |
@@ -636,7 +662,7 @@ swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | |||
636 | free_pages((unsigned long)vaddr, get_order(size)); | 662 | free_pages((unsigned long)vaddr, get_order(size)); |
637 | else | 663 | else |
638 | /* DMA_TO_DEVICE to avoid memcpy in swiotlb_tbl_unmap_single */ | 664 | /* DMA_TO_DEVICE to avoid memcpy in swiotlb_tbl_unmap_single */ |
639 | swiotlb_tbl_unmap_single(hwdev, vaddr, size, DMA_TO_DEVICE); | 665 | swiotlb_tbl_unmap_single(hwdev, paddr, size, DMA_TO_DEVICE); |
640 | } | 666 | } |
641 | EXPORT_SYMBOL(swiotlb_free_coherent); | 667 | EXPORT_SYMBOL(swiotlb_free_coherent); |
642 | 668 | ||
@@ -677,9 +703,8 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page, | |||
677 | enum dma_data_direction dir, | 703 | enum dma_data_direction dir, |
678 | struct dma_attrs *attrs) | 704 | struct dma_attrs *attrs) |
679 | { | 705 | { |
680 | phys_addr_t phys = page_to_phys(page) + offset; | 706 | phys_addr_t map, phys = page_to_phys(page) + offset; |
681 | dma_addr_t dev_addr = phys_to_dma(dev, phys); | 707 | dma_addr_t dev_addr = phys_to_dma(dev, phys); |
682 | void *map; | ||
683 | 708 | ||
684 | BUG_ON(dir == DMA_NONE); | 709 | BUG_ON(dir == DMA_NONE); |
685 | /* | 710 | /* |
@@ -690,23 +715,19 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page, | |||
690 | if (dma_capable(dev, dev_addr, size) && !swiotlb_force) | 715 | if (dma_capable(dev, dev_addr, size) && !swiotlb_force) |
691 | return dev_addr; | 716 | return dev_addr; |
692 | 717 | ||
693 | /* | 718 | /* Oh well, have to allocate and map a bounce buffer. */ |
694 | * Oh well, have to allocate and map a bounce buffer. | ||
695 | */ | ||
696 | map = map_single(dev, phys, size, dir); | 719 | map = map_single(dev, phys, size, dir); |
697 | if (!map) { | 720 | if (map == SWIOTLB_MAP_ERROR) { |
698 | swiotlb_full(dev, size, dir, 1); | 721 | swiotlb_full(dev, size, dir, 1); |
699 | map = io_tlb_overflow_buffer; | 722 | return phys_to_dma(dev, io_tlb_overflow_buffer); |
700 | } | 723 | } |
701 | 724 | ||
702 | dev_addr = swiotlb_virt_to_bus(dev, map); | 725 | dev_addr = phys_to_dma(dev, map); |
703 | 726 | ||
704 | /* | 727 | /* Ensure that the address returned is DMA'ble */ |
705 | * Ensure that the address returned is DMA'ble | ||
706 | */ | ||
707 | if (!dma_capable(dev, dev_addr, size)) { | 728 | if (!dma_capable(dev, dev_addr, size)) { |
708 | swiotlb_tbl_unmap_single(dev, map, size, dir); | 729 | swiotlb_tbl_unmap_single(dev, map, size, dir); |
709 | dev_addr = swiotlb_virt_to_bus(dev, io_tlb_overflow_buffer); | 730 | return phys_to_dma(dev, io_tlb_overflow_buffer); |
710 | } | 731 | } |
711 | 732 | ||
712 | return dev_addr; | 733 | return dev_addr; |
@@ -729,7 +750,7 @@ static void unmap_single(struct device *hwdev, dma_addr_t dev_addr, | |||
729 | BUG_ON(dir == DMA_NONE); | 750 | BUG_ON(dir == DMA_NONE); |
730 | 751 | ||
731 | if (is_swiotlb_buffer(paddr)) { | 752 | if (is_swiotlb_buffer(paddr)) { |
732 | swiotlb_tbl_unmap_single(hwdev, phys_to_virt(paddr), size, dir); | 753 | swiotlb_tbl_unmap_single(hwdev, paddr, size, dir); |
733 | return; | 754 | return; |
734 | } | 755 | } |
735 | 756 | ||
@@ -773,8 +794,7 @@ swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, | |||
773 | BUG_ON(dir == DMA_NONE); | 794 | BUG_ON(dir == DMA_NONE); |
774 | 795 | ||
775 | if (is_swiotlb_buffer(paddr)) { | 796 | if (is_swiotlb_buffer(paddr)) { |
776 | swiotlb_tbl_sync_single(hwdev, phys_to_virt(paddr), size, dir, | 797 | swiotlb_tbl_sync_single(hwdev, paddr, size, dir, target); |
777 | target); | ||
778 | return; | 798 | return; |
779 | } | 799 | } |
780 | 800 | ||
@@ -831,9 +851,9 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, | |||
831 | 851 | ||
832 | if (swiotlb_force || | 852 | if (swiotlb_force || |
833 | !dma_capable(hwdev, dev_addr, sg->length)) { | 853 | !dma_capable(hwdev, dev_addr, sg->length)) { |
834 | void *map = map_single(hwdev, sg_phys(sg), | 854 | phys_addr_t map = map_single(hwdev, sg_phys(sg), |
835 | sg->length, dir); | 855 | sg->length, dir); |
836 | if (!map) { | 856 | if (map == SWIOTLB_MAP_ERROR) { |
837 | /* Don't panic here, we expect map_sg users | 857 | /* Don't panic here, we expect map_sg users |
838 | to do proper error handling. */ | 858 | to do proper error handling. */ |
839 | swiotlb_full(hwdev, sg->length, dir, 0); | 859 | swiotlb_full(hwdev, sg->length, dir, 0); |
@@ -842,7 +862,7 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, | |||
842 | sgl[0].dma_length = 0; | 862 | sgl[0].dma_length = 0; |
843 | return 0; | 863 | return 0; |
844 | } | 864 | } |
845 | sg->dma_address = swiotlb_virt_to_bus(hwdev, map); | 865 | sg->dma_address = phys_to_dma(hwdev, map); |
846 | } else | 866 | } else |
847 | sg->dma_address = dev_addr; | 867 | sg->dma_address = dev_addr; |
848 | sg->dma_length = sg->length; | 868 | sg->dma_length = sg->length; |
@@ -925,7 +945,7 @@ EXPORT_SYMBOL(swiotlb_sync_sg_for_device); | |||
925 | int | 945 | int |
926 | swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr) | 946 | swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr) |
927 | { | 947 | { |
928 | return (dma_addr == swiotlb_virt_to_bus(hwdev, io_tlb_overflow_buffer)); | 948 | return (dma_addr == phys_to_dma(hwdev, io_tlb_overflow_buffer)); |
929 | } | 949 | } |
930 | EXPORT_SYMBOL(swiotlb_dma_mapping_error); | 950 | EXPORT_SYMBOL(swiotlb_dma_mapping_error); |
931 | 951 | ||
@@ -938,6 +958,6 @@ EXPORT_SYMBOL(swiotlb_dma_mapping_error); | |||
938 | int | 958 | int |
939 | swiotlb_dma_supported(struct device *hwdev, u64 mask) | 959 | swiotlb_dma_supported(struct device *hwdev, u64 mask) |
940 | { | 960 | { |
941 | return swiotlb_virt_to_bus(hwdev, io_tlb_end - 1) <= mask; | 961 | return phys_to_dma(hwdev, io_tlb_end - 1) <= mask; |
942 | } | 962 | } |
943 | EXPORT_SYMBOL(swiotlb_dma_supported); | 963 | EXPORT_SYMBOL(swiotlb_dma_supported); |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 39c99fea7c03..0d62fd700f68 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -23,12 +23,12 @@ | |||
23 | #include <linux/ctype.h> | 23 | #include <linux/ctype.h> |
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/kallsyms.h> | 25 | #include <linux/kallsyms.h> |
26 | #include <linux/math64.h> | ||
26 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
27 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
28 | #include <net/addrconf.h> | 29 | #include <net/addrconf.h> |
29 | 30 | ||
30 | #include <asm/page.h> /* for PAGE_SIZE */ | 31 | #include <asm/page.h> /* for PAGE_SIZE */ |
31 | #include <asm/div64.h> | ||
32 | #include <asm/sections.h> /* for dereference_function_descriptor() */ | 32 | #include <asm/sections.h> /* for dereference_function_descriptor() */ |
33 | 33 | ||
34 | #include "kstrtox.h" | 34 | #include "kstrtox.h" |
@@ -38,6 +38,8 @@ | |||
38 | * @cp: The start of the string | 38 | * @cp: The start of the string |
39 | * @endp: A pointer to the end of the parsed string will be placed here | 39 | * @endp: A pointer to the end of the parsed string will be placed here |
40 | * @base: The number base to use | 40 | * @base: The number base to use |
41 | * | ||
42 | * This function is obsolete. Please use kstrtoull instead. | ||
41 | */ | 43 | */ |
42 | unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) | 44 | unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) |
43 | { | 45 | { |
@@ -61,6 +63,8 @@ EXPORT_SYMBOL(simple_strtoull); | |||
61 | * @cp: The start of the string | 63 | * @cp: The start of the string |
62 | * @endp: A pointer to the end of the parsed string will be placed here | 64 | * @endp: A pointer to the end of the parsed string will be placed here |
63 | * @base: The number base to use | 65 | * @base: The number base to use |
66 | * | ||
67 | * This function is obsolete. Please use kstrtoul instead. | ||
64 | */ | 68 | */ |
65 | unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) | 69 | unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) |
66 | { | 70 | { |
@@ -73,6 +77,8 @@ EXPORT_SYMBOL(simple_strtoul); | |||
73 | * @cp: The start of the string | 77 | * @cp: The start of the string |
74 | * @endp: A pointer to the end of the parsed string will be placed here | 78 | * @endp: A pointer to the end of the parsed string will be placed here |
75 | * @base: The number base to use | 79 | * @base: The number base to use |
80 | * | ||
81 | * This function is obsolete. Please use kstrtol instead. | ||
76 | */ | 82 | */ |
77 | long simple_strtol(const char *cp, char **endp, unsigned int base) | 83 | long simple_strtol(const char *cp, char **endp, unsigned int base) |
78 | { | 84 | { |
@@ -88,6 +94,8 @@ EXPORT_SYMBOL(simple_strtol); | |||
88 | * @cp: The start of the string | 94 | * @cp: The start of the string |
89 | * @endp: A pointer to the end of the parsed string will be placed here | 95 | * @endp: A pointer to the end of the parsed string will be placed here |
90 | * @base: The number base to use | 96 | * @base: The number base to use |
97 | * | ||
98 | * This function is obsolete. Please use kstrtoll instead. | ||
91 | */ | 99 | */ |
92 | long long simple_strtoll(const char *cp, char **endp, unsigned int base) | 100 | long long simple_strtoll(const char *cp, char **endp, unsigned int base) |
93 | { | 101 | { |
@@ -1022,6 +1030,7 @@ int kptr_restrict __read_mostly; | |||
1022 | * N no separator | 1030 | * N no separator |
1023 | * The maximum supported length is 64 bytes of the input. Consider | 1031 | * The maximum supported length is 64 bytes of the input. Consider |
1024 | * to use print_hex_dump() for the larger input. | 1032 | * to use print_hex_dump() for the larger input. |
1033 | * - 'a' For a phys_addr_t type and its derivative types (passed by reference) | ||
1025 | * | 1034 | * |
1026 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 | 1035 | * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 |
1027 | * function pointers are really function descriptors, which contain a | 1036 | * function pointers are really function descriptors, which contain a |
@@ -1112,6 +1121,12 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
1112 | return netdev_feature_string(buf, end, ptr, spec); | 1121 | return netdev_feature_string(buf, end, ptr, spec); |
1113 | } | 1122 | } |
1114 | break; | 1123 | break; |
1124 | case 'a': | ||
1125 | spec.flags |= SPECIAL | SMALL | ZEROPAD; | ||
1126 | spec.field_width = sizeof(phys_addr_t) * 2 + 2; | ||
1127 | spec.base = 16; | ||
1128 | return number(buf, end, | ||
1129 | (unsigned long long) *((phys_addr_t *)ptr), spec); | ||
1115 | } | 1130 | } |
1116 | spec.flags |= SMALL; | 1131 | spec.flags |= SMALL; |
1117 | if (spec.field_width == -1) { | 1132 | if (spec.field_width == -1) { |
@@ -1485,7 +1500,10 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | |||
1485 | num = va_arg(args, long); | 1500 | num = va_arg(args, long); |
1486 | break; | 1501 | break; |
1487 | case FORMAT_TYPE_SIZE_T: | 1502 | case FORMAT_TYPE_SIZE_T: |
1488 | num = va_arg(args, size_t); | 1503 | if (spec.flags & SIGN) |
1504 | num = va_arg(args, ssize_t); | ||
1505 | else | ||
1506 | num = va_arg(args, size_t); | ||
1489 | break; | 1507 | break; |
1490 | case FORMAT_TYPE_PTRDIFF: | 1508 | case FORMAT_TYPE_PTRDIFF: |
1491 | num = va_arg(args, ptrdiff_t); | 1509 | num = va_arg(args, ptrdiff_t); |
@@ -2013,7 +2031,11 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
2013 | char digit; | 2031 | char digit; |
2014 | int num = 0; | 2032 | int num = 0; |
2015 | u8 qualifier; | 2033 | u8 qualifier; |
2016 | u8 base; | 2034 | unsigned int base; |
2035 | union { | ||
2036 | long long s; | ||
2037 | unsigned long long u; | ||
2038 | } val; | ||
2017 | s16 field_width; | 2039 | s16 field_width; |
2018 | bool is_sign; | 2040 | bool is_sign; |
2019 | 2041 | ||
@@ -2053,8 +2075,11 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
2053 | 2075 | ||
2054 | /* get field width */ | 2076 | /* get field width */ |
2055 | field_width = -1; | 2077 | field_width = -1; |
2056 | if (isdigit(*fmt)) | 2078 | if (isdigit(*fmt)) { |
2057 | field_width = skip_atoi(&fmt); | 2079 | field_width = skip_atoi(&fmt); |
2080 | if (field_width <= 0) | ||
2081 | break; | ||
2082 | } | ||
2058 | 2083 | ||
2059 | /* get conversion qualifier */ | 2084 | /* get conversion qualifier */ |
2060 | qualifier = -1; | 2085 | qualifier = -1; |
@@ -2154,58 +2179,61 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
2154 | || (base == 0 && !isdigit(digit))) | 2179 | || (base == 0 && !isdigit(digit))) |
2155 | break; | 2180 | break; |
2156 | 2181 | ||
2182 | if (is_sign) | ||
2183 | val.s = qualifier != 'L' ? | ||
2184 | simple_strtol(str, &next, base) : | ||
2185 | simple_strtoll(str, &next, base); | ||
2186 | else | ||
2187 | val.u = qualifier != 'L' ? | ||
2188 | simple_strtoul(str, &next, base) : | ||
2189 | simple_strtoull(str, &next, base); | ||
2190 | |||
2191 | if (field_width > 0 && next - str > field_width) { | ||
2192 | if (base == 0) | ||
2193 | _parse_integer_fixup_radix(str, &base); | ||
2194 | while (next - str > field_width) { | ||
2195 | if (is_sign) | ||
2196 | val.s = div_s64(val.s, base); | ||
2197 | else | ||
2198 | val.u = div_u64(val.u, base); | ||
2199 | --next; | ||
2200 | } | ||
2201 | } | ||
2202 | |||
2157 | switch (qualifier) { | 2203 | switch (qualifier) { |
2158 | case 'H': /* that's 'hh' in format */ | 2204 | case 'H': /* that's 'hh' in format */ |
2159 | if (is_sign) { | 2205 | if (is_sign) |
2160 | signed char *s = (signed char *)va_arg(args, signed char *); | 2206 | *va_arg(args, signed char *) = val.s; |
2161 | *s = (signed char)simple_strtol(str, &next, base); | 2207 | else |
2162 | } else { | 2208 | *va_arg(args, unsigned char *) = val.u; |
2163 | unsigned char *s = (unsigned char *)va_arg(args, unsigned char *); | ||
2164 | *s = (unsigned char)simple_strtoul(str, &next, base); | ||
2165 | } | ||
2166 | break; | 2209 | break; |
2167 | case 'h': | 2210 | case 'h': |
2168 | if (is_sign) { | 2211 | if (is_sign) |
2169 | short *s = (short *)va_arg(args, short *); | 2212 | *va_arg(args, short *) = val.s; |
2170 | *s = (short)simple_strtol(str, &next, base); | 2213 | else |
2171 | } else { | 2214 | *va_arg(args, unsigned short *) = val.u; |
2172 | unsigned short *s = (unsigned short *)va_arg(args, unsigned short *); | ||
2173 | *s = (unsigned short)simple_strtoul(str, &next, base); | ||
2174 | } | ||
2175 | break; | 2215 | break; |
2176 | case 'l': | 2216 | case 'l': |
2177 | if (is_sign) { | 2217 | if (is_sign) |
2178 | long *l = (long *)va_arg(args, long *); | 2218 | *va_arg(args, long *) = val.s; |
2179 | *l = simple_strtol(str, &next, base); | 2219 | else |
2180 | } else { | 2220 | *va_arg(args, unsigned long *) = val.u; |
2181 | unsigned long *l = (unsigned long *)va_arg(args, unsigned long *); | ||
2182 | *l = simple_strtoul(str, &next, base); | ||
2183 | } | ||
2184 | break; | 2221 | break; |
2185 | case 'L': | 2222 | case 'L': |
2186 | if (is_sign) { | 2223 | if (is_sign) |
2187 | long long *l = (long long *)va_arg(args, long long *); | 2224 | *va_arg(args, long long *) = val.s; |
2188 | *l = simple_strtoll(str, &next, base); | 2225 | else |
2189 | } else { | 2226 | *va_arg(args, unsigned long long *) = val.u; |
2190 | unsigned long long *l = (unsigned long long *)va_arg(args, unsigned long long *); | ||
2191 | *l = simple_strtoull(str, &next, base); | ||
2192 | } | ||
2193 | break; | 2227 | break; |
2194 | case 'Z': | 2228 | case 'Z': |
2195 | case 'z': | 2229 | case 'z': |
2196 | { | 2230 | *va_arg(args, size_t *) = val.u; |
2197 | size_t *s = (size_t *)va_arg(args, size_t *); | 2231 | break; |
2198 | *s = (size_t)simple_strtoul(str, &next, base); | ||
2199 | } | ||
2200 | break; | ||
2201 | default: | 2232 | default: |
2202 | if (is_sign) { | 2233 | if (is_sign) |
2203 | int *i = (int *)va_arg(args, int *); | 2234 | *va_arg(args, int *) = val.s; |
2204 | *i = (int)simple_strtol(str, &next, base); | 2235 | else |
2205 | } else { | 2236 | *va_arg(args, unsigned int *) = val.u; |
2206 | unsigned int *i = (unsigned int *)va_arg(args, unsigned int*); | ||
2207 | *i = (unsigned int)simple_strtoul(str, &next, base); | ||
2208 | } | ||
2209 | break; | 2237 | break; |
2210 | } | 2238 | } |
2211 | num++; | 2239 | num++; |
diff --git a/lib/xz/Kconfig b/lib/xz/Kconfig index 60a6088d0e5e..08837db52d94 100644 --- a/lib/xz/Kconfig +++ b/lib/xz/Kconfig | |||
@@ -6,42 +6,40 @@ config XZ_DEC | |||
6 | the .xz file format as the container. For integrity checking, | 6 | the .xz file format as the container. For integrity checking, |
7 | CRC32 is supported. See Documentation/xz.txt for more information. | 7 | CRC32 is supported. See Documentation/xz.txt for more information. |
8 | 8 | ||
9 | if XZ_DEC | ||
10 | |||
9 | config XZ_DEC_X86 | 11 | config XZ_DEC_X86 |
10 | bool "x86 BCJ filter decoder" if EXPERT | 12 | bool "x86 BCJ filter decoder" |
11 | default y | 13 | default y if X86 |
12 | depends on XZ_DEC | ||
13 | select XZ_DEC_BCJ | 14 | select XZ_DEC_BCJ |
14 | 15 | ||
15 | config XZ_DEC_POWERPC | 16 | config XZ_DEC_POWERPC |
16 | bool "PowerPC BCJ filter decoder" if EXPERT | 17 | bool "PowerPC BCJ filter decoder" |
17 | default y | 18 | default y if PPC |
18 | depends on XZ_DEC | ||
19 | select XZ_DEC_BCJ | 19 | select XZ_DEC_BCJ |
20 | 20 | ||
21 | config XZ_DEC_IA64 | 21 | config XZ_DEC_IA64 |
22 | bool "IA-64 BCJ filter decoder" if EXPERT | 22 | bool "IA-64 BCJ filter decoder" |
23 | default y | 23 | default y if IA64 |
24 | depends on XZ_DEC | ||
25 | select XZ_DEC_BCJ | 24 | select XZ_DEC_BCJ |
26 | 25 | ||
27 | config XZ_DEC_ARM | 26 | config XZ_DEC_ARM |
28 | bool "ARM BCJ filter decoder" if EXPERT | 27 | bool "ARM BCJ filter decoder" |
29 | default y | 28 | default y if ARM |
30 | depends on XZ_DEC | ||
31 | select XZ_DEC_BCJ | 29 | select XZ_DEC_BCJ |
32 | 30 | ||
33 | config XZ_DEC_ARMTHUMB | 31 | config XZ_DEC_ARMTHUMB |
34 | bool "ARM-Thumb BCJ filter decoder" if EXPERT | 32 | bool "ARM-Thumb BCJ filter decoder" |
35 | default y | 33 | default y if (ARM && ARM_THUMB) |
36 | depends on XZ_DEC | ||
37 | select XZ_DEC_BCJ | 34 | select XZ_DEC_BCJ |
38 | 35 | ||
39 | config XZ_DEC_SPARC | 36 | config XZ_DEC_SPARC |
40 | bool "SPARC BCJ filter decoder" if EXPERT | 37 | bool "SPARC BCJ filter decoder" |
41 | default y | 38 | default y if SPARC |
42 | depends on XZ_DEC | ||
43 | select XZ_DEC_BCJ | 39 | select XZ_DEC_BCJ |
44 | 40 | ||
41 | endif | ||
42 | |||
45 | config XZ_DEC_BCJ | 43 | config XZ_DEC_BCJ |
46 | bool | 44 | bool |
47 | default n | 45 | default n |