diff options
94 files changed, 2033 insertions, 1338 deletions
@@ -84,6 +84,7 @@ Mayuresh Janorkar <mayur@ti.com> | |||
84 | Michael Buesch <m@bues.ch> | 84 | Michael Buesch <m@bues.ch> |
85 | Michel Dänzer <michel@tungstengraphics.com> | 85 | Michel Dänzer <michel@tungstengraphics.com> |
86 | Mitesh shah <mshah@teja.com> | 86 | Mitesh shah <mshah@teja.com> |
87 | Mohit Kumar <mohit.kumar@st.com> <mohit.kumar.dhaka@gmail.com> | ||
87 | Morten Welinder <terra@gnome.org> | 88 | Morten Welinder <terra@gnome.org> |
88 | Morten Welinder <welinder@anemone.rentec.com> | 89 | Morten Welinder <welinder@anemone.rentec.com> |
89 | Morten Welinder <welinder@darter.rentec.com> | 90 | Morten Welinder <welinder@darter.rentec.com> |
@@ -95,10 +96,12 @@ Patrick Mochel <mochel@digitalimplant.org> | |||
95 | Peter A Jonsson <pj@ludd.ltu.se> | 96 | Peter A Jonsson <pj@ludd.ltu.se> |
96 | Peter Oruba <peter@oruba.de> | 97 | Peter Oruba <peter@oruba.de> |
97 | Peter Oruba <peter.oruba@amd.com> | 98 | Peter Oruba <peter.oruba@amd.com> |
99 | Pratyush Anand <pratyush.anand@gmail.com> <pratyush.anand@st.com> | ||
98 | Praveen BP <praveenbp@ti.com> | 100 | Praveen BP <praveenbp@ti.com> |
99 | Rajesh Shah <rajesh.shah@intel.com> | 101 | Rajesh Shah <rajesh.shah@intel.com> |
100 | Ralf Baechle <ralf@linux-mips.org> | 102 | Ralf Baechle <ralf@linux-mips.org> |
101 | Ralf Wildenhues <Ralf.Wildenhues@gmx.de> | 103 | Ralf Wildenhues <Ralf.Wildenhues@gmx.de> |
104 | Randy Dunlap <rdunlap@infradead.org> <rdunlap@xenotime.net> | ||
102 | Rémi Denis-Courmont <rdenis@simphalempin.com> | 105 | Rémi Denis-Courmont <rdenis@simphalempin.com> |
103 | Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> | 106 | Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> |
104 | Rudolf Marek <R.Marek@sh.cvut.cz> | 107 | Rudolf Marek <R.Marek@sh.cvut.cz> |
diff --git a/Documentation/ABI/testing/configfs-spear-pcie-gadget b/Documentation/ABI/testing/configfs-spear-pcie-gadget index 875988146a63..840c324ef34d 100644 --- a/Documentation/ABI/testing/configfs-spear-pcie-gadget +++ b/Documentation/ABI/testing/configfs-spear-pcie-gadget | |||
@@ -1,7 +1,7 @@ | |||
1 | What: /config/pcie-gadget | 1 | What: /config/pcie-gadget |
2 | Date: Feb 2011 | 2 | Date: Feb 2011 |
3 | KernelVersion: 2.6.37 | 3 | KernelVersion: 2.6.37 |
4 | Contact: Pratyush Anand <pratyush.anand@st.com> | 4 | Contact: Pratyush Anand <pratyush.anand@gmail.com> |
5 | Description: | 5 | Description: |
6 | 6 | ||
7 | Interface is used to configure selected dual mode PCIe controller | 7 | Interface is used to configure selected dual mode PCIe controller |
diff --git a/Documentation/ABI/testing/dev-kmsg b/Documentation/ABI/testing/dev-kmsg index bb820be48179..fff817efa508 100644 --- a/Documentation/ABI/testing/dev-kmsg +++ b/Documentation/ABI/testing/dev-kmsg | |||
@@ -98,4 +98,13 @@ Description: The /dev/kmsg character device node provides userspace access | |||
98 | logic is used internally when messages are printed to the | 98 | logic is used internally when messages are printed to the |
99 | console, /proc/kmsg or the syslog() syscall. | 99 | console, /proc/kmsg or the syslog() syscall. |
100 | 100 | ||
101 | By default, kernel tries to avoid fragments by concatenating | ||
102 | when it can and fragments are rare; however, when extended | ||
103 | console support is enabled, the in-kernel concatenation is | ||
104 | disabled and /dev/kmsg output will contain more fragments. If | ||
105 | the log consumer performs concatenation, the end result | ||
106 | should be the same. In the future, the in-kernel concatenation | ||
107 | may be removed entirely and /dev/kmsg users are recommended to | ||
108 | implement fragment handling. | ||
109 | |||
101 | Users: dmesg(1), userspace kernel log consumers | 110 | Users: dmesg(1), userspace kernel log consumers |
diff --git a/Documentation/ABI/testing/sysfs-bus-usb-lvstest b/Documentation/ABI/testing/sysfs-bus-usb-lvstest index aae68fc2d842..5151290cf8e7 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb-lvstest +++ b/Documentation/ABI/testing/sysfs-bus-usb-lvstest | |||
@@ -4,14 +4,14 @@ driver is bound with root hub device. | |||
4 | 4 | ||
5 | What: /sys/bus/usb/devices/.../get_dev_desc | 5 | What: /sys/bus/usb/devices/.../get_dev_desc |
6 | Date: March 2014 | 6 | Date: March 2014 |
7 | Contact: Pratyush Anand <pratyush.anand@st.com> | 7 | Contact: Pratyush Anand <pratyush.anand@gmail.com> |
8 | Description: | 8 | Description: |
9 | Write to this node to issue "Get Device Descriptor" | 9 | Write to this node to issue "Get Device Descriptor" |
10 | for Link Layer Validation device. It is needed for TD.7.06. | 10 | for Link Layer Validation device. It is needed for TD.7.06. |
11 | 11 | ||
12 | What: /sys/bus/usb/devices/.../u1_timeout | 12 | What: /sys/bus/usb/devices/.../u1_timeout |
13 | Date: March 2014 | 13 | Date: March 2014 |
14 | Contact: Pratyush Anand <pratyush.anand@st.com> | 14 | Contact: Pratyush Anand <pratyush.anand@gmail.com> |
15 | Description: | 15 | Description: |
16 | Set "U1 timeout" for the downstream port where Link Layer | 16 | Set "U1 timeout" for the downstream port where Link Layer |
17 | Validation device is connected. Timeout value must be between 0 | 17 | Validation device is connected. Timeout value must be between 0 |
@@ -19,7 +19,7 @@ Description: | |||
19 | 19 | ||
20 | What: /sys/bus/usb/devices/.../u2_timeout | 20 | What: /sys/bus/usb/devices/.../u2_timeout |
21 | Date: March 2014 | 21 | Date: March 2014 |
22 | Contact: Pratyush Anand <pratyush.anand@st.com> | 22 | Contact: Pratyush Anand <pratyush.anand@gmail.com> |
23 | Description: | 23 | Description: |
24 | Set "U2 timeout" for the downstream port where Link Layer | 24 | Set "U2 timeout" for the downstream port where Link Layer |
25 | Validation device is connected. Timeout value must be between 0 | 25 | Validation device is connected. Timeout value must be between 0 |
@@ -27,21 +27,21 @@ Description: | |||
27 | 27 | ||
28 | What: /sys/bus/usb/devices/.../hot_reset | 28 | What: /sys/bus/usb/devices/.../hot_reset |
29 | Date: March 2014 | 29 | Date: March 2014 |
30 | Contact: Pratyush Anand <pratyush.anand@st.com> | 30 | Contact: Pratyush Anand <pratyush.anand@gmail.com> |
31 | Description: | 31 | Description: |
32 | Write to this node to issue "Reset" for Link Layer Validation | 32 | Write to this node to issue "Reset" for Link Layer Validation |
33 | device. It is needed for TD.7.29, TD.7.31, TD.7.34 and TD.7.35. | 33 | device. It is needed for TD.7.29, TD.7.31, TD.7.34 and TD.7.35. |
34 | 34 | ||
35 | What: /sys/bus/usb/devices/.../u3_entry | 35 | What: /sys/bus/usb/devices/.../u3_entry |
36 | Date: March 2014 | 36 | Date: March 2014 |
37 | Contact: Pratyush Anand <pratyush.anand@st.com> | 37 | Contact: Pratyush Anand <pratyush.anand@gmail.com> |
38 | Description: | 38 | Description: |
39 | Write to this node to issue "U3 entry" for Link Layer | 39 | Write to this node to issue "U3 entry" for Link Layer |
40 | Validation device. It is needed for TD.7.35 and TD.7.36. | 40 | Validation device. It is needed for TD.7.35 and TD.7.36. |
41 | 41 | ||
42 | What: /sys/bus/usb/devices/.../u3_exit | 42 | What: /sys/bus/usb/devices/.../u3_exit |
43 | Date: March 2014 | 43 | Date: March 2014 |
44 | Contact: Pratyush Anand <pratyush.anand@st.com> | 44 | Contact: Pratyush Anand <pratyush.anand@gmail.com> |
45 | Description: | 45 | Description: |
46 | Write to this node to issue "U3 exit" for Link Layer | 46 | Write to this node to issue "U3 exit" for Link Layer |
47 | Validation device. It is needed for TD.7.36. | 47 | Validation device. It is needed for TD.7.36. |
diff --git a/Documentation/ABI/testing/sysfs-class-zram b/Documentation/ABI/testing/sysfs-class-zram new file mode 100644 index 000000000000..48ddacbe0e69 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-zram | |||
@@ -0,0 +1,24 @@ | |||
1 | What: /sys/class/zram-control/ | ||
2 | Date: August 2015 | ||
3 | KernelVersion: 4.2 | ||
4 | Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> | ||
5 | Description: | ||
6 | The zram-control/ class sub-directory belongs to zram | ||
7 | device class | ||
8 | |||
9 | What: /sys/class/zram-control/hot_add | ||
10 | Date: August 2015 | ||
11 | KernelVersion: 4.2 | ||
12 | Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> | ||
13 | Description: | ||
14 | RO attribute. Read operation will cause zram to add a new | ||
15 | device and return its device id back to user (so one can | ||
16 | use /dev/zram<id>), or error code. | ||
17 | |||
18 | What: /sys/class/zram-control/hot_remove | ||
19 | Date: August 2015 | ||
20 | KernelVersion: 4.2 | ||
21 | Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> | ||
22 | Description: | ||
23 | WO attribute. Remove a specific /dev/zramX device, where X | ||
24 | is a device_id provided by user. | ||
diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt index 48a183e29988..c4de576093af 100644 --- a/Documentation/blockdev/zram.txt +++ b/Documentation/blockdev/zram.txt | |||
@@ -19,7 +19,9 @@ Following shows a typical sequence of steps for using zram. | |||
19 | 1) Load Module: | 19 | 1) Load Module: |
20 | modprobe zram num_devices=4 | 20 | modprobe zram num_devices=4 |
21 | This creates 4 devices: /dev/zram{0,1,2,3} | 21 | This creates 4 devices: /dev/zram{0,1,2,3} |
22 | (num_devices parameter is optional. Default: 1) | 22 | |
23 | num_devices parameter is optional and tells zram how many devices should be | ||
24 | pre-created. Default: 1. | ||
23 | 25 | ||
24 | 2) Set max number of compression streams | 26 | 2) Set max number of compression streams |
25 | Compression backend may use up to max_comp_streams compression streams, | 27 | Compression backend may use up to max_comp_streams compression streams, |
@@ -97,7 +99,24 @@ size of the disk when not in use so a huge zram is wasteful. | |||
97 | mkfs.ext4 /dev/zram1 | 99 | mkfs.ext4 /dev/zram1 |
98 | mount /dev/zram1 /tmp | 100 | mount /dev/zram1 /tmp |
99 | 101 | ||
100 | 7) Stats: | 102 | 7) Add/remove zram devices |
103 | |||
104 | zram provides a control interface, which enables dynamic (on-demand) device | ||
105 | addition and removal. | ||
106 | |||
107 | In order to add a new /dev/zramX device, perform read operation on hot_add | ||
108 | attribute. This will return either new device's device id (meaning that you | ||
109 | can use /dev/zram<id>) or error code. | ||
110 | |||
111 | Example: | ||
112 | cat /sys/class/zram-control/hot_add | ||
113 | 1 | ||
114 | |||
115 | To remove the existing /dev/zramX device (where X is a device id) | ||
116 | execute | ||
117 | echo X > /sys/class/zram-control/hot_remove | ||
118 | |||
119 | 8) Stats: | ||
101 | Per-device statistics are exported as various nodes under /sys/block/zram<id>/ | 120 | Per-device statistics are exported as various nodes under /sys/block/zram<id>/ |
102 | 121 | ||
103 | A brief description of exported device attritbutes. For more details please | 122 | A brief description of exported device attritbutes. For more details please |
@@ -126,7 +145,7 @@ mem_used_max RW the maximum amount memory zram have consumed to | |||
126 | mem_limit RW the maximum amount of memory ZRAM can use to store | 145 | mem_limit RW the maximum amount of memory ZRAM can use to store |
127 | the compressed data | 146 | the compressed data |
128 | num_migrated RO the number of objects migrated migrated by compaction | 147 | num_migrated RO the number of objects migrated migrated by compaction |
129 | 148 | compact WO trigger memory compaction | |
130 | 149 | ||
131 | WARNING | 150 | WARNING |
132 | ======= | 151 | ======= |
@@ -172,11 +191,11 @@ line of text and contains the following stats separated by whitespace: | |||
172 | zero_pages | 191 | zero_pages |
173 | num_migrated | 192 | num_migrated |
174 | 193 | ||
175 | 8) Deactivate: | 194 | 9) Deactivate: |
176 | swapoff /dev/zram0 | 195 | swapoff /dev/zram0 |
177 | umount /dev/zram1 | 196 | umount /dev/zram1 |
178 | 197 | ||
179 | 9) Reset: | 198 | 10) Reset: |
180 | Write any positive value to 'reset' sysfs node | 199 | Write any positive value to 'reset' sysfs node |
181 | echo 1 > /sys/block/zram0/reset | 200 | echo 1 > /sys/block/zram0/reset |
182 | echo 1 > /sys/block/zram1/reset | 201 | echo 1 > /sys/block/zram1/reset |
diff --git a/Documentation/misc-devices/spear-pcie-gadget.txt b/Documentation/misc-devices/spear-pcie-gadget.txt index 02c13ef5e908..89b88dee4143 100644 --- a/Documentation/misc-devices/spear-pcie-gadget.txt +++ b/Documentation/misc-devices/spear-pcie-gadget.txt | |||
@@ -2,7 +2,7 @@ Spear PCIe Gadget Driver: | |||
2 | 2 | ||
3 | Author | 3 | Author |
4 | ============= | 4 | ============= |
5 | Pratyush Anand (pratyush.anand@st.com) | 5 | Pratyush Anand (pratyush.anand@gmail.com) |
6 | 6 | ||
7 | Location | 7 | Location |
8 | ============ | 8 | ============ |
diff --git a/Documentation/networking/netconsole.txt b/Documentation/networking/netconsole.txt index a5d574a9ae09..30409a36e95d 100644 --- a/Documentation/networking/netconsole.txt +++ b/Documentation/networking/netconsole.txt | |||
@@ -2,6 +2,7 @@ | |||
2 | started by Ingo Molnar <mingo@redhat.com>, 2001.09.17 | 2 | started by Ingo Molnar <mingo@redhat.com>, 2001.09.17 |
3 | 2.6 port and netpoll api by Matt Mackall <mpm@selenic.com>, Sep 9 2003 | 3 | 2.6 port and netpoll api by Matt Mackall <mpm@selenic.com>, Sep 9 2003 |
4 | IPv6 support by Cong Wang <xiyou.wangcong@gmail.com>, Jan 1 2013 | 4 | IPv6 support by Cong Wang <xiyou.wangcong@gmail.com>, Jan 1 2013 |
5 | Extended console support by Tejun Heo <tj@kernel.org>, May 1 2015 | ||
5 | 6 | ||
6 | Please send bug reports to Matt Mackall <mpm@selenic.com> | 7 | Please send bug reports to Matt Mackall <mpm@selenic.com> |
7 | Satyam Sharma <satyam.sharma@gmail.com>, and Cong Wang <xiyou.wangcong@gmail.com> | 8 | Satyam Sharma <satyam.sharma@gmail.com>, and Cong Wang <xiyou.wangcong@gmail.com> |
@@ -24,9 +25,10 @@ Sender and receiver configuration: | |||
24 | It takes a string configuration parameter "netconsole" in the | 25 | It takes a string configuration parameter "netconsole" in the |
25 | following format: | 26 | following format: |
26 | 27 | ||
27 | netconsole=[src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr] | 28 | netconsole=[+][src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr] |
28 | 29 | ||
29 | where | 30 | where |
31 | + if present, enable extended console support | ||
30 | src-port source for UDP packets (defaults to 6665) | 32 | src-port source for UDP packets (defaults to 6665) |
31 | src-ip source IP to use (interface address) | 33 | src-ip source IP to use (interface address) |
32 | dev network interface (eth0) | 34 | dev network interface (eth0) |
@@ -107,6 +109,7 @@ To remove a target: | |||
107 | The interface exposes these parameters of a netconsole target to userspace: | 109 | The interface exposes these parameters of a netconsole target to userspace: |
108 | 110 | ||
109 | enabled Is this target currently enabled? (read-write) | 111 | enabled Is this target currently enabled? (read-write) |
112 | extended Extended mode enabled (read-write) | ||
110 | dev_name Local network interface name (read-write) | 113 | dev_name Local network interface name (read-write) |
111 | local_port Source UDP port to use (read-write) | 114 | local_port Source UDP port to use (read-write) |
112 | remote_port Remote agent's UDP port (read-write) | 115 | remote_port Remote agent's UDP port (read-write) |
@@ -132,6 +135,36 @@ You can also update the local interface dynamically. This is especially | |||
132 | useful if you want to use interfaces that have newly come up (and may not | 135 | useful if you want to use interfaces that have newly come up (and may not |
133 | have existed when netconsole was loaded / initialized). | 136 | have existed when netconsole was loaded / initialized). |
134 | 137 | ||
138 | Extended console: | ||
139 | ================= | ||
140 | |||
141 | If '+' is prefixed to the configuration line or "extended" config file | ||
142 | is set to 1, extended console support is enabled. An example boot | ||
143 | param follows. | ||
144 | |||
145 | linux netconsole=+4444@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc | ||
146 | |||
147 | Log messages are transmitted with extended metadata header in the | ||
148 | following format which is the same as /dev/kmsg. | ||
149 | |||
150 | <level>,<sequnum>,<timestamp>,<contflag>;<message text> | ||
151 | |||
152 | Non printable characters in <message text> are escaped using "\xff" | ||
153 | notation. If the message contains optional dictionary, verbatim | ||
154 | newline is used as the delimeter. | ||
155 | |||
156 | If a message doesn't fit in certain number of bytes (currently 1000), | ||
157 | the message is split into multiple fragments by netconsole. These | ||
158 | fragments are transmitted with "ncfrag" header field added. | ||
159 | |||
160 | ncfrag=<byte-offset>/<total-bytes> | ||
161 | |||
162 | For example, assuming a lot smaller chunk size, a message "the first | ||
163 | chunk, the 2nd chunk." may be split as follows. | ||
164 | |||
165 | 6,416,1758426,-,ncfrag=0/31;the first chunk, | ||
166 | 6,416,1758426,-,ncfrag=16/31; the 2nd chunk. | ||
167 | |||
135 | Miscellaneous notes: | 168 | Miscellaneous notes: |
136 | ==================== | 169 | ==================== |
137 | 170 | ||
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index e5d528e0c46e..6fccb69c03e7 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt | |||
@@ -197,8 +197,8 @@ core_pattern is used to specify a core dumpfile pattern name. | |||
197 | %P global pid (init PID namespace) | 197 | %P global pid (init PID namespace) |
198 | %i tid | 198 | %i tid |
199 | %I global tid (init PID namespace) | 199 | %I global tid (init PID namespace) |
200 | %u uid | 200 | %u uid (in initial user namespace) |
201 | %g gid | 201 | %g gid (in initial user namespace) |
202 | %d dump mode, matches PR_SET_DUMPABLE and | 202 | %d dump mode, matches PR_SET_DUMPABLE and |
203 | /proc/sys/fs/suid_dumpable | 203 | /proc/sys/fs/suid_dumpable |
204 | %s signal number | 204 | %s signal number |
diff --git a/Documentation/vm/zswap.txt b/Documentation/vm/zswap.txt index 00c3d31e7971..8458c0861e4e 100644 --- a/Documentation/vm/zswap.txt +++ b/Documentation/vm/zswap.txt | |||
@@ -26,8 +26,22 @@ Zswap evicts pages from compressed cache on an LRU basis to the backing swap | |||
26 | device when the compressed pool reaches its size limit. This requirement had | 26 | device when the compressed pool reaches its size limit. This requirement had |
27 | been identified in prior community discussions. | 27 | been identified in prior community discussions. |
28 | 28 | ||
29 | To enabled zswap, the "enabled" attribute must be set to 1 at boot time. e.g. | 29 | Zswap is disabled by default but can be enabled at boot time by setting |
30 | zswap.enabled=1 | 30 | the "enabled" attribute to 1 at boot time. ie: zswap.enabled=1. Zswap |
31 | can also be enabled and disabled at runtime using the sysfs interface. | ||
32 | An example command to enable zswap at runtime, assuming sysfs is mounted | ||
33 | at /sys, is: | ||
34 | |||
35 | echo 1 > /sys/modules/zswap/parameters/enabled | ||
36 | |||
37 | When zswap is disabled at runtime it will stop storing pages that are | ||
38 | being swapped out. However, it will _not_ immediately write out or fault | ||
39 | back into memory all of the pages stored in the compressed pool. The | ||
40 | pages stored in zswap will remain in the compressed pool until they are | ||
41 | either invalidated or faulted back into memory. In order to force all | ||
42 | pages out of the compressed pool, a swapoff on the swap device(s) will | ||
43 | fault back into memory all swapped out pages, including those in the | ||
44 | compressed pool. | ||
31 | 45 | ||
32 | Design: | 46 | Design: |
33 | 47 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index a01df3088b01..5f2956c24a9c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -259,7 +259,7 @@ S: Maintained | |||
259 | F: drivers/platform/x86/acer-wmi.c | 259 | F: drivers/platform/x86/acer-wmi.c |
260 | 260 | ||
261 | ACPI | 261 | ACPI |
262 | M: Rafael J. Wysocki <rjw@rjwysocki.net> | 262 | M: "Rafael J. Wysocki" <rjw@rjwysocki.net> |
263 | M: Len Brown <lenb@kernel.org> | 263 | M: Len Brown <lenb@kernel.org> |
264 | L: linux-acpi@vger.kernel.org | 264 | L: linux-acpi@vger.kernel.org |
265 | W: https://01.org/linux-acpi | 265 | W: https://01.org/linux-acpi |
@@ -280,7 +280,7 @@ F: tools/power/acpi/ | |||
280 | ACPI COMPONENT ARCHITECTURE (ACPICA) | 280 | ACPI COMPONENT ARCHITECTURE (ACPICA) |
281 | M: Robert Moore <robert.moore@intel.com> | 281 | M: Robert Moore <robert.moore@intel.com> |
282 | M: Lv Zheng <lv.zheng@intel.com> | 282 | M: Lv Zheng <lv.zheng@intel.com> |
283 | M: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 283 | M: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> |
284 | L: linux-acpi@vger.kernel.org | 284 | L: linux-acpi@vger.kernel.org |
285 | L: devel@acpica.org | 285 | L: devel@acpica.org |
286 | W: https://acpica.org/ | 286 | W: https://acpica.org/ |
@@ -2515,7 +2515,7 @@ F: arch/powerpc/oprofile/*cell* | |||
2515 | F: arch/powerpc/platforms/cell/ | 2515 | F: arch/powerpc/platforms/cell/ |
2516 | 2516 | ||
2517 | CEPH DISTRIBUTED FILE SYSTEM CLIENT | 2517 | CEPH DISTRIBUTED FILE SYSTEM CLIENT |
2518 | M: Yan, Zheng <zyan@redhat.com> | 2518 | M: "Yan, Zheng" <zyan@redhat.com> |
2519 | M: Sage Weil <sage@redhat.com> | 2519 | M: Sage Weil <sage@redhat.com> |
2520 | L: ceph-devel@vger.kernel.org | 2520 | L: ceph-devel@vger.kernel.org |
2521 | W: http://ceph.com/ | 2521 | W: http://ceph.com/ |
@@ -2829,7 +2829,7 @@ S: Maintained | |||
2829 | F: drivers/net/ethernet/ti/cpmac.c | 2829 | F: drivers/net/ethernet/ti/cpmac.c |
2830 | 2830 | ||
2831 | CPU FREQUENCY DRIVERS | 2831 | CPU FREQUENCY DRIVERS |
2832 | M: Rafael J. Wysocki <rjw@rjwysocki.net> | 2832 | M: "Rafael J. Wysocki" <rjw@rjwysocki.net> |
2833 | M: Viresh Kumar <viresh.kumar@linaro.org> | 2833 | M: Viresh Kumar <viresh.kumar@linaro.org> |
2834 | L: linux-pm@vger.kernel.org | 2834 | L: linux-pm@vger.kernel.org |
2835 | S: Maintained | 2835 | S: Maintained |
@@ -2868,7 +2868,7 @@ F: drivers/cpuidle/cpuidle-exynos.c | |||
2868 | F: arch/arm/mach-exynos/pm.c | 2868 | F: arch/arm/mach-exynos/pm.c |
2869 | 2869 | ||
2870 | CPUIDLE DRIVERS | 2870 | CPUIDLE DRIVERS |
2871 | M: Rafael J. Wysocki <rjw@rjwysocki.net> | 2871 | M: "Rafael J. Wysocki" <rjw@rjwysocki.net> |
2872 | M: Daniel Lezcano <daniel.lezcano@linaro.org> | 2872 | M: Daniel Lezcano <daniel.lezcano@linaro.org> |
2873 | L: linux-pm@vger.kernel.org | 2873 | L: linux-pm@vger.kernel.org |
2874 | S: Maintained | 2874 | S: Maintained |
@@ -4103,7 +4103,7 @@ F: include/uapi/scsi/fc/ | |||
4103 | 4103 | ||
4104 | FILE LOCKING (flock() and fcntl()/lockf()) | 4104 | FILE LOCKING (flock() and fcntl()/lockf()) |
4105 | M: Jeff Layton <jlayton@poochiereds.net> | 4105 | M: Jeff Layton <jlayton@poochiereds.net> |
4106 | M: J. Bruce Fields <bfields@fieldses.org> | 4106 | M: "J. Bruce Fields" <bfields@fieldses.org> |
4107 | L: linux-fsdevel@vger.kernel.org | 4107 | L: linux-fsdevel@vger.kernel.org |
4108 | S: Maintained | 4108 | S: Maintained |
4109 | F: include/linux/fcntl.h | 4109 | F: include/linux/fcntl.h |
@@ -4299,7 +4299,7 @@ F: sound/soc/fsl/imx* | |||
4299 | F: sound/soc/fsl/mpc8610_hpcd.c | 4299 | F: sound/soc/fsl/mpc8610_hpcd.c |
4300 | 4300 | ||
4301 | FREESCALE QORIQ MANAGEMENT COMPLEX DRIVER | 4301 | FREESCALE QORIQ MANAGEMENT COMPLEX DRIVER |
4302 | M: J. German Rivera <German.Rivera@freescale.com> | 4302 | M: "J. German Rivera" <German.Rivera@freescale.com> |
4303 | L: linux-kernel@vger.kernel.org | 4303 | L: linux-kernel@vger.kernel.org |
4304 | S: Maintained | 4304 | S: Maintained |
4305 | F: drivers/staging/fsl-mc/ | 4305 | F: drivers/staging/fsl-mc/ |
@@ -4581,7 +4581,7 @@ S: Maintained | |||
4581 | F: drivers/media/usb/gspca/ | 4581 | F: drivers/media/usb/gspca/ |
4582 | 4582 | ||
4583 | GUID PARTITION TABLE (GPT) | 4583 | GUID PARTITION TABLE (GPT) |
4584 | M: Davidlohr Bueso <davidlohr@hp.com> | 4584 | M: Davidlohr Bueso <dave@stgolabs.net> |
4585 | L: linux-efi@vger.kernel.org | 4585 | L: linux-efi@vger.kernel.org |
4586 | S: Maintained | 4586 | S: Maintained |
4587 | F: block/partitions/efi.* | 4587 | F: block/partitions/efi.* |
@@ -4871,7 +4871,7 @@ S: Maintained | |||
4871 | F: fs/hugetlbfs/ | 4871 | F: fs/hugetlbfs/ |
4872 | 4872 | ||
4873 | Hyper-V CORE AND DRIVERS | 4873 | Hyper-V CORE AND DRIVERS |
4874 | M: K. Y. Srinivasan <kys@microsoft.com> | 4874 | M: "K. Y. Srinivasan" <kys@microsoft.com> |
4875 | M: Haiyang Zhang <haiyangz@microsoft.com> | 4875 | M: Haiyang Zhang <haiyangz@microsoft.com> |
4876 | L: devel@linuxdriverproject.org | 4876 | L: devel@linuxdriverproject.org |
4877 | S: Maintained | 4877 | S: Maintained |
@@ -5233,7 +5233,7 @@ K: \b(ABS|SYN)_MT_ | |||
5233 | 5233 | ||
5234 | INTEL ASoC BDW/HSW DRIVERS | 5234 | INTEL ASoC BDW/HSW DRIVERS |
5235 | M: Jie Yang <yang.jie@linux.intel.com> | 5235 | M: Jie Yang <yang.jie@linux.intel.com> |
5236 | L: alsa-devel@alsa-project.org | 5236 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
5237 | S: Supported | 5237 | S: Supported |
5238 | F: sound/soc/intel/sst-haswell* | 5238 | F: sound/soc/intel/sst-haswell* |
5239 | F: sound/soc/intel/sst-dsp* | 5239 | F: sound/soc/intel/sst-dsp* |
@@ -6825,7 +6825,7 @@ F: drivers/net/ethernet/natsemi/natsemi.c | |||
6825 | NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER | 6825 | NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER |
6826 | M: Daniel Mack <zonque@gmail.com> | 6826 | M: Daniel Mack <zonque@gmail.com> |
6827 | S: Maintained | 6827 | S: Maintained |
6828 | L: alsa-devel@alsa-project.org | 6828 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
6829 | W: http://www.native-instruments.com | 6829 | W: http://www.native-instruments.com |
6830 | F: sound/usb/caiaq/ | 6830 | F: sound/usb/caiaq/ |
6831 | 6831 | ||
@@ -7243,7 +7243,7 @@ F: arch/arm/mach-omap2/prm* | |||
7243 | OMAP AUDIO SUPPORT | 7243 | OMAP AUDIO SUPPORT |
7244 | M: Peter Ujfalusi <peter.ujfalusi@ti.com> | 7244 | M: Peter Ujfalusi <peter.ujfalusi@ti.com> |
7245 | M: Jarkko Nikula <jarkko.nikula@bitmer.com> | 7245 | M: Jarkko Nikula <jarkko.nikula@bitmer.com> |
7246 | L: alsa-devel@alsa-project.org (subscribers-only) | 7246 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
7247 | L: linux-omap@vger.kernel.org | 7247 | L: linux-omap@vger.kernel.org |
7248 | S: Maintained | 7248 | S: Maintained |
7249 | F: sound/soc/omap/ | 7249 | F: sound/soc/omap/ |
@@ -7945,7 +7945,7 @@ F: include/linux/power_supply.h | |||
7945 | F: drivers/power/ | 7945 | F: drivers/power/ |
7946 | 7946 | ||
7947 | PNP SUPPORT | 7947 | PNP SUPPORT |
7948 | M: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 7948 | M: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> |
7949 | S: Maintained | 7949 | S: Maintained |
7950 | F: drivers/pnp/ | 7950 | F: drivers/pnp/ |
7951 | 7951 | ||
@@ -8951,7 +8951,7 @@ F: drivers/mmc/host/sdhci-spear.c | |||
8951 | 8951 | ||
8952 | SECURITY SUBSYSTEM | 8952 | SECURITY SUBSYSTEM |
8953 | M: James Morris <james.l.morris@oracle.com> | 8953 | M: James Morris <james.l.morris@oracle.com> |
8954 | M: Serge E. Hallyn <serge@hallyn.com> | 8954 | M: "Serge E. Hallyn" <serge@hallyn.com> |
8955 | L: linux-security-module@vger.kernel.org (suggested Cc:) | 8955 | L: linux-security-module@vger.kernel.org (suggested Cc:) |
8956 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git | 8956 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git |
8957 | W: http://kernsec.org/ | 8957 | W: http://kernsec.org/ |
@@ -9171,7 +9171,7 @@ F: arch/arm/mach-davinci/ | |||
9171 | F: drivers/i2c/busses/i2c-davinci.c | 9171 | F: drivers/i2c/busses/i2c-davinci.c |
9172 | 9172 | ||
9173 | TI DAVINCI SERIES MEDIA DRIVER | 9173 | TI DAVINCI SERIES MEDIA DRIVER |
9174 | M: Lad, Prabhakar <prabhakar.csengg@gmail.com> | 9174 | M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com> |
9175 | L: linux-media@vger.kernel.org | 9175 | L: linux-media@vger.kernel.org |
9176 | W: http://linuxtv.org/ | 9176 | W: http://linuxtv.org/ |
9177 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ | 9177 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
@@ -9181,7 +9181,7 @@ F: drivers/media/platform/davinci/ | |||
9181 | F: include/media/davinci/ | 9181 | F: include/media/davinci/ |
9182 | 9182 | ||
9183 | TI AM437X VPFE DRIVER | 9183 | TI AM437X VPFE DRIVER |
9184 | M: Lad, Prabhakar <prabhakar.csengg@gmail.com> | 9184 | M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com> |
9185 | L: linux-media@vger.kernel.org | 9185 | L: linux-media@vger.kernel.org |
9186 | W: http://linuxtv.org/ | 9186 | W: http://linuxtv.org/ |
9187 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ | 9187 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
@@ -9190,7 +9190,7 @@ S: Maintained | |||
9190 | F: drivers/media/platform/am437x/ | 9190 | F: drivers/media/platform/am437x/ |
9191 | 9191 | ||
9192 | OV2659 OMNIVISION SENSOR DRIVER | 9192 | OV2659 OMNIVISION SENSOR DRIVER |
9193 | M: Lad, Prabhakar <prabhakar.csengg@gmail.com> | 9193 | M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com> |
9194 | L: linux-media@vger.kernel.org | 9194 | L: linux-media@vger.kernel.org |
9195 | W: http://linuxtv.org/ | 9195 | W: http://linuxtv.org/ |
9196 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ | 9196 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
@@ -9755,7 +9755,7 @@ F: fs/sysv/ | |||
9755 | F: include/linux/sysv_fs.h | 9755 | F: include/linux/sysv_fs.h |
9756 | 9756 | ||
9757 | TARGET SUBSYSTEM | 9757 | TARGET SUBSYSTEM |
9758 | M: Nicholas A. Bellinger <nab@linux-iscsi.org> | 9758 | M: "Nicholas A. Bellinger" <nab@linux-iscsi.org> |
9759 | L: linux-scsi@vger.kernel.org | 9759 | L: linux-scsi@vger.kernel.org |
9760 | L: target-devel@vger.kernel.org | 9760 | L: target-devel@vger.kernel.org |
9761 | W: http://www.linux-iscsi.org | 9761 | W: http://www.linux-iscsi.org |
@@ -9897,7 +9897,7 @@ F: include/linux/if_team.h | |||
9897 | F: include/uapi/linux/if_team.h | 9897 | F: include/uapi/linux/if_team.h |
9898 | 9898 | ||
9899 | TECHNOLOGIC SYSTEMS TS-5500 PLATFORM SUPPORT | 9899 | TECHNOLOGIC SYSTEMS TS-5500 PLATFORM SUPPORT |
9900 | M: Savoir-faire Linux Inc. <kernel@savoirfairelinux.com> | 9900 | M: "Savoir-faire Linux Inc." <kernel@savoirfairelinux.com> |
9901 | S: Maintained | 9901 | S: Maintained |
9902 | F: arch/x86/platform/ts5500/ | 9902 | F: arch/x86/platform/ts5500/ |
9903 | 9903 | ||
diff --git a/arch/Kconfig b/arch/Kconfig index a65eafb24997..bec6666a3cc4 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -499,6 +499,13 @@ config ARCH_HAS_ELF_RANDOMIZE | |||
499 | - arch_mmap_rnd() | 499 | - arch_mmap_rnd() |
500 | - arch_randomize_brk() | 500 | - arch_randomize_brk() |
501 | 501 | ||
502 | config HAVE_COPY_THREAD_TLS | ||
503 | bool | ||
504 | help | ||
505 | Architecture provides copy_thread_tls to accept tls argument via | ||
506 | normal C parameter passing, rather than extracting the syscall | ||
507 | argument from pt_regs. | ||
508 | |||
502 | # | 509 | # |
503 | # ABI hall of shame | 510 | # ABI hall of shame |
504 | # | 511 | # |
diff --git a/arch/arm/include/asm/hugetlb.h b/arch/arm/include/asm/hugetlb.h index 31bb7dccb971..7d26f6c4f0f5 100644 --- a/arch/arm/include/asm/hugetlb.h +++ b/arch/arm/include/asm/hugetlb.h | |||
@@ -63,15 +63,6 @@ static inline pte_t huge_pte_wrprotect(pte_t pte) | |||
63 | return pte_wrprotect(pte); | 63 | return pte_wrprotect(pte); |
64 | } | 64 | } |
65 | 65 | ||
66 | static inline int arch_prepare_hugepage(struct page *page) | ||
67 | { | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static inline void arch_release_hugepage(struct page *page) | ||
72 | { | ||
73 | } | ||
74 | |||
75 | static inline void arch_clear_hugepage_flags(struct page *page) | 66 | static inline void arch_clear_hugepage_flags(struct page *page) |
76 | { | 67 | { |
77 | clear_bit(PG_dcache_clean, &page->flags); | 68 | clear_bit(PG_dcache_clean, &page->flags); |
diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h index 734c17e89e94..2fd9b14ca295 100644 --- a/arch/arm64/include/asm/hugetlb.h +++ b/arch/arm64/include/asm/hugetlb.h | |||
@@ -96,15 +96,6 @@ static inline pte_t huge_pte_wrprotect(pte_t pte) | |||
96 | return pte_wrprotect(pte); | 96 | return pte_wrprotect(pte); |
97 | } | 97 | } |
98 | 98 | ||
99 | static inline int arch_prepare_hugepage(struct page *page) | ||
100 | { | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static inline void arch_release_hugepage(struct page *page) | ||
105 | { | ||
106 | } | ||
107 | |||
108 | static inline void arch_clear_hugepage_flags(struct page *page) | 99 | static inline void arch_clear_hugepage_flags(struct page *page) |
109 | { | 100 | { |
110 | clear_bit(PG_dcache_clean, &page->flags); | 101 | clear_bit(PG_dcache_clean, &page->flags); |
diff --git a/arch/avr32/include/asm/dma-mapping.h b/arch/avr32/include/asm/dma-mapping.h index b3d18f9f3e8d..ae7ac9205d20 100644 --- a/arch/avr32/include/asm/dma-mapping.h +++ b/arch/avr32/include/asm/dma-mapping.h | |||
@@ -209,17 +209,18 @@ dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, | |||
209 | * the same here. | 209 | * the same here. |
210 | */ | 210 | */ |
211 | static inline int | 211 | static inline int |
212 | dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | 212 | dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents, |
213 | enum dma_data_direction direction) | 213 | enum dma_data_direction direction) |
214 | { | 214 | { |
215 | int i; | 215 | int i; |
216 | struct scatterlist *sg; | ||
216 | 217 | ||
217 | for (i = 0; i < nents; i++) { | 218 | for_each_sg(sglist, sg, nents, i) { |
218 | char *virt; | 219 | char *virt; |
219 | 220 | ||
220 | sg[i].dma_address = page_to_bus(sg_page(&sg[i])) + sg[i].offset; | 221 | sg->dma_address = page_to_bus(sg_page(sg)) + sg->offset; |
221 | virt = sg_virt(&sg[i]); | 222 | virt = sg_virt(sg); |
222 | dma_cache_sync(dev, virt, sg[i].length, direction); | 223 | dma_cache_sync(dev, virt, sg->length, direction); |
223 | } | 224 | } |
224 | 225 | ||
225 | return nents; | 226 | return nents; |
@@ -321,14 +322,14 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, | |||
321 | } | 322 | } |
322 | 323 | ||
323 | static inline void | 324 | static inline void |
324 | dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, | 325 | dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist, |
325 | int nents, enum dma_data_direction direction) | 326 | int nents, enum dma_data_direction direction) |
326 | { | 327 | { |
327 | int i; | 328 | int i; |
329 | struct scatterlist *sg; | ||
328 | 330 | ||
329 | for (i = 0; i < nents; i++) { | 331 | for_each_sg(sglist, sg, nents, i) |
330 | dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, direction); | 332 | dma_cache_sync(dev, sg_virt(sg), sg->length, direction); |
331 | } | ||
332 | } | 333 | } |
333 | 334 | ||
334 | /* Now for the API extensions over the pci_ one */ | 335 | /* Now for the API extensions over the pci_ one */ |
diff --git a/arch/frv/include/asm/sections.h b/arch/frv/include/asm/sections.h index 17d0fb171bba..d03fb64e93e9 100644 --- a/arch/frv/include/asm/sections.h +++ b/arch/frv/include/asm/sections.h | |||
@@ -35,12 +35,6 @@ extern unsigned long __nongprelbss memory_start; | |||
35 | extern unsigned long __nongprelbss memory_end; | 35 | extern unsigned long __nongprelbss memory_end; |
36 | extern unsigned long __nongprelbss rom_length; | 36 | extern unsigned long __nongprelbss rom_length; |
37 | 37 | ||
38 | /* determine if we're running from ROM */ | ||
39 | static inline int is_in_rom(unsigned long addr) | ||
40 | { | ||
41 | return 0; /* default case: not in ROM */ | ||
42 | } | ||
43 | |||
44 | #endif | 38 | #endif |
45 | #endif | 39 | #endif |
46 | #endif /* _ASM_SECTIONS_H */ | 40 | #endif /* _ASM_SECTIONS_H */ |
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c index b99c2a7cc7a4..8eeea0d77aad 100644 --- a/arch/frv/mb93090-mb00/pci-dma-nommu.c +++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c | |||
@@ -119,14 +119,16 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, | |||
119 | 119 | ||
120 | EXPORT_SYMBOL(dma_map_single); | 120 | EXPORT_SYMBOL(dma_map_single); |
121 | 121 | ||
122 | int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | 122 | int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents, |
123 | enum dma_data_direction direction) | 123 | enum dma_data_direction direction) |
124 | { | 124 | { |
125 | int i; | 125 | int i; |
126 | struct scatterlist *sg; | ||
126 | 127 | ||
127 | for (i=0; i<nents; i++) | 128 | for_each_sg(sglist, sg, nents, i) { |
128 | frv_cache_wback_inv(sg_dma_address(&sg[i]), | 129 | frv_cache_wback_inv(sg_dma_address(sg), |
129 | sg_dma_address(&sg[i]) + sg_dma_len(&sg[i])); | 130 | sg_dma_address(sg) + sg_dma_len(sg)); |
131 | } | ||
130 | 132 | ||
131 | BUG_ON(direction == DMA_NONE); | 133 | BUG_ON(direction == DMA_NONE); |
132 | 134 | ||
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c index 82478979ac9a..4d1f01dc46e5 100644 --- a/arch/frv/mb93090-mb00/pci-dma.c +++ b/arch/frv/mb93090-mb00/pci-dma.c | |||
@@ -50,19 +50,20 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, | |||
50 | 50 | ||
51 | EXPORT_SYMBOL(dma_map_single); | 51 | EXPORT_SYMBOL(dma_map_single); |
52 | 52 | ||
53 | int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | 53 | int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents, |
54 | enum dma_data_direction direction) | 54 | enum dma_data_direction direction) |
55 | { | 55 | { |
56 | unsigned long dampr2; | 56 | unsigned long dampr2; |
57 | void *vaddr; | 57 | void *vaddr; |
58 | int i; | 58 | int i; |
59 | struct scatterlist *sg; | ||
59 | 60 | ||
60 | BUG_ON(direction == DMA_NONE); | 61 | BUG_ON(direction == DMA_NONE); |
61 | 62 | ||
62 | dampr2 = __get_DAMPR(2); | 63 | dampr2 = __get_DAMPR(2); |
63 | 64 | ||
64 | for (i = 0; i < nents; i++) { | 65 | for_each_sg(sglist, sg, nents, i) { |
65 | vaddr = kmap_atomic_primary(sg_page(&sg[i])); | 66 | vaddr = kmap_atomic_primary(sg_page(sg)); |
66 | 67 | ||
67 | frv_dcache_writeback((unsigned long) vaddr, | 68 | frv_dcache_writeback((unsigned long) vaddr, |
68 | (unsigned long) vaddr + PAGE_SIZE); | 69 | (unsigned long) vaddr + PAGE_SIZE); |
diff --git a/arch/ia64/include/asm/hugetlb.h b/arch/ia64/include/asm/hugetlb.h index ff1377bc02a6..ef65f026b11e 100644 --- a/arch/ia64/include/asm/hugetlb.h +++ b/arch/ia64/include/asm/hugetlb.h | |||
@@ -65,15 +65,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep) | |||
65 | return *ptep; | 65 | return *ptep; |
66 | } | 66 | } |
67 | 67 | ||
68 | static inline int arch_prepare_hugepage(struct page *page) | ||
69 | { | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static inline void arch_release_hugepage(struct page *page) | ||
74 | { | ||
75 | } | ||
76 | |||
77 | static inline void arch_clear_hugepage_flags(struct page *page) | 68 | static inline void arch_clear_hugepage_flags(struct page *page) |
78 | { | 69 | { |
79 | } | 70 | } |
diff --git a/arch/metag/include/asm/hugetlb.h b/arch/metag/include/asm/hugetlb.h index f730b396d79b..905ed422dbeb 100644 --- a/arch/metag/include/asm/hugetlb.h +++ b/arch/metag/include/asm/hugetlb.h | |||
@@ -67,15 +67,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep) | |||
67 | return *ptep; | 67 | return *ptep; |
68 | } | 68 | } |
69 | 69 | ||
70 | static inline int arch_prepare_hugepage(struct page *page) | ||
71 | { | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static inline void arch_release_hugepage(struct page *page) | ||
76 | { | ||
77 | } | ||
78 | |||
79 | static inline void arch_clear_hugepage_flags(struct page *page) | 70 | static inline void arch_clear_hugepage_flags(struct page *page) |
80 | { | 71 | { |
81 | } | 72 | } |
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h index 4a5bb5453408..982bc0685330 100644 --- a/arch/mips/include/asm/hugetlb.h +++ b/arch/mips/include/asm/hugetlb.h | |||
@@ -110,15 +110,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep) | |||
110 | return *ptep; | 110 | return *ptep; |
111 | } | 111 | } |
112 | 112 | ||
113 | static inline int arch_prepare_hugepage(struct page *page) | ||
114 | { | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static inline void arch_release_hugepage(struct page *page) | ||
119 | { | ||
120 | } | ||
121 | |||
122 | static inline void arch_clear_hugepage_flags(struct page *page) | 113 | static inline void arch_clear_hugepage_flags(struct page *page) |
123 | { | 114 | { |
124 | } | 115 | } |
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 4bbd3c8c2888..7eac89b9f02e 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h | |||
@@ -168,15 +168,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep) | |||
168 | return *ptep; | 168 | return *ptep; |
169 | } | 169 | } |
170 | 170 | ||
171 | static inline int arch_prepare_hugepage(struct page *page) | ||
172 | { | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static inline void arch_release_hugepage(struct page *page) | ||
177 | { | ||
178 | } | ||
179 | |||
180 | static inline void arch_clear_hugepage_flags(struct page *page) | 171 | static inline void arch_clear_hugepage_flags(struct page *page) |
181 | { | 172 | { |
182 | } | 173 | } |
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h index dfb542ade6b1..0130d0379edd 100644 --- a/arch/s390/include/asm/hugetlb.h +++ b/arch/s390/include/asm/hugetlb.h | |||
@@ -37,9 +37,6 @@ static inline int prepare_hugepage_range(struct file *file, | |||
37 | 37 | ||
38 | #define arch_clear_hugepage_flags(page) do { } while (0) | 38 | #define arch_clear_hugepage_flags(page) do { } while (0) |
39 | 39 | ||
40 | int arch_prepare_hugepage(struct page *page); | ||
41 | void arch_release_hugepage(struct page *page); | ||
42 | |||
43 | static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr, | 40 | static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr, |
44 | pte_t *ptep) | 41 | pte_t *ptep) |
45 | { | 42 | { |
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 53eacbd4f09b..dd345238d9a7 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h | |||
@@ -17,7 +17,10 @@ | |||
17 | #define PAGE_DEFAULT_ACC 0 | 17 | #define PAGE_DEFAULT_ACC 0 |
18 | #define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4) | 18 | #define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4) |
19 | 19 | ||
20 | #define HPAGE_SHIFT 20 | 20 | #include <asm/setup.h> |
21 | #ifndef __ASSEMBLY__ | ||
22 | |||
23 | extern int HPAGE_SHIFT; | ||
21 | #define HPAGE_SIZE (1UL << HPAGE_SHIFT) | 24 | #define HPAGE_SIZE (1UL << HPAGE_SHIFT) |
22 | #define HPAGE_MASK (~(HPAGE_SIZE - 1)) | 25 | #define HPAGE_MASK (~(HPAGE_SIZE - 1)) |
23 | #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) | 26 | #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) |
@@ -27,9 +30,6 @@ | |||
27 | #define ARCH_HAS_PREPARE_HUGEPAGE | 30 | #define ARCH_HAS_PREPARE_HUGEPAGE |
28 | #define ARCH_HAS_HUGEPAGE_CLEAR_FLUSH | 31 | #define ARCH_HAS_HUGEPAGE_CLEAR_FLUSH |
29 | 32 | ||
30 | #include <asm/setup.h> | ||
31 | #ifndef __ASSEMBLY__ | ||
32 | |||
33 | static inline void storage_key_init_range(unsigned long start, unsigned long end) | 33 | static inline void storage_key_init_range(unsigned long start, unsigned long end) |
34 | { | 34 | { |
35 | #if PAGE_DEFAULT_KEY | 35 | #if PAGE_DEFAULT_KEY |
diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c index d7fa2f0f1425..f8498dde67b1 100644 --- a/arch/s390/kernel/compat_wrapper.c +++ b/arch/s390/kernel/compat_wrapper.c | |||
@@ -202,7 +202,7 @@ COMPAT_SYSCALL_WRAP1(epoll_create1, int, flags); | |||
202 | COMPAT_SYSCALL_WRAP2(tkill, int, pid, int, sig); | 202 | COMPAT_SYSCALL_WRAP2(tkill, int, pid, int, sig); |
203 | COMPAT_SYSCALL_WRAP3(tgkill, int, tgid, int, pid, int, sig); | 203 | COMPAT_SYSCALL_WRAP3(tgkill, int, tgid, int, pid, int, sig); |
204 | COMPAT_SYSCALL_WRAP5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t, pid, int, cpu, int, group_fd, unsigned long, flags); | 204 | COMPAT_SYSCALL_WRAP5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t, pid, int, cpu, int, group_fd, unsigned long, flags); |
205 | COMPAT_SYSCALL_WRAP5(clone, unsigned long, newsp, unsigned long, clone_flags, int __user *, parent_tidptr, int __user *, child_tidptr, int, tls_val); | 205 | COMPAT_SYSCALL_WRAP5(clone, unsigned long, newsp, unsigned long, clone_flags, int __user *, parent_tidptr, int __user *, child_tidptr, unsigned long, tls); |
206 | COMPAT_SYSCALL_WRAP2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags); | 206 | COMPAT_SYSCALL_WRAP2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags); |
207 | COMPAT_SYSCALL_WRAP4(prlimit64, pid_t, pid, unsigned int, resource, const struct rlimit64 __user *, new_rlim, struct rlimit64 __user *, old_rlim); | 207 | COMPAT_SYSCALL_WRAP4(prlimit64, pid_t, pid, unsigned int, resource, const struct rlimit64 __user *, new_rlim, struct rlimit64 __user *, old_rlim); |
208 | COMPAT_SYSCALL_WRAP5(name_to_handle_at, int, dfd, const char __user *, name, struct file_handle __user *, handle, int __user *, mnt_id, int, flag); | 208 | COMPAT_SYSCALL_WRAP5(name_to_handle_at, int, dfd, const char __user *, name, struct file_handle __user *, handle, int __user *, mnt_id, int, flag); |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index af4f41d52cde..73941bf42350 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -880,6 +880,8 @@ void __init setup_arch(char **cmdline_p) | |||
880 | */ | 880 | */ |
881 | setup_hwcaps(); | 881 | setup_hwcaps(); |
882 | 882 | ||
883 | HPAGE_SHIFT = MACHINE_HAS_HPAGE ? 20 : 0; | ||
884 | |||
883 | /* | 885 | /* |
884 | * Create kernel page tables and switch to virtual addressing. | 886 | * Create kernel page tables and switch to virtual addressing. |
885 | */ | 887 | */ |
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c index c3f8e3df92ff..fb4bf2c4379e 100644 --- a/arch/s390/mm/hugetlbpage.c +++ b/arch/s390/mm/hugetlbpage.c | |||
@@ -86,31 +86,16 @@ static inline pte_t __pmd_to_pte(pmd_t pmd) | |||
86 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 86 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
87 | pte_t *ptep, pte_t pte) | 87 | pte_t *ptep, pte_t pte) |
88 | { | 88 | { |
89 | pmd_t pmd; | 89 | pmd_t pmd = __pte_to_pmd(pte); |
90 | 90 | ||
91 | pmd = __pte_to_pmd(pte); | 91 | pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE; |
92 | if (!MACHINE_HAS_HPAGE) { | ||
93 | /* Emulated huge ptes loose the dirty and young bit */ | ||
94 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_ORIGIN; | ||
95 | pmd_val(pmd) |= pte_page(pte)[1].index; | ||
96 | } else | ||
97 | pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE; | ||
98 | *(pmd_t *) ptep = pmd; | 92 | *(pmd_t *) ptep = pmd; |
99 | } | 93 | } |
100 | 94 | ||
101 | pte_t huge_ptep_get(pte_t *ptep) | 95 | pte_t huge_ptep_get(pte_t *ptep) |
102 | { | 96 | { |
103 | unsigned long origin; | 97 | pmd_t pmd = *(pmd_t *) ptep; |
104 | pmd_t pmd; | ||
105 | 98 | ||
106 | pmd = *(pmd_t *) ptep; | ||
107 | if (!MACHINE_HAS_HPAGE && pmd_present(pmd)) { | ||
108 | origin = pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN; | ||
109 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_ORIGIN; | ||
110 | pmd_val(pmd) |= *(unsigned long *) origin; | ||
111 | /* Emulated huge ptes are young and dirty by definition */ | ||
112 | pmd_val(pmd) |= _SEGMENT_ENTRY_YOUNG | _SEGMENT_ENTRY_DIRTY; | ||
113 | } | ||
114 | return __pmd_to_pte(pmd); | 99 | return __pmd_to_pte(pmd); |
115 | } | 100 | } |
116 | 101 | ||
@@ -125,45 +110,6 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | |||
125 | return pte; | 110 | return pte; |
126 | } | 111 | } |
127 | 112 | ||
128 | int arch_prepare_hugepage(struct page *page) | ||
129 | { | ||
130 | unsigned long addr = page_to_phys(page); | ||
131 | pte_t pte; | ||
132 | pte_t *ptep; | ||
133 | int i; | ||
134 | |||
135 | if (MACHINE_HAS_HPAGE) | ||
136 | return 0; | ||
137 | |||
138 | ptep = (pte_t *) pte_alloc_one(&init_mm, addr); | ||
139 | if (!ptep) | ||
140 | return -ENOMEM; | ||
141 | |||
142 | pte_val(pte) = addr; | ||
143 | for (i = 0; i < PTRS_PER_PTE; i++) { | ||
144 | set_pte_at(&init_mm, addr + i * PAGE_SIZE, ptep + i, pte); | ||
145 | pte_val(pte) += PAGE_SIZE; | ||
146 | } | ||
147 | page[1].index = (unsigned long) ptep; | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | void arch_release_hugepage(struct page *page) | ||
152 | { | ||
153 | pte_t *ptep; | ||
154 | |||
155 | if (MACHINE_HAS_HPAGE) | ||
156 | return; | ||
157 | |||
158 | ptep = (pte_t *) page[1].index; | ||
159 | if (!ptep) | ||
160 | return; | ||
161 | clear_table((unsigned long *) ptep, _PAGE_INVALID, | ||
162 | PTRS_PER_PTE * sizeof(pte_t)); | ||
163 | page_table_free(&init_mm, (unsigned long *) ptep); | ||
164 | page[1].index = 0; | ||
165 | } | ||
166 | |||
167 | pte_t *huge_pte_alloc(struct mm_struct *mm, | 113 | pte_t *huge_pte_alloc(struct mm_struct *mm, |
168 | unsigned long addr, unsigned long sz) | 114 | unsigned long addr, unsigned long sz) |
169 | { | 115 | { |
@@ -195,10 +141,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) | |||
195 | 141 | ||
196 | int pmd_huge(pmd_t pmd) | 142 | int pmd_huge(pmd_t pmd) |
197 | { | 143 | { |
198 | if (!MACHINE_HAS_HPAGE) | 144 | return pmd_large(pmd); |
199 | return 0; | ||
200 | |||
201 | return !!(pmd_val(pmd) & _SEGMENT_ENTRY_LARGE); | ||
202 | } | 145 | } |
203 | 146 | ||
204 | int pud_huge(pud_t pud) | 147 | int pud_huge(pud_t pud) |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index b33f66110ca9..33082d0d101b 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #define ALLOC_ORDER 2 | 31 | #define ALLOC_ORDER 2 |
32 | #define FRAG_MASK 0x03 | 32 | #define FRAG_MASK 0x03 |
33 | 33 | ||
34 | int HPAGE_SHIFT; | ||
35 | |||
34 | unsigned long *crst_table_alloc(struct mm_struct *mm) | 36 | unsigned long *crst_table_alloc(struct mm_struct *mm) |
35 | { | 37 | { |
36 | struct page *page = alloc_pages(GFP_KERNEL, ALLOC_ORDER); | 38 | struct page *page = alloc_pages(GFP_KERNEL, ALLOC_ORDER); |
diff --git a/arch/sh/include/asm/hugetlb.h b/arch/sh/include/asm/hugetlb.h index b788a9bc8918..ef489a56fcce 100644 --- a/arch/sh/include/asm/hugetlb.h +++ b/arch/sh/include/asm/hugetlb.h | |||
@@ -79,15 +79,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep) | |||
79 | return *ptep; | 79 | return *ptep; |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline int arch_prepare_hugepage(struct page *page) | ||
83 | { | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static inline void arch_release_hugepage(struct page *page) | ||
88 | { | ||
89 | } | ||
90 | |||
91 | static inline void arch_clear_hugepage_flags(struct page *page) | 82 | static inline void arch_clear_hugepage_flags(struct page *page) |
92 | { | 83 | { |
93 | clear_bit(PG_dcache_clean, &page->flags); | 84 | clear_bit(PG_dcache_clean, &page->flags); |
diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h index 3130d7636312..139e711ff80c 100644 --- a/arch/sparc/include/asm/hugetlb.h +++ b/arch/sparc/include/asm/hugetlb.h | |||
@@ -78,15 +78,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep) | |||
78 | return *ptep; | 78 | return *ptep; |
79 | } | 79 | } |
80 | 80 | ||
81 | static inline int arch_prepare_hugepage(struct page *page) | ||
82 | { | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static inline void arch_release_hugepage(struct page *page) | ||
87 | { | ||
88 | } | ||
89 | |||
90 | static inline void arch_clear_hugepage_flags(struct page *page) | 81 | static inline void arch_clear_hugepage_flags(struct page *page) |
91 | { | 82 | { |
92 | } | 83 | } |
diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h index 1abd00c55236..2fac5be4de26 100644 --- a/arch/tile/include/asm/hugetlb.h +++ b/arch/tile/include/asm/hugetlb.h | |||
@@ -94,15 +94,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep) | |||
94 | return *ptep; | 94 | return *ptep; |
95 | } | 95 | } |
96 | 96 | ||
97 | static inline int arch_prepare_hugepage(struct page *page) | ||
98 | { | ||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static inline void arch_release_hugepage(struct page *page) | ||
103 | { | ||
104 | } | ||
105 | |||
106 | static inline void arch_clear_hugepage_flags(struct page *page) | 97 | static inline void arch_clear_hugepage_flags(struct page *page) |
107 | { | 98 | { |
108 | } | 99 | } |
diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h index dab7a3a750bf..f8a29d2c97b0 100644 --- a/arch/x86/include/asm/hugetlb.h +++ b/arch/x86/include/asm/hugetlb.h | |||
@@ -80,15 +80,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep) | |||
80 | return *ptep; | 80 | return *ptep; |
81 | } | 81 | } |
82 | 82 | ||
83 | static inline int arch_prepare_hugepage(struct page *page) | ||
84 | { | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static inline void arch_release_hugepage(struct page *page) | ||
89 | { | ||
90 | } | ||
91 | |||
92 | static inline void arch_clear_hugepage_flags(struct page *page) | 83 | static inline void arch_clear_hugepage_flags(struct page *page) |
93 | { | 84 | { |
94 | } | 85 | } |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 21d13038534e..dafae6d2f7ac 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -1303,12 +1303,11 @@ const char *device_get_devnode(struct device *dev, | |||
1303 | return dev_name(dev); | 1303 | return dev_name(dev); |
1304 | 1304 | ||
1305 | /* replace '!' in the name with '/' */ | 1305 | /* replace '!' in the name with '/' */ |
1306 | *tmp = kstrdup(dev_name(dev), GFP_KERNEL); | 1306 | s = kstrdup(dev_name(dev), GFP_KERNEL); |
1307 | if (!*tmp) | 1307 | if (!s) |
1308 | return NULL; | 1308 | return NULL; |
1309 | while ((s = strchr(*tmp, '!'))) | 1309 | strreplace(s, '!', '/'); |
1310 | s[0] = '/'; | 1310 | return *tmp = s; |
1311 | return *tmp; | ||
1312 | } | 1311 | } |
1313 | 1312 | ||
1314 | /** | 1313 | /** |
diff --git a/drivers/block/zram/Kconfig b/drivers/block/zram/Kconfig index 6489c0fd0ea6..386ba3d1a6ee 100644 --- a/drivers/block/zram/Kconfig +++ b/drivers/block/zram/Kconfig | |||
@@ -23,12 +23,4 @@ config ZRAM_LZ4_COMPRESS | |||
23 | default n | 23 | default n |
24 | help | 24 | help |
25 | This option enables LZ4 compression algorithm support. Compression | 25 | This option enables LZ4 compression algorithm support. Compression |
26 | algorithm can be changed using `comp_algorithm' device attribute. | 26 | algorithm can be changed using `comp_algorithm' device attribute. \ No newline at end of file |
27 | |||
28 | config ZRAM_DEBUG | ||
29 | bool "Compressed RAM block device debug support" | ||
30 | depends on ZRAM | ||
31 | default n | ||
32 | help | ||
33 | This option adds additional debugging code to the compressed | ||
34 | RAM block device driver. | ||
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index f1ff39a3d1c1..965d1afb0eaa 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c | |||
@@ -274,7 +274,7 @@ ssize_t zcomp_available_show(const char *comp, char *buf) | |||
274 | int i = 0; | 274 | int i = 0; |
275 | 275 | ||
276 | while (backends[i]) { | 276 | while (backends[i]) { |
277 | if (sysfs_streq(comp, backends[i]->name)) | 277 | if (!strcmp(comp, backends[i]->name)) |
278 | sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2, | 278 | sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2, |
279 | "[%s] ", backends[i]->name); | 279 | "[%s] ", backends[i]->name); |
280 | else | 280 | else |
@@ -286,6 +286,11 @@ ssize_t zcomp_available_show(const char *comp, char *buf) | |||
286 | return sz; | 286 | return sz; |
287 | } | 287 | } |
288 | 288 | ||
289 | bool zcomp_available_algorithm(const char *comp) | ||
290 | { | ||
291 | return find_backend(comp) != NULL; | ||
292 | } | ||
293 | |||
289 | bool zcomp_set_max_streams(struct zcomp *comp, int num_strm) | 294 | bool zcomp_set_max_streams(struct zcomp *comp, int num_strm) |
290 | { | 295 | { |
291 | return comp->set_max_streams(comp, num_strm); | 296 | return comp->set_max_streams(comp, num_strm); |
diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h index c59d1fca72c0..46e2b9f8f1f0 100644 --- a/drivers/block/zram/zcomp.h +++ b/drivers/block/zram/zcomp.h | |||
@@ -51,6 +51,7 @@ struct zcomp { | |||
51 | }; | 51 | }; |
52 | 52 | ||
53 | ssize_t zcomp_available_show(const char *comp, char *buf); | 53 | ssize_t zcomp_available_show(const char *comp, char *buf); |
54 | bool zcomp_available_algorithm(const char *comp); | ||
54 | 55 | ||
55 | struct zcomp *zcomp_create(const char *comp, int max_strm); | 56 | struct zcomp *zcomp_create(const char *comp, int max_strm); |
56 | void zcomp_destroy(struct zcomp *comp); | 57 | void zcomp_destroy(struct zcomp *comp); |
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 6e134f4759c0..fb655e8d1e3b 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c | |||
@@ -15,10 +15,6 @@ | |||
15 | #define KMSG_COMPONENT "zram" | 15 | #define KMSG_COMPONENT "zram" |
16 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 16 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
17 | 17 | ||
18 | #ifdef CONFIG_ZRAM_DEBUG | ||
19 | #define DEBUG | ||
20 | #endif | ||
21 | |||
22 | #include <linux/module.h> | 18 | #include <linux/module.h> |
23 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
24 | #include <linux/bio.h> | 20 | #include <linux/bio.h> |
@@ -32,12 +28,16 @@ | |||
32 | #include <linux/string.h> | 28 | #include <linux/string.h> |
33 | #include <linux/vmalloc.h> | 29 | #include <linux/vmalloc.h> |
34 | #include <linux/err.h> | 30 | #include <linux/err.h> |
31 | #include <linux/idr.h> | ||
32 | #include <linux/sysfs.h> | ||
35 | 33 | ||
36 | #include "zram_drv.h" | 34 | #include "zram_drv.h" |
37 | 35 | ||
38 | /* Globals */ | 36 | static DEFINE_IDR(zram_index_idr); |
37 | /* idr index must be protected */ | ||
38 | static DEFINE_MUTEX(zram_index_mutex); | ||
39 | |||
39 | static int zram_major; | 40 | static int zram_major; |
40 | static struct zram *zram_devices; | ||
41 | static const char *default_compressor = "lzo"; | 41 | static const char *default_compressor = "lzo"; |
42 | 42 | ||
43 | /* Module params (documentation at end) */ | 43 | /* Module params (documentation at end) */ |
@@ -53,7 +53,7 @@ static inline void deprecated_attr_warn(const char *name) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | #define ZRAM_ATTR_RO(name) \ | 55 | #define ZRAM_ATTR_RO(name) \ |
56 | static ssize_t name##_show(struct device *d, \ | 56 | static ssize_t name##_show(struct device *d, \ |
57 | struct device_attribute *attr, char *b) \ | 57 | struct device_attribute *attr, char *b) \ |
58 | { \ | 58 | { \ |
59 | struct zram *zram = dev_to_zram(d); \ | 59 | struct zram *zram = dev_to_zram(d); \ |
@@ -74,33 +74,117 @@ static inline struct zram *dev_to_zram(struct device *dev) | |||
74 | return (struct zram *)dev_to_disk(dev)->private_data; | 74 | return (struct zram *)dev_to_disk(dev)->private_data; |
75 | } | 75 | } |
76 | 76 | ||
77 | static ssize_t compact_store(struct device *dev, | 77 | /* flag operations require table entry bit_spin_lock() being held */ |
78 | struct device_attribute *attr, const char *buf, size_t len) | 78 | static int zram_test_flag(struct zram_meta *meta, u32 index, |
79 | enum zram_pageflags flag) | ||
79 | { | 80 | { |
80 | unsigned long nr_migrated; | 81 | return meta->table[index].value & BIT(flag); |
81 | struct zram *zram = dev_to_zram(dev); | 82 | } |
82 | struct zram_meta *meta; | ||
83 | 83 | ||
84 | down_read(&zram->init_lock); | 84 | static void zram_set_flag(struct zram_meta *meta, u32 index, |
85 | if (!init_done(zram)) { | 85 | enum zram_pageflags flag) |
86 | up_read(&zram->init_lock); | 86 | { |
87 | return -EINVAL; | 87 | meta->table[index].value |= BIT(flag); |
88 | } | 88 | } |
89 | 89 | ||
90 | meta = zram->meta; | 90 | static void zram_clear_flag(struct zram_meta *meta, u32 index, |
91 | nr_migrated = zs_compact(meta->mem_pool); | 91 | enum zram_pageflags flag) |
92 | atomic64_add(nr_migrated, &zram->stats.num_migrated); | 92 | { |
93 | up_read(&zram->init_lock); | 93 | meta->table[index].value &= ~BIT(flag); |
94 | } | ||
94 | 95 | ||
95 | return len; | 96 | static size_t zram_get_obj_size(struct zram_meta *meta, u32 index) |
97 | { | ||
98 | return meta->table[index].value & (BIT(ZRAM_FLAG_SHIFT) - 1); | ||
96 | } | 99 | } |
97 | 100 | ||
98 | static ssize_t disksize_show(struct device *dev, | 101 | static void zram_set_obj_size(struct zram_meta *meta, |
99 | struct device_attribute *attr, char *buf) | 102 | u32 index, size_t size) |
100 | { | 103 | { |
101 | struct zram *zram = dev_to_zram(dev); | 104 | unsigned long flags = meta->table[index].value >> ZRAM_FLAG_SHIFT; |
102 | 105 | ||
103 | return scnprintf(buf, PAGE_SIZE, "%llu\n", zram->disksize); | 106 | meta->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; |
107 | } | ||
108 | |||
109 | static inline int is_partial_io(struct bio_vec *bvec) | ||
110 | { | ||
111 | return bvec->bv_len != PAGE_SIZE; | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * Check if request is within bounds and aligned on zram logical blocks. | ||
116 | */ | ||
117 | static inline int valid_io_request(struct zram *zram, | ||
118 | sector_t start, unsigned int size) | ||
119 | { | ||
120 | u64 end, bound; | ||
121 | |||
122 | /* unaligned request */ | ||
123 | if (unlikely(start & (ZRAM_SECTOR_PER_LOGICAL_BLOCK - 1))) | ||
124 | return 0; | ||
125 | if (unlikely(size & (ZRAM_LOGICAL_BLOCK_SIZE - 1))) | ||
126 | return 0; | ||
127 | |||
128 | end = start + (size >> SECTOR_SHIFT); | ||
129 | bound = zram->disksize >> SECTOR_SHIFT; | ||
130 | /* out of range range */ | ||
131 | if (unlikely(start >= bound || end > bound || start > end)) | ||
132 | return 0; | ||
133 | |||
134 | /* I/O request is valid */ | ||
135 | return 1; | ||
136 | } | ||
137 | |||
138 | static void update_position(u32 *index, int *offset, struct bio_vec *bvec) | ||
139 | { | ||
140 | if (*offset + bvec->bv_len >= PAGE_SIZE) | ||
141 | (*index)++; | ||
142 | *offset = (*offset + bvec->bv_len) % PAGE_SIZE; | ||
143 | } | ||
144 | |||
145 | static inline void update_used_max(struct zram *zram, | ||
146 | const unsigned long pages) | ||
147 | { | ||
148 | unsigned long old_max, cur_max; | ||
149 | |||
150 | old_max = atomic_long_read(&zram->stats.max_used_pages); | ||
151 | |||
152 | do { | ||
153 | cur_max = old_max; | ||
154 | if (pages > cur_max) | ||
155 | old_max = atomic_long_cmpxchg( | ||
156 | &zram->stats.max_used_pages, cur_max, pages); | ||
157 | } while (old_max != cur_max); | ||
158 | } | ||
159 | |||
160 | static int page_zero_filled(void *ptr) | ||
161 | { | ||
162 | unsigned int pos; | ||
163 | unsigned long *page; | ||
164 | |||
165 | page = (unsigned long *)ptr; | ||
166 | |||
167 | for (pos = 0; pos != PAGE_SIZE / sizeof(*page); pos++) { | ||
168 | if (page[pos]) | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | return 1; | ||
173 | } | ||
174 | |||
175 | static void handle_zero_page(struct bio_vec *bvec) | ||
176 | { | ||
177 | struct page *page = bvec->bv_page; | ||
178 | void *user_mem; | ||
179 | |||
180 | user_mem = kmap_atomic(page); | ||
181 | if (is_partial_io(bvec)) | ||
182 | memset(user_mem + bvec->bv_offset, 0, bvec->bv_len); | ||
183 | else | ||
184 | clear_page(user_mem); | ||
185 | kunmap_atomic(user_mem); | ||
186 | |||
187 | flush_dcache_page(page); | ||
104 | } | 188 | } |
105 | 189 | ||
106 | static ssize_t initstate_show(struct device *dev, | 190 | static ssize_t initstate_show(struct device *dev, |
@@ -116,6 +200,14 @@ static ssize_t initstate_show(struct device *dev, | |||
116 | return scnprintf(buf, PAGE_SIZE, "%u\n", val); | 200 | return scnprintf(buf, PAGE_SIZE, "%u\n", val); |
117 | } | 201 | } |
118 | 202 | ||
203 | static ssize_t disksize_show(struct device *dev, | ||
204 | struct device_attribute *attr, char *buf) | ||
205 | { | ||
206 | struct zram *zram = dev_to_zram(dev); | ||
207 | |||
208 | return scnprintf(buf, PAGE_SIZE, "%llu\n", zram->disksize); | ||
209 | } | ||
210 | |||
119 | static ssize_t orig_data_size_show(struct device *dev, | 211 | static ssize_t orig_data_size_show(struct device *dev, |
120 | struct device_attribute *attr, char *buf) | 212 | struct device_attribute *attr, char *buf) |
121 | { | 213 | { |
@@ -143,19 +235,6 @@ static ssize_t mem_used_total_show(struct device *dev, | |||
143 | return scnprintf(buf, PAGE_SIZE, "%llu\n", val << PAGE_SHIFT); | 235 | return scnprintf(buf, PAGE_SIZE, "%llu\n", val << PAGE_SHIFT); |
144 | } | 236 | } |
145 | 237 | ||
146 | static ssize_t max_comp_streams_show(struct device *dev, | ||
147 | struct device_attribute *attr, char *buf) | ||
148 | { | ||
149 | int val; | ||
150 | struct zram *zram = dev_to_zram(dev); | ||
151 | |||
152 | down_read(&zram->init_lock); | ||
153 | val = zram->max_comp_streams; | ||
154 | up_read(&zram->init_lock); | ||
155 | |||
156 | return scnprintf(buf, PAGE_SIZE, "%d\n", val); | ||
157 | } | ||
158 | |||
159 | static ssize_t mem_limit_show(struct device *dev, | 238 | static ssize_t mem_limit_show(struct device *dev, |
160 | struct device_attribute *attr, char *buf) | 239 | struct device_attribute *attr, char *buf) |
161 | { | 240 | { |
@@ -225,6 +304,19 @@ static ssize_t mem_used_max_store(struct device *dev, | |||
225 | return len; | 304 | return len; |
226 | } | 305 | } |
227 | 306 | ||
307 | static ssize_t max_comp_streams_show(struct device *dev, | ||
308 | struct device_attribute *attr, char *buf) | ||
309 | { | ||
310 | int val; | ||
311 | struct zram *zram = dev_to_zram(dev); | ||
312 | |||
313 | down_read(&zram->init_lock); | ||
314 | val = zram->max_comp_streams; | ||
315 | up_read(&zram->init_lock); | ||
316 | |||
317 | return scnprintf(buf, PAGE_SIZE, "%d\n", val); | ||
318 | } | ||
319 | |||
228 | static ssize_t max_comp_streams_store(struct device *dev, | 320 | static ssize_t max_comp_streams_store(struct device *dev, |
229 | struct device_attribute *attr, const char *buf, size_t len) | 321 | struct device_attribute *attr, const char *buf, size_t len) |
230 | { | 322 | { |
@@ -271,6 +363,8 @@ static ssize_t comp_algorithm_store(struct device *dev, | |||
271 | struct device_attribute *attr, const char *buf, size_t len) | 363 | struct device_attribute *attr, const char *buf, size_t len) |
272 | { | 364 | { |
273 | struct zram *zram = dev_to_zram(dev); | 365 | struct zram *zram = dev_to_zram(dev); |
366 | size_t sz; | ||
367 | |||
274 | down_write(&zram->init_lock); | 368 | down_write(&zram->init_lock); |
275 | if (init_done(zram)) { | 369 | if (init_done(zram)) { |
276 | up_write(&zram->init_lock); | 370 | up_write(&zram->init_lock); |
@@ -278,69 +372,108 @@ static ssize_t comp_algorithm_store(struct device *dev, | |||
278 | return -EBUSY; | 372 | return -EBUSY; |
279 | } | 373 | } |
280 | strlcpy(zram->compressor, buf, sizeof(zram->compressor)); | 374 | strlcpy(zram->compressor, buf, sizeof(zram->compressor)); |
375 | |||
376 | /* ignore trailing newline */ | ||
377 | sz = strlen(zram->compressor); | ||
378 | if (sz > 0 && zram->compressor[sz - 1] == '\n') | ||
379 | zram->compressor[sz - 1] = 0x00; | ||
380 | |||
381 | if (!zcomp_available_algorithm(zram->compressor)) | ||
382 | len = -EINVAL; | ||
383 | |||
281 | up_write(&zram->init_lock); | 384 | up_write(&zram->init_lock); |
282 | return len; | 385 | return len; |
283 | } | 386 | } |
284 | 387 | ||
285 | /* flag operations needs meta->tb_lock */ | 388 | static ssize_t compact_store(struct device *dev, |
286 | static int zram_test_flag(struct zram_meta *meta, u32 index, | 389 | struct device_attribute *attr, const char *buf, size_t len) |
287 | enum zram_pageflags flag) | ||
288 | { | 390 | { |
289 | return meta->table[index].value & BIT(flag); | 391 | unsigned long nr_migrated; |
290 | } | 392 | struct zram *zram = dev_to_zram(dev); |
393 | struct zram_meta *meta; | ||
291 | 394 | ||
292 | static void zram_set_flag(struct zram_meta *meta, u32 index, | 395 | down_read(&zram->init_lock); |
293 | enum zram_pageflags flag) | 396 | if (!init_done(zram)) { |
294 | { | 397 | up_read(&zram->init_lock); |
295 | meta->table[index].value |= BIT(flag); | 398 | return -EINVAL; |
296 | } | 399 | } |
297 | 400 | ||
298 | static void zram_clear_flag(struct zram_meta *meta, u32 index, | 401 | meta = zram->meta; |
299 | enum zram_pageflags flag) | 402 | nr_migrated = zs_compact(meta->mem_pool); |
300 | { | 403 | atomic64_add(nr_migrated, &zram->stats.num_migrated); |
301 | meta->table[index].value &= ~BIT(flag); | 404 | up_read(&zram->init_lock); |
405 | |||
406 | return len; | ||
302 | } | 407 | } |
303 | 408 | ||
304 | static size_t zram_get_obj_size(struct zram_meta *meta, u32 index) | 409 | static ssize_t io_stat_show(struct device *dev, |
410 | struct device_attribute *attr, char *buf) | ||
305 | { | 411 | { |
306 | return meta->table[index].value & (BIT(ZRAM_FLAG_SHIFT) - 1); | 412 | struct zram *zram = dev_to_zram(dev); |
413 | ssize_t ret; | ||
414 | |||
415 | down_read(&zram->init_lock); | ||
416 | ret = scnprintf(buf, PAGE_SIZE, | ||
417 | "%8llu %8llu %8llu %8llu\n", | ||
418 | (u64)atomic64_read(&zram->stats.failed_reads), | ||
419 | (u64)atomic64_read(&zram->stats.failed_writes), | ||
420 | (u64)atomic64_read(&zram->stats.invalid_io), | ||
421 | (u64)atomic64_read(&zram->stats.notify_free)); | ||
422 | up_read(&zram->init_lock); | ||
423 | |||
424 | return ret; | ||
307 | } | 425 | } |
308 | 426 | ||
309 | static void zram_set_obj_size(struct zram_meta *meta, | 427 | static ssize_t mm_stat_show(struct device *dev, |
310 | u32 index, size_t size) | 428 | struct device_attribute *attr, char *buf) |
311 | { | 429 | { |
312 | unsigned long flags = meta->table[index].value >> ZRAM_FLAG_SHIFT; | 430 | struct zram *zram = dev_to_zram(dev); |
431 | u64 orig_size, mem_used = 0; | ||
432 | long max_used; | ||
433 | ssize_t ret; | ||
313 | 434 | ||
314 | meta->table[index].value = (flags << ZRAM_FLAG_SHIFT) | size; | 435 | down_read(&zram->init_lock); |
436 | if (init_done(zram)) | ||
437 | mem_used = zs_get_total_pages(zram->meta->mem_pool); | ||
438 | |||
439 | orig_size = atomic64_read(&zram->stats.pages_stored); | ||
440 | max_used = atomic_long_read(&zram->stats.max_used_pages); | ||
441 | |||
442 | ret = scnprintf(buf, PAGE_SIZE, | ||
443 | "%8llu %8llu %8llu %8lu %8ld %8llu %8llu\n", | ||
444 | orig_size << PAGE_SHIFT, | ||
445 | (u64)atomic64_read(&zram->stats.compr_data_size), | ||
446 | mem_used << PAGE_SHIFT, | ||
447 | zram->limit_pages << PAGE_SHIFT, | ||
448 | max_used << PAGE_SHIFT, | ||
449 | (u64)atomic64_read(&zram->stats.zero_pages), | ||
450 | (u64)atomic64_read(&zram->stats.num_migrated)); | ||
451 | up_read(&zram->init_lock); | ||
452 | |||
453 | return ret; | ||
315 | } | 454 | } |
316 | 455 | ||
317 | static inline int is_partial_io(struct bio_vec *bvec) | 456 | static DEVICE_ATTR_RO(io_stat); |
457 | static DEVICE_ATTR_RO(mm_stat); | ||
458 | ZRAM_ATTR_RO(num_reads); | ||
459 | ZRAM_ATTR_RO(num_writes); | ||
460 | ZRAM_ATTR_RO(failed_reads); | ||
461 | ZRAM_ATTR_RO(failed_writes); | ||
462 | ZRAM_ATTR_RO(invalid_io); | ||
463 | ZRAM_ATTR_RO(notify_free); | ||
464 | ZRAM_ATTR_RO(zero_pages); | ||
465 | ZRAM_ATTR_RO(compr_data_size); | ||
466 | |||
467 | static inline bool zram_meta_get(struct zram *zram) | ||
318 | { | 468 | { |
319 | return bvec->bv_len != PAGE_SIZE; | 469 | if (atomic_inc_not_zero(&zram->refcount)) |
470 | return true; | ||
471 | return false; | ||
320 | } | 472 | } |
321 | 473 | ||
322 | /* | 474 | static inline void zram_meta_put(struct zram *zram) |
323 | * Check if request is within bounds and aligned on zram logical blocks. | ||
324 | */ | ||
325 | static inline int valid_io_request(struct zram *zram, | ||
326 | sector_t start, unsigned int size) | ||
327 | { | 475 | { |
328 | u64 end, bound; | 476 | atomic_dec(&zram->refcount); |
329 | |||
330 | /* unaligned request */ | ||
331 | if (unlikely(start & (ZRAM_SECTOR_PER_LOGICAL_BLOCK - 1))) | ||
332 | return 0; | ||
333 | if (unlikely(size & (ZRAM_LOGICAL_BLOCK_SIZE - 1))) | ||
334 | return 0; | ||
335 | |||
336 | end = start + (size >> SECTOR_SHIFT); | ||
337 | bound = zram->disksize >> SECTOR_SHIFT; | ||
338 | /* out of range range */ | ||
339 | if (unlikely(start >= bound || end > bound || start > end)) | ||
340 | return 0; | ||
341 | |||
342 | /* I/O request is valid */ | ||
343 | return 1; | ||
344 | } | 477 | } |
345 | 478 | ||
346 | static void zram_meta_free(struct zram_meta *meta, u64 disksize) | 479 | static void zram_meta_free(struct zram_meta *meta, u64 disksize) |
@@ -394,56 +527,6 @@ out_error: | |||
394 | return NULL; | 527 | return NULL; |
395 | } | 528 | } |
396 | 529 | ||
397 | static inline bool zram_meta_get(struct zram *zram) | ||
398 | { | ||
399 | if (atomic_inc_not_zero(&zram->refcount)) | ||
400 | return true; | ||
401 | return false; | ||
402 | } | ||
403 | |||
404 | static inline void zram_meta_put(struct zram *zram) | ||
405 | { | ||
406 | atomic_dec(&zram->refcount); | ||
407 | } | ||
408 | |||
409 | static void update_position(u32 *index, int *offset, struct bio_vec *bvec) | ||
410 | { | ||
411 | if (*offset + bvec->bv_len >= PAGE_SIZE) | ||
412 | (*index)++; | ||
413 | *offset = (*offset + bvec->bv_len) % PAGE_SIZE; | ||
414 | } | ||
415 | |||
416 | static int page_zero_filled(void *ptr) | ||
417 | { | ||
418 | unsigned int pos; | ||
419 | unsigned long *page; | ||
420 | |||
421 | page = (unsigned long *)ptr; | ||
422 | |||
423 | for (pos = 0; pos != PAGE_SIZE / sizeof(*page); pos++) { | ||
424 | if (page[pos]) | ||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | return 1; | ||
429 | } | ||
430 | |||
431 | static void handle_zero_page(struct bio_vec *bvec) | ||
432 | { | ||
433 | struct page *page = bvec->bv_page; | ||
434 | void *user_mem; | ||
435 | |||
436 | user_mem = kmap_atomic(page); | ||
437 | if (is_partial_io(bvec)) | ||
438 | memset(user_mem + bvec->bv_offset, 0, bvec->bv_len); | ||
439 | else | ||
440 | clear_page(user_mem); | ||
441 | kunmap_atomic(user_mem); | ||
442 | |||
443 | flush_dcache_page(page); | ||
444 | } | ||
445 | |||
446 | |||
447 | /* | 530 | /* |
448 | * To protect concurrent access to the same index entry, | 531 | * To protect concurrent access to the same index entry, |
449 | * caller should hold this table index entry's bit_spinlock to | 532 | * caller should hold this table index entry's bit_spinlock to |
@@ -561,21 +644,6 @@ out_cleanup: | |||
561 | return ret; | 644 | return ret; |
562 | } | 645 | } |
563 | 646 | ||
564 | static inline void update_used_max(struct zram *zram, | ||
565 | const unsigned long pages) | ||
566 | { | ||
567 | unsigned long old_max, cur_max; | ||
568 | |||
569 | old_max = atomic_long_read(&zram->stats.max_used_pages); | ||
570 | |||
571 | do { | ||
572 | cur_max = old_max; | ||
573 | if (pages > cur_max) | ||
574 | old_max = atomic_long_cmpxchg( | ||
575 | &zram->stats.max_used_pages, cur_max, pages); | ||
576 | } while (old_max != cur_max); | ||
577 | } | ||
578 | |||
579 | static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | 647 | static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, |
580 | int offset) | 648 | int offset) |
581 | { | 649 | { |
@@ -585,8 +653,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
585 | struct page *page; | 653 | struct page *page; |
586 | unsigned char *user_mem, *cmem, *src, *uncmem = NULL; | 654 | unsigned char *user_mem, *cmem, *src, *uncmem = NULL; |
587 | struct zram_meta *meta = zram->meta; | 655 | struct zram_meta *meta = zram->meta; |
588 | struct zcomp_strm *zstrm; | 656 | struct zcomp_strm *zstrm = NULL; |
589 | bool locked = false; | ||
590 | unsigned long alloced_pages; | 657 | unsigned long alloced_pages; |
591 | 658 | ||
592 | page = bvec->bv_page; | 659 | page = bvec->bv_page; |
@@ -606,7 +673,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
606 | } | 673 | } |
607 | 674 | ||
608 | zstrm = zcomp_strm_find(zram->comp); | 675 | zstrm = zcomp_strm_find(zram->comp); |
609 | locked = true; | ||
610 | user_mem = kmap_atomic(page); | 676 | user_mem = kmap_atomic(page); |
611 | 677 | ||
612 | if (is_partial_io(bvec)) { | 678 | if (is_partial_io(bvec)) { |
@@ -678,7 +744,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
678 | } | 744 | } |
679 | 745 | ||
680 | zcomp_strm_release(zram->comp, zstrm); | 746 | zcomp_strm_release(zram->comp, zstrm); |
681 | locked = false; | 747 | zstrm = NULL; |
682 | zs_unmap_object(meta->mem_pool, handle); | 748 | zs_unmap_object(meta->mem_pool, handle); |
683 | 749 | ||
684 | /* | 750 | /* |
@@ -696,42 +762,13 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
696 | atomic64_add(clen, &zram->stats.compr_data_size); | 762 | atomic64_add(clen, &zram->stats.compr_data_size); |
697 | atomic64_inc(&zram->stats.pages_stored); | 763 | atomic64_inc(&zram->stats.pages_stored); |
698 | out: | 764 | out: |
699 | if (locked) | 765 | if (zstrm) |
700 | zcomp_strm_release(zram->comp, zstrm); | 766 | zcomp_strm_release(zram->comp, zstrm); |
701 | if (is_partial_io(bvec)) | 767 | if (is_partial_io(bvec)) |
702 | kfree(uncmem); | 768 | kfree(uncmem); |
703 | return ret; | 769 | return ret; |
704 | } | 770 | } |
705 | 771 | ||
706 | static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index, | ||
707 | int offset, int rw) | ||
708 | { | ||
709 | unsigned long start_time = jiffies; | ||
710 | int ret; | ||
711 | |||
712 | generic_start_io_acct(rw, bvec->bv_len >> SECTOR_SHIFT, | ||
713 | &zram->disk->part0); | ||
714 | |||
715 | if (rw == READ) { | ||
716 | atomic64_inc(&zram->stats.num_reads); | ||
717 | ret = zram_bvec_read(zram, bvec, index, offset); | ||
718 | } else { | ||
719 | atomic64_inc(&zram->stats.num_writes); | ||
720 | ret = zram_bvec_write(zram, bvec, index, offset); | ||
721 | } | ||
722 | |||
723 | generic_end_io_acct(rw, &zram->disk->part0, start_time); | ||
724 | |||
725 | if (unlikely(ret)) { | ||
726 | if (rw == READ) | ||
727 | atomic64_inc(&zram->stats.failed_reads); | ||
728 | else | ||
729 | atomic64_inc(&zram->stats.failed_writes); | ||
730 | } | ||
731 | |||
732 | return ret; | ||
733 | } | ||
734 | |||
735 | /* | 772 | /* |
736 | * zram_bio_discard - handler on discard request | 773 | * zram_bio_discard - handler on discard request |
737 | * @index: physical block index in PAGE_SIZE units | 774 | * @index: physical block index in PAGE_SIZE units |
@@ -771,151 +808,32 @@ static void zram_bio_discard(struct zram *zram, u32 index, | |||
771 | } | 808 | } |
772 | } | 809 | } |
773 | 810 | ||
774 | static void zram_reset_device(struct zram *zram) | 811 | static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index, |
775 | { | 812 | int offset, int rw) |
776 | struct zram_meta *meta; | ||
777 | struct zcomp *comp; | ||
778 | u64 disksize; | ||
779 | |||
780 | down_write(&zram->init_lock); | ||
781 | |||
782 | zram->limit_pages = 0; | ||
783 | |||
784 | if (!init_done(zram)) { | ||
785 | up_write(&zram->init_lock); | ||
786 | return; | ||
787 | } | ||
788 | |||
789 | meta = zram->meta; | ||
790 | comp = zram->comp; | ||
791 | disksize = zram->disksize; | ||
792 | /* | ||
793 | * Refcount will go down to 0 eventually and r/w handler | ||
794 | * cannot handle further I/O so it will bail out by | ||
795 | * check zram_meta_get. | ||
796 | */ | ||
797 | zram_meta_put(zram); | ||
798 | /* | ||
799 | * We want to free zram_meta in process context to avoid | ||
800 | * deadlock between reclaim path and any other locks. | ||
801 | */ | ||
802 | wait_event(zram->io_done, atomic_read(&zram->refcount) == 0); | ||
803 | |||
804 | /* Reset stats */ | ||
805 | memset(&zram->stats, 0, sizeof(zram->stats)); | ||
806 | zram->disksize = 0; | ||
807 | zram->max_comp_streams = 1; | ||
808 | |||
809 | set_capacity(zram->disk, 0); | ||
810 | part_stat_set_all(&zram->disk->part0, 0); | ||
811 | |||
812 | up_write(&zram->init_lock); | ||
813 | /* I/O operation under all of CPU are done so let's free */ | ||
814 | zram_meta_free(meta, disksize); | ||
815 | zcomp_destroy(comp); | ||
816 | } | ||
817 | |||
818 | static ssize_t disksize_store(struct device *dev, | ||
819 | struct device_attribute *attr, const char *buf, size_t len) | ||
820 | { | ||
821 | u64 disksize; | ||
822 | struct zcomp *comp; | ||
823 | struct zram_meta *meta; | ||
824 | struct zram *zram = dev_to_zram(dev); | ||
825 | int err; | ||
826 | |||
827 | disksize = memparse(buf, NULL); | ||
828 | if (!disksize) | ||
829 | return -EINVAL; | ||
830 | |||
831 | disksize = PAGE_ALIGN(disksize); | ||
832 | meta = zram_meta_alloc(zram->disk->first_minor, disksize); | ||
833 | if (!meta) | ||
834 | return -ENOMEM; | ||
835 | |||
836 | comp = zcomp_create(zram->compressor, zram->max_comp_streams); | ||
837 | if (IS_ERR(comp)) { | ||
838 | pr_info("Cannot initialise %s compressing backend\n", | ||
839 | zram->compressor); | ||
840 | err = PTR_ERR(comp); | ||
841 | goto out_free_meta; | ||
842 | } | ||
843 | |||
844 | down_write(&zram->init_lock); | ||
845 | if (init_done(zram)) { | ||
846 | pr_info("Cannot change disksize for initialized device\n"); | ||
847 | err = -EBUSY; | ||
848 | goto out_destroy_comp; | ||
849 | } | ||
850 | |||
851 | init_waitqueue_head(&zram->io_done); | ||
852 | atomic_set(&zram->refcount, 1); | ||
853 | zram->meta = meta; | ||
854 | zram->comp = comp; | ||
855 | zram->disksize = disksize; | ||
856 | set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); | ||
857 | up_write(&zram->init_lock); | ||
858 | |||
859 | /* | ||
860 | * Revalidate disk out of the init_lock to avoid lockdep splat. | ||
861 | * It's okay because disk's capacity is protected by init_lock | ||
862 | * so that revalidate_disk always sees up-to-date capacity. | ||
863 | */ | ||
864 | revalidate_disk(zram->disk); | ||
865 | |||
866 | return len; | ||
867 | |||
868 | out_destroy_comp: | ||
869 | up_write(&zram->init_lock); | ||
870 | zcomp_destroy(comp); | ||
871 | out_free_meta: | ||
872 | zram_meta_free(meta, disksize); | ||
873 | return err; | ||
874 | } | ||
875 | |||
876 | static ssize_t reset_store(struct device *dev, | ||
877 | struct device_attribute *attr, const char *buf, size_t len) | ||
878 | { | 813 | { |
814 | unsigned long start_time = jiffies; | ||
879 | int ret; | 815 | int ret; |
880 | unsigned short do_reset; | ||
881 | struct zram *zram; | ||
882 | struct block_device *bdev; | ||
883 | 816 | ||
884 | zram = dev_to_zram(dev); | 817 | generic_start_io_acct(rw, bvec->bv_len >> SECTOR_SHIFT, |
885 | bdev = bdget_disk(zram->disk, 0); | 818 | &zram->disk->part0); |
886 | |||
887 | if (!bdev) | ||
888 | return -ENOMEM; | ||
889 | 819 | ||
890 | mutex_lock(&bdev->bd_mutex); | 820 | if (rw == READ) { |
891 | /* Do not reset an active device! */ | 821 | atomic64_inc(&zram->stats.num_reads); |
892 | if (bdev->bd_openers) { | 822 | ret = zram_bvec_read(zram, bvec, index, offset); |
893 | ret = -EBUSY; | 823 | } else { |
894 | goto out; | 824 | atomic64_inc(&zram->stats.num_writes); |
825 | ret = zram_bvec_write(zram, bvec, index, offset); | ||
895 | } | 826 | } |
896 | 827 | ||
897 | ret = kstrtou16(buf, 10, &do_reset); | 828 | generic_end_io_acct(rw, &zram->disk->part0, start_time); |
898 | if (ret) | ||
899 | goto out; | ||
900 | 829 | ||
901 | if (!do_reset) { | 830 | if (unlikely(ret)) { |
902 | ret = -EINVAL; | 831 | if (rw == READ) |
903 | goto out; | 832 | atomic64_inc(&zram->stats.failed_reads); |
833 | else | ||
834 | atomic64_inc(&zram->stats.failed_writes); | ||
904 | } | 835 | } |
905 | 836 | ||
906 | /* Make sure all pending I/O is finished */ | ||
907 | fsync_bdev(bdev); | ||
908 | zram_reset_device(zram); | ||
909 | |||
910 | mutex_unlock(&bdev->bd_mutex); | ||
911 | revalidate_disk(zram->disk); | ||
912 | bdput(bdev); | ||
913 | |||
914 | return len; | ||
915 | |||
916 | out: | ||
917 | mutex_unlock(&bdev->bd_mutex); | ||
918 | bdput(bdev); | ||
919 | return ret; | 837 | return ret; |
920 | } | 838 | } |
921 | 839 | ||
@@ -1055,80 +973,185 @@ out: | |||
1055 | return err; | 973 | return err; |
1056 | } | 974 | } |
1057 | 975 | ||
1058 | static const struct block_device_operations zram_devops = { | 976 | static void zram_reset_device(struct zram *zram) |
1059 | .swap_slot_free_notify = zram_slot_free_notify, | 977 | { |
1060 | .rw_page = zram_rw_page, | 978 | struct zram_meta *meta; |
1061 | .owner = THIS_MODULE | 979 | struct zcomp *comp; |
1062 | }; | 980 | u64 disksize; |
1063 | 981 | ||
1064 | static DEVICE_ATTR_WO(compact); | 982 | down_write(&zram->init_lock); |
1065 | static DEVICE_ATTR_RW(disksize); | ||
1066 | static DEVICE_ATTR_RO(initstate); | ||
1067 | static DEVICE_ATTR_WO(reset); | ||
1068 | static DEVICE_ATTR_RO(orig_data_size); | ||
1069 | static DEVICE_ATTR_RO(mem_used_total); | ||
1070 | static DEVICE_ATTR_RW(mem_limit); | ||
1071 | static DEVICE_ATTR_RW(mem_used_max); | ||
1072 | static DEVICE_ATTR_RW(max_comp_streams); | ||
1073 | static DEVICE_ATTR_RW(comp_algorithm); | ||
1074 | 983 | ||
1075 | static ssize_t io_stat_show(struct device *dev, | 984 | zram->limit_pages = 0; |
1076 | struct device_attribute *attr, char *buf) | 985 | |
986 | if (!init_done(zram)) { | ||
987 | up_write(&zram->init_lock); | ||
988 | return; | ||
989 | } | ||
990 | |||
991 | meta = zram->meta; | ||
992 | comp = zram->comp; | ||
993 | disksize = zram->disksize; | ||
994 | /* | ||
995 | * Refcount will go down to 0 eventually and r/w handler | ||
996 | * cannot handle further I/O so it will bail out by | ||
997 | * check zram_meta_get. | ||
998 | */ | ||
999 | zram_meta_put(zram); | ||
1000 | /* | ||
1001 | * We want to free zram_meta in process context to avoid | ||
1002 | * deadlock between reclaim path and any other locks. | ||
1003 | */ | ||
1004 | wait_event(zram->io_done, atomic_read(&zram->refcount) == 0); | ||
1005 | |||
1006 | /* Reset stats */ | ||
1007 | memset(&zram->stats, 0, sizeof(zram->stats)); | ||
1008 | zram->disksize = 0; | ||
1009 | zram->max_comp_streams = 1; | ||
1010 | |||
1011 | set_capacity(zram->disk, 0); | ||
1012 | part_stat_set_all(&zram->disk->part0, 0); | ||
1013 | |||
1014 | up_write(&zram->init_lock); | ||
1015 | /* I/O operation under all of CPU are done so let's free */ | ||
1016 | zram_meta_free(meta, disksize); | ||
1017 | zcomp_destroy(comp); | ||
1018 | } | ||
1019 | |||
1020 | static ssize_t disksize_store(struct device *dev, | ||
1021 | struct device_attribute *attr, const char *buf, size_t len) | ||
1077 | { | 1022 | { |
1023 | u64 disksize; | ||
1024 | struct zcomp *comp; | ||
1025 | struct zram_meta *meta; | ||
1078 | struct zram *zram = dev_to_zram(dev); | 1026 | struct zram *zram = dev_to_zram(dev); |
1079 | ssize_t ret; | 1027 | int err; |
1080 | 1028 | ||
1081 | down_read(&zram->init_lock); | 1029 | disksize = memparse(buf, NULL); |
1082 | ret = scnprintf(buf, PAGE_SIZE, | 1030 | if (!disksize) |
1083 | "%8llu %8llu %8llu %8llu\n", | 1031 | return -EINVAL; |
1084 | (u64)atomic64_read(&zram->stats.failed_reads), | ||
1085 | (u64)atomic64_read(&zram->stats.failed_writes), | ||
1086 | (u64)atomic64_read(&zram->stats.invalid_io), | ||
1087 | (u64)atomic64_read(&zram->stats.notify_free)); | ||
1088 | up_read(&zram->init_lock); | ||
1089 | 1032 | ||
1090 | return ret; | 1033 | disksize = PAGE_ALIGN(disksize); |
1034 | meta = zram_meta_alloc(zram->disk->first_minor, disksize); | ||
1035 | if (!meta) | ||
1036 | return -ENOMEM; | ||
1037 | |||
1038 | comp = zcomp_create(zram->compressor, zram->max_comp_streams); | ||
1039 | if (IS_ERR(comp)) { | ||
1040 | pr_info("Cannot initialise %s compressing backend\n", | ||
1041 | zram->compressor); | ||
1042 | err = PTR_ERR(comp); | ||
1043 | goto out_free_meta; | ||
1044 | } | ||
1045 | |||
1046 | down_write(&zram->init_lock); | ||
1047 | if (init_done(zram)) { | ||
1048 | pr_info("Cannot change disksize for initialized device\n"); | ||
1049 | err = -EBUSY; | ||
1050 | goto out_destroy_comp; | ||
1051 | } | ||
1052 | |||
1053 | init_waitqueue_head(&zram->io_done); | ||
1054 | atomic_set(&zram->refcount, 1); | ||
1055 | zram->meta = meta; | ||
1056 | zram->comp = comp; | ||
1057 | zram->disksize = disksize; | ||
1058 | set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); | ||
1059 | up_write(&zram->init_lock); | ||
1060 | |||
1061 | /* | ||
1062 | * Revalidate disk out of the init_lock to avoid lockdep splat. | ||
1063 | * It's okay because disk's capacity is protected by init_lock | ||
1064 | * so that revalidate_disk always sees up-to-date capacity. | ||
1065 | */ | ||
1066 | revalidate_disk(zram->disk); | ||
1067 | |||
1068 | return len; | ||
1069 | |||
1070 | out_destroy_comp: | ||
1071 | up_write(&zram->init_lock); | ||
1072 | zcomp_destroy(comp); | ||
1073 | out_free_meta: | ||
1074 | zram_meta_free(meta, disksize); | ||
1075 | return err; | ||
1091 | } | 1076 | } |
1092 | 1077 | ||
1093 | static ssize_t mm_stat_show(struct device *dev, | 1078 | static ssize_t reset_store(struct device *dev, |
1094 | struct device_attribute *attr, char *buf) | 1079 | struct device_attribute *attr, const char *buf, size_t len) |
1095 | { | 1080 | { |
1096 | struct zram *zram = dev_to_zram(dev); | 1081 | int ret; |
1097 | u64 orig_size, mem_used = 0; | 1082 | unsigned short do_reset; |
1098 | long max_used; | 1083 | struct zram *zram; |
1099 | ssize_t ret; | 1084 | struct block_device *bdev; |
1100 | 1085 | ||
1101 | down_read(&zram->init_lock); | 1086 | ret = kstrtou16(buf, 10, &do_reset); |
1102 | if (init_done(zram)) | 1087 | if (ret) |
1103 | mem_used = zs_get_total_pages(zram->meta->mem_pool); | 1088 | return ret; |
1104 | 1089 | ||
1105 | orig_size = atomic64_read(&zram->stats.pages_stored); | 1090 | if (!do_reset) |
1106 | max_used = atomic_long_read(&zram->stats.max_used_pages); | 1091 | return -EINVAL; |
1107 | 1092 | ||
1108 | ret = scnprintf(buf, PAGE_SIZE, | 1093 | zram = dev_to_zram(dev); |
1109 | "%8llu %8llu %8llu %8lu %8ld %8llu %8llu\n", | 1094 | bdev = bdget_disk(zram->disk, 0); |
1110 | orig_size << PAGE_SHIFT, | 1095 | if (!bdev) |
1111 | (u64)atomic64_read(&zram->stats.compr_data_size), | 1096 | return -ENOMEM; |
1112 | mem_used << PAGE_SHIFT, | 1097 | |
1113 | zram->limit_pages << PAGE_SHIFT, | 1098 | mutex_lock(&bdev->bd_mutex); |
1114 | max_used << PAGE_SHIFT, | 1099 | /* Do not reset an active device or claimed device */ |
1115 | (u64)atomic64_read(&zram->stats.zero_pages), | 1100 | if (bdev->bd_openers || zram->claim) { |
1116 | (u64)atomic64_read(&zram->stats.num_migrated)); | 1101 | mutex_unlock(&bdev->bd_mutex); |
1117 | up_read(&zram->init_lock); | 1102 | bdput(bdev); |
1103 | return -EBUSY; | ||
1104 | } | ||
1105 | |||
1106 | /* From now on, anyone can't open /dev/zram[0-9] */ | ||
1107 | zram->claim = true; | ||
1108 | mutex_unlock(&bdev->bd_mutex); | ||
1109 | |||
1110 | /* Make sure all the pending I/O are finished */ | ||
1111 | fsync_bdev(bdev); | ||
1112 | zram_reset_device(zram); | ||
1113 | revalidate_disk(zram->disk); | ||
1114 | bdput(bdev); | ||
1115 | |||
1116 | mutex_lock(&bdev->bd_mutex); | ||
1117 | zram->claim = false; | ||
1118 | mutex_unlock(&bdev->bd_mutex); | ||
1119 | |||
1120 | return len; | ||
1121 | } | ||
1122 | |||
1123 | static int zram_open(struct block_device *bdev, fmode_t mode) | ||
1124 | { | ||
1125 | int ret = 0; | ||
1126 | struct zram *zram; | ||
1127 | |||
1128 | WARN_ON(!mutex_is_locked(&bdev->bd_mutex)); | ||
1129 | |||
1130 | zram = bdev->bd_disk->private_data; | ||
1131 | /* zram was claimed to reset so open request fails */ | ||
1132 | if (zram->claim) | ||
1133 | ret = -EBUSY; | ||
1118 | 1134 | ||
1119 | return ret; | 1135 | return ret; |
1120 | } | 1136 | } |
1121 | 1137 | ||
1122 | static DEVICE_ATTR_RO(io_stat); | 1138 | static const struct block_device_operations zram_devops = { |
1123 | static DEVICE_ATTR_RO(mm_stat); | 1139 | .open = zram_open, |
1124 | ZRAM_ATTR_RO(num_reads); | 1140 | .swap_slot_free_notify = zram_slot_free_notify, |
1125 | ZRAM_ATTR_RO(num_writes); | 1141 | .rw_page = zram_rw_page, |
1126 | ZRAM_ATTR_RO(failed_reads); | 1142 | .owner = THIS_MODULE |
1127 | ZRAM_ATTR_RO(failed_writes); | 1143 | }; |
1128 | ZRAM_ATTR_RO(invalid_io); | 1144 | |
1129 | ZRAM_ATTR_RO(notify_free); | 1145 | static DEVICE_ATTR_WO(compact); |
1130 | ZRAM_ATTR_RO(zero_pages); | 1146 | static DEVICE_ATTR_RW(disksize); |
1131 | ZRAM_ATTR_RO(compr_data_size); | 1147 | static DEVICE_ATTR_RO(initstate); |
1148 | static DEVICE_ATTR_WO(reset); | ||
1149 | static DEVICE_ATTR_RO(orig_data_size); | ||
1150 | static DEVICE_ATTR_RO(mem_used_total); | ||
1151 | static DEVICE_ATTR_RW(mem_limit); | ||
1152 | static DEVICE_ATTR_RW(mem_used_max); | ||
1153 | static DEVICE_ATTR_RW(max_comp_streams); | ||
1154 | static DEVICE_ATTR_RW(comp_algorithm); | ||
1132 | 1155 | ||
1133 | static struct attribute *zram_disk_attrs[] = { | 1156 | static struct attribute *zram_disk_attrs[] = { |
1134 | &dev_attr_disksize.attr, | 1157 | &dev_attr_disksize.attr, |
@@ -1158,10 +1181,24 @@ static struct attribute_group zram_disk_attr_group = { | |||
1158 | .attrs = zram_disk_attrs, | 1181 | .attrs = zram_disk_attrs, |
1159 | }; | 1182 | }; |
1160 | 1183 | ||
1161 | static int create_device(struct zram *zram, int device_id) | 1184 | /* |
1185 | * Allocate and initialize new zram device. the function returns | ||
1186 | * '>= 0' device_id upon success, and negative value otherwise. | ||
1187 | */ | ||
1188 | static int zram_add(void) | ||
1162 | { | 1189 | { |
1190 | struct zram *zram; | ||
1163 | struct request_queue *queue; | 1191 | struct request_queue *queue; |
1164 | int ret = -ENOMEM; | 1192 | int ret, device_id; |
1193 | |||
1194 | zram = kzalloc(sizeof(struct zram), GFP_KERNEL); | ||
1195 | if (!zram) | ||
1196 | return -ENOMEM; | ||
1197 | |||
1198 | ret = idr_alloc(&zram_index_idr, zram, 0, 0, GFP_KERNEL); | ||
1199 | if (ret < 0) | ||
1200 | goto out_free_dev; | ||
1201 | device_id = ret; | ||
1165 | 1202 | ||
1166 | init_rwsem(&zram->init_lock); | 1203 | init_rwsem(&zram->init_lock); |
1167 | 1204 | ||
@@ -1169,12 +1206,13 @@ static int create_device(struct zram *zram, int device_id) | |||
1169 | if (!queue) { | 1206 | if (!queue) { |
1170 | pr_err("Error allocating disk queue for device %d\n", | 1207 | pr_err("Error allocating disk queue for device %d\n", |
1171 | device_id); | 1208 | device_id); |
1172 | goto out; | 1209 | ret = -ENOMEM; |
1210 | goto out_free_idr; | ||
1173 | } | 1211 | } |
1174 | 1212 | ||
1175 | blk_queue_make_request(queue, zram_make_request); | 1213 | blk_queue_make_request(queue, zram_make_request); |
1176 | 1214 | ||
1177 | /* gendisk structure */ | 1215 | /* gendisk structure */ |
1178 | zram->disk = alloc_disk(1); | 1216 | zram->disk = alloc_disk(1); |
1179 | if (!zram->disk) { | 1217 | if (!zram->disk) { |
1180 | pr_warn("Error allocating disk structure for device %d\n", | 1218 | pr_warn("Error allocating disk structure for device %d\n", |
@@ -1232,90 +1270,177 @@ static int create_device(struct zram *zram, int device_id) | |||
1232 | strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor)); | 1270 | strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor)); |
1233 | zram->meta = NULL; | 1271 | zram->meta = NULL; |
1234 | zram->max_comp_streams = 1; | 1272 | zram->max_comp_streams = 1; |
1235 | return 0; | 1273 | |
1274 | pr_info("Added device: %s\n", zram->disk->disk_name); | ||
1275 | return device_id; | ||
1236 | 1276 | ||
1237 | out_free_disk: | 1277 | out_free_disk: |
1238 | del_gendisk(zram->disk); | 1278 | del_gendisk(zram->disk); |
1239 | put_disk(zram->disk); | 1279 | put_disk(zram->disk); |
1240 | out_free_queue: | 1280 | out_free_queue: |
1241 | blk_cleanup_queue(queue); | 1281 | blk_cleanup_queue(queue); |
1242 | out: | 1282 | out_free_idr: |
1283 | idr_remove(&zram_index_idr, device_id); | ||
1284 | out_free_dev: | ||
1285 | kfree(zram); | ||
1243 | return ret; | 1286 | return ret; |
1244 | } | 1287 | } |
1245 | 1288 | ||
1246 | static void destroy_devices(unsigned int nr) | 1289 | static int zram_remove(struct zram *zram) |
1290 | { | ||
1291 | struct block_device *bdev; | ||
1292 | |||
1293 | bdev = bdget_disk(zram->disk, 0); | ||
1294 | if (!bdev) | ||
1295 | return -ENOMEM; | ||
1296 | |||
1297 | mutex_lock(&bdev->bd_mutex); | ||
1298 | if (bdev->bd_openers || zram->claim) { | ||
1299 | mutex_unlock(&bdev->bd_mutex); | ||
1300 | bdput(bdev); | ||
1301 | return -EBUSY; | ||
1302 | } | ||
1303 | |||
1304 | zram->claim = true; | ||
1305 | mutex_unlock(&bdev->bd_mutex); | ||
1306 | |||
1307 | /* | ||
1308 | * Remove sysfs first, so no one will perform a disksize | ||
1309 | * store while we destroy the devices. This also helps during | ||
1310 | * hot_remove -- zram_reset_device() is the last holder of | ||
1311 | * ->init_lock, no later/concurrent disksize_store() or any | ||
1312 | * other sysfs handlers are possible. | ||
1313 | */ | ||
1314 | sysfs_remove_group(&disk_to_dev(zram->disk)->kobj, | ||
1315 | &zram_disk_attr_group); | ||
1316 | |||
1317 | /* Make sure all the pending I/O are finished */ | ||
1318 | fsync_bdev(bdev); | ||
1319 | zram_reset_device(zram); | ||
1320 | bdput(bdev); | ||
1321 | |||
1322 | pr_info("Removed device: %s\n", zram->disk->disk_name); | ||
1323 | |||
1324 | idr_remove(&zram_index_idr, zram->disk->first_minor); | ||
1325 | blk_cleanup_queue(zram->disk->queue); | ||
1326 | del_gendisk(zram->disk); | ||
1327 | put_disk(zram->disk); | ||
1328 | kfree(zram); | ||
1329 | return 0; | ||
1330 | } | ||
1331 | |||
1332 | /* zram-control sysfs attributes */ | ||
1333 | static ssize_t hot_add_show(struct class *class, | ||
1334 | struct class_attribute *attr, | ||
1335 | char *buf) | ||
1336 | { | ||
1337 | int ret; | ||
1338 | |||
1339 | mutex_lock(&zram_index_mutex); | ||
1340 | ret = zram_add(); | ||
1341 | mutex_unlock(&zram_index_mutex); | ||
1342 | |||
1343 | if (ret < 0) | ||
1344 | return ret; | ||
1345 | return scnprintf(buf, PAGE_SIZE, "%d\n", ret); | ||
1346 | } | ||
1347 | |||
1348 | static ssize_t hot_remove_store(struct class *class, | ||
1349 | struct class_attribute *attr, | ||
1350 | const char *buf, | ||
1351 | size_t count) | ||
1247 | { | 1352 | { |
1248 | struct zram *zram; | 1353 | struct zram *zram; |
1249 | unsigned int i; | 1354 | int ret, dev_id; |
1250 | 1355 | ||
1251 | for (i = 0; i < nr; i++) { | 1356 | /* dev_id is gendisk->first_minor, which is `int' */ |
1252 | zram = &zram_devices[i]; | 1357 | ret = kstrtoint(buf, 10, &dev_id); |
1253 | /* | 1358 | if (ret) |
1254 | * Remove sysfs first, so no one will perform a disksize | 1359 | return ret; |
1255 | * store while we destroy the devices | 1360 | if (dev_id < 0) |
1256 | */ | 1361 | return -EINVAL; |
1257 | sysfs_remove_group(&disk_to_dev(zram->disk)->kobj, | ||
1258 | &zram_disk_attr_group); | ||
1259 | 1362 | ||
1260 | zram_reset_device(zram); | 1363 | mutex_lock(&zram_index_mutex); |
1261 | 1364 | ||
1262 | blk_cleanup_queue(zram->disk->queue); | 1365 | zram = idr_find(&zram_index_idr, dev_id); |
1263 | del_gendisk(zram->disk); | 1366 | if (zram) |
1264 | put_disk(zram->disk); | 1367 | ret = zram_remove(zram); |
1265 | } | 1368 | else |
1369 | ret = -ENODEV; | ||
1266 | 1370 | ||
1267 | kfree(zram_devices); | 1371 | mutex_unlock(&zram_index_mutex); |
1372 | return ret ? ret : count; | ||
1373 | } | ||
1374 | |||
1375 | static struct class_attribute zram_control_class_attrs[] = { | ||
1376 | __ATTR_RO(hot_add), | ||
1377 | __ATTR_WO(hot_remove), | ||
1378 | __ATTR_NULL, | ||
1379 | }; | ||
1380 | |||
1381 | static struct class zram_control_class = { | ||
1382 | .name = "zram-control", | ||
1383 | .owner = THIS_MODULE, | ||
1384 | .class_attrs = zram_control_class_attrs, | ||
1385 | }; | ||
1386 | |||
1387 | static int zram_remove_cb(int id, void *ptr, void *data) | ||
1388 | { | ||
1389 | zram_remove(ptr); | ||
1390 | return 0; | ||
1391 | } | ||
1392 | |||
1393 | static void destroy_devices(void) | ||
1394 | { | ||
1395 | class_unregister(&zram_control_class); | ||
1396 | idr_for_each(&zram_index_idr, &zram_remove_cb, NULL); | ||
1397 | idr_destroy(&zram_index_idr); | ||
1268 | unregister_blkdev(zram_major, "zram"); | 1398 | unregister_blkdev(zram_major, "zram"); |
1269 | pr_info("Destroyed %u device(s)\n", nr); | ||
1270 | } | 1399 | } |
1271 | 1400 | ||
1272 | static int __init zram_init(void) | 1401 | static int __init zram_init(void) |
1273 | { | 1402 | { |
1274 | int ret, dev_id; | 1403 | int ret; |
1275 | 1404 | ||
1276 | if (num_devices > max_num_devices) { | 1405 | ret = class_register(&zram_control_class); |
1277 | pr_warn("Invalid value for num_devices: %u\n", | 1406 | if (ret) { |
1278 | num_devices); | 1407 | pr_warn("Unable to register zram-control class\n"); |
1279 | return -EINVAL; | 1408 | return ret; |
1280 | } | 1409 | } |
1281 | 1410 | ||
1282 | zram_major = register_blkdev(0, "zram"); | 1411 | zram_major = register_blkdev(0, "zram"); |
1283 | if (zram_major <= 0) { | 1412 | if (zram_major <= 0) { |
1284 | pr_warn("Unable to get major number\n"); | 1413 | pr_warn("Unable to get major number\n"); |
1414 | class_unregister(&zram_control_class); | ||
1285 | return -EBUSY; | 1415 | return -EBUSY; |
1286 | } | 1416 | } |
1287 | 1417 | ||
1288 | /* Allocate the device array and initialize each one */ | 1418 | while (num_devices != 0) { |
1289 | zram_devices = kzalloc(num_devices * sizeof(struct zram), GFP_KERNEL); | 1419 | mutex_lock(&zram_index_mutex); |
1290 | if (!zram_devices) { | 1420 | ret = zram_add(); |
1291 | unregister_blkdev(zram_major, "zram"); | 1421 | mutex_unlock(&zram_index_mutex); |
1292 | return -ENOMEM; | 1422 | if (ret < 0) |
1293 | } | ||
1294 | |||
1295 | for (dev_id = 0; dev_id < num_devices; dev_id++) { | ||
1296 | ret = create_device(&zram_devices[dev_id], dev_id); | ||
1297 | if (ret) | ||
1298 | goto out_error; | 1423 | goto out_error; |
1424 | num_devices--; | ||
1299 | } | 1425 | } |
1300 | 1426 | ||
1301 | pr_info("Created %u device(s)\n", num_devices); | ||
1302 | return 0; | 1427 | return 0; |
1303 | 1428 | ||
1304 | out_error: | 1429 | out_error: |
1305 | destroy_devices(dev_id); | 1430 | destroy_devices(); |
1306 | return ret; | 1431 | return ret; |
1307 | } | 1432 | } |
1308 | 1433 | ||
1309 | static void __exit zram_exit(void) | 1434 | static void __exit zram_exit(void) |
1310 | { | 1435 | { |
1311 | destroy_devices(num_devices); | 1436 | destroy_devices(); |
1312 | } | 1437 | } |
1313 | 1438 | ||
1314 | module_init(zram_init); | 1439 | module_init(zram_init); |
1315 | module_exit(zram_exit); | 1440 | module_exit(zram_exit); |
1316 | 1441 | ||
1317 | module_param(num_devices, uint, 0); | 1442 | module_param(num_devices, uint, 0); |
1318 | MODULE_PARM_DESC(num_devices, "Number of zram devices"); | 1443 | MODULE_PARM_DESC(num_devices, "Number of pre-created zram devices"); |
1319 | 1444 | ||
1320 | MODULE_LICENSE("Dual BSD/GPL"); | 1445 | MODULE_LICENSE("Dual BSD/GPL"); |
1321 | MODULE_AUTHOR("Nitin Gupta <ngupta@vflare.org>"); | 1446 | MODULE_AUTHOR("Nitin Gupta <ngupta@vflare.org>"); |
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index 570c598f4ce9..6dbe2df506bf 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h | |||
@@ -20,12 +20,6 @@ | |||
20 | 20 | ||
21 | #include "zcomp.h" | 21 | #include "zcomp.h" |
22 | 22 | ||
23 | /* | ||
24 | * Some arbitrary value. This is just to catch | ||
25 | * invalid value for num_devices module parameter. | ||
26 | */ | ||
27 | static const unsigned max_num_devices = 32; | ||
28 | |||
29 | /*-- Configurable parameters */ | 23 | /*-- Configurable parameters */ |
30 | 24 | ||
31 | /* | 25 | /* |
@@ -121,5 +115,9 @@ struct zram { | |||
121 | */ | 115 | */ |
122 | u64 disksize; /* bytes */ | 116 | u64 disksize; /* bytes */ |
123 | char compressor[10]; | 117 | char compressor[10]; |
118 | /* | ||
119 | * zram is claimed so open request will be failed | ||
120 | */ | ||
121 | bool claim; /* Protected by bdev->bd_mutex */ | ||
124 | }; | 122 | }; |
125 | #endif | 123 | #endif |
diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index cc016c615c19..5de3ed29282c 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c | |||
@@ -144,7 +144,9 @@ static struct kobj_type __refdata memmap_ktype = { | |||
144 | * | 144 | * |
145 | * Common implementation of firmware_map_add() and firmware_map_add_early() | 145 | * Common implementation of firmware_map_add() and firmware_map_add_early() |
146 | * which expects a pre-allocated struct firmware_map_entry. | 146 | * which expects a pre-allocated struct firmware_map_entry. |
147 | **/ | 147 | * |
148 | * Return: 0 always | ||
149 | */ | ||
148 | static int firmware_map_add_entry(u64 start, u64 end, | 150 | static int firmware_map_add_entry(u64 start, u64 end, |
149 | const char *type, | 151 | const char *type, |
150 | struct firmware_map_entry *entry) | 152 | struct firmware_map_entry *entry) |
@@ -170,7 +172,7 @@ static int firmware_map_add_entry(u64 start, u64 end, | |||
170 | * @entry: removed entry. | 172 | * @entry: removed entry. |
171 | * | 173 | * |
172 | * The caller must hold map_entries_lock, and release it properly. | 174 | * The caller must hold map_entries_lock, and release it properly. |
173 | **/ | 175 | */ |
174 | static inline void firmware_map_remove_entry(struct firmware_map_entry *entry) | 176 | static inline void firmware_map_remove_entry(struct firmware_map_entry *entry) |
175 | { | 177 | { |
176 | list_del(&entry->list); | 178 | list_del(&entry->list); |
@@ -208,7 +210,7 @@ static inline void remove_sysfs_fw_map_entry(struct firmware_map_entry *entry) | |||
208 | kobject_put(&entry->kobj); | 210 | kobject_put(&entry->kobj); |
209 | } | 211 | } |
210 | 212 | ||
211 | /* | 213 | /** |
212 | * firmware_map_find_entry_in_list() - Search memmap entry in a given list. | 214 | * firmware_map_find_entry_in_list() - Search memmap entry in a given list. |
213 | * @start: Start of the memory range. | 215 | * @start: Start of the memory range. |
214 | * @end: End of the memory range (exclusive). | 216 | * @end: End of the memory range (exclusive). |
@@ -236,7 +238,7 @@ firmware_map_find_entry_in_list(u64 start, u64 end, const char *type, | |||
236 | return NULL; | 238 | return NULL; |
237 | } | 239 | } |
238 | 240 | ||
239 | /* | 241 | /** |
240 | * firmware_map_find_entry() - Search memmap entry in map_entries. | 242 | * firmware_map_find_entry() - Search memmap entry in map_entries. |
241 | * @start: Start of the memory range. | 243 | * @start: Start of the memory range. |
242 | * @end: End of the memory range (exclusive). | 244 | * @end: End of the memory range (exclusive). |
@@ -254,7 +256,7 @@ firmware_map_find_entry(u64 start, u64 end, const char *type) | |||
254 | return firmware_map_find_entry_in_list(start, end, type, &map_entries); | 256 | return firmware_map_find_entry_in_list(start, end, type, &map_entries); |
255 | } | 257 | } |
256 | 258 | ||
257 | /* | 259 | /** |
258 | * firmware_map_find_entry_bootmem() - Search memmap entry in map_entries_bootmem. | 260 | * firmware_map_find_entry_bootmem() - Search memmap entry in map_entries_bootmem. |
259 | * @start: Start of the memory range. | 261 | * @start: Start of the memory range. |
260 | * @end: End of the memory range (exclusive). | 262 | * @end: End of the memory range (exclusive). |
@@ -283,8 +285,8 @@ firmware_map_find_entry_bootmem(u64 start, u64 end, const char *type) | |||
283 | * similar to function firmware_map_add_early(). The only difference is that | 285 | * similar to function firmware_map_add_early(). The only difference is that |
284 | * it will create the syfs entry dynamically. | 286 | * it will create the syfs entry dynamically. |
285 | * | 287 | * |
286 | * Returns 0 on success, or -ENOMEM if no memory could be allocated. | 288 | * Return: 0 on success, or -ENOMEM if no memory could be allocated. |
287 | **/ | 289 | */ |
288 | int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type) | 290 | int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type) |
289 | { | 291 | { |
290 | struct firmware_map_entry *entry; | 292 | struct firmware_map_entry *entry; |
@@ -325,8 +327,8 @@ int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type) | |||
325 | * | 327 | * |
326 | * That function must be called before late_initcall. | 328 | * That function must be called before late_initcall. |
327 | * | 329 | * |
328 | * Returns 0 on success, or -ENOMEM if no memory could be allocated. | 330 | * Return: 0 on success, or -ENOMEM if no memory could be allocated. |
329 | **/ | 331 | */ |
330 | int __init firmware_map_add_early(u64 start, u64 end, const char *type) | 332 | int __init firmware_map_add_early(u64 start, u64 end, const char *type) |
331 | { | 333 | { |
332 | struct firmware_map_entry *entry; | 334 | struct firmware_map_entry *entry; |
@@ -346,8 +348,8 @@ int __init firmware_map_add_early(u64 start, u64 end, const char *type) | |||
346 | * | 348 | * |
347 | * removes a firmware mapping entry. | 349 | * removes a firmware mapping entry. |
348 | * | 350 | * |
349 | * Returns 0 on success, or -EINVAL if no entry. | 351 | * Return: 0 on success, or -EINVAL if no entry. |
350 | **/ | 352 | */ |
351 | int __meminit firmware_map_remove(u64 start, u64 end, const char *type) | 353 | int __meminit firmware_map_remove(u64 start, u64 end, const char *type) |
352 | { | 354 | { |
353 | struct firmware_map_entry *entry; | 355 | struct firmware_map_entry *entry; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 4dbed4a67aaf..8d9f89b4519d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2024,7 +2024,6 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev) | |||
2024 | { | 2024 | { |
2025 | char b[BDEVNAME_SIZE]; | 2025 | char b[BDEVNAME_SIZE]; |
2026 | struct kobject *ko; | 2026 | struct kobject *ko; |
2027 | char *s; | ||
2028 | int err; | 2027 | int err; |
2029 | 2028 | ||
2030 | /* prevent duplicates */ | 2029 | /* prevent duplicates */ |
@@ -2070,8 +2069,7 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev) | |||
2070 | return -EBUSY; | 2069 | return -EBUSY; |
2071 | } | 2070 | } |
2072 | bdevname(rdev->bdev,b); | 2071 | bdevname(rdev->bdev,b); |
2073 | while ( (s=strchr(b, '/')) != NULL) | 2072 | strreplace(b, '/', '!'); |
2074 | *s = '!'; | ||
2075 | 2073 | ||
2076 | rdev->mddev = mddev; | 2074 | rdev->mddev = mddev; |
2077 | printk(KERN_INFO "md: bind<%s>\n", b); | 2075 | printk(KERN_INFO "md: bind<%s>\n", b); |
diff --git a/drivers/misc/altera-stapl/altera.c b/drivers/misc/altera-stapl/altera.c index bca2630d006f..f53e217e963f 100644 --- a/drivers/misc/altera-stapl/altera.c +++ b/drivers/misc/altera-stapl/altera.c | |||
@@ -2451,7 +2451,7 @@ int altera_init(struct altera_config *config, const struct firmware *fw) | |||
2451 | 2451 | ||
2452 | astate->config = config; | 2452 | astate->config = config; |
2453 | if (!astate->config->jtag_io) { | 2453 | if (!astate->config->jtag_io) { |
2454 | dprintk(KERN_INFO "%s: using byteblaster!\n", __func__); | 2454 | dprintk("%s: using byteblaster!\n", __func__); |
2455 | astate->config->jtag_io = netup_jtag_io_lpt; | 2455 | astate->config->jtag_io = netup_jtag_io_lpt; |
2456 | } | 2456 | } |
2457 | 2457 | ||
diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index 36f5d52775a9..9a60bd4d3c49 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c | |||
@@ -220,7 +220,7 @@ static unsigned long lookup_addr(char *arg) | |||
220 | else if (!strcmp(arg, "sys_open")) | 220 | else if (!strcmp(arg, "sys_open")) |
221 | addr = (unsigned long)do_sys_open; | 221 | addr = (unsigned long)do_sys_open; |
222 | else if (!strcmp(arg, "do_fork")) | 222 | else if (!strcmp(arg, "do_fork")) |
223 | addr = (unsigned long)do_fork; | 223 | addr = (unsigned long)_do_fork; |
224 | else if (!strcmp(arg, "hw_break_val")) | 224 | else if (!strcmp(arg, "hw_break_val")) |
225 | addr = (unsigned long)&hw_break_val; | 225 | addr = (unsigned long)&hw_break_val; |
226 | addr = (unsigned long) dereference_function_descriptor((void *)addr); | 226 | addr = (unsigned long) dereference_function_descriptor((void *)addr); |
diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c index fe3ad0ca9a3e..b8374cdaf9c9 100644 --- a/drivers/misc/spear13xx_pcie_gadget.c +++ b/drivers/misc/spear13xx_pcie_gadget.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * drivers/misc/spear13xx_pcie_gadget.c | 2 | * drivers/misc/spear13xx_pcie_gadget.c |
3 | * | 3 | * |
4 | * Copyright (C) 2010 ST Microelectronics | 4 | * Copyright (C) 2010 ST Microelectronics |
5 | * Pratyush Anand<pratyush.anand@st.com> | 5 | * Pratyush Anand<pratyush.anand@gmail.com> |
6 | * | 6 | * |
7 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
8 | * License version 2. This program is licensed "as is" without any | 8 | * License version 2. This program is licensed "as is" without any |
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 15731d1db918..97f3acd44798 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c | |||
@@ -79,6 +79,12 @@ static LIST_HEAD(target_list); | |||
79 | /* This needs to be a spinlock because write_msg() cannot sleep */ | 79 | /* This needs to be a spinlock because write_msg() cannot sleep */ |
80 | static DEFINE_SPINLOCK(target_list_lock); | 80 | static DEFINE_SPINLOCK(target_list_lock); |
81 | 81 | ||
82 | /* | ||
83 | * Console driver for extended netconsoles. Registered on the first use to | ||
84 | * avoid unnecessarily enabling ext message formatting. | ||
85 | */ | ||
86 | static struct console netconsole_ext; | ||
87 | |||
82 | /** | 88 | /** |
83 | * struct netconsole_target - Represents a configured netconsole target. | 89 | * struct netconsole_target - Represents a configured netconsole target. |
84 | * @list: Links this target into the target_list. | 90 | * @list: Links this target into the target_list. |
@@ -104,14 +110,15 @@ struct netconsole_target { | |||
104 | #ifdef CONFIG_NETCONSOLE_DYNAMIC | 110 | #ifdef CONFIG_NETCONSOLE_DYNAMIC |
105 | struct config_item item; | 111 | struct config_item item; |
106 | #endif | 112 | #endif |
107 | int enabled; | 113 | bool enabled; |
108 | struct mutex mutex; | 114 | bool extended; |
109 | struct netpoll np; | 115 | struct netpoll np; |
110 | }; | 116 | }; |
111 | 117 | ||
112 | #ifdef CONFIG_NETCONSOLE_DYNAMIC | 118 | #ifdef CONFIG_NETCONSOLE_DYNAMIC |
113 | 119 | ||
114 | static struct configfs_subsystem netconsole_subsys; | 120 | static struct configfs_subsystem netconsole_subsys; |
121 | static DEFINE_MUTEX(dynamic_netconsole_mutex); | ||
115 | 122 | ||
116 | static int __init dynamic_netconsole_init(void) | 123 | static int __init dynamic_netconsole_init(void) |
117 | { | 124 | { |
@@ -185,9 +192,13 @@ static struct netconsole_target *alloc_param_target(char *target_config) | |||
185 | strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ); | 192 | strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ); |
186 | nt->np.local_port = 6665; | 193 | nt->np.local_port = 6665; |
187 | nt->np.remote_port = 6666; | 194 | nt->np.remote_port = 6666; |
188 | mutex_init(&nt->mutex); | ||
189 | eth_broadcast_addr(nt->np.remote_mac); | 195 | eth_broadcast_addr(nt->np.remote_mac); |
190 | 196 | ||
197 | if (*target_config == '+') { | ||
198 | nt->extended = true; | ||
199 | target_config++; | ||
200 | } | ||
201 | |||
191 | /* Parse parameters and setup netpoll */ | 202 | /* Parse parameters and setup netpoll */ |
192 | err = netpoll_parse_options(&nt->np, target_config); | 203 | err = netpoll_parse_options(&nt->np, target_config); |
193 | if (err) | 204 | if (err) |
@@ -197,7 +208,7 @@ static struct netconsole_target *alloc_param_target(char *target_config) | |||
197 | if (err) | 208 | if (err) |
198 | goto fail; | 209 | goto fail; |
199 | 210 | ||
200 | nt->enabled = 1; | 211 | nt->enabled = true; |
201 | 212 | ||
202 | return nt; | 213 | return nt; |
203 | 214 | ||
@@ -258,6 +269,11 @@ static ssize_t show_enabled(struct netconsole_target *nt, char *buf) | |||
258 | return snprintf(buf, PAGE_SIZE, "%d\n", nt->enabled); | 269 | return snprintf(buf, PAGE_SIZE, "%d\n", nt->enabled); |
259 | } | 270 | } |
260 | 271 | ||
272 | static ssize_t show_extended(struct netconsole_target *nt, char *buf) | ||
273 | { | ||
274 | return snprintf(buf, PAGE_SIZE, "%d\n", nt->extended); | ||
275 | } | ||
276 | |||
261 | static ssize_t show_dev_name(struct netconsole_target *nt, char *buf) | 277 | static ssize_t show_dev_name(struct netconsole_target *nt, char *buf) |
262 | { | 278 | { |
263 | return snprintf(buf, PAGE_SIZE, "%s\n", nt->np.dev_name); | 279 | return snprintf(buf, PAGE_SIZE, "%s\n", nt->np.dev_name); |
@@ -322,13 +338,18 @@ static ssize_t store_enabled(struct netconsole_target *nt, | |||
322 | return err; | 338 | return err; |
323 | if (enabled < 0 || enabled > 1) | 339 | if (enabled < 0 || enabled > 1) |
324 | return -EINVAL; | 340 | return -EINVAL; |
325 | if (enabled == nt->enabled) { | 341 | if ((bool)enabled == nt->enabled) { |
326 | pr_info("network logging has already %s\n", | 342 | pr_info("network logging has already %s\n", |
327 | nt->enabled ? "started" : "stopped"); | 343 | nt->enabled ? "started" : "stopped"); |
328 | return -EINVAL; | 344 | return -EINVAL; |
329 | } | 345 | } |
330 | 346 | ||
331 | if (enabled) { /* 1 */ | 347 | if (enabled) { /* true */ |
348 | if (nt->extended && !(netconsole_ext.flags & CON_ENABLED)) { | ||
349 | netconsole_ext.flags |= CON_ENABLED; | ||
350 | register_console(&netconsole_ext); | ||
351 | } | ||
352 | |||
332 | /* | 353 | /* |
333 | * Skip netpoll_parse_options() -- all the attributes are | 354 | * Skip netpoll_parse_options() -- all the attributes are |
334 | * already configured via configfs. Just print them out. | 355 | * already configured via configfs. Just print them out. |
@@ -340,13 +361,13 @@ static ssize_t store_enabled(struct netconsole_target *nt, | |||
340 | return err; | 361 | return err; |
341 | 362 | ||
342 | pr_info("netconsole: network logging started\n"); | 363 | pr_info("netconsole: network logging started\n"); |
343 | } else { /* 0 */ | 364 | } else { /* false */ |
344 | /* We need to disable the netconsole before cleaning it up | 365 | /* We need to disable the netconsole before cleaning it up |
345 | * otherwise we might end up in write_msg() with | 366 | * otherwise we might end up in write_msg() with |
346 | * nt->np.dev == NULL and nt->enabled == 1 | 367 | * nt->np.dev == NULL and nt->enabled == true |
347 | */ | 368 | */ |
348 | spin_lock_irqsave(&target_list_lock, flags); | 369 | spin_lock_irqsave(&target_list_lock, flags); |
349 | nt->enabled = 0; | 370 | nt->enabled = false; |
350 | spin_unlock_irqrestore(&target_list_lock, flags); | 371 | spin_unlock_irqrestore(&target_list_lock, flags); |
351 | netpoll_cleanup(&nt->np); | 372 | netpoll_cleanup(&nt->np); |
352 | } | 373 | } |
@@ -356,6 +377,30 @@ static ssize_t store_enabled(struct netconsole_target *nt, | |||
356 | return strnlen(buf, count); | 377 | return strnlen(buf, count); |
357 | } | 378 | } |
358 | 379 | ||
380 | static ssize_t store_extended(struct netconsole_target *nt, | ||
381 | const char *buf, | ||
382 | size_t count) | ||
383 | { | ||
384 | int extended; | ||
385 | int err; | ||
386 | |||
387 | if (nt->enabled) { | ||
388 | pr_err("target (%s) is enabled, disable to update parameters\n", | ||
389 | config_item_name(&nt->item)); | ||
390 | return -EINVAL; | ||
391 | } | ||
392 | |||
393 | err = kstrtoint(buf, 10, &extended); | ||
394 | if (err < 0) | ||
395 | return err; | ||
396 | if (extended < 0 || extended > 1) | ||
397 | return -EINVAL; | ||
398 | |||
399 | nt->extended = extended; | ||
400 | |||
401 | return strnlen(buf, count); | ||
402 | } | ||
403 | |||
359 | static ssize_t store_dev_name(struct netconsole_target *nt, | 404 | static ssize_t store_dev_name(struct netconsole_target *nt, |
360 | const char *buf, | 405 | const char *buf, |
361 | size_t count) | 406 | size_t count) |
@@ -508,6 +553,7 @@ static struct netconsole_target_attr netconsole_target_##_name = \ | |||
508 | __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, show_##_name, store_##_name) | 553 | __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, show_##_name, store_##_name) |
509 | 554 | ||
510 | NETCONSOLE_TARGET_ATTR_RW(enabled); | 555 | NETCONSOLE_TARGET_ATTR_RW(enabled); |
556 | NETCONSOLE_TARGET_ATTR_RW(extended); | ||
511 | NETCONSOLE_TARGET_ATTR_RW(dev_name); | 557 | NETCONSOLE_TARGET_ATTR_RW(dev_name); |
512 | NETCONSOLE_TARGET_ATTR_RW(local_port); | 558 | NETCONSOLE_TARGET_ATTR_RW(local_port); |
513 | NETCONSOLE_TARGET_ATTR_RW(remote_port); | 559 | NETCONSOLE_TARGET_ATTR_RW(remote_port); |
@@ -518,6 +564,7 @@ NETCONSOLE_TARGET_ATTR_RW(remote_mac); | |||
518 | 564 | ||
519 | static struct configfs_attribute *netconsole_target_attrs[] = { | 565 | static struct configfs_attribute *netconsole_target_attrs[] = { |
520 | &netconsole_target_enabled.attr, | 566 | &netconsole_target_enabled.attr, |
567 | &netconsole_target_extended.attr, | ||
521 | &netconsole_target_dev_name.attr, | 568 | &netconsole_target_dev_name.attr, |
522 | &netconsole_target_local_port.attr, | 569 | &netconsole_target_local_port.attr, |
523 | &netconsole_target_remote_port.attr, | 570 | &netconsole_target_remote_port.attr, |
@@ -562,10 +609,10 @@ static ssize_t netconsole_target_attr_store(struct config_item *item, | |||
562 | struct netconsole_target_attr *na = | 609 | struct netconsole_target_attr *na = |
563 | container_of(attr, struct netconsole_target_attr, attr); | 610 | container_of(attr, struct netconsole_target_attr, attr); |
564 | 611 | ||
565 | mutex_lock(&nt->mutex); | 612 | mutex_lock(&dynamic_netconsole_mutex); |
566 | if (na->store) | 613 | if (na->store) |
567 | ret = na->store(nt, buf, count); | 614 | ret = na->store(nt, buf, count); |
568 | mutex_unlock(&nt->mutex); | 615 | mutex_unlock(&dynamic_netconsole_mutex); |
569 | 616 | ||
570 | return ret; | 617 | return ret; |
571 | } | 618 | } |
@@ -594,7 +641,7 @@ static struct config_item *make_netconsole_target(struct config_group *group, | |||
594 | 641 | ||
595 | /* | 642 | /* |
596 | * Allocate and initialize with defaults. | 643 | * Allocate and initialize with defaults. |
597 | * Target is disabled at creation (enabled == 0). | 644 | * Target is disabled at creation (!enabled). |
598 | */ | 645 | */ |
599 | nt = kzalloc(sizeof(*nt), GFP_KERNEL); | 646 | nt = kzalloc(sizeof(*nt), GFP_KERNEL); |
600 | if (!nt) | 647 | if (!nt) |
@@ -604,7 +651,6 @@ static struct config_item *make_netconsole_target(struct config_group *group, | |||
604 | strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ); | 651 | strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ); |
605 | nt->np.local_port = 6665; | 652 | nt->np.local_port = 6665; |
606 | nt->np.remote_port = 6666; | 653 | nt->np.remote_port = 6666; |
607 | mutex_init(&nt->mutex); | ||
608 | eth_broadcast_addr(nt->np.remote_mac); | 654 | eth_broadcast_addr(nt->np.remote_mac); |
609 | 655 | ||
610 | /* Initialize the config_item member */ | 656 | /* Initialize the config_item member */ |
@@ -695,7 +741,7 @@ restart: | |||
695 | spin_lock_irqsave(&target_list_lock, flags); | 741 | spin_lock_irqsave(&target_list_lock, flags); |
696 | dev_put(nt->np.dev); | 742 | dev_put(nt->np.dev); |
697 | nt->np.dev = NULL; | 743 | nt->np.dev = NULL; |
698 | nt->enabled = 0; | 744 | nt->enabled = false; |
699 | stopped = true; | 745 | stopped = true; |
700 | netconsole_target_put(nt); | 746 | netconsole_target_put(nt); |
701 | goto restart; | 747 | goto restart; |
@@ -729,6 +775,82 @@ static struct notifier_block netconsole_netdev_notifier = { | |||
729 | .notifier_call = netconsole_netdev_event, | 775 | .notifier_call = netconsole_netdev_event, |
730 | }; | 776 | }; |
731 | 777 | ||
778 | /** | ||
779 | * send_ext_msg_udp - send extended log message to target | ||
780 | * @nt: target to send message to | ||
781 | * @msg: extended log message to send | ||
782 | * @msg_len: length of message | ||
783 | * | ||
784 | * Transfer extended log @msg to @nt. If @msg is longer than | ||
785 | * MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with | ||
786 | * ncfrag header field added to identify them. | ||
787 | */ | ||
788 | static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg, | ||
789 | int msg_len) | ||
790 | { | ||
791 | static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */ | ||
792 | const char *header, *body; | ||
793 | int offset = 0; | ||
794 | int header_len, body_len; | ||
795 | |||
796 | if (msg_len <= MAX_PRINT_CHUNK) { | ||
797 | netpoll_send_udp(&nt->np, msg, msg_len); | ||
798 | return; | ||
799 | } | ||
800 | |||
801 | /* need to insert extra header fields, detect header and body */ | ||
802 | header = msg; | ||
803 | body = memchr(msg, ';', msg_len); | ||
804 | if (WARN_ON_ONCE(!body)) | ||
805 | return; | ||
806 | |||
807 | header_len = body - header; | ||
808 | body_len = msg_len - header_len - 1; | ||
809 | body++; | ||
810 | |||
811 | /* | ||
812 | * Transfer multiple chunks with the following extra header. | ||
813 | * "ncfrag=<byte-offset>/<total-bytes>" | ||
814 | */ | ||
815 | memcpy(buf, header, header_len); | ||
816 | |||
817 | while (offset < body_len) { | ||
818 | int this_header = header_len; | ||
819 | int this_chunk; | ||
820 | |||
821 | this_header += scnprintf(buf + this_header, | ||
822 | sizeof(buf) - this_header, | ||
823 | ",ncfrag=%d/%d;", offset, body_len); | ||
824 | |||
825 | this_chunk = min(body_len - offset, | ||
826 | MAX_PRINT_CHUNK - this_header); | ||
827 | if (WARN_ON_ONCE(this_chunk <= 0)) | ||
828 | return; | ||
829 | |||
830 | memcpy(buf + this_header, body + offset, this_chunk); | ||
831 | |||
832 | netpoll_send_udp(&nt->np, buf, this_header + this_chunk); | ||
833 | |||
834 | offset += this_chunk; | ||
835 | } | ||
836 | } | ||
837 | |||
838 | static void write_ext_msg(struct console *con, const char *msg, | ||
839 | unsigned int len) | ||
840 | { | ||
841 | struct netconsole_target *nt; | ||
842 | unsigned long flags; | ||
843 | |||
844 | if ((oops_only && !oops_in_progress) || list_empty(&target_list)) | ||
845 | return; | ||
846 | |||
847 | spin_lock_irqsave(&target_list_lock, flags); | ||
848 | list_for_each_entry(nt, &target_list, list) | ||
849 | if (nt->extended && nt->enabled && netif_running(nt->np.dev)) | ||
850 | send_ext_msg_udp(nt, msg, len); | ||
851 | spin_unlock_irqrestore(&target_list_lock, flags); | ||
852 | } | ||
853 | |||
732 | static void write_msg(struct console *con, const char *msg, unsigned int len) | 854 | static void write_msg(struct console *con, const char *msg, unsigned int len) |
733 | { | 855 | { |
734 | int frag, left; | 856 | int frag, left; |
@@ -744,8 +866,7 @@ static void write_msg(struct console *con, const char *msg, unsigned int len) | |||
744 | 866 | ||
745 | spin_lock_irqsave(&target_list_lock, flags); | 867 | spin_lock_irqsave(&target_list_lock, flags); |
746 | list_for_each_entry(nt, &target_list, list) { | 868 | list_for_each_entry(nt, &target_list, list) { |
747 | netconsole_target_get(nt); | 869 | if (!nt->extended && nt->enabled && netif_running(nt->np.dev)) { |
748 | if (nt->enabled && netif_running(nt->np.dev)) { | ||
749 | /* | 870 | /* |
750 | * We nest this inside the for-each-target loop above | 871 | * We nest this inside the for-each-target loop above |
751 | * so that we're able to get as much logging out to | 872 | * so that we're able to get as much logging out to |
@@ -760,11 +881,16 @@ static void write_msg(struct console *con, const char *msg, unsigned int len) | |||
760 | left -= frag; | 881 | left -= frag; |
761 | } | 882 | } |
762 | } | 883 | } |
763 | netconsole_target_put(nt); | ||
764 | } | 884 | } |
765 | spin_unlock_irqrestore(&target_list_lock, flags); | 885 | spin_unlock_irqrestore(&target_list_lock, flags); |
766 | } | 886 | } |
767 | 887 | ||
888 | static struct console netconsole_ext = { | ||
889 | .name = "netcon_ext", | ||
890 | .flags = CON_EXTENDED, /* starts disabled, registered on first use */ | ||
891 | .write = write_ext_msg, | ||
892 | }; | ||
893 | |||
768 | static struct console netconsole = { | 894 | static struct console netconsole = { |
769 | .name = "netcon", | 895 | .name = "netcon", |
770 | .flags = CON_ENABLED, | 896 | .flags = CON_ENABLED, |
@@ -787,7 +913,11 @@ static int __init init_netconsole(void) | |||
787 | goto fail; | 913 | goto fail; |
788 | } | 914 | } |
789 | /* Dump existing printks when we register */ | 915 | /* Dump existing printks when we register */ |
790 | netconsole.flags |= CON_PRINTBUFFER; | 916 | if (nt->extended) |
917 | netconsole_ext.flags |= CON_PRINTBUFFER | | ||
918 | CON_ENABLED; | ||
919 | else | ||
920 | netconsole.flags |= CON_PRINTBUFFER; | ||
791 | 921 | ||
792 | spin_lock_irqsave(&target_list_lock, flags); | 922 | spin_lock_irqsave(&target_list_lock, flags); |
793 | list_add(&nt->list, &target_list); | 923 | list_add(&nt->list, &target_list); |
@@ -803,6 +933,8 @@ static int __init init_netconsole(void) | |||
803 | if (err) | 933 | if (err) |
804 | goto undonotifier; | 934 | goto undonotifier; |
805 | 935 | ||
936 | if (netconsole_ext.flags & CON_ENABLED) | ||
937 | register_console(&netconsole_ext); | ||
806 | register_console(&netconsole); | 938 | register_console(&netconsole); |
807 | pr_info("network logging started\n"); | 939 | pr_info("network logging started\n"); |
808 | 940 | ||
@@ -831,6 +963,7 @@ static void __exit cleanup_netconsole(void) | |||
831 | { | 963 | { |
832 | struct netconsole_target *nt, *tmp; | 964 | struct netconsole_target *nt, *tmp; |
833 | 965 | ||
966 | unregister_console(&netconsole_ext); | ||
834 | unregister_console(&netconsole); | 967 | unregister_console(&netconsole); |
835 | dynamic_netconsole_exit(); | 968 | dynamic_netconsole_exit(); |
836 | unregister_netdevice_notifier(&netconsole_netdev_notifier); | 969 | unregister_netdevice_notifier(&netconsole_netdev_notifier); |
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c index dfec4281bd50..c49fbdc0f6e4 100644 --- a/drivers/pci/host/pcie-spear13xx.c +++ b/drivers/pci/host/pcie-spear13xx.c | |||
@@ -4,8 +4,8 @@ | |||
4 | * SPEAr13xx PCIe Glue Layer Source Code | 4 | * SPEAr13xx PCIe Glue Layer Source Code |
5 | * | 5 | * |
6 | * Copyright (C) 2010-2014 ST Microelectronics | 6 | * Copyright (C) 2010-2014 ST Microelectronics |
7 | * Pratyush Anand <pratyush.anand@st.com> | 7 | * Pratyush Anand <pratyush.anand@gmail.com> |
8 | * Mohit Kumar <mohit.kumar@st.com> | 8 | * Mohit Kumar <mohit.kumar.dhaka@gmail.com> |
9 | * | 9 | * |
10 | * This file is licensed under the terms of the GNU General Public | 10 | * This file is licensed under the terms of the GNU General Public |
11 | * License version 2. This program is licensed "as is" without any | 11 | * License version 2. This program is licensed "as is" without any |
@@ -386,5 +386,5 @@ static int __init spear13xx_pcie_init(void) | |||
386 | module_init(spear13xx_pcie_init); | 386 | module_init(spear13xx_pcie_init); |
387 | 387 | ||
388 | MODULE_DESCRIPTION("ST Microelectronics SPEAr13xx PCIe host controller driver"); | 388 | MODULE_DESCRIPTION("ST Microelectronics SPEAr13xx PCIe host controller driver"); |
389 | MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>"); | 389 | MODULE_AUTHOR("Pratyush Anand <pratyush.anand@gmail.com>"); |
390 | MODULE_LICENSE("GPL v2"); | 390 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/phy/phy-spear1310-miphy.c b/drivers/phy/phy-spear1310-miphy.c index 65ae640cfbd1..45d0005b2203 100644 --- a/drivers/phy/phy-spear1310-miphy.c +++ b/drivers/phy/phy-spear1310-miphy.c | |||
@@ -2,8 +2,8 @@ | |||
2 | * ST SPEAr1310-miphy driver | 2 | * ST SPEAr1310-miphy driver |
3 | * | 3 | * |
4 | * Copyright (C) 2014 ST Microelectronics | 4 | * Copyright (C) 2014 ST Microelectronics |
5 | * Pratyush Anand <pratyush.anand@st.com> | 5 | * Pratyush Anand <pratyush.anand@gmail.com> |
6 | * Mohit Kumar <mohit.kumar@st.com> | 6 | * Mohit Kumar <mohit.kumar.dhaka@gmail.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -257,5 +257,5 @@ static struct platform_driver spear1310_miphy_driver = { | |||
257 | module_platform_driver(spear1310_miphy_driver); | 257 | module_platform_driver(spear1310_miphy_driver); |
258 | 258 | ||
259 | MODULE_DESCRIPTION("ST SPEAR1310-MIPHY driver"); | 259 | MODULE_DESCRIPTION("ST SPEAR1310-MIPHY driver"); |
260 | MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>"); | 260 | MODULE_AUTHOR("Pratyush Anand <pratyush.anand@gmail.com>"); |
261 | MODULE_LICENSE("GPL v2"); | 261 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/phy/phy-spear1340-miphy.c b/drivers/phy/phy-spear1340-miphy.c index 1a00c2817f34..494240da4a39 100644 --- a/drivers/phy/phy-spear1340-miphy.c +++ b/drivers/phy/phy-spear1340-miphy.c | |||
@@ -2,8 +2,8 @@ | |||
2 | * ST spear1340-miphy driver | 2 | * ST spear1340-miphy driver |
3 | * | 3 | * |
4 | * Copyright (C) 2014 ST Microelectronics | 4 | * Copyright (C) 2014 ST Microelectronics |
5 | * Pratyush Anand <pratyush.anand@st.com> | 5 | * Pratyush Anand <pratyush.anand@gmail.com> |
6 | * Mohit Kumar <mohit.kumar@st.com> | 6 | * Mohit Kumar <mohit.kumar.dhaka@gmail.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -290,5 +290,5 @@ static struct platform_driver spear1340_miphy_driver = { | |||
290 | module_platform_driver(spear1340_miphy_driver); | 290 | module_platform_driver(spear1340_miphy_driver); |
291 | 291 | ||
292 | MODULE_DESCRIPTION("ST SPEAR1340-MIPHY driver"); | 292 | MODULE_DESCRIPTION("ST SPEAR1340-MIPHY driver"); |
293 | MODULE_AUTHOR("Pratyush Anand <pratyush.anand@st.com>"); | 293 | MODULE_AUTHOR("Pratyush Anand <pratyush.anand@gmail.com>"); |
294 | MODULE_LICENSE("GPL v2"); | 294 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c index 62cb8cd08403..86b4e4b2ab9a 100644 --- a/drivers/usb/misc/lvstest.c +++ b/drivers/usb/misc/lvstest.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Test pattern generation for Link Layer Validation System Tests | 4 | * Test pattern generation for Link Layer Validation System Tests |
5 | * | 5 | * |
6 | * Copyright (C) 2014 ST Microelectronics | 6 | * Copyright (C) 2014 ST Microelectronics |
7 | * Pratyush Anand <pratyush.anand@st.com> | 7 | * Pratyush Anand <pratyush.anand@gmail.com> |
8 | * | 8 | * |
9 | * This file is licensed under the terms of the GNU General Public | 9 | * This file is licensed under the terms of the GNU General Public |
10 | * License version 2. This program is licensed "as is" without any | 10 | * License version 2. This program is licensed "as is" without any |
diff --git a/fs/befs/btree.c b/fs/befs/btree.c index 0826e91dacda..22c166280883 100644 --- a/fs/befs/btree.c +++ b/fs/befs/btree.c | |||
@@ -137,8 +137,8 @@ static int | |||
137 | befs_bt_read_super(struct super_block *sb, befs_data_stream * ds, | 137 | befs_bt_read_super(struct super_block *sb, befs_data_stream * ds, |
138 | befs_btree_super * sup) | 138 | befs_btree_super * sup) |
139 | { | 139 | { |
140 | struct buffer_head *bh = NULL; | 140 | struct buffer_head *bh; |
141 | befs_disk_btree_super *od_sup = NULL; | 141 | befs_disk_btree_super *od_sup; |
142 | 142 | ||
143 | befs_debug(sb, "---> %s", __func__); | 143 | befs_debug(sb, "---> %s", __func__); |
144 | 144 | ||
@@ -250,7 +250,7 @@ int | |||
250 | befs_btree_find(struct super_block *sb, befs_data_stream * ds, | 250 | befs_btree_find(struct super_block *sb, befs_data_stream * ds, |
251 | const char *key, befs_off_t * value) | 251 | const char *key, befs_off_t * value) |
252 | { | 252 | { |
253 | struct befs_btree_node *this_node = NULL; | 253 | struct befs_btree_node *this_node; |
254 | befs_btree_super bt_super; | 254 | befs_btree_super bt_super; |
255 | befs_off_t node_off; | 255 | befs_off_t node_off; |
256 | int res; | 256 | int res; |
diff --git a/fs/coredump.c b/fs/coredump.c index bbbe139ab280..e52e0064feac 100644 --- a/fs/coredump.c +++ b/fs/coredump.c | |||
@@ -70,7 +70,8 @@ static int expand_corename(struct core_name *cn, int size) | |||
70 | return 0; | 70 | return 0; |
71 | } | 71 | } |
72 | 72 | ||
73 | static int cn_vprintf(struct core_name *cn, const char *fmt, va_list arg) | 73 | static __printf(2, 0) int cn_vprintf(struct core_name *cn, const char *fmt, |
74 | va_list arg) | ||
74 | { | 75 | { |
75 | int free, need; | 76 | int free, need; |
76 | va_list arg_copy; | 77 | va_list arg_copy; |
@@ -93,7 +94,7 @@ again: | |||
93 | return -ENOMEM; | 94 | return -ENOMEM; |
94 | } | 95 | } |
95 | 96 | ||
96 | static int cn_printf(struct core_name *cn, const char *fmt, ...) | 97 | static __printf(2, 3) int cn_printf(struct core_name *cn, const char *fmt, ...) |
97 | { | 98 | { |
98 | va_list arg; | 99 | va_list arg; |
99 | int ret; | 100 | int ret; |
@@ -105,7 +106,8 @@ static int cn_printf(struct core_name *cn, const char *fmt, ...) | |||
105 | return ret; | 106 | return ret; |
106 | } | 107 | } |
107 | 108 | ||
108 | static int cn_esc_printf(struct core_name *cn, const char *fmt, ...) | 109 | static __printf(2, 3) |
110 | int cn_esc_printf(struct core_name *cn, const char *fmt, ...) | ||
109 | { | 111 | { |
110 | int cur = cn->used; | 112 | int cur = cn->used; |
111 | va_list arg; | 113 | va_list arg; |
@@ -209,11 +211,15 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm) | |||
209 | break; | 211 | break; |
210 | /* uid */ | 212 | /* uid */ |
211 | case 'u': | 213 | case 'u': |
212 | err = cn_printf(cn, "%d", cred->uid); | 214 | err = cn_printf(cn, "%u", |
215 | from_kuid(&init_user_ns, | ||
216 | cred->uid)); | ||
213 | break; | 217 | break; |
214 | /* gid */ | 218 | /* gid */ |
215 | case 'g': | 219 | case 'g': |
216 | err = cn_printf(cn, "%d", cred->gid); | 220 | err = cn_printf(cn, "%u", |
221 | from_kgid(&init_user_ns, | ||
222 | cred->gid)); | ||
217 | break; | 223 | break; |
218 | case 'd': | 224 | case 'd': |
219 | err = cn_printf(cn, "%d", | 225 | err = cn_printf(cn, "%d", |
@@ -221,7 +227,8 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm) | |||
221 | break; | 227 | break; |
222 | /* signal that caused the coredump */ | 228 | /* signal that caused the coredump */ |
223 | case 's': | 229 | case 's': |
224 | err = cn_printf(cn, "%ld", cprm->siginfo->si_signo); | 230 | err = cn_printf(cn, "%d", |
231 | cprm->siginfo->si_signo); | ||
225 | break; | 232 | break; |
226 | /* UNIX time of coredump */ | 233 | /* UNIX time of coredump */ |
227 | case 't': { | 234 | case 't': { |
diff --git a/fs/efs/super.c b/fs/efs/super.c index 7fca462ea4e3..c8411a30f7da 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c | |||
@@ -67,7 +67,7 @@ static struct kmem_cache * efs_inode_cachep; | |||
67 | static struct inode *efs_alloc_inode(struct super_block *sb) | 67 | static struct inode *efs_alloc_inode(struct super_block *sb) |
68 | { | 68 | { |
69 | struct efs_inode_info *ei; | 69 | struct efs_inode_info *ei; |
70 | ei = (struct efs_inode_info *)kmem_cache_alloc(efs_inode_cachep, GFP_KERNEL); | 70 | ei = kmem_cache_alloc(efs_inode_cachep, GFP_KERNEL); |
71 | if (!ei) | 71 | if (!ei) |
72 | return NULL; | 72 | return NULL; |
73 | return &ei->vfs_inode; | 73 | return &ei->vfs_inode; |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index a7b4b6e10269..5c787647afe2 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -3446,7 +3446,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3446 | unsigned long journal_devnum = 0; | 3446 | unsigned long journal_devnum = 0; |
3447 | unsigned long def_mount_opts; | 3447 | unsigned long def_mount_opts; |
3448 | struct inode *root; | 3448 | struct inode *root; |
3449 | char *cp; | ||
3450 | const char *descr; | 3449 | const char *descr; |
3451 | int ret = -ENOMEM; | 3450 | int ret = -ENOMEM; |
3452 | int blocksize, clustersize; | 3451 | int blocksize, clustersize; |
@@ -3477,8 +3476,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3477 | part_stat_read(sb->s_bdev->bd_part, sectors[1]); | 3476 | part_stat_read(sb->s_bdev->bd_part, sectors[1]); |
3478 | 3477 | ||
3479 | /* Cleanup superblock name */ | 3478 | /* Cleanup superblock name */ |
3480 | for (cp = sb->s_id; (cp = strchr(cp, '/'));) | 3479 | strreplace(sb->s_id, '/', '!'); |
3481 | *cp = '!'; | ||
3482 | 3480 | ||
3483 | /* -EINVAL is default */ | 3481 | /* -EINVAL is default */ |
3484 | ret = -EINVAL; | 3482 | ret = -EINVAL; |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 179d7d8733f2..4ff3fad4e9e3 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -1135,7 +1135,6 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev, | |||
1135 | { | 1135 | { |
1136 | journal_t *journal = journal_init_common(); | 1136 | journal_t *journal = journal_init_common(); |
1137 | struct buffer_head *bh; | 1137 | struct buffer_head *bh; |
1138 | char *p; | ||
1139 | int n; | 1138 | int n; |
1140 | 1139 | ||
1141 | if (!journal) | 1140 | if (!journal) |
@@ -1148,9 +1147,7 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev, | |||
1148 | journal->j_blk_offset = start; | 1147 | journal->j_blk_offset = start; |
1149 | journal->j_maxlen = len; | 1148 | journal->j_maxlen = len; |
1150 | bdevname(journal->j_dev, journal->j_devname); | 1149 | bdevname(journal->j_dev, journal->j_devname); |
1151 | p = journal->j_devname; | 1150 | strreplace(journal->j_devname, '/', '!'); |
1152 | while ((p = strchr(p, '/'))) | ||
1153 | *p = '!'; | ||
1154 | jbd2_stats_proc_init(journal); | 1151 | jbd2_stats_proc_init(journal); |
1155 | n = journal->j_blocksize / sizeof(journal_block_tag_t); | 1152 | n = journal->j_blocksize / sizeof(journal_block_tag_t); |
1156 | journal->j_wbufsize = n; | 1153 | journal->j_wbufsize = n; |
@@ -1202,10 +1199,7 @@ journal_t * jbd2_journal_init_inode (struct inode *inode) | |||
1202 | journal->j_dev = journal->j_fs_dev = inode->i_sb->s_bdev; | 1199 | journal->j_dev = journal->j_fs_dev = inode->i_sb->s_bdev; |
1203 | journal->j_inode = inode; | 1200 | journal->j_inode = inode; |
1204 | bdevname(journal->j_dev, journal->j_devname); | 1201 | bdevname(journal->j_dev, journal->j_devname); |
1205 | p = journal->j_devname; | 1202 | p = strreplace(journal->j_devname, '/', '!'); |
1206 | while ((p = strchr(p, '/'))) | ||
1207 | *p = '!'; | ||
1208 | p = journal->j_devname + strlen(journal->j_devname); | ||
1209 | sprintf(p, "-%lu", journal->j_inode->i_ino); | 1203 | sprintf(p, "-%lu", journal->j_inode->i_ino); |
1210 | jbd_debug(1, | 1204 | jbd_debug(1, |
1211 | "journal %p: inode %s/%ld, size %Ld, bits %d, blksize %ld\n", | 1205 | "journal %p: inode %s/%ld, size %Ld, bits %d, blksize %ld\n", |
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 1182d1e26a9c..086cd0a61e80 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
@@ -62,7 +62,7 @@ static struct kmem_cache * minix_inode_cachep; | |||
62 | static struct inode *minix_alloc_inode(struct super_block *sb) | 62 | static struct inode *minix_alloc_inode(struct super_block *sb) |
63 | { | 63 | { |
64 | struct minix_inode_info *ei; | 64 | struct minix_inode_info *ei; |
65 | ei = (struct minix_inode_info *)kmem_cache_alloc(minix_inode_cachep, GFP_KERNEL); | 65 | ei = kmem_cache_alloc(minix_inode_cachep, GFP_KERNEL); |
66 | if (!ei) | 66 | if (!ei) |
67 | return NULL; | 67 | return NULL; |
68 | return &ei->vfs_inode; | 68 | return &ei->vfs_inode; |
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index 22180836ec22..37dd6b05b1b5 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
@@ -496,8 +496,7 @@ static struct dentry *nilfs_fh_to_dentry(struct super_block *sb, struct fid *fh, | |||
496 | { | 496 | { |
497 | struct nilfs_fid *fid = (struct nilfs_fid *)fh; | 497 | struct nilfs_fid *fid = (struct nilfs_fid *)fh; |
498 | 498 | ||
499 | if ((fh_len != NILFS_FID_SIZE_NON_CONNECTABLE && | 499 | if (fh_len < NILFS_FID_SIZE_NON_CONNECTABLE || |
500 | fh_len != NILFS_FID_SIZE_CONNECTABLE) || | ||
501 | (fh_type != FILEID_NILFS_WITH_PARENT && | 500 | (fh_type != FILEID_NILFS_WITH_PARENT && |
502 | fh_type != FILEID_NILFS_WITHOUT_PARENT)) | 501 | fh_type != FILEID_NILFS_WITHOUT_PARENT)) |
503 | return NULL; | 502 | return NULL; |
@@ -510,7 +509,7 @@ static struct dentry *nilfs_fh_to_parent(struct super_block *sb, struct fid *fh, | |||
510 | { | 509 | { |
511 | struct nilfs_fid *fid = (struct nilfs_fid *)fh; | 510 | struct nilfs_fid *fid = (struct nilfs_fid *)fh; |
512 | 511 | ||
513 | if (fh_len != NILFS_FID_SIZE_CONNECTABLE || | 512 | if (fh_len < NILFS_FID_SIZE_CONNECTABLE || |
514 | fh_type != FILEID_NILFS_WITH_PARENT) | 513 | fh_type != FILEID_NILFS_WITH_PARENT) |
515 | return NULL; | 514 | return NULL; |
516 | 515 | ||
diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig index 2183fcf41d59..d751fcb637bb 100644 --- a/fs/proc/Kconfig +++ b/fs/proc/Kconfig | |||
@@ -71,3 +71,7 @@ config PROC_PAGE_MONITOR | |||
71 | /proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap, | 71 | /proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap, |
72 | /proc/kpagecount, and /proc/kpageflags. Disabling these | 72 | /proc/kpagecount, and /proc/kpageflags. Disabling these |
73 | interfaces will reduce the size of the kernel by approximately 4kb. | 73 | interfaces will reduce the size of the kernel by approximately 4kb. |
74 | |||
75 | config PROC_CHILDREN | ||
76 | bool "Include /proc/<pid>/task/<tid>/children file" | ||
77 | default n | ||
diff --git a/fs/proc/array.c b/fs/proc/array.c index 3f57dac31ba6..ce065cf3104f 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -577,7 +577,7 @@ int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns, | |||
577 | return 0; | 577 | return 0; |
578 | } | 578 | } |
579 | 579 | ||
580 | #ifdef CONFIG_CHECKPOINT_RESTORE | 580 | #ifdef CONFIG_PROC_CHILDREN |
581 | static struct pid * | 581 | static struct pid * |
582 | get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos) | 582 | get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos) |
583 | { | 583 | { |
@@ -700,4 +700,4 @@ const struct file_operations proc_tid_children_operations = { | |||
700 | .llseek = seq_lseek, | 700 | .llseek = seq_lseek, |
701 | .release = children_seq_release, | 701 | .release = children_seq_release, |
702 | }; | 702 | }; |
703 | #endif /* CONFIG_CHECKPOINT_RESTORE */ | 703 | #endif /* CONFIG_PROC_CHILDREN */ |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 286a422f440e..1d540b3f226f 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -196,18 +196,205 @@ static int proc_root_link(struct dentry *dentry, struct path *path) | |||
196 | return result; | 196 | return result; |
197 | } | 197 | } |
198 | 198 | ||
199 | static int proc_pid_cmdline(struct seq_file *m, struct pid_namespace *ns, | 199 | static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, |
200 | struct pid *pid, struct task_struct *task) | 200 | size_t _count, loff_t *pos) |
201 | { | 201 | { |
202 | struct task_struct *tsk; | ||
203 | struct mm_struct *mm; | ||
204 | char *page; | ||
205 | unsigned long count = _count; | ||
206 | unsigned long arg_start, arg_end, env_start, env_end; | ||
207 | unsigned long len1, len2, len; | ||
208 | unsigned long p; | ||
209 | char c; | ||
210 | ssize_t rv; | ||
211 | |||
212 | BUG_ON(*pos < 0); | ||
213 | |||
214 | tsk = get_proc_task(file_inode(file)); | ||
215 | if (!tsk) | ||
216 | return -ESRCH; | ||
217 | mm = get_task_mm(tsk); | ||
218 | put_task_struct(tsk); | ||
219 | if (!mm) | ||
220 | return 0; | ||
221 | /* Check if process spawned far enough to have cmdline. */ | ||
222 | if (!mm->env_end) { | ||
223 | rv = 0; | ||
224 | goto out_mmput; | ||
225 | } | ||
226 | |||
227 | page = (char *)__get_free_page(GFP_TEMPORARY); | ||
228 | if (!page) { | ||
229 | rv = -ENOMEM; | ||
230 | goto out_mmput; | ||
231 | } | ||
232 | |||
233 | down_read(&mm->mmap_sem); | ||
234 | arg_start = mm->arg_start; | ||
235 | arg_end = mm->arg_end; | ||
236 | env_start = mm->env_start; | ||
237 | env_end = mm->env_end; | ||
238 | up_read(&mm->mmap_sem); | ||
239 | |||
240 | BUG_ON(arg_start > arg_end); | ||
241 | BUG_ON(env_start > env_end); | ||
242 | |||
243 | len1 = arg_end - arg_start; | ||
244 | len2 = env_end - env_start; | ||
245 | |||
202 | /* | 246 | /* |
203 | * Rely on struct seq_operations::show() being called once | 247 | * Inherently racy -- command line shares address space |
204 | * per internal buffer allocation. See single_open(), traverse(). | 248 | * with code and data. |
205 | */ | 249 | */ |
206 | BUG_ON(m->size < PAGE_SIZE); | 250 | rv = access_remote_vm(mm, arg_end - 1, &c, 1, 0); |
207 | m->count += get_cmdline(task, m->buf, PAGE_SIZE); | 251 | if (rv <= 0) |
208 | return 0; | 252 | goto out_free_page; |
253 | |||
254 | rv = 0; | ||
255 | |||
256 | if (c == '\0') { | ||
257 | /* Command line (set of strings) occupies whole ARGV. */ | ||
258 | if (len1 <= *pos) | ||
259 | goto out_free_page; | ||
260 | |||
261 | p = arg_start + *pos; | ||
262 | len = len1 - *pos; | ||
263 | while (count > 0 && len > 0) { | ||
264 | unsigned int _count; | ||
265 | int nr_read; | ||
266 | |||
267 | _count = min3(count, len, PAGE_SIZE); | ||
268 | nr_read = access_remote_vm(mm, p, page, _count, 0); | ||
269 | if (nr_read < 0) | ||
270 | rv = nr_read; | ||
271 | if (nr_read <= 0) | ||
272 | goto out_free_page; | ||
273 | |||
274 | if (copy_to_user(buf, page, nr_read)) { | ||
275 | rv = -EFAULT; | ||
276 | goto out_free_page; | ||
277 | } | ||
278 | |||
279 | p += nr_read; | ||
280 | len -= nr_read; | ||
281 | buf += nr_read; | ||
282 | count -= nr_read; | ||
283 | rv += nr_read; | ||
284 | } | ||
285 | } else { | ||
286 | /* | ||
287 | * Command line (1 string) occupies ARGV and maybe | ||
288 | * extends into ENVP. | ||
289 | */ | ||
290 | if (len1 + len2 <= *pos) | ||
291 | goto skip_argv_envp; | ||
292 | if (len1 <= *pos) | ||
293 | goto skip_argv; | ||
294 | |||
295 | p = arg_start + *pos; | ||
296 | len = len1 - *pos; | ||
297 | while (count > 0 && len > 0) { | ||
298 | unsigned int _count, l; | ||
299 | int nr_read; | ||
300 | bool final; | ||
301 | |||
302 | _count = min3(count, len, PAGE_SIZE); | ||
303 | nr_read = access_remote_vm(mm, p, page, _count, 0); | ||
304 | if (nr_read < 0) | ||
305 | rv = nr_read; | ||
306 | if (nr_read <= 0) | ||
307 | goto out_free_page; | ||
308 | |||
309 | /* | ||
310 | * Command line can be shorter than whole ARGV | ||
311 | * even if last "marker" byte says it is not. | ||
312 | */ | ||
313 | final = false; | ||
314 | l = strnlen(page, nr_read); | ||
315 | if (l < nr_read) { | ||
316 | nr_read = l; | ||
317 | final = true; | ||
318 | } | ||
319 | |||
320 | if (copy_to_user(buf, page, nr_read)) { | ||
321 | rv = -EFAULT; | ||
322 | goto out_free_page; | ||
323 | } | ||
324 | |||
325 | p += nr_read; | ||
326 | len -= nr_read; | ||
327 | buf += nr_read; | ||
328 | count -= nr_read; | ||
329 | rv += nr_read; | ||
330 | |||
331 | if (final) | ||
332 | goto out_free_page; | ||
333 | } | ||
334 | skip_argv: | ||
335 | /* | ||
336 | * Command line (1 string) occupies ARGV and | ||
337 | * extends into ENVP. | ||
338 | */ | ||
339 | if (len1 <= *pos) { | ||
340 | p = env_start + *pos - len1; | ||
341 | len = len1 + len2 - *pos; | ||
342 | } else { | ||
343 | p = env_start; | ||
344 | len = len2; | ||
345 | } | ||
346 | while (count > 0 && len > 0) { | ||
347 | unsigned int _count, l; | ||
348 | int nr_read; | ||
349 | bool final; | ||
350 | |||
351 | _count = min3(count, len, PAGE_SIZE); | ||
352 | nr_read = access_remote_vm(mm, p, page, _count, 0); | ||
353 | if (nr_read < 0) | ||
354 | rv = nr_read; | ||
355 | if (nr_read <= 0) | ||
356 | goto out_free_page; | ||
357 | |||
358 | /* Find EOS. */ | ||
359 | final = false; | ||
360 | l = strnlen(page, nr_read); | ||
361 | if (l < nr_read) { | ||
362 | nr_read = l; | ||
363 | final = true; | ||
364 | } | ||
365 | |||
366 | if (copy_to_user(buf, page, nr_read)) { | ||
367 | rv = -EFAULT; | ||
368 | goto out_free_page; | ||
369 | } | ||
370 | |||
371 | p += nr_read; | ||
372 | len -= nr_read; | ||
373 | buf += nr_read; | ||
374 | count -= nr_read; | ||
375 | rv += nr_read; | ||
376 | |||
377 | if (final) | ||
378 | goto out_free_page; | ||
379 | } | ||
380 | skip_argv_envp: | ||
381 | ; | ||
382 | } | ||
383 | |||
384 | out_free_page: | ||
385 | free_page((unsigned long)page); | ||
386 | out_mmput: | ||
387 | mmput(mm); | ||
388 | if (rv > 0) | ||
389 | *pos += rv; | ||
390 | return rv; | ||
209 | } | 391 | } |
210 | 392 | ||
393 | static const struct file_operations proc_pid_cmdline_ops = { | ||
394 | .read = proc_pid_cmdline_read, | ||
395 | .llseek = generic_file_llseek, | ||
396 | }; | ||
397 | |||
211 | static int proc_pid_auxv(struct seq_file *m, struct pid_namespace *ns, | 398 | static int proc_pid_auxv(struct seq_file *m, struct pid_namespace *ns, |
212 | struct pid *pid, struct task_struct *task) | 399 | struct pid *pid, struct task_struct *task) |
213 | { | 400 | { |
@@ -2572,7 +2759,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2572 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 2759 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
2573 | ONE("syscall", S_IRUSR, proc_pid_syscall), | 2760 | ONE("syscall", S_IRUSR, proc_pid_syscall), |
2574 | #endif | 2761 | #endif |
2575 | ONE("cmdline", S_IRUGO, proc_pid_cmdline), | 2762 | REG("cmdline", S_IRUGO, proc_pid_cmdline_ops), |
2576 | ONE("stat", S_IRUGO, proc_tgid_stat), | 2763 | ONE("stat", S_IRUGO, proc_tgid_stat), |
2577 | ONE("statm", S_IRUGO, proc_pid_statm), | 2764 | ONE("statm", S_IRUGO, proc_pid_statm), |
2578 | REG("maps", S_IRUGO, proc_pid_maps_operations), | 2765 | REG("maps", S_IRUGO, proc_pid_maps_operations), |
@@ -2918,11 +3105,11 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2918 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 3105 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
2919 | ONE("syscall", S_IRUSR, proc_pid_syscall), | 3106 | ONE("syscall", S_IRUSR, proc_pid_syscall), |
2920 | #endif | 3107 | #endif |
2921 | ONE("cmdline", S_IRUGO, proc_pid_cmdline), | 3108 | REG("cmdline", S_IRUGO, proc_pid_cmdline_ops), |
2922 | ONE("stat", S_IRUGO, proc_tid_stat), | 3109 | ONE("stat", S_IRUGO, proc_tid_stat), |
2923 | ONE("statm", S_IRUGO, proc_pid_statm), | 3110 | ONE("statm", S_IRUGO, proc_pid_statm), |
2924 | REG("maps", S_IRUGO, proc_tid_maps_operations), | 3111 | REG("maps", S_IRUGO, proc_tid_maps_operations), |
2925 | #ifdef CONFIG_CHECKPOINT_RESTORE | 3112 | #ifdef CONFIG_PROC_CHILDREN |
2926 | REG("children", S_IRUGO, proc_tid_children_operations), | 3113 | REG("children", S_IRUGO, proc_tid_children_operations), |
2927 | #endif | 3114 | #endif |
2928 | #ifdef CONFIG_NUMA | 3115 | #ifdef CONFIG_NUMA |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 3e0af317fcc3..0e4cf728126f 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -589,8 +589,7 @@ static struct kmem_cache *reiserfs_inode_cachep; | |||
589 | static struct inode *reiserfs_alloc_inode(struct super_block *sb) | 589 | static struct inode *reiserfs_alloc_inode(struct super_block *sb) |
590 | { | 590 | { |
591 | struct reiserfs_inode_info *ei; | 591 | struct reiserfs_inode_info *ei; |
592 | ei = (struct reiserfs_inode_info *) | 592 | ei = kmem_cache_alloc(reiserfs_inode_cachep, GFP_KERNEL); |
593 | kmem_cache_alloc(reiserfs_inode_cachep, GFP_KERNEL); | ||
594 | if (!ei) | 593 | if (!ei) |
595 | return NULL; | 594 | return NULL; |
596 | atomic_set(&ei->openers, 0); | 595 | atomic_set(&ei->openers, 0); |
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 371e560d13cf..dfaa7b3e9ae9 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h | |||
@@ -5,9 +5,9 @@ | |||
5 | /* | 5 | /* |
6 | * Common definitions for all gcc versions go here. | 6 | * Common definitions for all gcc versions go here. |
7 | */ | 7 | */ |
8 | #define GCC_VERSION (__GNUC__ * 10000 \ | 8 | #define GCC_VERSION (__GNUC__ * 10000 \ |
9 | + __GNUC_MINOR__ * 100 \ | 9 | + __GNUC_MINOR__ * 100 \ |
10 | + __GNUC_PATCHLEVEL__) | 10 | + __GNUC_PATCHLEVEL__) |
11 | 11 | ||
12 | /* Optimization barrier */ | 12 | /* Optimization barrier */ |
13 | 13 | ||
@@ -46,55 +46,63 @@ | |||
46 | * the inline assembly constraint from =g to =r, in this particular | 46 | * the inline assembly constraint from =g to =r, in this particular |
47 | * case either is valid. | 47 | * case either is valid. |
48 | */ | 48 | */ |
49 | #define RELOC_HIDE(ptr, off) \ | 49 | #define RELOC_HIDE(ptr, off) \ |
50 | ({ unsigned long __ptr; \ | 50 | ({ \ |
51 | __asm__ ("" : "=r"(__ptr) : "0"(ptr)); \ | 51 | unsigned long __ptr; \ |
52 | (typeof(ptr)) (__ptr + (off)); }) | 52 | __asm__ ("" : "=r"(__ptr) : "0"(ptr)); \ |
53 | (typeof(ptr)) (__ptr + (off)); \ | ||
54 | }) | ||
53 | 55 | ||
54 | /* Make the optimizer believe the variable can be manipulated arbitrarily. */ | 56 | /* Make the optimizer believe the variable can be manipulated arbitrarily. */ |
55 | #define OPTIMIZER_HIDE_VAR(var) __asm__ ("" : "=r" (var) : "0" (var)) | 57 | #define OPTIMIZER_HIDE_VAR(var) \ |
58 | __asm__ ("" : "=r" (var) : "0" (var)) | ||
56 | 59 | ||
57 | #ifdef __CHECKER__ | 60 | #ifdef __CHECKER__ |
58 | #define __must_be_array(arr) 0 | 61 | #define __must_be_array(a) 0 |
59 | #else | 62 | #else |
60 | /* &a[0] degrades to a pointer: a different type from an array */ | 63 | /* &a[0] degrades to a pointer: a different type from an array */ |
61 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | 64 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) |
62 | #endif | 65 | #endif |
63 | 66 | ||
64 | /* | 67 | /* |
65 | * Force always-inline if the user requests it so via the .config, | 68 | * Force always-inline if the user requests it so via the .config, |
66 | * or if gcc is too old: | 69 | * or if gcc is too old: |
67 | */ | 70 | */ |
68 | #if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ | 71 | #if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ |
69 | !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4) | 72 | !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4) |
70 | # define inline inline __attribute__((always_inline)) notrace | 73 | #define inline inline __attribute__((always_inline)) notrace |
71 | # define __inline__ __inline__ __attribute__((always_inline)) notrace | 74 | #define __inline__ __inline__ __attribute__((always_inline)) notrace |
72 | # define __inline __inline __attribute__((always_inline)) notrace | 75 | #define __inline __inline __attribute__((always_inline)) notrace |
73 | #else | 76 | #else |
74 | /* A lot of inline functions can cause havoc with function tracing */ | 77 | /* A lot of inline functions can cause havoc with function tracing */ |
75 | # define inline inline notrace | 78 | #define inline inline notrace |
76 | # define __inline__ __inline__ notrace | 79 | #define __inline__ __inline__ notrace |
77 | # define __inline __inline notrace | 80 | #define __inline __inline notrace |
78 | #endif | 81 | #endif |
79 | 82 | ||
80 | #define __deprecated __attribute__((deprecated)) | 83 | #define __always_inline inline __attribute__((always_inline)) |
81 | #define __packed __attribute__((packed)) | 84 | #define noinline __attribute__((noinline)) |
82 | #define __weak __attribute__((weak)) | 85 | |
83 | #define __alias(symbol) __attribute__((alias(#symbol))) | 86 | #define __deprecated __attribute__((deprecated)) |
87 | #define __packed __attribute__((packed)) | ||
88 | #define __weak __attribute__((weak)) | ||
89 | #define __alias(symbol) __attribute__((alias(#symbol))) | ||
84 | 90 | ||
85 | /* | 91 | /* |
86 | * it doesn't make sense on ARM (currently the only user of __naked) to trace | 92 | * it doesn't make sense on ARM (currently the only user of __naked) |
87 | * naked functions because then mcount is called without stack and frame pointer | 93 | * to trace naked functions because then mcount is called without |
88 | * being set up and there is no chance to restore the lr register to the value | 94 | * stack and frame pointer being set up and there is no chance to |
89 | * before mcount was called. | 95 | * restore the lr register to the value before mcount was called. |
96 | * | ||
97 | * The asm() bodies of naked functions often depend on standard calling | ||
98 | * conventions, therefore they must be noinline and noclone. | ||
90 | * | 99 | * |
91 | * The asm() bodies of naked functions often depend on standard calling conventions, | 100 | * GCC 4.[56] currently fail to enforce this, so we must do so ourselves. |
92 | * therefore they must be noinline and noclone. GCC 4.[56] currently fail to enforce | 101 | * See GCC PR44290. |
93 | * this, so we must do so ourselves. See GCC PR44290. | ||
94 | */ | 102 | */ |
95 | #define __naked __attribute__((naked)) noinline __noclone notrace | 103 | #define __naked __attribute__((naked)) noinline __noclone notrace |
96 | 104 | ||
97 | #define __noreturn __attribute__((noreturn)) | 105 | #define __noreturn __attribute__((noreturn)) |
98 | 106 | ||
99 | /* | 107 | /* |
100 | * From the GCC manual: | 108 | * From the GCC manual: |
@@ -106,19 +114,130 @@ | |||
106 | * would be. | 114 | * would be. |
107 | * [...] | 115 | * [...] |
108 | */ | 116 | */ |
109 | #define __pure __attribute__((pure)) | 117 | #define __pure __attribute__((pure)) |
110 | #define __aligned(x) __attribute__((aligned(x))) | 118 | #define __aligned(x) __attribute__((aligned(x))) |
111 | #define __printf(a, b) __attribute__((format(printf, a, b))) | 119 | #define __printf(a, b) __attribute__((format(printf, a, b))) |
112 | #define __scanf(a, b) __attribute__((format(scanf, a, b))) | 120 | #define __scanf(a, b) __attribute__((format(scanf, a, b))) |
113 | #define noinline __attribute__((noinline)) | 121 | #define __attribute_const__ __attribute__((__const__)) |
114 | #define __attribute_const__ __attribute__((__const__)) | 122 | #define __maybe_unused __attribute__((unused)) |
115 | #define __maybe_unused __attribute__((unused)) | 123 | #define __always_unused __attribute__((unused)) |
116 | #define __always_unused __attribute__((unused)) | 124 | |
117 | 125 | /* gcc version specific checks */ | |
118 | #define __gcc_header(x) #x | 126 | |
119 | #define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h) | 127 | #if GCC_VERSION < 30200 |
120 | #define gcc_header(x) _gcc_header(x) | 128 | # error Sorry, your compiler is too old - please upgrade it. |
121 | #include gcc_header(__GNUC__) | 129 | #endif |
130 | |||
131 | #if GCC_VERSION < 30300 | ||
132 | # define __used __attribute__((__unused__)) | ||
133 | #else | ||
134 | # define __used __attribute__((__used__)) | ||
135 | #endif | ||
136 | |||
137 | #ifdef CONFIG_GCOV_KERNEL | ||
138 | # if GCC_VERSION < 30400 | ||
139 | # error "GCOV profiling support for gcc versions below 3.4 not included" | ||
140 | # endif /* __GNUC_MINOR__ */ | ||
141 | #endif /* CONFIG_GCOV_KERNEL */ | ||
142 | |||
143 | #if GCC_VERSION >= 30400 | ||
144 | #define __must_check __attribute__((warn_unused_result)) | ||
145 | #endif | ||
146 | |||
147 | #if GCC_VERSION >= 40000 | ||
148 | |||
149 | /* GCC 4.1.[01] miscompiles __weak */ | ||
150 | #ifdef __KERNEL__ | ||
151 | # if GCC_VERSION >= 40100 && GCC_VERSION <= 40101 | ||
152 | # error Your version of gcc miscompiles the __weak directive | ||
153 | # endif | ||
154 | #endif | ||
155 | |||
156 | #define __used __attribute__((__used__)) | ||
157 | #define __compiler_offsetof(a, b) \ | ||
158 | __builtin_offsetof(a, b) | ||
159 | |||
160 | #if GCC_VERSION >= 40100 && GCC_VERSION < 40600 | ||
161 | # define __compiletime_object_size(obj) __builtin_object_size(obj, 0) | ||
162 | #endif | ||
163 | |||
164 | #if GCC_VERSION >= 40300 | ||
165 | /* Mark functions as cold. gcc will assume any path leading to a call | ||
166 | * to them will be unlikely. This means a lot of manual unlikely()s | ||
167 | * are unnecessary now for any paths leading to the usual suspects | ||
168 | * like BUG(), printk(), panic() etc. [but let's keep them for now for | ||
169 | * older compilers] | ||
170 | * | ||
171 | * Early snapshots of gcc 4.3 don't support this and we can't detect this | ||
172 | * in the preprocessor, but we can live with this because they're unreleased. | ||
173 | * Maketime probing would be overkill here. | ||
174 | * | ||
175 | * gcc also has a __attribute__((__hot__)) to move hot functions into | ||
176 | * a special section, but I don't see any sense in this right now in | ||
177 | * the kernel context | ||
178 | */ | ||
179 | #define __cold __attribute__((__cold__)) | ||
180 | |||
181 | #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) | ||
182 | |||
183 | #ifndef __CHECKER__ | ||
184 | # define __compiletime_warning(message) __attribute__((warning(message))) | ||
185 | # define __compiletime_error(message) __attribute__((error(message))) | ||
186 | #endif /* __CHECKER__ */ | ||
187 | #endif /* GCC_VERSION >= 40300 */ | ||
188 | |||
189 | #if GCC_VERSION >= 40500 | ||
190 | /* | ||
191 | * Mark a position in code as unreachable. This can be used to | ||
192 | * suppress control flow warnings after asm blocks that transfer | ||
193 | * control elsewhere. | ||
194 | * | ||
195 | * Early snapshots of gcc 4.5 don't support this and we can't detect | ||
196 | * this in the preprocessor, but we can live with this because they're | ||
197 | * unreleased. Really, we need to have autoconf for the kernel. | ||
198 | */ | ||
199 | #define unreachable() __builtin_unreachable() | ||
200 | |||
201 | /* Mark a function definition as prohibited from being cloned. */ | ||
202 | #define __noclone __attribute__((__noclone__)) | ||
203 | |||
204 | #endif /* GCC_VERSION >= 40500 */ | ||
205 | |||
206 | #if GCC_VERSION >= 40600 | ||
207 | /* | ||
208 | * Tell the optimizer that something else uses this function or variable. | ||
209 | */ | ||
210 | #define __visible __attribute__((externally_visible)) | ||
211 | #endif | ||
212 | |||
213 | /* | ||
214 | * GCC 'asm goto' miscompiles certain code sequences: | ||
215 | * | ||
216 | * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 | ||
217 | * | ||
218 | * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. | ||
219 | * | ||
220 | * (asm goto is automatically volatile - the naming reflects this.) | ||
221 | */ | ||
222 | #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) | ||
223 | |||
224 | #ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP | ||
225 | #if GCC_VERSION >= 40400 | ||
226 | #define __HAVE_BUILTIN_BSWAP32__ | ||
227 | #define __HAVE_BUILTIN_BSWAP64__ | ||
228 | #endif | ||
229 | #if GCC_VERSION >= 40800 || (defined(__powerpc__) && GCC_VERSION >= 40600) | ||
230 | #define __HAVE_BUILTIN_BSWAP16__ | ||
231 | #endif | ||
232 | #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ | ||
233 | |||
234 | #if GCC_VERSION >= 50000 | ||
235 | #define KASAN_ABI_VERSION 4 | ||
236 | #elif GCC_VERSION >= 40902 | ||
237 | #define KASAN_ABI_VERSION 3 | ||
238 | #endif | ||
239 | |||
240 | #endif /* gcc version >= 40000 specific checks */ | ||
122 | 241 | ||
123 | #if !defined(__noclone) | 242 | #if !defined(__noclone) |
124 | #define __noclone /* not needed */ | 243 | #define __noclone /* not needed */ |
@@ -129,5 +248,3 @@ | |||
129 | * code | 248 | * code |
130 | */ | 249 | */ |
131 | #define uninitialized_var(x) x = x | 250 | #define uninitialized_var(x) x = x |
132 | |||
133 | #define __always_inline inline __attribute__((always_inline)) | ||
diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h deleted file mode 100644 index 7d89febe4d79..000000000000 --- a/include/linux/compiler-gcc3.h +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | #ifndef __LINUX_COMPILER_H | ||
2 | #error "Please don't include <linux/compiler-gcc3.h> directly, include <linux/compiler.h> instead." | ||
3 | #endif | ||
4 | |||
5 | #if GCC_VERSION < 30200 | ||
6 | # error Sorry, your compiler is too old - please upgrade it. | ||
7 | #endif | ||
8 | |||
9 | #if GCC_VERSION >= 30300 | ||
10 | # define __used __attribute__((__used__)) | ||
11 | #else | ||
12 | # define __used __attribute__((__unused__)) | ||
13 | #endif | ||
14 | |||
15 | #if GCC_VERSION >= 30400 | ||
16 | #define __must_check __attribute__((warn_unused_result)) | ||
17 | #endif | ||
18 | |||
19 | #ifdef CONFIG_GCOV_KERNEL | ||
20 | # if GCC_VERSION < 30400 | ||
21 | # error "GCOV profiling support for gcc versions below 3.4 not included" | ||
22 | # endif /* __GNUC_MINOR__ */ | ||
23 | #endif /* CONFIG_GCOV_KERNEL */ | ||
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h deleted file mode 100644 index 769e19864632..000000000000 --- a/include/linux/compiler-gcc4.h +++ /dev/null | |||
@@ -1,91 +0,0 @@ | |||
1 | #ifndef __LINUX_COMPILER_H | ||
2 | #error "Please don't include <linux/compiler-gcc4.h> directly, include <linux/compiler.h> instead." | ||
3 | #endif | ||
4 | |||
5 | /* GCC 4.1.[01] miscompiles __weak */ | ||
6 | #ifdef __KERNEL__ | ||
7 | # if GCC_VERSION >= 40100 && GCC_VERSION <= 40101 | ||
8 | # error Your version of gcc miscompiles the __weak directive | ||
9 | # endif | ||
10 | #endif | ||
11 | |||
12 | #define __used __attribute__((__used__)) | ||
13 | #define __must_check __attribute__((warn_unused_result)) | ||
14 | #define __compiler_offsetof(a,b) __builtin_offsetof(a,b) | ||
15 | |||
16 | #if GCC_VERSION >= 40100 && GCC_VERSION < 40600 | ||
17 | # define __compiletime_object_size(obj) __builtin_object_size(obj, 0) | ||
18 | #endif | ||
19 | |||
20 | #if GCC_VERSION >= 40300 | ||
21 | /* Mark functions as cold. gcc will assume any path leading to a call | ||
22 | to them will be unlikely. This means a lot of manual unlikely()s | ||
23 | are unnecessary now for any paths leading to the usual suspects | ||
24 | like BUG(), printk(), panic() etc. [but let's keep them for now for | ||
25 | older compilers] | ||
26 | |||
27 | Early snapshots of gcc 4.3 don't support this and we can't detect this | ||
28 | in the preprocessor, but we can live with this because they're unreleased. | ||
29 | Maketime probing would be overkill here. | ||
30 | |||
31 | gcc also has a __attribute__((__hot__)) to move hot functions into | ||
32 | a special section, but I don't see any sense in this right now in | ||
33 | the kernel context */ | ||
34 | #define __cold __attribute__((__cold__)) | ||
35 | |||
36 | #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) | ||
37 | |||
38 | #ifndef __CHECKER__ | ||
39 | # define __compiletime_warning(message) __attribute__((warning(message))) | ||
40 | # define __compiletime_error(message) __attribute__((error(message))) | ||
41 | #endif /* __CHECKER__ */ | ||
42 | #endif /* GCC_VERSION >= 40300 */ | ||
43 | |||
44 | #if GCC_VERSION >= 40500 | ||
45 | /* | ||
46 | * Mark a position in code as unreachable. This can be used to | ||
47 | * suppress control flow warnings after asm blocks that transfer | ||
48 | * control elsewhere. | ||
49 | * | ||
50 | * Early snapshots of gcc 4.5 don't support this and we can't detect | ||
51 | * this in the preprocessor, but we can live with this because they're | ||
52 | * unreleased. Really, we need to have autoconf for the kernel. | ||
53 | */ | ||
54 | #define unreachable() __builtin_unreachable() | ||
55 | |||
56 | /* Mark a function definition as prohibited from being cloned. */ | ||
57 | #define __noclone __attribute__((__noclone__)) | ||
58 | |||
59 | #endif /* GCC_VERSION >= 40500 */ | ||
60 | |||
61 | #if GCC_VERSION >= 40600 | ||
62 | /* | ||
63 | * Tell the optimizer that something else uses this function or variable. | ||
64 | */ | ||
65 | #define __visible __attribute__((externally_visible)) | ||
66 | #endif | ||
67 | |||
68 | /* | ||
69 | * GCC 'asm goto' miscompiles certain code sequences: | ||
70 | * | ||
71 | * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 | ||
72 | * | ||
73 | * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. | ||
74 | * | ||
75 | * (asm goto is automatically volatile - the naming reflects this.) | ||
76 | */ | ||
77 | #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) | ||
78 | |||
79 | #ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP | ||
80 | #if GCC_VERSION >= 40400 | ||
81 | #define __HAVE_BUILTIN_BSWAP32__ | ||
82 | #define __HAVE_BUILTIN_BSWAP64__ | ||
83 | #endif | ||
84 | #if GCC_VERSION >= 40800 || (defined(__powerpc__) && GCC_VERSION >= 40600) | ||
85 | #define __HAVE_BUILTIN_BSWAP16__ | ||
86 | #endif | ||
87 | #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ | ||
88 | |||
89 | #if GCC_VERSION >= 40902 | ||
90 | #define KASAN_ABI_VERSION 3 | ||
91 | #endif | ||
diff --git a/include/linux/compiler-gcc5.h b/include/linux/compiler-gcc5.h deleted file mode 100644 index efee493714eb..000000000000 --- a/include/linux/compiler-gcc5.h +++ /dev/null | |||
@@ -1,67 +0,0 @@ | |||
1 | #ifndef __LINUX_COMPILER_H | ||
2 | #error "Please don't include <linux/compiler-gcc5.h> directly, include <linux/compiler.h> instead." | ||
3 | #endif | ||
4 | |||
5 | #define __used __attribute__((__used__)) | ||
6 | #define __must_check __attribute__((warn_unused_result)) | ||
7 | #define __compiler_offsetof(a, b) __builtin_offsetof(a, b) | ||
8 | |||
9 | /* Mark functions as cold. gcc will assume any path leading to a call | ||
10 | to them will be unlikely. This means a lot of manual unlikely()s | ||
11 | are unnecessary now for any paths leading to the usual suspects | ||
12 | like BUG(), printk(), panic() etc. [but let's keep them for now for | ||
13 | older compilers] | ||
14 | |||
15 | Early snapshots of gcc 4.3 don't support this and we can't detect this | ||
16 | in the preprocessor, but we can live with this because they're unreleased. | ||
17 | Maketime probing would be overkill here. | ||
18 | |||
19 | gcc also has a __attribute__((__hot__)) to move hot functions into | ||
20 | a special section, but I don't see any sense in this right now in | ||
21 | the kernel context */ | ||
22 | #define __cold __attribute__((__cold__)) | ||
23 | |||
24 | #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) | ||
25 | |||
26 | #ifndef __CHECKER__ | ||
27 | # define __compiletime_warning(message) __attribute__((warning(message))) | ||
28 | # define __compiletime_error(message) __attribute__((error(message))) | ||
29 | #endif /* __CHECKER__ */ | ||
30 | |||
31 | /* | ||
32 | * Mark a position in code as unreachable. This can be used to | ||
33 | * suppress control flow warnings after asm blocks that transfer | ||
34 | * control elsewhere. | ||
35 | * | ||
36 | * Early snapshots of gcc 4.5 don't support this and we can't detect | ||
37 | * this in the preprocessor, but we can live with this because they're | ||
38 | * unreleased. Really, we need to have autoconf for the kernel. | ||
39 | */ | ||
40 | #define unreachable() __builtin_unreachable() | ||
41 | |||
42 | /* Mark a function definition as prohibited from being cloned. */ | ||
43 | #define __noclone __attribute__((__noclone__)) | ||
44 | |||
45 | /* | ||
46 | * Tell the optimizer that something else uses this function or variable. | ||
47 | */ | ||
48 | #define __visible __attribute__((externally_visible)) | ||
49 | |||
50 | /* | ||
51 | * GCC 'asm goto' miscompiles certain code sequences: | ||
52 | * | ||
53 | * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 | ||
54 | * | ||
55 | * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. | ||
56 | * | ||
57 | * (asm goto is automatically volatile - the naming reflects this.) | ||
58 | */ | ||
59 | #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) | ||
60 | |||
61 | #ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP | ||
62 | #define __HAVE_BUILTIN_BSWAP32__ | ||
63 | #define __HAVE_BUILTIN_BSWAP64__ | ||
64 | #define __HAVE_BUILTIN_BSWAP16__ | ||
65 | #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ | ||
66 | |||
67 | #define KASAN_ABI_VERSION 4 | ||
diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h index 0c9a2f2c2802..d4c71132d07f 100644 --- a/include/linux/compiler-intel.h +++ b/include/linux/compiler-intel.h | |||
@@ -13,10 +13,12 @@ | |||
13 | /* Intel ECC compiler doesn't support gcc specific asm stmts. | 13 | /* Intel ECC compiler doesn't support gcc specific asm stmts. |
14 | * It uses intrinsics to do the equivalent things. | 14 | * It uses intrinsics to do the equivalent things. |
15 | */ | 15 | */ |
16 | #undef barrier | ||
16 | #undef barrier_data | 17 | #undef barrier_data |
17 | #undef RELOC_HIDE | 18 | #undef RELOC_HIDE |
18 | #undef OPTIMIZER_HIDE_VAR | 19 | #undef OPTIMIZER_HIDE_VAR |
19 | 20 | ||
21 | #define barrier() __memory_barrier() | ||
20 | #define barrier_data(ptr) barrier() | 22 | #define barrier_data(ptr) barrier() |
21 | 23 | ||
22 | #define RELOC_HIDE(ptr, off) \ | 24 | #define RELOC_HIDE(ptr, off) \ |
diff --git a/include/linux/console.h b/include/linux/console.h index 9f50fb413c11..bd194343c346 100644 --- a/include/linux/console.h +++ b/include/linux/console.h | |||
@@ -115,6 +115,7 @@ static inline int con_debug_leave(void) | |||
115 | #define CON_BOOT (8) | 115 | #define CON_BOOT (8) |
116 | #define CON_ANYTIME (16) /* Safe to call when cpu is offline */ | 116 | #define CON_ANYTIME (16) /* Safe to call when cpu is offline */ |
117 | #define CON_BRL (32) /* Used for a braille device */ | 117 | #define CON_BRL (32) /* Used for a braille device */ |
118 | #define CON_EXTENDED (64) /* Use the extended output format a la /dev/kmsg */ | ||
118 | 119 | ||
119 | struct console { | 120 | struct console { |
120 | char name[16]; | 121 | char name[16]; |
diff --git a/include/linux/printk.h b/include/linux/printk.h index 9b30871c9149..58b1fec40d37 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h | |||
@@ -30,6 +30,8 @@ static inline const char *printk_skip_level(const char *buffer) | |||
30 | return buffer; | 30 | return buffer; |
31 | } | 31 | } |
32 | 32 | ||
33 | #define CONSOLE_EXT_LOG_MAX 8192 | ||
34 | |||
33 | /* printk's without a loglevel use this.. */ | 35 | /* printk's without a loglevel use this.. */ |
34 | #define MESSAGE_LOGLEVEL_DEFAULT CONFIG_MESSAGE_LOGLEVEL_DEFAULT | 36 | #define MESSAGE_LOGLEVEL_DEFAULT CONFIG_MESSAGE_LOGLEVEL_DEFAULT |
35 | 37 | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index 6633e83e608a..93ed0b682adb 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -2556,8 +2556,22 @@ extern struct mm_struct *mm_access(struct task_struct *task, unsigned int mode); | |||
2556 | /* Remove the current tasks stale references to the old mm_struct */ | 2556 | /* Remove the current tasks stale references to the old mm_struct */ |
2557 | extern void mm_release(struct task_struct *, struct mm_struct *); | 2557 | extern void mm_release(struct task_struct *, struct mm_struct *); |
2558 | 2558 | ||
2559 | #ifdef CONFIG_HAVE_COPY_THREAD_TLS | ||
2560 | extern int copy_thread_tls(unsigned long, unsigned long, unsigned long, | ||
2561 | struct task_struct *, unsigned long); | ||
2562 | #else | ||
2559 | extern int copy_thread(unsigned long, unsigned long, unsigned long, | 2563 | extern int copy_thread(unsigned long, unsigned long, unsigned long, |
2560 | struct task_struct *); | 2564 | struct task_struct *); |
2565 | |||
2566 | /* Architectures that haven't opted into copy_thread_tls get the tls argument | ||
2567 | * via pt_regs, so ignore the tls argument passed via C. */ | ||
2568 | static inline int copy_thread_tls( | ||
2569 | unsigned long clone_flags, unsigned long sp, unsigned long arg, | ||
2570 | struct task_struct *p, unsigned long tls) | ||
2571 | { | ||
2572 | return copy_thread(clone_flags, sp, arg, p); | ||
2573 | } | ||
2574 | #endif | ||
2561 | extern void flush_thread(void); | 2575 | extern void flush_thread(void); |
2562 | extern void exit_thread(void); | 2576 | extern void exit_thread(void); |
2563 | 2577 | ||
@@ -2576,6 +2590,7 @@ extern int do_execveat(int, struct filename *, | |||
2576 | const char __user * const __user *, | 2590 | const char __user * const __user *, |
2577 | const char __user * const __user *, | 2591 | const char __user * const __user *, |
2578 | int); | 2592 | int); |
2593 | extern long _do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *, unsigned long); | ||
2579 | extern long do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *); | 2594 | extern long do_fork(unsigned long, unsigned long, unsigned long, int __user *, int __user *); |
2580 | struct task_struct *fork_idle(int); | 2595 | struct task_struct *fork_idle(int); |
2581 | extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); | 2596 | extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); |
diff --git a/include/linux/stddef.h b/include/linux/stddef.h index 076af437284d..9c61c7cda936 100644 --- a/include/linux/stddef.h +++ b/include/linux/stddef.h | |||
@@ -3,7 +3,6 @@ | |||
3 | 3 | ||
4 | #include <uapi/linux/stddef.h> | 4 | #include <uapi/linux/stddef.h> |
5 | 5 | ||
6 | |||
7 | #undef NULL | 6 | #undef NULL |
8 | #define NULL ((void *)0) | 7 | #define NULL ((void *)0) |
9 | 8 | ||
@@ -14,10 +13,9 @@ enum { | |||
14 | 13 | ||
15 | #undef offsetof | 14 | #undef offsetof |
16 | #ifdef __compiler_offsetof | 15 | #ifdef __compiler_offsetof |
17 | #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER) | 16 | #define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER) |
18 | #else | 17 | #else |
19 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) | 18 | #define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER) |
20 | #endif | ||
21 | #endif | 19 | #endif |
22 | 20 | ||
23 | /** | 21 | /** |
@@ -28,3 +26,5 @@ enum { | |||
28 | */ | 26 | */ |
29 | #define offsetofend(TYPE, MEMBER) \ | 27 | #define offsetofend(TYPE, MEMBER) \ |
30 | (offsetof(TYPE, MEMBER) + sizeof(((TYPE *)0)->MEMBER)) | 28 | (offsetof(TYPE, MEMBER) + sizeof(((TYPE *)0)->MEMBER)) |
29 | |||
30 | #endif | ||
diff --git a/include/linux/string.h b/include/linux/string.h index e40099e585c9..a8d90db9c4b0 100644 --- a/include/linux/string.h +++ b/include/linux/string.h | |||
@@ -111,6 +111,7 @@ extern int memcmp(const void *,const void *,__kernel_size_t); | |||
111 | extern void * memchr(const void *,int,__kernel_size_t); | 111 | extern void * memchr(const void *,int,__kernel_size_t); |
112 | #endif | 112 | #endif |
113 | void *memchr_inv(const void *s, int c, size_t n); | 113 | void *memchr_inv(const void *s, int c, size_t n); |
114 | char *strreplace(char *s, char old, char new); | ||
114 | 115 | ||
115 | extern void kfree_const(const void *x); | 116 | extern void kfree_const(const void *x); |
116 | 117 | ||
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 76d1e38aabe1..bb51becf23f8 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -827,15 +827,15 @@ asmlinkage long sys_syncfs(int fd); | |||
827 | asmlinkage long sys_fork(void); | 827 | asmlinkage long sys_fork(void); |
828 | asmlinkage long sys_vfork(void); | 828 | asmlinkage long sys_vfork(void); |
829 | #ifdef CONFIG_CLONE_BACKWARDS | 829 | #ifdef CONFIG_CLONE_BACKWARDS |
830 | asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, int, | 830 | asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, unsigned long, |
831 | int __user *); | 831 | int __user *); |
832 | #else | 832 | #else |
833 | #ifdef CONFIG_CLONE_BACKWARDS3 | 833 | #ifdef CONFIG_CLONE_BACKWARDS3 |
834 | asmlinkage long sys_clone(unsigned long, unsigned long, int, int __user *, | 834 | asmlinkage long sys_clone(unsigned long, unsigned long, int, int __user *, |
835 | int __user *, int); | 835 | int __user *, unsigned long); |
836 | #else | 836 | #else |
837 | asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, | 837 | asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, |
838 | int __user *, int); | 838 | int __user *, unsigned long); |
839 | #endif | 839 | #endif |
840 | #endif | 840 | #endif |
841 | 841 | ||
diff --git a/include/linux/syslog.h b/include/linux/syslog.h index 4b7b875a7ce1..c3a7f0cc3a27 100644 --- a/include/linux/syslog.h +++ b/include/linux/syslog.h | |||
@@ -47,12 +47,12 @@ | |||
47 | #define SYSLOG_FROM_READER 0 | 47 | #define SYSLOG_FROM_READER 0 |
48 | #define SYSLOG_FROM_PROC 1 | 48 | #define SYSLOG_FROM_PROC 1 |
49 | 49 | ||
50 | int do_syslog(int type, char __user *buf, int count, bool from_file); | 50 | int do_syslog(int type, char __user *buf, int count, int source); |
51 | 51 | ||
52 | #ifdef CONFIG_PRINTK | 52 | #ifdef CONFIG_PRINTK |
53 | int check_syslog_permissions(int type, bool from_file); | 53 | int check_syslog_permissions(int type, int source); |
54 | #else | 54 | #else |
55 | static inline int check_syslog_permissions(int type, bool from_file) | 55 | static inline int check_syslog_permissions(int type, int source) |
56 | { | 56 | { |
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
diff --git a/include/linux/zpool.h b/include/linux/zpool.h index 56529b34dc63..d30eff3d84d5 100644 --- a/include/linux/zpool.h +++ b/include/linux/zpool.h | |||
@@ -81,7 +81,8 @@ struct zpool_driver { | |||
81 | atomic_t refcount; | 81 | atomic_t refcount; |
82 | struct list_head list; | 82 | struct list_head list; |
83 | 83 | ||
84 | void *(*create)(char *name, gfp_t gfp, struct zpool_ops *ops); | 84 | void *(*create)(char *name, gfp_t gfp, struct zpool_ops *ops, |
85 | struct zpool *zpool); | ||
85 | void (*destroy)(void *pool); | 86 | void (*destroy)(void *pool); |
86 | 87 | ||
87 | int (*malloc)(void *pool, size_t size, gfp_t gfp, | 88 | int (*malloc)(void *pool, size_t size, gfp_t gfp, |
@@ -102,6 +103,4 @@ void zpool_register_driver(struct zpool_driver *driver); | |||
102 | 103 | ||
103 | int zpool_unregister_driver(struct zpool_driver *driver); | 104 | int zpool_unregister_driver(struct zpool_driver *driver); |
104 | 105 | ||
105 | int zpool_evict(void *pool, unsigned long handle); | ||
106 | |||
107 | #endif | 106 | #endif |
diff --git a/init/Kconfig b/init/Kconfig index 7260b27ebbab..f0c2e681b506 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -1136,6 +1136,7 @@ endif # CGROUPS | |||
1136 | 1136 | ||
1137 | config CHECKPOINT_RESTORE | 1137 | config CHECKPOINT_RESTORE |
1138 | bool "Checkpoint/restore support" if EXPERT | 1138 | bool "Checkpoint/restore support" if EXPERT |
1139 | select PROC_CHILDREN | ||
1139 | default n | 1140 | default n |
1140 | help | 1141 | help |
1141 | Enables additional kernel features in a sake of checkpoint/restore. | 1142 | Enables additional kernel features in a sake of checkpoint/restore. |
diff --git a/init/do_mounts.c b/init/do_mounts.c index a95bbdb2a502..dea5de95c2dd 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c | |||
@@ -533,8 +533,13 @@ void __init mount_root(void) | |||
533 | } | 533 | } |
534 | #endif | 534 | #endif |
535 | #ifdef CONFIG_BLOCK | 535 | #ifdef CONFIG_BLOCK |
536 | create_dev("/dev/root", ROOT_DEV); | 536 | { |
537 | mount_block_root("/dev/root", root_mountflags); | 537 | int err = create_dev("/dev/root", ROOT_DEV); |
538 | |||
539 | if (err < 0) | ||
540 | pr_emerg("Failed to create /dev/root: %d\n", err); | ||
541 | mount_block_root("/dev/root", root_mountflags); | ||
542 | } | ||
538 | #endif | 543 | #endif |
539 | } | 544 | } |
540 | 545 | ||
diff --git a/kernel/exit.c b/kernel/exit.c index 185752a729f6..031325e9acf9 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -711,10 +711,10 @@ void do_exit(long code) | |||
711 | current->comm, task_pid_nr(current), | 711 | current->comm, task_pid_nr(current), |
712 | preempt_count()); | 712 | preempt_count()); |
713 | 713 | ||
714 | acct_update_integrals(tsk); | ||
715 | /* sync mm's RSS info before statistics gathering */ | 714 | /* sync mm's RSS info before statistics gathering */ |
716 | if (tsk->mm) | 715 | if (tsk->mm) |
717 | sync_mm_rss(tsk->mm); | 716 | sync_mm_rss(tsk->mm); |
717 | acct_update_integrals(tsk); | ||
718 | group_dead = atomic_dec_and_test(&tsk->signal->live); | 718 | group_dead = atomic_dec_and_test(&tsk->signal->live); |
719 | if (group_dead) { | 719 | if (group_dead) { |
720 | hrtimer_cancel(&tsk->signal->real_timer); | 720 | hrtimer_cancel(&tsk->signal->real_timer); |
diff --git a/kernel/fork.c b/kernel/fork.c index 0bb88b555550..4c95cb34243c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1238,7 +1238,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1238 | unsigned long stack_size, | 1238 | unsigned long stack_size, |
1239 | int __user *child_tidptr, | 1239 | int __user *child_tidptr, |
1240 | struct pid *pid, | 1240 | struct pid *pid, |
1241 | int trace) | 1241 | int trace, |
1242 | unsigned long tls) | ||
1242 | { | 1243 | { |
1243 | int retval; | 1244 | int retval; |
1244 | struct task_struct *p; | 1245 | struct task_struct *p; |
@@ -1447,7 +1448,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1447 | retval = copy_io(clone_flags, p); | 1448 | retval = copy_io(clone_flags, p); |
1448 | if (retval) | 1449 | if (retval) |
1449 | goto bad_fork_cleanup_namespaces; | 1450 | goto bad_fork_cleanup_namespaces; |
1450 | retval = copy_thread(clone_flags, stack_start, stack_size, p); | 1451 | retval = copy_thread_tls(clone_flags, stack_start, stack_size, p, tls); |
1451 | if (retval) | 1452 | if (retval) |
1452 | goto bad_fork_cleanup_io; | 1453 | goto bad_fork_cleanup_io; |
1453 | 1454 | ||
@@ -1659,7 +1660,7 @@ static inline void init_idle_pids(struct pid_link *links) | |||
1659 | struct task_struct *fork_idle(int cpu) | 1660 | struct task_struct *fork_idle(int cpu) |
1660 | { | 1661 | { |
1661 | struct task_struct *task; | 1662 | struct task_struct *task; |
1662 | task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0); | 1663 | task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0, 0); |
1663 | if (!IS_ERR(task)) { | 1664 | if (!IS_ERR(task)) { |
1664 | init_idle_pids(task->pids); | 1665 | init_idle_pids(task->pids); |
1665 | init_idle(task, cpu); | 1666 | init_idle(task, cpu); |
@@ -1674,11 +1675,12 @@ struct task_struct *fork_idle(int cpu) | |||
1674 | * It copies the process, and if successful kick-starts | 1675 | * It copies the process, and if successful kick-starts |
1675 | * it and waits for it to finish using the VM if required. | 1676 | * it and waits for it to finish using the VM if required. |
1676 | */ | 1677 | */ |
1677 | long do_fork(unsigned long clone_flags, | 1678 | long _do_fork(unsigned long clone_flags, |
1678 | unsigned long stack_start, | 1679 | unsigned long stack_start, |
1679 | unsigned long stack_size, | 1680 | unsigned long stack_size, |
1680 | int __user *parent_tidptr, | 1681 | int __user *parent_tidptr, |
1681 | int __user *child_tidptr) | 1682 | int __user *child_tidptr, |
1683 | unsigned long tls) | ||
1682 | { | 1684 | { |
1683 | struct task_struct *p; | 1685 | struct task_struct *p; |
1684 | int trace = 0; | 1686 | int trace = 0; |
@@ -1703,7 +1705,7 @@ long do_fork(unsigned long clone_flags, | |||
1703 | } | 1705 | } |
1704 | 1706 | ||
1705 | p = copy_process(clone_flags, stack_start, stack_size, | 1707 | p = copy_process(clone_flags, stack_start, stack_size, |
1706 | child_tidptr, NULL, trace); | 1708 | child_tidptr, NULL, trace, tls); |
1707 | /* | 1709 | /* |
1708 | * Do this prior waking up the new thread - the thread pointer | 1710 | * Do this prior waking up the new thread - the thread pointer |
1709 | * might get invalid after that point, if the thread exits quickly. | 1711 | * might get invalid after that point, if the thread exits quickly. |
@@ -1744,20 +1746,34 @@ long do_fork(unsigned long clone_flags, | |||
1744 | return nr; | 1746 | return nr; |
1745 | } | 1747 | } |
1746 | 1748 | ||
1749 | #ifndef CONFIG_HAVE_COPY_THREAD_TLS | ||
1750 | /* For compatibility with architectures that call do_fork directly rather than | ||
1751 | * using the syscall entry points below. */ | ||
1752 | long do_fork(unsigned long clone_flags, | ||
1753 | unsigned long stack_start, | ||
1754 | unsigned long stack_size, | ||
1755 | int __user *parent_tidptr, | ||
1756 | int __user *child_tidptr) | ||
1757 | { | ||
1758 | return _do_fork(clone_flags, stack_start, stack_size, | ||
1759 | parent_tidptr, child_tidptr, 0); | ||
1760 | } | ||
1761 | #endif | ||
1762 | |||
1747 | /* | 1763 | /* |
1748 | * Create a kernel thread. | 1764 | * Create a kernel thread. |
1749 | */ | 1765 | */ |
1750 | pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | 1766 | pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) |
1751 | { | 1767 | { |
1752 | return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, | 1768 | return _do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, |
1753 | (unsigned long)arg, NULL, NULL); | 1769 | (unsigned long)arg, NULL, NULL, 0); |
1754 | } | 1770 | } |
1755 | 1771 | ||
1756 | #ifdef __ARCH_WANT_SYS_FORK | 1772 | #ifdef __ARCH_WANT_SYS_FORK |
1757 | SYSCALL_DEFINE0(fork) | 1773 | SYSCALL_DEFINE0(fork) |
1758 | { | 1774 | { |
1759 | #ifdef CONFIG_MMU | 1775 | #ifdef CONFIG_MMU |
1760 | return do_fork(SIGCHLD, 0, 0, NULL, NULL); | 1776 | return _do_fork(SIGCHLD, 0, 0, NULL, NULL, 0); |
1761 | #else | 1777 | #else |
1762 | /* can not support in nommu mode */ | 1778 | /* can not support in nommu mode */ |
1763 | return -EINVAL; | 1779 | return -EINVAL; |
@@ -1768,8 +1784,8 @@ SYSCALL_DEFINE0(fork) | |||
1768 | #ifdef __ARCH_WANT_SYS_VFORK | 1784 | #ifdef __ARCH_WANT_SYS_VFORK |
1769 | SYSCALL_DEFINE0(vfork) | 1785 | SYSCALL_DEFINE0(vfork) |
1770 | { | 1786 | { |
1771 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, | 1787 | return _do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, |
1772 | 0, NULL, NULL); | 1788 | 0, NULL, NULL, 0); |
1773 | } | 1789 | } |
1774 | #endif | 1790 | #endif |
1775 | 1791 | ||
@@ -1777,27 +1793,27 @@ SYSCALL_DEFINE0(vfork) | |||
1777 | #ifdef CONFIG_CLONE_BACKWARDS | 1793 | #ifdef CONFIG_CLONE_BACKWARDS |
1778 | SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, | 1794 | SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, |
1779 | int __user *, parent_tidptr, | 1795 | int __user *, parent_tidptr, |
1780 | int, tls_val, | 1796 | unsigned long, tls, |
1781 | int __user *, child_tidptr) | 1797 | int __user *, child_tidptr) |
1782 | #elif defined(CONFIG_CLONE_BACKWARDS2) | 1798 | #elif defined(CONFIG_CLONE_BACKWARDS2) |
1783 | SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags, | 1799 | SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags, |
1784 | int __user *, parent_tidptr, | 1800 | int __user *, parent_tidptr, |
1785 | int __user *, child_tidptr, | 1801 | int __user *, child_tidptr, |
1786 | int, tls_val) | 1802 | unsigned long, tls) |
1787 | #elif defined(CONFIG_CLONE_BACKWARDS3) | 1803 | #elif defined(CONFIG_CLONE_BACKWARDS3) |
1788 | SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp, | 1804 | SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp, |
1789 | int, stack_size, | 1805 | int, stack_size, |
1790 | int __user *, parent_tidptr, | 1806 | int __user *, parent_tidptr, |
1791 | int __user *, child_tidptr, | 1807 | int __user *, child_tidptr, |
1792 | int, tls_val) | 1808 | unsigned long, tls) |
1793 | #else | 1809 | #else |
1794 | SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, | 1810 | SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, |
1795 | int __user *, parent_tidptr, | 1811 | int __user *, parent_tidptr, |
1796 | int __user *, child_tidptr, | 1812 | int __user *, child_tidptr, |
1797 | int, tls_val) | 1813 | unsigned long, tls) |
1798 | #endif | 1814 | #endif |
1799 | { | 1815 | { |
1800 | return do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr); | 1816 | return _do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr, tls); |
1801 | } | 1817 | } |
1802 | #endif | 1818 | #endif |
1803 | 1819 | ||
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index c099b082cd02..de553849f3ac 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c | |||
@@ -85,6 +85,18 @@ static struct lockdep_map console_lock_dep_map = { | |||
85 | #endif | 85 | #endif |
86 | 86 | ||
87 | /* | 87 | /* |
88 | * Number of registered extended console drivers. | ||
89 | * | ||
90 | * If extended consoles are present, in-kernel cont reassembly is disabled | ||
91 | * and each fragment is stored as a separate log entry with proper | ||
92 | * continuation flag so that every emitted message has full metadata. This | ||
93 | * doesn't change the result for regular consoles or /proc/kmsg. For | ||
94 | * /dev/kmsg, as long as the reader concatenates messages according to | ||
95 | * consecutive continuation flags, the end result should be the same too. | ||
96 | */ | ||
97 | static int nr_ext_console_drivers; | ||
98 | |||
99 | /* | ||
88 | * Helper macros to handle lockdep when locking/unlocking console_sem. We use | 100 | * Helper macros to handle lockdep when locking/unlocking console_sem. We use |
89 | * macros instead of functions so that _RET_IP_ contains useful information. | 101 | * macros instead of functions so that _RET_IP_ contains useful information. |
90 | */ | 102 | */ |
@@ -195,7 +207,7 @@ static int console_may_schedule; | |||
195 | * need to be changed in the future, when the requirements change. | 207 | * need to be changed in the future, when the requirements change. |
196 | * | 208 | * |
197 | * /dev/kmsg exports the structured data in the following line format: | 209 | * /dev/kmsg exports the structured data in the following line format: |
198 | * "level,sequnum,timestamp;<message text>\n" | 210 | * "<level>,<sequnum>,<timestamp>,<contflag>;<message text>\n" |
199 | * | 211 | * |
200 | * The optional key/value pairs are attached as continuation lines starting | 212 | * The optional key/value pairs are attached as continuation lines starting |
201 | * with a space character and terminated by a newline. All possible | 213 | * with a space character and terminated by a newline. All possible |
@@ -477,18 +489,18 @@ static int syslog_action_restricted(int type) | |||
477 | type != SYSLOG_ACTION_SIZE_BUFFER; | 489 | type != SYSLOG_ACTION_SIZE_BUFFER; |
478 | } | 490 | } |
479 | 491 | ||
480 | int check_syslog_permissions(int type, bool from_file) | 492 | int check_syslog_permissions(int type, int source) |
481 | { | 493 | { |
482 | /* | 494 | /* |
483 | * If this is from /proc/kmsg and we've already opened it, then we've | 495 | * If this is from /proc/kmsg and we've already opened it, then we've |
484 | * already done the capabilities checks at open time. | 496 | * already done the capabilities checks at open time. |
485 | */ | 497 | */ |
486 | if (from_file && type != SYSLOG_ACTION_OPEN) | 498 | if (source == SYSLOG_FROM_PROC && type != SYSLOG_ACTION_OPEN) |
487 | return 0; | 499 | goto ok; |
488 | 500 | ||
489 | if (syslog_action_restricted(type)) { | 501 | if (syslog_action_restricted(type)) { |
490 | if (capable(CAP_SYSLOG)) | 502 | if (capable(CAP_SYSLOG)) |
491 | return 0; | 503 | goto ok; |
492 | /* | 504 | /* |
493 | * For historical reasons, accept CAP_SYS_ADMIN too, with | 505 | * For historical reasons, accept CAP_SYS_ADMIN too, with |
494 | * a warning. | 506 | * a warning. |
@@ -498,13 +510,94 @@ int check_syslog_permissions(int type, bool from_file) | |||
498 | "CAP_SYS_ADMIN but no CAP_SYSLOG " | 510 | "CAP_SYS_ADMIN but no CAP_SYSLOG " |
499 | "(deprecated).\n", | 511 | "(deprecated).\n", |
500 | current->comm, task_pid_nr(current)); | 512 | current->comm, task_pid_nr(current)); |
501 | return 0; | 513 | goto ok; |
502 | } | 514 | } |
503 | return -EPERM; | 515 | return -EPERM; |
504 | } | 516 | } |
517 | ok: | ||
505 | return security_syslog(type); | 518 | return security_syslog(type); |
506 | } | 519 | } |
507 | 520 | ||
521 | static void append_char(char **pp, char *e, char c) | ||
522 | { | ||
523 | if (*pp < e) | ||
524 | *(*pp)++ = c; | ||
525 | } | ||
526 | |||
527 | static ssize_t msg_print_ext_header(char *buf, size_t size, | ||
528 | struct printk_log *msg, u64 seq, | ||
529 | enum log_flags prev_flags) | ||
530 | { | ||
531 | u64 ts_usec = msg->ts_nsec; | ||
532 | char cont = '-'; | ||
533 | |||
534 | do_div(ts_usec, 1000); | ||
535 | |||
536 | /* | ||
537 | * If we couldn't merge continuation line fragments during the print, | ||
538 | * export the stored flags to allow an optional external merge of the | ||
539 | * records. Merging the records isn't always neccessarily correct, like | ||
540 | * when we hit a race during printing. In most cases though, it produces | ||
541 | * better readable output. 'c' in the record flags mark the first | ||
542 | * fragment of a line, '+' the following. | ||
543 | */ | ||
544 | if (msg->flags & LOG_CONT && !(prev_flags & LOG_CONT)) | ||
545 | cont = 'c'; | ||
546 | else if ((msg->flags & LOG_CONT) || | ||
547 | ((prev_flags & LOG_CONT) && !(msg->flags & LOG_PREFIX))) | ||
548 | cont = '+'; | ||
549 | |||
550 | return scnprintf(buf, size, "%u,%llu,%llu,%c;", | ||
551 | (msg->facility << 3) | msg->level, seq, ts_usec, cont); | ||
552 | } | ||
553 | |||
554 | static ssize_t msg_print_ext_body(char *buf, size_t size, | ||
555 | char *dict, size_t dict_len, | ||
556 | char *text, size_t text_len) | ||
557 | { | ||
558 | char *p = buf, *e = buf + size; | ||
559 | size_t i; | ||
560 | |||
561 | /* escape non-printable characters */ | ||
562 | for (i = 0; i < text_len; i++) { | ||
563 | unsigned char c = text[i]; | ||
564 | |||
565 | if (c < ' ' || c >= 127 || c == '\\') | ||
566 | p += scnprintf(p, e - p, "\\x%02x", c); | ||
567 | else | ||
568 | append_char(&p, e, c); | ||
569 | } | ||
570 | append_char(&p, e, '\n'); | ||
571 | |||
572 | if (dict_len) { | ||
573 | bool line = true; | ||
574 | |||
575 | for (i = 0; i < dict_len; i++) { | ||
576 | unsigned char c = dict[i]; | ||
577 | |||
578 | if (line) { | ||
579 | append_char(&p, e, ' '); | ||
580 | line = false; | ||
581 | } | ||
582 | |||
583 | if (c == '\0') { | ||
584 | append_char(&p, e, '\n'); | ||
585 | line = true; | ||
586 | continue; | ||
587 | } | ||
588 | |||
589 | if (c < ' ' || c >= 127 || c == '\\') { | ||
590 | p += scnprintf(p, e - p, "\\x%02x", c); | ||
591 | continue; | ||
592 | } | ||
593 | |||
594 | append_char(&p, e, c); | ||
595 | } | ||
596 | append_char(&p, e, '\n'); | ||
597 | } | ||
598 | |||
599 | return p - buf; | ||
600 | } | ||
508 | 601 | ||
509 | /* /dev/kmsg - userspace message inject/listen interface */ | 602 | /* /dev/kmsg - userspace message inject/listen interface */ |
510 | struct devkmsg_user { | 603 | struct devkmsg_user { |
@@ -512,7 +605,7 @@ struct devkmsg_user { | |||
512 | u32 idx; | 605 | u32 idx; |
513 | enum log_flags prev; | 606 | enum log_flags prev; |
514 | struct mutex lock; | 607 | struct mutex lock; |
515 | char buf[8192]; | 608 | char buf[CONSOLE_EXT_LOG_MAX]; |
516 | }; | 609 | }; |
517 | 610 | ||
518 | static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from) | 611 | static ssize_t devkmsg_write(struct kiocb *iocb, struct iov_iter *from) |
@@ -570,9 +663,6 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, | |||
570 | { | 663 | { |
571 | struct devkmsg_user *user = file->private_data; | 664 | struct devkmsg_user *user = file->private_data; |
572 | struct printk_log *msg; | 665 | struct printk_log *msg; |
573 | u64 ts_usec; | ||
574 | size_t i; | ||
575 | char cont = '-'; | ||
576 | size_t len; | 666 | size_t len; |
577 | ssize_t ret; | 667 | ssize_t ret; |
578 | 668 | ||
@@ -608,66 +698,13 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, | |||
608 | } | 698 | } |
609 | 699 | ||
610 | msg = log_from_idx(user->idx); | 700 | msg = log_from_idx(user->idx); |
611 | ts_usec = msg->ts_nsec; | 701 | len = msg_print_ext_header(user->buf, sizeof(user->buf), |
612 | do_div(ts_usec, 1000); | 702 | msg, user->seq, user->prev); |
703 | len += msg_print_ext_body(user->buf + len, sizeof(user->buf) - len, | ||
704 | log_dict(msg), msg->dict_len, | ||
705 | log_text(msg), msg->text_len); | ||
613 | 706 | ||
614 | /* | ||
615 | * If we couldn't merge continuation line fragments during the print, | ||
616 | * export the stored flags to allow an optional external merge of the | ||
617 | * records. Merging the records isn't always neccessarily correct, like | ||
618 | * when we hit a race during printing. In most cases though, it produces | ||
619 | * better readable output. 'c' in the record flags mark the first | ||
620 | * fragment of a line, '+' the following. | ||
621 | */ | ||
622 | if (msg->flags & LOG_CONT && !(user->prev & LOG_CONT)) | ||
623 | cont = 'c'; | ||
624 | else if ((msg->flags & LOG_CONT) || | ||
625 | ((user->prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))) | ||
626 | cont = '+'; | ||
627 | |||
628 | len = sprintf(user->buf, "%u,%llu,%llu,%c;", | ||
629 | (msg->facility << 3) | msg->level, | ||
630 | user->seq, ts_usec, cont); | ||
631 | user->prev = msg->flags; | 707 | user->prev = msg->flags; |
632 | |||
633 | /* escape non-printable characters */ | ||
634 | for (i = 0; i < msg->text_len; i++) { | ||
635 | unsigned char c = log_text(msg)[i]; | ||
636 | |||
637 | if (c < ' ' || c >= 127 || c == '\\') | ||
638 | len += sprintf(user->buf + len, "\\x%02x", c); | ||
639 | else | ||
640 | user->buf[len++] = c; | ||
641 | } | ||
642 | user->buf[len++] = '\n'; | ||
643 | |||
644 | if (msg->dict_len) { | ||
645 | bool line = true; | ||
646 | |||
647 | for (i = 0; i < msg->dict_len; i++) { | ||
648 | unsigned char c = log_dict(msg)[i]; | ||
649 | |||
650 | if (line) { | ||
651 | user->buf[len++] = ' '; | ||
652 | line = false; | ||
653 | } | ||
654 | |||
655 | if (c == '\0') { | ||
656 | user->buf[len++] = '\n'; | ||
657 | line = true; | ||
658 | continue; | ||
659 | } | ||
660 | |||
661 | if (c < ' ' || c >= 127 || c == '\\') { | ||
662 | len += sprintf(user->buf + len, "\\x%02x", c); | ||
663 | continue; | ||
664 | } | ||
665 | |||
666 | user->buf[len++] = c; | ||
667 | } | ||
668 | user->buf[len++] = '\n'; | ||
669 | } | ||
670 | |||
671 | user->idx = log_next(user->idx); | 708 | user->idx = log_next(user->idx); |
672 | user->seq++; | 709 | user->seq++; |
673 | raw_spin_unlock_irq(&logbuf_lock); | 710 | raw_spin_unlock_irq(&logbuf_lock); |
@@ -1253,20 +1290,16 @@ static int syslog_print_all(char __user *buf, int size, bool clear) | |||
1253 | return len; | 1290 | return len; |
1254 | } | 1291 | } |
1255 | 1292 | ||
1256 | int do_syslog(int type, char __user *buf, int len, bool from_file) | 1293 | int do_syslog(int type, char __user *buf, int len, int source) |
1257 | { | 1294 | { |
1258 | bool clear = false; | 1295 | bool clear = false; |
1259 | static int saved_console_loglevel = LOGLEVEL_DEFAULT; | 1296 | static int saved_console_loglevel = LOGLEVEL_DEFAULT; |
1260 | int error; | 1297 | int error; |
1261 | 1298 | ||
1262 | error = check_syslog_permissions(type, from_file); | 1299 | error = check_syslog_permissions(type, source); |
1263 | if (error) | 1300 | if (error) |
1264 | goto out; | 1301 | goto out; |
1265 | 1302 | ||
1266 | error = security_syslog(type); | ||
1267 | if (error) | ||
1268 | return error; | ||
1269 | |||
1270 | switch (type) { | 1303 | switch (type) { |
1271 | case SYSLOG_ACTION_CLOSE: /* Close log */ | 1304 | case SYSLOG_ACTION_CLOSE: /* Close log */ |
1272 | break; | 1305 | break; |
@@ -1346,7 +1379,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
1346 | syslog_prev = 0; | 1379 | syslog_prev = 0; |
1347 | syslog_partial = 0; | 1380 | syslog_partial = 0; |
1348 | } | 1381 | } |
1349 | if (from_file) { | 1382 | if (source == SYSLOG_FROM_PROC) { |
1350 | /* | 1383 | /* |
1351 | * Short-cut for poll(/"proc/kmsg") which simply checks | 1384 | * Short-cut for poll(/"proc/kmsg") which simply checks |
1352 | * for pending data, not the size; return the count of | 1385 | * for pending data, not the size; return the count of |
@@ -1393,7 +1426,9 @@ SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) | |||
1393 | * log_buf[start] to log_buf[end - 1]. | 1426 | * log_buf[start] to log_buf[end - 1]. |
1394 | * The console_lock must be held. | 1427 | * The console_lock must be held. |
1395 | */ | 1428 | */ |
1396 | static void call_console_drivers(int level, const char *text, size_t len) | 1429 | static void call_console_drivers(int level, |
1430 | const char *ext_text, size_t ext_len, | ||
1431 | const char *text, size_t len) | ||
1397 | { | 1432 | { |
1398 | struct console *con; | 1433 | struct console *con; |
1399 | 1434 | ||
@@ -1414,7 +1449,10 @@ static void call_console_drivers(int level, const char *text, size_t len) | |||
1414 | if (!cpu_online(smp_processor_id()) && | 1449 | if (!cpu_online(smp_processor_id()) && |
1415 | !(con->flags & CON_ANYTIME)) | 1450 | !(con->flags & CON_ANYTIME)) |
1416 | continue; | 1451 | continue; |
1417 | con->write(con, text, len); | 1452 | if (con->flags & CON_EXTENDED) |
1453 | con->write(con, ext_text, ext_len); | ||
1454 | else | ||
1455 | con->write(con, text, len); | ||
1418 | } | 1456 | } |
1419 | } | 1457 | } |
1420 | 1458 | ||
@@ -1557,8 +1595,12 @@ static bool cont_add(int facility, int level, const char *text, size_t len) | |||
1557 | if (cont.len && cont.flushed) | 1595 | if (cont.len && cont.flushed) |
1558 | return false; | 1596 | return false; |
1559 | 1597 | ||
1560 | if (cont.len + len > sizeof(cont.buf)) { | 1598 | /* |
1561 | /* the line gets too long, split it up in separate records */ | 1599 | * If ext consoles are present, flush and skip in-kernel |
1600 | * continuation. See nr_ext_console_drivers definition. Also, if | ||
1601 | * the line gets too long, split it up in separate records. | ||
1602 | */ | ||
1603 | if (nr_ext_console_drivers || cont.len + len > sizeof(cont.buf)) { | ||
1562 | cont_flush(LOG_CONT); | 1604 | cont_flush(LOG_CONT); |
1563 | return false; | 1605 | return false; |
1564 | } | 1606 | } |
@@ -1893,9 +1935,19 @@ static struct cont { | |||
1893 | u8 level; | 1935 | u8 level; |
1894 | bool flushed:1; | 1936 | bool flushed:1; |
1895 | } cont; | 1937 | } cont; |
1938 | static char *log_text(const struct printk_log *msg) { return NULL; } | ||
1939 | static char *log_dict(const struct printk_log *msg) { return NULL; } | ||
1896 | static struct printk_log *log_from_idx(u32 idx) { return NULL; } | 1940 | static struct printk_log *log_from_idx(u32 idx) { return NULL; } |
1897 | static u32 log_next(u32 idx) { return 0; } | 1941 | static u32 log_next(u32 idx) { return 0; } |
1898 | static void call_console_drivers(int level, const char *text, size_t len) {} | 1942 | static ssize_t msg_print_ext_header(char *buf, size_t size, |
1943 | struct printk_log *msg, u64 seq, | ||
1944 | enum log_flags prev_flags) { return 0; } | ||
1945 | static ssize_t msg_print_ext_body(char *buf, size_t size, | ||
1946 | char *dict, size_t dict_len, | ||
1947 | char *text, size_t text_len) { return 0; } | ||
1948 | static void call_console_drivers(int level, | ||
1949 | const char *ext_text, size_t ext_len, | ||
1950 | const char *text, size_t len) {} | ||
1899 | static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev, | 1951 | static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev, |
1900 | bool syslog, char *buf, size_t size) { return 0; } | 1952 | bool syslog, char *buf, size_t size) { return 0; } |
1901 | static size_t cont_print_text(char *text, size_t size) { return 0; } | 1953 | static size_t cont_print_text(char *text, size_t size) { return 0; } |
@@ -2148,7 +2200,7 @@ static void console_cont_flush(char *text, size_t size) | |||
2148 | len = cont_print_text(text, size); | 2200 | len = cont_print_text(text, size); |
2149 | raw_spin_unlock(&logbuf_lock); | 2201 | raw_spin_unlock(&logbuf_lock); |
2150 | stop_critical_timings(); | 2202 | stop_critical_timings(); |
2151 | call_console_drivers(cont.level, text, len); | 2203 | call_console_drivers(cont.level, NULL, 0, text, len); |
2152 | start_critical_timings(); | 2204 | start_critical_timings(); |
2153 | local_irq_restore(flags); | 2205 | local_irq_restore(flags); |
2154 | return; | 2206 | return; |
@@ -2172,6 +2224,7 @@ out: | |||
2172 | */ | 2224 | */ |
2173 | void console_unlock(void) | 2225 | void console_unlock(void) |
2174 | { | 2226 | { |
2227 | static char ext_text[CONSOLE_EXT_LOG_MAX]; | ||
2175 | static char text[LOG_LINE_MAX + PREFIX_MAX]; | 2228 | static char text[LOG_LINE_MAX + PREFIX_MAX]; |
2176 | static u64 seen_seq; | 2229 | static u64 seen_seq; |
2177 | unsigned long flags; | 2230 | unsigned long flags; |
@@ -2190,6 +2243,7 @@ void console_unlock(void) | |||
2190 | again: | 2243 | again: |
2191 | for (;;) { | 2244 | for (;;) { |
2192 | struct printk_log *msg; | 2245 | struct printk_log *msg; |
2246 | size_t ext_len = 0; | ||
2193 | size_t len; | 2247 | size_t len; |
2194 | int level; | 2248 | int level; |
2195 | 2249 | ||
@@ -2235,13 +2289,22 @@ skip: | |||
2235 | level = msg->level; | 2289 | level = msg->level; |
2236 | len += msg_print_text(msg, console_prev, false, | 2290 | len += msg_print_text(msg, console_prev, false, |
2237 | text + len, sizeof(text) - len); | 2291 | text + len, sizeof(text) - len); |
2292 | if (nr_ext_console_drivers) { | ||
2293 | ext_len = msg_print_ext_header(ext_text, | ||
2294 | sizeof(ext_text), | ||
2295 | msg, console_seq, console_prev); | ||
2296 | ext_len += msg_print_ext_body(ext_text + ext_len, | ||
2297 | sizeof(ext_text) - ext_len, | ||
2298 | log_dict(msg), msg->dict_len, | ||
2299 | log_text(msg), msg->text_len); | ||
2300 | } | ||
2238 | console_idx = log_next(console_idx); | 2301 | console_idx = log_next(console_idx); |
2239 | console_seq++; | 2302 | console_seq++; |
2240 | console_prev = msg->flags; | 2303 | console_prev = msg->flags; |
2241 | raw_spin_unlock(&logbuf_lock); | 2304 | raw_spin_unlock(&logbuf_lock); |
2242 | 2305 | ||
2243 | stop_critical_timings(); /* don't trace print latency */ | 2306 | stop_critical_timings(); /* don't trace print latency */ |
2244 | call_console_drivers(level, text, len); | 2307 | call_console_drivers(level, ext_text, ext_len, text, len); |
2245 | start_critical_timings(); | 2308 | start_critical_timings(); |
2246 | local_irq_restore(flags); | 2309 | local_irq_restore(flags); |
2247 | } | 2310 | } |
@@ -2497,6 +2560,11 @@ void register_console(struct console *newcon) | |||
2497 | newcon->next = console_drivers->next; | 2560 | newcon->next = console_drivers->next; |
2498 | console_drivers->next = newcon; | 2561 | console_drivers->next = newcon; |
2499 | } | 2562 | } |
2563 | |||
2564 | if (newcon->flags & CON_EXTENDED) | ||
2565 | if (!nr_ext_console_drivers++) | ||
2566 | pr_info("printk: continuation disabled due to ext consoles, expect more fragments in /dev/kmsg\n"); | ||
2567 | |||
2500 | if (newcon->flags & CON_PRINTBUFFER) { | 2568 | if (newcon->flags & CON_PRINTBUFFER) { |
2501 | /* | 2569 | /* |
2502 | * console_unlock(); will print out the buffered messages | 2570 | * console_unlock(); will print out the buffered messages |
@@ -2569,6 +2637,9 @@ int unregister_console(struct console *console) | |||
2569 | } | 2637 | } |
2570 | } | 2638 | } |
2571 | 2639 | ||
2640 | if (!res && (console->flags & CON_EXTENDED)) | ||
2641 | nr_ext_console_drivers--; | ||
2642 | |||
2572 | /* | 2643 | /* |
2573 | * If this isn't the last console and it has CON_CONSDEV set, we | 2644 | * If this isn't the last console and it has CON_CONSDEV set, we |
2574 | * need to set it on the next preferred console. | 2645 | * need to set it on the next preferred console. |
diff --git a/kernel/sys.c b/kernel/sys.c index 8571296b7ddb..259fda25eb6b 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1722,7 +1722,6 @@ exit_err: | |||
1722 | goto exit; | 1722 | goto exit; |
1723 | } | 1723 | } |
1724 | 1724 | ||
1725 | #ifdef CONFIG_CHECKPOINT_RESTORE | ||
1726 | /* | 1725 | /* |
1727 | * WARNING: we don't require any capability here so be very careful | 1726 | * WARNING: we don't require any capability here so be very careful |
1728 | * in what is allowed for modification from userspace. | 1727 | * in what is allowed for modification from userspace. |
@@ -1818,6 +1817,7 @@ out: | |||
1818 | return error; | 1817 | return error; |
1819 | } | 1818 | } |
1820 | 1819 | ||
1820 | #ifdef CONFIG_CHECKPOINT_RESTORE | ||
1821 | static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data_size) | 1821 | static int prctl_set_mm_map(int opt, const void __user *addr, unsigned long data_size) |
1822 | { | 1822 | { |
1823 | struct prctl_mm_map prctl_map = { .exe_fd = (u32)-1, }; | 1823 | struct prctl_mm_map prctl_map = { .exe_fd = (u32)-1, }; |
@@ -1902,10 +1902,41 @@ out: | |||
1902 | } | 1902 | } |
1903 | #endif /* CONFIG_CHECKPOINT_RESTORE */ | 1903 | #endif /* CONFIG_CHECKPOINT_RESTORE */ |
1904 | 1904 | ||
1905 | static int prctl_set_auxv(struct mm_struct *mm, unsigned long addr, | ||
1906 | unsigned long len) | ||
1907 | { | ||
1908 | /* | ||
1909 | * This doesn't move the auxiliary vector itself since it's pinned to | ||
1910 | * mm_struct, but it permits filling the vector with new values. It's | ||
1911 | * up to the caller to provide sane values here, otherwise userspace | ||
1912 | * tools which use this vector might be unhappy. | ||
1913 | */ | ||
1914 | unsigned long user_auxv[AT_VECTOR_SIZE]; | ||
1915 | |||
1916 | if (len > sizeof(user_auxv)) | ||
1917 | return -EINVAL; | ||
1918 | |||
1919 | if (copy_from_user(user_auxv, (const void __user *)addr, len)) | ||
1920 | return -EFAULT; | ||
1921 | |||
1922 | /* Make sure the last entry is always AT_NULL */ | ||
1923 | user_auxv[AT_VECTOR_SIZE - 2] = 0; | ||
1924 | user_auxv[AT_VECTOR_SIZE - 1] = 0; | ||
1925 | |||
1926 | BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv)); | ||
1927 | |||
1928 | task_lock(current); | ||
1929 | memcpy(mm->saved_auxv, user_auxv, len); | ||
1930 | task_unlock(current); | ||
1931 | |||
1932 | return 0; | ||
1933 | } | ||
1934 | |||
1905 | static int prctl_set_mm(int opt, unsigned long addr, | 1935 | static int prctl_set_mm(int opt, unsigned long addr, |
1906 | unsigned long arg4, unsigned long arg5) | 1936 | unsigned long arg4, unsigned long arg5) |
1907 | { | 1937 | { |
1908 | struct mm_struct *mm = current->mm; | 1938 | struct mm_struct *mm = current->mm; |
1939 | struct prctl_mm_map prctl_map; | ||
1909 | struct vm_area_struct *vma; | 1940 | struct vm_area_struct *vma; |
1910 | int error; | 1941 | int error; |
1911 | 1942 | ||
@@ -1925,6 +1956,9 @@ static int prctl_set_mm(int opt, unsigned long addr, | |||
1925 | if (opt == PR_SET_MM_EXE_FILE) | 1956 | if (opt == PR_SET_MM_EXE_FILE) |
1926 | return prctl_set_mm_exe_file(mm, (unsigned int)addr); | 1957 | return prctl_set_mm_exe_file(mm, (unsigned int)addr); |
1927 | 1958 | ||
1959 | if (opt == PR_SET_MM_AUXV) | ||
1960 | return prctl_set_auxv(mm, addr, arg4); | ||
1961 | |||
1928 | if (addr >= TASK_SIZE || addr < mmap_min_addr) | 1962 | if (addr >= TASK_SIZE || addr < mmap_min_addr) |
1929 | return -EINVAL; | 1963 | return -EINVAL; |
1930 | 1964 | ||
@@ -1933,42 +1967,64 @@ static int prctl_set_mm(int opt, unsigned long addr, | |||
1933 | down_read(&mm->mmap_sem); | 1967 | down_read(&mm->mmap_sem); |
1934 | vma = find_vma(mm, addr); | 1968 | vma = find_vma(mm, addr); |
1935 | 1969 | ||
1970 | prctl_map.start_code = mm->start_code; | ||
1971 | prctl_map.end_code = mm->end_code; | ||
1972 | prctl_map.start_data = mm->start_data; | ||
1973 | prctl_map.end_data = mm->end_data; | ||
1974 | prctl_map.start_brk = mm->start_brk; | ||
1975 | prctl_map.brk = mm->brk; | ||
1976 | prctl_map.start_stack = mm->start_stack; | ||
1977 | prctl_map.arg_start = mm->arg_start; | ||
1978 | prctl_map.arg_end = mm->arg_end; | ||
1979 | prctl_map.env_start = mm->env_start; | ||
1980 | prctl_map.env_end = mm->env_end; | ||
1981 | prctl_map.auxv = NULL; | ||
1982 | prctl_map.auxv_size = 0; | ||
1983 | prctl_map.exe_fd = -1; | ||
1984 | |||
1936 | switch (opt) { | 1985 | switch (opt) { |
1937 | case PR_SET_MM_START_CODE: | 1986 | case PR_SET_MM_START_CODE: |
1938 | mm->start_code = addr; | 1987 | prctl_map.start_code = addr; |
1939 | break; | 1988 | break; |
1940 | case PR_SET_MM_END_CODE: | 1989 | case PR_SET_MM_END_CODE: |
1941 | mm->end_code = addr; | 1990 | prctl_map.end_code = addr; |
1942 | break; | 1991 | break; |
1943 | case PR_SET_MM_START_DATA: | 1992 | case PR_SET_MM_START_DATA: |
1944 | mm->start_data = addr; | 1993 | prctl_map.start_data = addr; |
1945 | break; | 1994 | break; |
1946 | case PR_SET_MM_END_DATA: | 1995 | case PR_SET_MM_END_DATA: |
1947 | mm->end_data = addr; | 1996 | prctl_map.end_data = addr; |
1997 | break; | ||
1998 | case PR_SET_MM_START_STACK: | ||
1999 | prctl_map.start_stack = addr; | ||
1948 | break; | 2000 | break; |
1949 | |||
1950 | case PR_SET_MM_START_BRK: | 2001 | case PR_SET_MM_START_BRK: |
1951 | if (addr <= mm->end_data) | 2002 | prctl_map.start_brk = addr; |
1952 | goto out; | ||
1953 | |||
1954 | if (check_data_rlimit(rlimit(RLIMIT_DATA), mm->brk, addr, | ||
1955 | mm->end_data, mm->start_data)) | ||
1956 | goto out; | ||
1957 | |||
1958 | mm->start_brk = addr; | ||
1959 | break; | 2003 | break; |
1960 | |||
1961 | case PR_SET_MM_BRK: | 2004 | case PR_SET_MM_BRK: |
1962 | if (addr <= mm->end_data) | 2005 | prctl_map.brk = addr; |
1963 | goto out; | ||
1964 | |||
1965 | if (check_data_rlimit(rlimit(RLIMIT_DATA), addr, mm->start_brk, | ||
1966 | mm->end_data, mm->start_data)) | ||
1967 | goto out; | ||
1968 | |||
1969 | mm->brk = addr; | ||
1970 | break; | 2006 | break; |
2007 | case PR_SET_MM_ARG_START: | ||
2008 | prctl_map.arg_start = addr; | ||
2009 | break; | ||
2010 | case PR_SET_MM_ARG_END: | ||
2011 | prctl_map.arg_end = addr; | ||
2012 | break; | ||
2013 | case PR_SET_MM_ENV_START: | ||
2014 | prctl_map.env_start = addr; | ||
2015 | break; | ||
2016 | case PR_SET_MM_ENV_END: | ||
2017 | prctl_map.env_end = addr; | ||
2018 | break; | ||
2019 | default: | ||
2020 | goto out; | ||
2021 | } | ||
2022 | |||
2023 | error = validate_prctl_map(&prctl_map); | ||
2024 | if (error) | ||
2025 | goto out; | ||
1971 | 2026 | ||
2027 | switch (opt) { | ||
1972 | /* | 2028 | /* |
1973 | * If command line arguments and environment | 2029 | * If command line arguments and environment |
1974 | * are placed somewhere else on stack, we can | 2030 | * are placed somewhere else on stack, we can |
@@ -1985,52 +2041,20 @@ static int prctl_set_mm(int opt, unsigned long addr, | |||
1985 | error = -EFAULT; | 2041 | error = -EFAULT; |
1986 | goto out; | 2042 | goto out; |
1987 | } | 2043 | } |
1988 | if (opt == PR_SET_MM_START_STACK) | ||
1989 | mm->start_stack = addr; | ||
1990 | else if (opt == PR_SET_MM_ARG_START) | ||
1991 | mm->arg_start = addr; | ||
1992 | else if (opt == PR_SET_MM_ARG_END) | ||
1993 | mm->arg_end = addr; | ||
1994 | else if (opt == PR_SET_MM_ENV_START) | ||
1995 | mm->env_start = addr; | ||
1996 | else if (opt == PR_SET_MM_ENV_END) | ||
1997 | mm->env_end = addr; | ||
1998 | break; | ||
1999 | |||
2000 | /* | ||
2001 | * This doesn't move auxiliary vector itself | ||
2002 | * since it's pinned to mm_struct, but allow | ||
2003 | * to fill vector with new values. It's up | ||
2004 | * to a caller to provide sane values here | ||
2005 | * otherwise user space tools which use this | ||
2006 | * vector might be unhappy. | ||
2007 | */ | ||
2008 | case PR_SET_MM_AUXV: { | ||
2009 | unsigned long user_auxv[AT_VECTOR_SIZE]; | ||
2010 | |||
2011 | if (arg4 > sizeof(user_auxv)) | ||
2012 | goto out; | ||
2013 | up_read(&mm->mmap_sem); | ||
2014 | |||
2015 | if (copy_from_user(user_auxv, (const void __user *)addr, arg4)) | ||
2016 | return -EFAULT; | ||
2017 | |||
2018 | /* Make sure the last entry is always AT_NULL */ | ||
2019 | user_auxv[AT_VECTOR_SIZE - 2] = 0; | ||
2020 | user_auxv[AT_VECTOR_SIZE - 1] = 0; | ||
2021 | |||
2022 | BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv)); | ||
2023 | |||
2024 | task_lock(current); | ||
2025 | memcpy(mm->saved_auxv, user_auxv, arg4); | ||
2026 | task_unlock(current); | ||
2027 | |||
2028 | return 0; | ||
2029 | } | ||
2030 | default: | ||
2031 | goto out; | ||
2032 | } | 2044 | } |
2033 | 2045 | ||
2046 | mm->start_code = prctl_map.start_code; | ||
2047 | mm->end_code = prctl_map.end_code; | ||
2048 | mm->start_data = prctl_map.start_data; | ||
2049 | mm->end_data = prctl_map.end_data; | ||
2050 | mm->start_brk = prctl_map.start_brk; | ||
2051 | mm->brk = prctl_map.brk; | ||
2052 | mm->start_stack = prctl_map.start_stack; | ||
2053 | mm->arg_start = prctl_map.arg_start; | ||
2054 | mm->arg_end = prctl_map.arg_end; | ||
2055 | mm->env_start = prctl_map.env_start; | ||
2056 | mm->env_end = prctl_map.env_end; | ||
2057 | |||
2034 | error = 0; | 2058 | error = 0; |
2035 | out: | 2059 | out: |
2036 | up_read(&mm->mmap_sem); | 2060 | up_read(&mm->mmap_sem); |
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 483cecfa5c17..4eeae4674b5a 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
@@ -439,7 +439,7 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | |||
439 | { | 439 | { |
440 | struct blk_trace *old_bt, *bt = NULL; | 440 | struct blk_trace *old_bt, *bt = NULL; |
441 | struct dentry *dir = NULL; | 441 | struct dentry *dir = NULL; |
442 | int ret, i; | 442 | int ret; |
443 | 443 | ||
444 | if (!buts->buf_size || !buts->buf_nr) | 444 | if (!buts->buf_size || !buts->buf_nr) |
445 | return -EINVAL; | 445 | return -EINVAL; |
@@ -451,9 +451,7 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | |||
451 | * some device names have larger paths - convert the slashes | 451 | * some device names have larger paths - convert the slashes |
452 | * to underscores for this to work as expected | 452 | * to underscores for this to work as expected |
453 | */ | 453 | */ |
454 | for (i = 0; i < strlen(buts->name); i++) | 454 | strreplace(buts->name, '/', '_'); |
455 | if (buts->name[i] == '/') | ||
456 | buts->name[i] = '_'; | ||
457 | 455 | ||
458 | bt = kzalloc(sizeof(*bt), GFP_KERNEL); | 456 | bt = kzalloc(sizeof(*bt), GFP_KERNEL); |
459 | if (!bt) | 457 | if (!bt) |
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 7f2e97ce71a7..9d4a78f45dc4 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
@@ -2082,7 +2082,7 @@ struct function_filter_data { | |||
2082 | static char ** | 2082 | static char ** |
2083 | ftrace_function_filter_re(char *buf, int len, int *count) | 2083 | ftrace_function_filter_re(char *buf, int len, int *count) |
2084 | { | 2084 | { |
2085 | char *str, *sep, **re; | 2085 | char *str, **re; |
2086 | 2086 | ||
2087 | str = kstrndup(buf, len, GFP_KERNEL); | 2087 | str = kstrndup(buf, len, GFP_KERNEL); |
2088 | if (!str) | 2088 | if (!str) |
@@ -2092,8 +2092,7 @@ ftrace_function_filter_re(char *buf, int len, int *count) | |||
2092 | * The argv_split function takes white space | 2092 | * The argv_split function takes white space |
2093 | * as a separator, so convert ',' into spaces. | 2093 | * as a separator, so convert ',' into spaces. |
2094 | */ | 2094 | */ |
2095 | while ((sep = strchr(str, ','))) | 2095 | strreplace(str, ',', ' '); |
2096 | *sep = ' '; | ||
2097 | 2096 | ||
2098 | re = argv_split(GFP_KERNEL, str, count); | 2097 | re = argv_split(GFP_KERNEL, str, count); |
2099 | kfree(str); | 2098 | kfree(str); |
diff --git a/lib/bitmap.c b/lib/bitmap.c index 64c0926f5dd8..a578a0189199 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c | |||
@@ -462,19 +462,20 @@ EXPORT_SYMBOL(bitmap_parse_user); | |||
462 | * Output format is a comma-separated list of decimal numbers and | 462 | * Output format is a comma-separated list of decimal numbers and |
463 | * ranges if list is specified or hex digits grouped into comma-separated | 463 | * ranges if list is specified or hex digits grouped into comma-separated |
464 | * sets of 8 digits/set. Returns the number of characters written to buf. | 464 | * sets of 8 digits/set. Returns the number of characters written to buf. |
465 | * | ||
466 | * It is assumed that @buf is a pointer into a PAGE_SIZE area and that | ||
467 | * sufficient storage remains at @buf to accommodate the | ||
468 | * bitmap_print_to_pagebuf() output. | ||
465 | */ | 469 | */ |
466 | int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp, | 470 | int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp, |
467 | int nmaskbits) | 471 | int nmaskbits) |
468 | { | 472 | { |
469 | ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf - 2; | 473 | ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf; |
470 | int n = 0; | 474 | int n = 0; |
471 | 475 | ||
472 | if (len > 1) { | 476 | if (len > 1) |
473 | n = list ? scnprintf(buf, len, "%*pbl", nmaskbits, maskp) : | 477 | n = list ? scnprintf(buf, len, "%*pbl\n", nmaskbits, maskp) : |
474 | scnprintf(buf, len, "%*pb", nmaskbits, maskp); | 478 | scnprintf(buf, len, "%*pb\n", nmaskbits, maskp); |
475 | buf[n++] = '\n'; | ||
476 | buf[n] = '\0'; | ||
477 | } | ||
478 | return n; | 479 | return n; |
479 | } | 480 | } |
480 | EXPORT_SYMBOL(bitmap_print_to_pagebuf); | 481 | EXPORT_SYMBOL(bitmap_print_to_pagebuf); |
@@ -506,12 +507,12 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, | |||
506 | unsigned a, b; | 507 | unsigned a, b; |
507 | int c, old_c, totaldigits; | 508 | int c, old_c, totaldigits; |
508 | const char __user __force *ubuf = (const char __user __force *)buf; | 509 | const char __user __force *ubuf = (const char __user __force *)buf; |
509 | int exp_digit, in_range; | 510 | int at_start, in_range; |
510 | 511 | ||
511 | totaldigits = c = 0; | 512 | totaldigits = c = 0; |
512 | bitmap_zero(maskp, nmaskbits); | 513 | bitmap_zero(maskp, nmaskbits); |
513 | do { | 514 | do { |
514 | exp_digit = 1; | 515 | at_start = 1; |
515 | in_range = 0; | 516 | in_range = 0; |
516 | a = b = 0; | 517 | a = b = 0; |
517 | 518 | ||
@@ -540,11 +541,10 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, | |||
540 | break; | 541 | break; |
541 | 542 | ||
542 | if (c == '-') { | 543 | if (c == '-') { |
543 | if (exp_digit || in_range) | 544 | if (at_start || in_range) |
544 | return -EINVAL; | 545 | return -EINVAL; |
545 | b = 0; | 546 | b = 0; |
546 | in_range = 1; | 547 | in_range = 1; |
547 | exp_digit = 1; | ||
548 | continue; | 548 | continue; |
549 | } | 549 | } |
550 | 550 | ||
@@ -554,16 +554,18 @@ static int __bitmap_parselist(const char *buf, unsigned int buflen, | |||
554 | b = b * 10 + (c - '0'); | 554 | b = b * 10 + (c - '0'); |
555 | if (!in_range) | 555 | if (!in_range) |
556 | a = b; | 556 | a = b; |
557 | exp_digit = 0; | 557 | at_start = 0; |
558 | totaldigits++; | 558 | totaldigits++; |
559 | } | 559 | } |
560 | if (!(a <= b)) | 560 | if (!(a <= b)) |
561 | return -EINVAL; | 561 | return -EINVAL; |
562 | if (b >= nmaskbits) | 562 | if (b >= nmaskbits) |
563 | return -ERANGE; | 563 | return -ERANGE; |
564 | while (a <= b) { | 564 | if (!at_start) { |
565 | set_bit(a, maskp); | 565 | while (a <= b) { |
566 | a++; | 566 | set_bit(a, maskp); |
567 | a++; | ||
568 | } | ||
567 | } | 569 | } |
568 | } while (buflen && c == ','); | 570 | } while (buflen && c == ','); |
569 | return 0; | 571 | return 0; |
diff --git a/lib/kobject.c b/lib/kobject.c index 3b841b97fccd..75ee63834fd1 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -257,23 +257,20 @@ static int kobject_add_internal(struct kobject *kobj) | |||
257 | int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, | 257 | int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, |
258 | va_list vargs) | 258 | va_list vargs) |
259 | { | 259 | { |
260 | const char *old_name = kobj->name; | ||
261 | char *s; | 260 | char *s; |
262 | 261 | ||
263 | if (kobj->name && !fmt) | 262 | if (kobj->name && !fmt) |
264 | return 0; | 263 | return 0; |
265 | 264 | ||
266 | kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs); | 265 | s = kvasprintf(GFP_KERNEL, fmt, vargs); |
267 | if (!kobj->name) { | 266 | if (!s) |
268 | kobj->name = old_name; | ||
269 | return -ENOMEM; | 267 | return -ENOMEM; |
270 | } | ||
271 | 268 | ||
272 | /* ewww... some of these buggers have '/' in the name ... */ | 269 | /* ewww... some of these buggers have '/' in the name ... */ |
273 | while ((s = strchr(kobj->name, '/'))) | 270 | strreplace(s, '/', '!'); |
274 | s[0] = '!'; | 271 | kfree(kobj->name); |
272 | kobj->name = s; | ||
275 | 273 | ||
276 | kfree(old_name); | ||
277 | return 0; | 274 | return 0; |
278 | } | 275 | } |
279 | 276 | ||
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 061550de77bc..f9ebe1c82060 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -65,7 +65,8 @@ static struct kmem_cache *radix_tree_node_cachep; | |||
65 | */ | 65 | */ |
66 | struct radix_tree_preload { | 66 | struct radix_tree_preload { |
67 | int nr; | 67 | int nr; |
68 | struct radix_tree_node *nodes[RADIX_TREE_PRELOAD_SIZE]; | 68 | /* nodes->private_data points to next preallocated node */ |
69 | struct radix_tree_node *nodes; | ||
69 | }; | 70 | }; |
70 | static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, }; | 71 | static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, }; |
71 | 72 | ||
@@ -197,8 +198,9 @@ radix_tree_node_alloc(struct radix_tree_root *root) | |||
197 | */ | 198 | */ |
198 | rtp = this_cpu_ptr(&radix_tree_preloads); | 199 | rtp = this_cpu_ptr(&radix_tree_preloads); |
199 | if (rtp->nr) { | 200 | if (rtp->nr) { |
200 | ret = rtp->nodes[rtp->nr - 1]; | 201 | ret = rtp->nodes; |
201 | rtp->nodes[rtp->nr - 1] = NULL; | 202 | rtp->nodes = ret->private_data; |
203 | ret->private_data = NULL; | ||
202 | rtp->nr--; | 204 | rtp->nr--; |
203 | } | 205 | } |
204 | /* | 206 | /* |
@@ -257,17 +259,20 @@ static int __radix_tree_preload(gfp_t gfp_mask) | |||
257 | 259 | ||
258 | preempt_disable(); | 260 | preempt_disable(); |
259 | rtp = this_cpu_ptr(&radix_tree_preloads); | 261 | rtp = this_cpu_ptr(&radix_tree_preloads); |
260 | while (rtp->nr < ARRAY_SIZE(rtp->nodes)) { | 262 | while (rtp->nr < RADIX_TREE_PRELOAD_SIZE) { |
261 | preempt_enable(); | 263 | preempt_enable(); |
262 | node = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask); | 264 | node = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask); |
263 | if (node == NULL) | 265 | if (node == NULL) |
264 | goto out; | 266 | goto out; |
265 | preempt_disable(); | 267 | preempt_disable(); |
266 | rtp = this_cpu_ptr(&radix_tree_preloads); | 268 | rtp = this_cpu_ptr(&radix_tree_preloads); |
267 | if (rtp->nr < ARRAY_SIZE(rtp->nodes)) | 269 | if (rtp->nr < RADIX_TREE_PRELOAD_SIZE) { |
268 | rtp->nodes[rtp->nr++] = node; | 270 | node->private_data = rtp->nodes; |
269 | else | 271 | rtp->nodes = node; |
272 | rtp->nr++; | ||
273 | } else { | ||
270 | kmem_cache_free(radix_tree_node_cachep, node); | 274 | kmem_cache_free(radix_tree_node_cachep, node); |
275 | } | ||
271 | } | 276 | } |
272 | ret = 0; | 277 | ret = 0; |
273 | out: | 278 | out: |
@@ -1463,15 +1468,16 @@ static int radix_tree_callback(struct notifier_block *nfb, | |||
1463 | { | 1468 | { |
1464 | int cpu = (long)hcpu; | 1469 | int cpu = (long)hcpu; |
1465 | struct radix_tree_preload *rtp; | 1470 | struct radix_tree_preload *rtp; |
1471 | struct radix_tree_node *node; | ||
1466 | 1472 | ||
1467 | /* Free per-cpu pool of perloaded nodes */ | 1473 | /* Free per-cpu pool of perloaded nodes */ |
1468 | if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { | 1474 | if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { |
1469 | rtp = &per_cpu(radix_tree_preloads, cpu); | 1475 | rtp = &per_cpu(radix_tree_preloads, cpu); |
1470 | while (rtp->nr) { | 1476 | while (rtp->nr) { |
1471 | kmem_cache_free(radix_tree_node_cachep, | 1477 | node = rtp->nodes; |
1472 | rtp->nodes[rtp->nr-1]); | 1478 | rtp->nodes = node->private_data; |
1473 | rtp->nodes[rtp->nr-1] = NULL; | 1479 | kmem_cache_free(radix_tree_node_cachep, node); |
1474 | rtp->nr--; | 1480 | rtp->nr--; |
1475 | } | 1481 | } |
1476 | } | 1482 | } |
1477 | return NOTIFY_OK; | 1483 | return NOTIFY_OK; |
diff --git a/lib/sort.c b/lib/sort.c index 43c9fe73ae2e..fc20df42aa6f 100644 --- a/lib/sort.c +++ b/lib/sort.c | |||
@@ -8,6 +8,12 @@ | |||
8 | #include <linux/export.h> | 8 | #include <linux/export.h> |
9 | #include <linux/sort.h> | 9 | #include <linux/sort.h> |
10 | 10 | ||
11 | static int alignment_ok(const void *base, int align) | ||
12 | { | ||
13 | return IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) || | ||
14 | ((unsigned long)base & (align - 1)) == 0; | ||
15 | } | ||
16 | |||
11 | static void u32_swap(void *a, void *b, int size) | 17 | static void u32_swap(void *a, void *b, int size) |
12 | { | 18 | { |
13 | u32 t = *(u32 *)a; | 19 | u32 t = *(u32 *)a; |
@@ -15,6 +21,13 @@ static void u32_swap(void *a, void *b, int size) | |||
15 | *(u32 *)b = t; | 21 | *(u32 *)b = t; |
16 | } | 22 | } |
17 | 23 | ||
24 | static void u64_swap(void *a, void *b, int size) | ||
25 | { | ||
26 | u64 t = *(u64 *)a; | ||
27 | *(u64 *)a = *(u64 *)b; | ||
28 | *(u64 *)b = t; | ||
29 | } | ||
30 | |||
18 | static void generic_swap(void *a, void *b, int size) | 31 | static void generic_swap(void *a, void *b, int size) |
19 | { | 32 | { |
20 | char t; | 33 | char t; |
@@ -50,8 +63,14 @@ void sort(void *base, size_t num, size_t size, | |||
50 | /* pre-scale counters for performance */ | 63 | /* pre-scale counters for performance */ |
51 | int i = (num/2 - 1) * size, n = num * size, c, r; | 64 | int i = (num/2 - 1) * size, n = num * size, c, r; |
52 | 65 | ||
53 | if (!swap_func) | 66 | if (!swap_func) { |
54 | swap_func = (size == 4 ? u32_swap : generic_swap); | 67 | if (size == 4 && alignment_ok(base, 4)) |
68 | swap_func = u32_swap; | ||
69 | else if (size == 8 && alignment_ok(base, 8)) | ||
70 | swap_func = u64_swap; | ||
71 | else | ||
72 | swap_func = generic_swap; | ||
73 | } | ||
55 | 74 | ||
56 | /* heapify */ | 75 | /* heapify */ |
57 | for ( ; i >= 0; i -= size) { | 76 | for ( ; i >= 0; i -= size) { |
diff --git a/lib/string.c b/lib/string.c index bb3d4b6993c4..13d1e84ddb80 100644 --- a/lib/string.c +++ b/lib/string.c | |||
@@ -849,3 +849,20 @@ void *memchr_inv(const void *start, int c, size_t bytes) | |||
849 | return check_bytes8(start, value, bytes % 8); | 849 | return check_bytes8(start, value, bytes % 8); |
850 | } | 850 | } |
851 | EXPORT_SYMBOL(memchr_inv); | 851 | EXPORT_SYMBOL(memchr_inv); |
852 | |||
853 | /** | ||
854 | * strreplace - Replace all occurrences of character in string. | ||
855 | * @s: The string to operate on. | ||
856 | * @old: The character being replaced. | ||
857 | * @new: The character @old is replaced with. | ||
858 | * | ||
859 | * Returns pointer to the nul byte at the end of @s. | ||
860 | */ | ||
861 | char *strreplace(char *s, char old, char new) | ||
862 | { | ||
863 | for (; *s; ++s) | ||
864 | if (*s == old) | ||
865 | *s = new; | ||
866 | return s; | ||
867 | } | ||
868 | EXPORT_SYMBOL(strreplace); | ||
diff --git a/lib/test-hexdump.c b/lib/test-hexdump.c index c227cc43ec0a..5241df36eedf 100644 --- a/lib/test-hexdump.c +++ b/lib/test-hexdump.c | |||
@@ -25,19 +25,19 @@ static const char * const test_data_1_le[] __initconst = { | |||
25 | "4c", "d1", "19", "99", "43", "b1", "af", "0c", | 25 | "4c", "d1", "19", "99", "43", "b1", "af", "0c", |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static const char *test_data_2_le[] __initdata = { | 28 | static const char * const test_data_2_le[] __initconst = { |
29 | "32be", "7bdb", "180a", "b293", | 29 | "32be", "7bdb", "180a", "b293", |
30 | "ba70", "24c4", "837d", "9b34", | 30 | "ba70", "24c4", "837d", "9b34", |
31 | "9ca6", "ad31", "0f9c", "e9ac", | 31 | "9ca6", "ad31", "0f9c", "e9ac", |
32 | "d14c", "9919", "b143", "0caf", | 32 | "d14c", "9919", "b143", "0caf", |
33 | }; | 33 | }; |
34 | 34 | ||
35 | static const char *test_data_4_le[] __initdata = { | 35 | static const char * const test_data_4_le[] __initconst = { |
36 | "7bdb32be", "b293180a", "24c4ba70", "9b34837d", | 36 | "7bdb32be", "b293180a", "24c4ba70", "9b34837d", |
37 | "ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143", | 37 | "ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143", |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static const char *test_data_8_le[] __initdata = { | 40 | static const char * const test_data_8_le[] __initconst = { |
41 | "b293180a7bdb32be", "9b34837d24c4ba70", | 41 | "b293180a7bdb32be", "9b34837d24c4ba70", |
42 | "e9ac0f9cad319ca6", "0cafb1439919d14c", | 42 | "e9ac0f9cad319ca6", "0cafb1439919d14c", |
43 | }; | 43 | }; |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 75c0eef52c5d..a8c3087089d8 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -975,7 +975,6 @@ static void update_and_free_page(struct hstate *h, struct page *page) | |||
975 | destroy_compound_gigantic_page(page, huge_page_order(h)); | 975 | destroy_compound_gigantic_page(page, huge_page_order(h)); |
976 | free_gigantic_page(page, huge_page_order(h)); | 976 | free_gigantic_page(page, huge_page_order(h)); |
977 | } else { | 977 | } else { |
978 | arch_release_hugepage(page); | ||
979 | __free_pages(page, huge_page_order(h)); | 978 | __free_pages(page, huge_page_order(h)); |
980 | } | 979 | } |
981 | } | 980 | } |
@@ -1160,10 +1159,6 @@ static struct page *alloc_fresh_huge_page_node(struct hstate *h, int nid) | |||
1160 | __GFP_REPEAT|__GFP_NOWARN, | 1159 | __GFP_REPEAT|__GFP_NOWARN, |
1161 | huge_page_order(h)); | 1160 | huge_page_order(h)); |
1162 | if (page) { | 1161 | if (page) { |
1163 | if (arch_prepare_hugepage(page)) { | ||
1164 | __free_pages(page, huge_page_order(h)); | ||
1165 | return NULL; | ||
1166 | } | ||
1167 | prep_new_huge_page(h, page, nid); | 1162 | prep_new_huge_page(h, page, nid); |
1168 | } | 1163 | } |
1169 | 1164 | ||
@@ -1315,11 +1310,6 @@ static struct page *alloc_buddy_huge_page(struct hstate *h, int nid) | |||
1315 | htlb_alloc_mask(h)|__GFP_COMP|__GFP_THISNODE| | 1310 | htlb_alloc_mask(h)|__GFP_COMP|__GFP_THISNODE| |
1316 | __GFP_REPEAT|__GFP_NOWARN, huge_page_order(h)); | 1311 | __GFP_REPEAT|__GFP_NOWARN, huge_page_order(h)); |
1317 | 1312 | ||
1318 | if (page && arch_prepare_hugepage(page)) { | ||
1319 | __free_pages(page, huge_page_order(h)); | ||
1320 | page = NULL; | ||
1321 | } | ||
1322 | |||
1323 | spin_lock(&hugetlb_lock); | 1313 | spin_lock(&hugetlb_lock); |
1324 | if (page) { | 1314 | if (page) { |
1325 | INIT_LIST_HEAD(&page->lru); | 1315 | INIT_LIST_HEAD(&page->lru); |
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index 4986b0acab21..c242adf6bc85 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h | |||
@@ -7,7 +7,6 @@ | |||
7 | #define KASAN_SHADOW_MASK (KASAN_SHADOW_SCALE_SIZE - 1) | 7 | #define KASAN_SHADOW_MASK (KASAN_SHADOW_SCALE_SIZE - 1) |
8 | 8 | ||
9 | #define KASAN_FREE_PAGE 0xFF /* page was freed */ | 9 | #define KASAN_FREE_PAGE 0xFF /* page was freed */ |
10 | #define KASAN_FREE_PAGE 0xFF /* page was freed */ | ||
11 | #define KASAN_PAGE_REDZONE 0xFE /* redzone for kmalloc_large allocations */ | 10 | #define KASAN_PAGE_REDZONE 0xFE /* redzone for kmalloc_large allocations */ |
12 | #define KASAN_KMALLOC_REDZONE 0xFC /* redzone inside slub object */ | 11 | #define KASAN_KMALLOC_REDZONE 0xFC /* redzone inside slub object */ |
13 | #define KASAN_KMALLOC_FREE 0xFB /* object was freed (kmem_cache_free/kfree) */ | 12 | #define KASAN_KMALLOC_FREE 0xFB /* object was freed (kmem_cache_free/kfree) */ |
@@ -97,6 +97,10 @@ struct zbud_pool { | |||
97 | struct list_head lru; | 97 | struct list_head lru; |
98 | u64 pages_nr; | 98 | u64 pages_nr; |
99 | struct zbud_ops *ops; | 99 | struct zbud_ops *ops; |
100 | #ifdef CONFIG_ZPOOL | ||
101 | struct zpool *zpool; | ||
102 | struct zpool_ops *zpool_ops; | ||
103 | #endif | ||
100 | }; | 104 | }; |
101 | 105 | ||
102 | /* | 106 | /* |
@@ -123,7 +127,10 @@ struct zbud_header { | |||
123 | 127 | ||
124 | static int zbud_zpool_evict(struct zbud_pool *pool, unsigned long handle) | 128 | static int zbud_zpool_evict(struct zbud_pool *pool, unsigned long handle) |
125 | { | 129 | { |
126 | return zpool_evict(pool, handle); | 130 | if (pool->zpool && pool->zpool_ops && pool->zpool_ops->evict) |
131 | return pool->zpool_ops->evict(pool->zpool, handle); | ||
132 | else | ||
133 | return -ENOENT; | ||
127 | } | 134 | } |
128 | 135 | ||
129 | static struct zbud_ops zbud_zpool_ops = { | 136 | static struct zbud_ops zbud_zpool_ops = { |
@@ -131,9 +138,17 @@ static struct zbud_ops zbud_zpool_ops = { | |||
131 | }; | 138 | }; |
132 | 139 | ||
133 | static void *zbud_zpool_create(char *name, gfp_t gfp, | 140 | static void *zbud_zpool_create(char *name, gfp_t gfp, |
134 | struct zpool_ops *zpool_ops) | 141 | struct zpool_ops *zpool_ops, |
142 | struct zpool *zpool) | ||
135 | { | 143 | { |
136 | return zbud_create_pool(gfp, zpool_ops ? &zbud_zpool_ops : NULL); | 144 | struct zbud_pool *pool; |
145 | |||
146 | pool = zbud_create_pool(gfp, zpool_ops ? &zbud_zpool_ops : NULL); | ||
147 | if (pool) { | ||
148 | pool->zpool = zpool; | ||
149 | pool->zpool_ops = zpool_ops; | ||
150 | } | ||
151 | return pool; | ||
137 | } | 152 | } |
138 | 153 | ||
139 | static void zbud_zpool_destroy(void *pool) | 154 | static void zbud_zpool_destroy(void *pool) |
@@ -292,7 +307,7 @@ struct zbud_pool *zbud_create_pool(gfp_t gfp, struct zbud_ops *ops) | |||
292 | struct zbud_pool *pool; | 307 | struct zbud_pool *pool; |
293 | int i; | 308 | int i; |
294 | 309 | ||
295 | pool = kmalloc(sizeof(struct zbud_pool), gfp); | 310 | pool = kzalloc(sizeof(struct zbud_pool), gfp); |
296 | if (!pool) | 311 | if (!pool) |
297 | return NULL; | 312 | return NULL; |
298 | spin_lock_init(&pool->lock); | 313 | spin_lock_init(&pool->lock); |
diff --git a/mm/zpool.c b/mm/zpool.c index bacdab6e47de..722a4f60e90b 100644 --- a/mm/zpool.c +++ b/mm/zpool.c | |||
@@ -73,33 +73,6 @@ int zpool_unregister_driver(struct zpool_driver *driver) | |||
73 | } | 73 | } |
74 | EXPORT_SYMBOL(zpool_unregister_driver); | 74 | EXPORT_SYMBOL(zpool_unregister_driver); |
75 | 75 | ||
76 | /** | ||
77 | * zpool_evict() - evict callback from a zpool implementation. | ||
78 | * @pool: pool to evict from. | ||
79 | * @handle: handle to evict. | ||
80 | * | ||
81 | * This can be used by zpool implementations to call the | ||
82 | * user's evict zpool_ops struct evict callback. | ||
83 | */ | ||
84 | int zpool_evict(void *pool, unsigned long handle) | ||
85 | { | ||
86 | struct zpool *zpool; | ||
87 | |||
88 | spin_lock(&pools_lock); | ||
89 | list_for_each_entry(zpool, &pools_head, list) { | ||
90 | if (zpool->pool == pool) { | ||
91 | spin_unlock(&pools_lock); | ||
92 | if (!zpool->ops || !zpool->ops->evict) | ||
93 | return -EINVAL; | ||
94 | return zpool->ops->evict(zpool, handle); | ||
95 | } | ||
96 | } | ||
97 | spin_unlock(&pools_lock); | ||
98 | |||
99 | return -ENOENT; | ||
100 | } | ||
101 | EXPORT_SYMBOL(zpool_evict); | ||
102 | |||
103 | static struct zpool_driver *zpool_get_driver(char *type) | 76 | static struct zpool_driver *zpool_get_driver(char *type) |
104 | { | 77 | { |
105 | struct zpool_driver *driver; | 78 | struct zpool_driver *driver; |
@@ -147,7 +120,7 @@ struct zpool *zpool_create_pool(char *type, char *name, gfp_t gfp, | |||
147 | struct zpool_driver *driver; | 120 | struct zpool_driver *driver; |
148 | struct zpool *zpool; | 121 | struct zpool *zpool; |
149 | 122 | ||
150 | pr_info("creating pool type %s\n", type); | 123 | pr_debug("creating pool type %s\n", type); |
151 | 124 | ||
152 | driver = zpool_get_driver(type); | 125 | driver = zpool_get_driver(type); |
153 | 126 | ||
@@ -170,7 +143,7 @@ struct zpool *zpool_create_pool(char *type, char *name, gfp_t gfp, | |||
170 | 143 | ||
171 | zpool->type = driver->type; | 144 | zpool->type = driver->type; |
172 | zpool->driver = driver; | 145 | zpool->driver = driver; |
173 | zpool->pool = driver->create(name, gfp, ops); | 146 | zpool->pool = driver->create(name, gfp, ops, zpool); |
174 | zpool->ops = ops; | 147 | zpool->ops = ops; |
175 | 148 | ||
176 | if (!zpool->pool) { | 149 | if (!zpool->pool) { |
@@ -180,7 +153,7 @@ struct zpool *zpool_create_pool(char *type, char *name, gfp_t gfp, | |||
180 | return NULL; | 153 | return NULL; |
181 | } | 154 | } |
182 | 155 | ||
183 | pr_info("created %s pool\n", type); | 156 | pr_debug("created pool type %s\n", type); |
184 | 157 | ||
185 | spin_lock(&pools_lock); | 158 | spin_lock(&pools_lock); |
186 | list_add(&zpool->list, &pools_head); | 159 | list_add(&zpool->list, &pools_head); |
@@ -202,7 +175,7 @@ struct zpool *zpool_create_pool(char *type, char *name, gfp_t gfp, | |||
202 | */ | 175 | */ |
203 | void zpool_destroy_pool(struct zpool *zpool) | 176 | void zpool_destroy_pool(struct zpool *zpool) |
204 | { | 177 | { |
205 | pr_info("destroying pool type %s\n", zpool->type); | 178 | pr_debug("destroying pool type %s\n", zpool->type); |
206 | 179 | ||
207 | spin_lock(&pools_lock); | 180 | spin_lock(&pools_lock); |
208 | list_del(&zpool->list); | 181 | list_del(&zpool->list); |
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index a8b5e749e84e..0a7f81aa2249 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c | |||
@@ -45,10 +45,6 @@ | |||
45 | * | 45 | * |
46 | */ | 46 | */ |
47 | 47 | ||
48 | #ifdef CONFIG_ZSMALLOC_DEBUG | ||
49 | #define DEBUG | ||
50 | #endif | ||
51 | |||
52 | #include <linux/module.h> | 48 | #include <linux/module.h> |
53 | #include <linux/kernel.h> | 49 | #include <linux/kernel.h> |
54 | #include <linux/sched.h> | 50 | #include <linux/sched.h> |
@@ -313,7 +309,8 @@ static void record_obj(unsigned long handle, unsigned long obj) | |||
313 | 309 | ||
314 | #ifdef CONFIG_ZPOOL | 310 | #ifdef CONFIG_ZPOOL |
315 | 311 | ||
316 | static void *zs_zpool_create(char *name, gfp_t gfp, struct zpool_ops *zpool_ops) | 312 | static void *zs_zpool_create(char *name, gfp_t gfp, struct zpool_ops *zpool_ops, |
313 | struct zpool *zpool) | ||
317 | { | 314 | { |
318 | return zs_create_pool(name, gfp); | 315 | return zs_create_pool(name, gfp); |
319 | } | 316 | } |
diff --git a/mm/zswap.c b/mm/zswap.c index 4249e82ff934..2d5727baed59 100644 --- a/mm/zswap.c +++ b/mm/zswap.c | |||
@@ -75,9 +75,10 @@ static u64 zswap_duplicate_entry; | |||
75 | /********************************* | 75 | /********************************* |
76 | * tunables | 76 | * tunables |
77 | **********************************/ | 77 | **********************************/ |
78 | /* Enable/disable zswap (disabled by default, fixed at boot for now) */ | 78 | |
79 | static bool zswap_enabled __read_mostly; | 79 | /* Enable/disable zswap (disabled by default) */ |
80 | module_param_named(enabled, zswap_enabled, bool, 0444); | 80 | static bool zswap_enabled; |
81 | module_param_named(enabled, zswap_enabled, bool, 0644); | ||
81 | 82 | ||
82 | /* Compressor to be used by zswap (fixed at boot for now) */ | 83 | /* Compressor to be used by zswap (fixed at boot for now) */ |
83 | #define ZSWAP_COMPRESSOR_DEFAULT "lzo" | 84 | #define ZSWAP_COMPRESSOR_DEFAULT "lzo" |
@@ -648,7 +649,7 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset, | |||
648 | u8 *src, *dst; | 649 | u8 *src, *dst; |
649 | struct zswap_header *zhdr; | 650 | struct zswap_header *zhdr; |
650 | 651 | ||
651 | if (!tree) { | 652 | if (!zswap_enabled || !tree) { |
652 | ret = -ENODEV; | 653 | ret = -ENODEV; |
653 | goto reject; | 654 | goto reject; |
654 | } | 655 | } |
@@ -901,9 +902,6 @@ static int __init init_zswap(void) | |||
901 | { | 902 | { |
902 | gfp_t gfp = __GFP_NORETRY | __GFP_NOWARN; | 903 | gfp_t gfp = __GFP_NORETRY | __GFP_NOWARN; |
903 | 904 | ||
904 | if (!zswap_enabled) | ||
905 | return 0; | ||
906 | |||
907 | pr_info("loading zswap\n"); | 905 | pr_info("loading zswap\n"); |
908 | 906 | ||
909 | zswap_pool = zpool_create_pool(zswap_zpool_type, "zswap", gfp, | 907 | zswap_pool = zpool_create_pool(zswap_zpool_type, "zswap", gfp, |
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index c5ec977b9c37..90e1edc8dd42 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -9,6 +9,7 @@ use strict; | |||
9 | use POSIX; | 9 | use POSIX; |
10 | use File::Basename; | 10 | use File::Basename; |
11 | use Cwd 'abs_path'; | 11 | use Cwd 'abs_path'; |
12 | use Term::ANSIColor qw(:constants); | ||
12 | 13 | ||
13 | my $P = $0; | 14 | my $P = $0; |
14 | my $D = dirname(abs_path($P)); | 15 | my $D = dirname(abs_path($P)); |
@@ -24,6 +25,7 @@ my $chk_patch = 1; | |||
24 | my $tst_only; | 25 | my $tst_only; |
25 | my $emacs = 0; | 26 | my $emacs = 0; |
26 | my $terse = 0; | 27 | my $terse = 0; |
28 | my $showfile = 0; | ||
27 | my $file = 0; | 29 | my $file = 0; |
28 | my $check = 0; | 30 | my $check = 0; |
29 | my $check_orig = 0; | 31 | my $check_orig = 0; |
@@ -48,7 +50,8 @@ my $minimum_perl_version = 5.10.0; | |||
48 | my $min_conf_desc_length = 4; | 50 | my $min_conf_desc_length = 4; |
49 | my $spelling_file = "$D/spelling.txt"; | 51 | my $spelling_file = "$D/spelling.txt"; |
50 | my $codespell = 0; | 52 | my $codespell = 0; |
51 | my $codespellfile = "/usr/local/share/codespell/dictionary.txt"; | 53 | my $codespellfile = "/usr/share/codespell/dictionary.txt"; |
54 | my $color = 1; | ||
52 | 55 | ||
53 | sub help { | 56 | sub help { |
54 | my ($exitcode) = @_; | 57 | my ($exitcode) = @_; |
@@ -64,6 +67,7 @@ Options: | |||
64 | --patch treat FILE as patchfile (default) | 67 | --patch treat FILE as patchfile (default) |
65 | --emacs emacs compile window format | 68 | --emacs emacs compile window format |
66 | --terse one line per report | 69 | --terse one line per report |
70 | --showfile emit diffed file position, not input file position | ||
67 | -f, --file treat FILE as regular source file | 71 | -f, --file treat FILE as regular source file |
68 | --subjective, --strict enable more subjective tests | 72 | --subjective, --strict enable more subjective tests |
69 | --types TYPE(,TYPE2...) show only these comma separated message types | 73 | --types TYPE(,TYPE2...) show only these comma separated message types |
@@ -91,8 +95,9 @@ Options: | |||
91 | --ignore-perl-version override checking of perl version. expect | 95 | --ignore-perl-version override checking of perl version. expect |
92 | runtime errors. | 96 | runtime errors. |
93 | --codespell Use the codespell dictionary for spelling/typos | 97 | --codespell Use the codespell dictionary for spelling/typos |
94 | (default:/usr/local/share/codespell/dictionary.txt) | 98 | (default:/usr/share/codespell/dictionary.txt) |
95 | --codespellfile Use this codespell dictionary | 99 | --codespellfile Use this codespell dictionary |
100 | --color Use colors when output is STDOUT (default: on) | ||
96 | -h, --help, --version display this help and exit | 101 | -h, --help, --version display this help and exit |
97 | 102 | ||
98 | When FILE is - read standard input. | 103 | When FILE is - read standard input. |
@@ -134,6 +139,7 @@ GetOptions( | |||
134 | 'patch!' => \$chk_patch, | 139 | 'patch!' => \$chk_patch, |
135 | 'emacs!' => \$emacs, | 140 | 'emacs!' => \$emacs, |
136 | 'terse!' => \$terse, | 141 | 'terse!' => \$terse, |
142 | 'showfile!' => \$showfile, | ||
137 | 'f|file!' => \$file, | 143 | 'f|file!' => \$file, |
138 | 'subjective!' => \$check, | 144 | 'subjective!' => \$check, |
139 | 'strict!' => \$check, | 145 | 'strict!' => \$check, |
@@ -153,6 +159,7 @@ GetOptions( | |||
153 | 'test-only=s' => \$tst_only, | 159 | 'test-only=s' => \$tst_only, |
154 | 'codespell!' => \$codespell, | 160 | 'codespell!' => \$codespell, |
155 | 'codespellfile=s' => \$codespellfile, | 161 | 'codespellfile=s' => \$codespellfile, |
162 | 'color!' => \$color, | ||
156 | 'h|help' => \$help, | 163 | 'h|help' => \$help, |
157 | 'version' => \$help | 164 | 'version' => \$help |
158 | ) or help(1); | 165 | ) or help(1); |
@@ -196,12 +203,12 @@ sub hash_save_array_words { | |||
196 | sub hash_show_words { | 203 | sub hash_show_words { |
197 | my ($hashRef, $prefix) = @_; | 204 | my ($hashRef, $prefix) = @_; |
198 | 205 | ||
199 | if ($quiet == 0 && keys %$hashRef) { | 206 | if (keys %$hashRef) { |
200 | print "NOTE: $prefix message types:"; | 207 | print "\nNOTE: $prefix message types:"; |
201 | foreach my $word (sort keys %$hashRef) { | 208 | foreach my $word (sort keys %$hashRef) { |
202 | print " $word"; | 209 | print " $word"; |
203 | } | 210 | } |
204 | print "\n\n"; | 211 | print "\n"; |
205 | } | 212 | } |
206 | } | 213 | } |
207 | 214 | ||
@@ -347,15 +354,20 @@ our $UTF8 = qr{ | |||
347 | | $NON_ASCII_UTF8 | 354 | | $NON_ASCII_UTF8 |
348 | }x; | 355 | }x; |
349 | 356 | ||
357 | our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; | ||
350 | our $typeOtherOSTypedefs = qr{(?x: | 358 | our $typeOtherOSTypedefs = qr{(?x: |
351 | u_(?:char|short|int|long) | # bsd | 359 | u_(?:char|short|int|long) | # bsd |
352 | u(?:nchar|short|int|long) # sysv | 360 | u(?:nchar|short|int|long) # sysv |
353 | )}; | 361 | )}; |
354 | 362 | our $typeKernelTypedefs = qr{(?x: | |
355 | our $typeTypedefs = qr{(?x: | ||
356 | (?:__)?(?:u|s|be|le)(?:8|16|32|64)| | 363 | (?:__)?(?:u|s|be|le)(?:8|16|32|64)| |
357 | atomic_t | 364 | atomic_t |
358 | )}; | 365 | )}; |
366 | our $typeTypedefs = qr{(?x: | ||
367 | $typeC99Typedefs\b| | ||
368 | $typeOtherOSTypedefs\b| | ||
369 | $typeKernelTypedefs\b | ||
370 | )}; | ||
359 | 371 | ||
360 | our $logFunctions = qr{(?x: | 372 | our $logFunctions = qr{(?x: |
361 | printk(?:_ratelimited|_once|)| | 373 | printk(?:_ratelimited|_once|)| |
@@ -418,6 +430,7 @@ our @typeList = ( | |||
418 | qr{${Ident}_handler_fn}, | 430 | qr{${Ident}_handler_fn}, |
419 | @typeListMisordered, | 431 | @typeListMisordered, |
420 | ); | 432 | ); |
433 | our @typeListFile = (); | ||
421 | our @typeListWithAttr = ( | 434 | our @typeListWithAttr = ( |
422 | @typeList, | 435 | @typeList, |
423 | qr{struct\s+$InitAttribute\s+$Ident}, | 436 | qr{struct\s+$InitAttribute\s+$Ident}, |
@@ -427,6 +440,7 @@ our @typeListWithAttr = ( | |||
427 | our @modifierList = ( | 440 | our @modifierList = ( |
428 | qr{fastcall}, | 441 | qr{fastcall}, |
429 | ); | 442 | ); |
443 | our @modifierListFile = (); | ||
430 | 444 | ||
431 | our @mode_permission_funcs = ( | 445 | our @mode_permission_funcs = ( |
432 | ["module_param", 3], | 446 | ["module_param", 3], |
@@ -510,13 +524,12 @@ if ($codespell) { | |||
510 | $misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; | 524 | $misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; |
511 | 525 | ||
512 | sub build_types { | 526 | sub build_types { |
513 | my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; | 527 | my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; |
514 | my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; | 528 | my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; |
515 | my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; | 529 | my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; |
516 | my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; | 530 | my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; |
517 | $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; | 531 | $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; |
518 | $BasicType = qr{ | 532 | $BasicType = qr{ |
519 | (?:$typeOtherOSTypedefs\b)| | ||
520 | (?:$typeTypedefs\b)| | 533 | (?:$typeTypedefs\b)| |
521 | (?:${all}\b) | 534 | (?:${all}\b) |
522 | }x; | 535 | }x; |
@@ -524,7 +537,6 @@ sub build_types { | |||
524 | (?:$Modifier\s+|const\s+)* | 537 | (?:$Modifier\s+|const\s+)* |
525 | (?: | 538 | (?: |
526 | (?:typeof|__typeof__)\s*\([^\)]*\)| | 539 | (?:typeof|__typeof__)\s*\([^\)]*\)| |
527 | (?:$typeOtherOSTypedefs\b)| | ||
528 | (?:$typeTypedefs\b)| | 540 | (?:$typeTypedefs\b)| |
529 | (?:${all}\b) | 541 | (?:${all}\b) |
530 | ) | 542 | ) |
@@ -542,7 +554,6 @@ sub build_types { | |||
542 | (?: | 554 | (?: |
543 | (?:typeof|__typeof__)\s*\([^\)]*\)| | 555 | (?:typeof|__typeof__)\s*\([^\)]*\)| |
544 | (?:$typeTypedefs\b)| | 556 | (?:$typeTypedefs\b)| |
545 | (?:$typeOtherOSTypedefs\b)| | ||
546 | (?:${allWithAttr}\b) | 557 | (?:${allWithAttr}\b) |
547 | ) | 558 | ) |
548 | (?:\s+$Modifier|\s+const)* | 559 | (?:\s+$Modifier|\s+const)* |
@@ -737,6 +748,13 @@ for my $filename (@ARGV) { | |||
737 | push(@rawlines, $_); | 748 | push(@rawlines, $_); |
738 | } | 749 | } |
739 | close($FILE); | 750 | close($FILE); |
751 | |||
752 | if ($#ARGV > 0 && $quiet == 0) { | ||
753 | print '-' x length($vname) . "\n"; | ||
754 | print "$vname\n"; | ||
755 | print '-' x length($vname) . "\n"; | ||
756 | } | ||
757 | |||
740 | if (!process($filename)) { | 758 | if (!process($filename)) { |
741 | $exit = 1; | 759 | $exit = 1; |
742 | } | 760 | } |
@@ -746,6 +764,29 @@ for my $filename (@ARGV) { | |||
746 | @fixed_inserted = (); | 764 | @fixed_inserted = (); |
747 | @fixed_deleted = (); | 765 | @fixed_deleted = (); |
748 | $fixlinenr = -1; | 766 | $fixlinenr = -1; |
767 | @modifierListFile = (); | ||
768 | @typeListFile = (); | ||
769 | build_types(); | ||
770 | } | ||
771 | |||
772 | if (!$quiet) { | ||
773 | hash_show_words(\%use_type, "Used"); | ||
774 | hash_show_words(\%ignore_type, "Ignored"); | ||
775 | |||
776 | if ($^V lt 5.10.0) { | ||
777 | print << "EOM" | ||
778 | |||
779 | NOTE: perl $^V is not modern enough to detect all possible issues. | ||
780 | An upgrade to at least perl v5.10.0 is suggested. | ||
781 | EOM | ||
782 | } | ||
783 | if ($exit) { | ||
784 | print << "EOM" | ||
785 | |||
786 | NOTE: If any of the errors are false positives, please report | ||
787 | them to the maintainer, see CHECKPATCH in MAINTAINERS. | ||
788 | EOM | ||
789 | } | ||
749 | } | 790 | } |
750 | 791 | ||
751 | exit($exit); | 792 | exit($exit); |
@@ -1001,7 +1042,7 @@ sub sanitise_line { | |||
1001 | sub get_quoted_string { | 1042 | sub get_quoted_string { |
1002 | my ($line, $rawline) = @_; | 1043 | my ($line, $rawline) = @_; |
1003 | 1044 | ||
1004 | return "" if ($line !~ m/(\"[X\t]+\")/g); | 1045 | return "" if ($line !~ m/($String)/g); |
1005 | return substr($rawline, $-[0], $+[0] - $-[0]); | 1046 | return substr($rawline, $-[0], $+[0] - $-[0]); |
1006 | } | 1047 | } |
1007 | 1048 | ||
@@ -1610,13 +1651,13 @@ sub possible { | |||
1610 | for my $modifier (split(' ', $possible)) { | 1651 | for my $modifier (split(' ', $possible)) { |
1611 | if ($modifier !~ $notPermitted) { | 1652 | if ($modifier !~ $notPermitted) { |
1612 | warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); | 1653 | warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); |
1613 | push(@modifierList, $modifier); | 1654 | push(@modifierListFile, $modifier); |
1614 | } | 1655 | } |
1615 | } | 1656 | } |
1616 | 1657 | ||
1617 | } else { | 1658 | } else { |
1618 | warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); | 1659 | warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); |
1619 | push(@typeList, $possible); | 1660 | push(@typeListFile, $possible); |
1620 | } | 1661 | } |
1621 | build_types(); | 1662 | build_types(); |
1622 | } else { | 1663 | } else { |
@@ -1641,15 +1682,32 @@ sub report { | |||
1641 | (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { | 1682 | (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { |
1642 | return 0; | 1683 | return 0; |
1643 | } | 1684 | } |
1644 | my $line; | 1685 | my $output = ''; |
1686 | if (-t STDOUT && $color) { | ||
1687 | if ($level eq 'ERROR') { | ||
1688 | $output .= RED; | ||
1689 | } elsif ($level eq 'WARNING') { | ||
1690 | $output .= YELLOW; | ||
1691 | } else { | ||
1692 | $output .= GREEN; | ||
1693 | } | ||
1694 | } | ||
1695 | $output .= $prefix . $level . ':'; | ||
1645 | if ($show_types) { | 1696 | if ($show_types) { |
1646 | $line = "$prefix$level:$type: $msg\n"; | 1697 | $output .= BLUE if (-t STDOUT && $color); |
1647 | } else { | 1698 | $output .= "$type:"; |
1648 | $line = "$prefix$level: $msg\n"; | ||
1649 | } | 1699 | } |
1650 | $line = (split('\n', $line))[0] . "\n" if ($terse); | 1700 | $output .= RESET if (-t STDOUT && $color); |
1701 | $output .= ' ' . $msg . "\n"; | ||
1651 | 1702 | ||
1652 | push(our @report, $line); | 1703 | if ($showfile) { |
1704 | my @lines = split("\n", $output, -1); | ||
1705 | splice(@lines, 1, 1); | ||
1706 | $output = join("\n", @lines); | ||
1707 | } | ||
1708 | $output = (split('\n', $output))[0] . "\n" if ($terse); | ||
1709 | |||
1710 | push(our @report, $output); | ||
1653 | 1711 | ||
1654 | return 1; | 1712 | return 1; |
1655 | } | 1713 | } |
@@ -1899,6 +1957,7 @@ sub process { | |||
1899 | my $in_header_lines = $file ? 0 : 1; | 1957 | my $in_header_lines = $file ? 0 : 1; |
1900 | my $in_commit_log = 0; #Scanning lines before patch | 1958 | my $in_commit_log = 0; #Scanning lines before patch |
1901 | my $commit_log_long_line = 0; | 1959 | my $commit_log_long_line = 0; |
1960 | my $commit_log_has_diff = 0; | ||
1902 | my $reported_maintainer_file = 0; | 1961 | my $reported_maintainer_file = 0; |
1903 | my $non_utf8_charset = 0; | 1962 | my $non_utf8_charset = 0; |
1904 | 1963 | ||
@@ -2032,7 +2091,8 @@ sub process { | |||
2032 | my $rawline = $rawlines[$linenr - 1]; | 2091 | my $rawline = $rawlines[$linenr - 1]; |
2033 | 2092 | ||
2034 | #extract the line range in the file after the patch is applied | 2093 | #extract the line range in the file after the patch is applied |
2035 | if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { | 2094 | if (!$in_commit_log && |
2095 | $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { | ||
2036 | $is_patch = 1; | 2096 | $is_patch = 1; |
2037 | $first_line = $linenr + 1; | 2097 | $first_line = $linenr + 1; |
2038 | $realline=$1-1; | 2098 | $realline=$1-1; |
@@ -2073,10 +2133,6 @@ sub process { | |||
2073 | 2133 | ||
2074 | my $hunk_line = ($realcnt != 0); | 2134 | my $hunk_line = ($realcnt != 0); |
2075 | 2135 | ||
2076 | #make up the handle for any error we report on this line | ||
2077 | $prefix = "$filename:$realline: " if ($emacs && $file); | ||
2078 | $prefix = "$filename:$linenr: " if ($emacs && !$file); | ||
2079 | |||
2080 | $here = "#$linenr: " if (!$file); | 2136 | $here = "#$linenr: " if (!$file); |
2081 | $here = "#$realline: " if ($file); | 2137 | $here = "#$realline: " if ($file); |
2082 | 2138 | ||
@@ -2106,6 +2162,13 @@ sub process { | |||
2106 | $found_file = 1; | 2162 | $found_file = 1; |
2107 | } | 2163 | } |
2108 | 2164 | ||
2165 | #make up the handle for any error we report on this line | ||
2166 | if ($showfile) { | ||
2167 | $prefix = "$realfile:$realline: " | ||
2168 | } elsif ($emacs) { | ||
2169 | $prefix = "$filename:$linenr: "; | ||
2170 | } | ||
2171 | |||
2109 | if ($found_file) { | 2172 | if ($found_file) { |
2110 | if ($realfile =~ m@^(drivers/net/|net/)@) { | 2173 | if ($realfile =~ m@^(drivers/net/|net/)@) { |
2111 | $check = 1; | 2174 | $check = 1; |
@@ -2123,6 +2186,17 @@ sub process { | |||
2123 | 2186 | ||
2124 | $cnt_lines++ if ($realcnt != 0); | 2187 | $cnt_lines++ if ($realcnt != 0); |
2125 | 2188 | ||
2189 | # Check if the commit log has what seems like a diff which can confuse patch | ||
2190 | if ($in_commit_log && !$commit_log_has_diff && | ||
2191 | (($line =~ m@^\s+diff\b.*a/[\w/]+@ && | ||
2192 | $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) || | ||
2193 | $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || | ||
2194 | $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { | ||
2195 | ERROR("DIFF_IN_COMMIT_MSG", | ||
2196 | "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); | ||
2197 | $commit_log_has_diff = 1; | ||
2198 | } | ||
2199 | |||
2126 | # Check for incorrect file permissions | 2200 | # Check for incorrect file permissions |
2127 | if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { | 2201 | if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { |
2128 | my $permhere = $here . "FILE: $realfile\n"; | 2202 | my $permhere = $here . "FILE: $realfile\n"; |
@@ -2510,16 +2584,56 @@ sub process { | |||
2510 | # check we are in a valid source file if not then ignore this hunk | 2584 | # check we are in a valid source file if not then ignore this hunk |
2511 | next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/); | 2585 | next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/); |
2512 | 2586 | ||
2513 | #line length limit | 2587 | # line length limit (with some exclusions) |
2514 | if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && | 2588 | # |
2515 | $rawline !~ /^.\s*\*\s*\@$Ident\s/ && | 2589 | # There are a few types of lines that may extend beyond $max_line_length: |
2516 | !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ || | 2590 | # logging functions like pr_info that end in a string |
2517 | $line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || | 2591 | # lines with a single string |
2518 | $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) && | 2592 | # #defines that are a single string |
2519 | $length > $max_line_length) | 2593 | # |
2520 | { | 2594 | # There are 3 different line length message types: |
2521 | WARN("LONG_LINE", | 2595 | # LONG_LINE_COMMENT a comment starts before but extends beyond $max_linelength |
2522 | "line over $max_line_length characters\n" . $herecurr); | 2596 | # LONG_LINE_STRING a string starts before but extends beyond $max_line_length |
2597 | # LONG_LINE all other lines longer than $max_line_length | ||
2598 | # | ||
2599 | # if LONG_LINE is ignored, the other 2 types are also ignored | ||
2600 | # | ||
2601 | |||
2602 | if ($length > $max_line_length) { | ||
2603 | my $msg_type = "LONG_LINE"; | ||
2604 | |||
2605 | # Check the allowed long line types first | ||
2606 | |||
2607 | # logging functions that end in a string that starts | ||
2608 | # before $max_line_length | ||
2609 | if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && | ||
2610 | length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { | ||
2611 | $msg_type = ""; | ||
2612 | |||
2613 | # lines with only strings (w/ possible termination) | ||
2614 | # #defines with only strings | ||
2615 | } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || | ||
2616 | $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { | ||
2617 | $msg_type = ""; | ||
2618 | |||
2619 | # Otherwise set the alternate message types | ||
2620 | |||
2621 | # a comment starts before $max_line_length | ||
2622 | } elsif ($line =~ /($;[\s$;]*)$/ && | ||
2623 | length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { | ||
2624 | $msg_type = "LONG_LINE_COMMENT" | ||
2625 | |||
2626 | # a quoted string starts before $max_line_length | ||
2627 | } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && | ||
2628 | length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { | ||
2629 | $msg_type = "LONG_LINE_STRING" | ||
2630 | } | ||
2631 | |||
2632 | if ($msg_type ne "" && | ||
2633 | (show_type("LONG_LINE") || show_type($msg_type))) { | ||
2634 | WARN($msg_type, | ||
2635 | "line over $max_line_length characters\n" . $herecurr); | ||
2636 | } | ||
2523 | } | 2637 | } |
2524 | 2638 | ||
2525 | # check for adding lines without a newline. | 2639 | # check for adding lines without a newline. |
@@ -3264,7 +3378,6 @@ sub process { | |||
3264 | $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && | 3378 | $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && |
3265 | $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && | 3379 | $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && |
3266 | $line !~ /\b$typeTypedefs\b/ && | 3380 | $line !~ /\b$typeTypedefs\b/ && |
3267 | $line !~ /\b$typeOtherOSTypedefs\b/ && | ||
3268 | $line !~ /\b__bitwise(?:__|)\b/) { | 3381 | $line !~ /\b__bitwise(?:__|)\b/) { |
3269 | WARN("NEW_TYPEDEFS", | 3382 | WARN("NEW_TYPEDEFS", |
3270 | "do not add new typedefs\n" . $herecurr); | 3383 | "do not add new typedefs\n" . $herecurr); |
@@ -4337,8 +4450,8 @@ sub process { | |||
4337 | } | 4450 | } |
4338 | 4451 | ||
4339 | # Flatten any obvious string concatentation. | 4452 | # Flatten any obvious string concatentation. |
4340 | while ($dstat =~ s/("X*")\s*$Ident/$1/ || | 4453 | while ($dstat =~ s/($String)\s*$Ident/$1/ || |
4341 | $dstat =~ s/$Ident\s*("X*")/$1/) | 4454 | $dstat =~ s/$Ident\s*($String)/$1/) |
4342 | { | 4455 | { |
4343 | } | 4456 | } |
4344 | 4457 | ||
@@ -4619,7 +4732,7 @@ sub process { | |||
4619 | # to grep for the string. Make exceptions when the previous string ends in a | 4732 | # to grep for the string. Make exceptions when the previous string ends in a |
4620 | # newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' | 4733 | # newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' |
4621 | # (common in inline assembly) or is a octal \123 or hexadecimal \xaf value | 4734 | # (common in inline assembly) or is a octal \123 or hexadecimal \xaf value |
4622 | if ($line =~ /^\+\s*"[X\t]*"/ && | 4735 | if ($line =~ /^\+\s*$String/ && |
4623 | $prevline =~ /"\s*$/ && | 4736 | $prevline =~ /"\s*$/ && |
4624 | $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { | 4737 | $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { |
4625 | if (WARN("SPLIT_STRING", | 4738 | if (WARN("SPLIT_STRING", |
@@ -4665,13 +4778,13 @@ sub process { | |||
4665 | } | 4778 | } |
4666 | 4779 | ||
4667 | # concatenated string without spaces between elements | 4780 | # concatenated string without spaces between elements |
4668 | if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) { | 4781 | if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) { |
4669 | CHK("CONCATENATED_STRING", | 4782 | CHK("CONCATENATED_STRING", |
4670 | "Concatenated strings should use spaces between elements\n" . $herecurr); | 4783 | "Concatenated strings should use spaces between elements\n" . $herecurr); |
4671 | } | 4784 | } |
4672 | 4785 | ||
4673 | # uncoalesced string fragments | 4786 | # uncoalesced string fragments |
4674 | if ($line =~ /"X*"\s*"/) { | 4787 | if ($line =~ /$String\s*"/) { |
4675 | WARN("STRING_FRAGMENTS", | 4788 | WARN("STRING_FRAGMENTS", |
4676 | "Consecutive strings are generally better as a single string\n" . $herecurr); | 4789 | "Consecutive strings are generally better as a single string\n" . $herecurr); |
4677 | } | 4790 | } |
@@ -4898,6 +5011,13 @@ sub process { | |||
4898 | "memory barrier without comment\n" . $herecurr); | 5011 | "memory barrier without comment\n" . $herecurr); |
4899 | } | 5012 | } |
4900 | } | 5013 | } |
5014 | # check for waitqueue_active without a comment. | ||
5015 | if ($line =~ /\bwaitqueue_active\s*\(/) { | ||
5016 | if (!ctx_has_comment($first_line, $linenr)) { | ||
5017 | WARN("WAITQUEUE_ACTIVE", | ||
5018 | "waitqueue_active without comment\n" . $herecurr); | ||
5019 | } | ||
5020 | } | ||
4901 | # check of hardware specific defines | 5021 | # check of hardware specific defines |
4902 | if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { | 5022 | if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { |
4903 | CHK("ARCH_DEFINES", | 5023 | CHK("ARCH_DEFINES", |
@@ -4973,6 +5093,24 @@ sub process { | |||
4973 | "Using weak declarations can have unintended link defects\n" . $herecurr); | 5093 | "Using weak declarations can have unintended link defects\n" . $herecurr); |
4974 | } | 5094 | } |
4975 | 5095 | ||
5096 | # check for c99 types like uint8_t used outside of uapi/ | ||
5097 | if ($realfile !~ m@\binclude/uapi/@ && | ||
5098 | $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { | ||
5099 | my $type = $1; | ||
5100 | if ($type =~ /\b($typeC99Typedefs)\b/) { | ||
5101 | $type = $1; | ||
5102 | my $kernel_type = 'u'; | ||
5103 | $kernel_type = 's' if ($type =~ /^_*[si]/); | ||
5104 | $type =~ /(\d+)/; | ||
5105 | $kernel_type .= $1; | ||
5106 | if (CHK("PREFER_KERNEL_TYPES", | ||
5107 | "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && | ||
5108 | $fix) { | ||
5109 | $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; | ||
5110 | } | ||
5111 | } | ||
5112 | } | ||
5113 | |||
4976 | # check for sizeof(&) | 5114 | # check for sizeof(&) |
4977 | if ($line =~ /\bsizeof\s*\(\s*\&/) { | 5115 | if ($line =~ /\bsizeof\s*\(\s*\&/) { |
4978 | WARN("SIZEOF_ADDRESS", | 5116 | WARN("SIZEOF_ADDRESS", |
@@ -5010,7 +5148,7 @@ sub process { | |||
5010 | # Check for misused memsets | 5148 | # Check for misused memsets |
5011 | if ($^V && $^V ge 5.10.0 && | 5149 | if ($^V && $^V ge 5.10.0 && |
5012 | defined $stat && | 5150 | defined $stat && |
5013 | $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) { | 5151 | $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { |
5014 | 5152 | ||
5015 | my $ms_addr = $2; | 5153 | my $ms_addr = $2; |
5016 | my $ms_val = $7; | 5154 | my $ms_val = $7; |
@@ -5027,14 +5165,46 @@ sub process { | |||
5027 | 5165 | ||
5028 | # Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) | 5166 | # Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) |
5029 | if ($^V && $^V ge 5.10.0 && | 5167 | if ($^V && $^V ge 5.10.0 && |
5030 | $line =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/s) { | 5168 | defined $stat && |
5169 | $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { | ||
5031 | if (WARN("PREFER_ETHER_ADDR_COPY", | 5170 | if (WARN("PREFER_ETHER_ADDR_COPY", |
5032 | "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . $herecurr) && | 5171 | "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && |
5033 | $fix) { | 5172 | $fix) { |
5034 | $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; | 5173 | $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; |
5035 | } | 5174 | } |
5036 | } | 5175 | } |
5037 | 5176 | ||
5177 | # Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) | ||
5178 | if ($^V && $^V ge 5.10.0 && | ||
5179 | defined $stat && | ||
5180 | $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { | ||
5181 | WARN("PREFER_ETHER_ADDR_EQUAL", | ||
5182 | "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") | ||
5183 | } | ||
5184 | |||
5185 | # check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr | ||
5186 | # check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr | ||
5187 | if ($^V && $^V ge 5.10.0 && | ||
5188 | defined $stat && | ||
5189 | $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { | ||
5190 | |||
5191 | my $ms_val = $7; | ||
5192 | |||
5193 | if ($ms_val =~ /^(?:0x|)0+$/i) { | ||
5194 | if (WARN("PREFER_ETH_ZERO_ADDR", | ||
5195 | "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && | ||
5196 | $fix) { | ||
5197 | $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; | ||
5198 | } | ||
5199 | } elsif ($ms_val =~ /^(?:0xff|255)$/i) { | ||
5200 | if (WARN("PREFER_ETH_BROADCAST_ADDR", | ||
5201 | "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && | ||
5202 | $fix) { | ||
5203 | $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; | ||
5204 | } | ||
5205 | } | ||
5206 | } | ||
5207 | |||
5038 | # typecasts on min/max could be min_t/max_t | 5208 | # typecasts on min/max could be min_t/max_t |
5039 | if ($^V && $^V ge 5.10.0 && | 5209 | if ($^V && $^V ge 5.10.0 && |
5040 | defined $stat && | 5210 | defined $stat && |
@@ -5472,6 +5642,24 @@ sub process { | |||
5472 | } | 5642 | } |
5473 | } | 5643 | } |
5474 | } | 5644 | } |
5645 | |||
5646 | # validate content of MODULE_LICENSE against list from include/linux/module.h | ||
5647 | if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { | ||
5648 | my $extracted_string = get_quoted_string($line, $rawline); | ||
5649 | my $valid_licenses = qr{ | ||
5650 | GPL| | ||
5651 | GPL\ v2| | ||
5652 | GPL\ and\ additional\ rights| | ||
5653 | Dual\ BSD/GPL| | ||
5654 | Dual\ MIT/GPL| | ||
5655 | Dual\ MPL/GPL| | ||
5656 | Proprietary | ||
5657 | }x; | ||
5658 | if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { | ||
5659 | WARN("MODULE_LICENSE", | ||
5660 | "unknown module license " . $extracted_string . "\n" . $herecurr); | ||
5661 | } | ||
5662 | } | ||
5475 | } | 5663 | } |
5476 | 5664 | ||
5477 | # If we have no input at all, then there is nothing to report on | 5665 | # If we have no input at all, then there is nothing to report on |
@@ -5492,11 +5680,11 @@ sub process { | |||
5492 | exit(0); | 5680 | exit(0); |
5493 | } | 5681 | } |
5494 | 5682 | ||
5495 | if (!$is_patch) { | 5683 | if (!$is_patch && $file !~ /cover-letter\.patch$/) { |
5496 | ERROR("NOT_UNIFIED_DIFF", | 5684 | ERROR("NOT_UNIFIED_DIFF", |
5497 | "Does not appear to be a unified-diff format patch\n"); | 5685 | "Does not appear to be a unified-diff format patch\n"); |
5498 | } | 5686 | } |
5499 | if ($is_patch && $chk_signoff && $signoff == 0) { | 5687 | if ($is_patch && $filename ne '-' && $chk_signoff && $signoff == 0) { |
5500 | ERROR("MISSING_SIGN_OFF", | 5688 | ERROR("MISSING_SIGN_OFF", |
5501 | "Missing Signed-off-by: line(s)\n"); | 5689 | "Missing Signed-off-by: line(s)\n"); |
5502 | } | 5690 | } |
@@ -5507,28 +5695,21 @@ sub process { | |||
5507 | print "total: $cnt_error errors, $cnt_warn warnings, " . | 5695 | print "total: $cnt_error errors, $cnt_warn warnings, " . |
5508 | (($check)? "$cnt_chk checks, " : "") . | 5696 | (($check)? "$cnt_chk checks, " : "") . |
5509 | "$cnt_lines lines checked\n"; | 5697 | "$cnt_lines lines checked\n"; |
5510 | print "\n" if ($quiet == 0); | ||
5511 | } | 5698 | } |
5512 | 5699 | ||
5513 | if ($quiet == 0) { | 5700 | if ($quiet == 0) { |
5514 | |||
5515 | if ($^V lt 5.10.0) { | ||
5516 | print("NOTE: perl $^V is not modern enough to detect all possible issues.\n"); | ||
5517 | print("An upgrade to at least perl v5.10.0 is suggested.\n\n"); | ||
5518 | } | ||
5519 | |||
5520 | # If there were whitespace errors which cleanpatch can fix | 5701 | # If there were whitespace errors which cleanpatch can fix |
5521 | # then suggest that. | 5702 | # then suggest that. |
5522 | if ($rpt_cleaners) { | 5703 | if ($rpt_cleaners) { |
5523 | print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n"; | ||
5524 | print " scripts/cleanfile\n\n"; | ||
5525 | $rpt_cleaners = 0; | 5704 | $rpt_cleaners = 0; |
5705 | print << "EOM" | ||
5706 | |||
5707 | NOTE: Whitespace errors detected. | ||
5708 | You may wish to use scripts/cleanpatch or scripts/cleanfile | ||
5709 | EOM | ||
5526 | } | 5710 | } |
5527 | } | 5711 | } |
5528 | 5712 | ||
5529 | hash_show_words(\%use_type, "Used"); | ||
5530 | hash_show_words(\%ignore_type, "Ignored"); | ||
5531 | |||
5532 | if ($clean == 0 && $fix && | 5713 | if ($clean == 0 && $fix && |
5533 | ("@rawlines" ne "@fixed" || | 5714 | ("@rawlines" ne "@fixed" || |
5534 | $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { | 5715 | $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { |
@@ -5556,6 +5737,7 @@ sub process { | |||
5556 | 5737 | ||
5557 | if (!$quiet) { | 5738 | if (!$quiet) { |
5558 | print << "EOM"; | 5739 | print << "EOM"; |
5740 | |||
5559 | Wrote EXPERIMENTAL --fix correction(s) to '$newfile' | 5741 | Wrote EXPERIMENTAL --fix correction(s) to '$newfile' |
5560 | 5742 | ||
5561 | Do _NOT_ trust the results written to this file. | 5743 | Do _NOT_ trust the results written to this file. |
@@ -5563,22 +5745,17 @@ Do _NOT_ submit these changes without inspecting them for correctness. | |||
5563 | 5745 | ||
5564 | This EXPERIMENTAL file is simply a convenience to help rewrite patches. | 5746 | This EXPERIMENTAL file is simply a convenience to help rewrite patches. |
5565 | No warranties, expressed or implied... | 5747 | No warranties, expressed or implied... |
5566 | |||
5567 | EOM | 5748 | EOM |
5568 | } | 5749 | } |
5569 | } | 5750 | } |
5570 | 5751 | ||
5571 | if ($clean == 1 && $quiet == 0) { | 5752 | if ($quiet == 0) { |
5572 | print "$vname has no obvious style problems and is ready for submission.\n" | 5753 | print "\n"; |
5573 | } | 5754 | if ($clean == 1) { |
5574 | if ($clean == 0 && $quiet == 0) { | 5755 | print "$vname has no obvious style problems and is ready for submission.\n"; |
5575 | print << "EOM"; | 5756 | } else { |
5576 | $vname has style problems, please review. | 5757 | print "$vname has style problems, please review.\n"; |
5577 | 5758 | } | |
5578 | If any of these errors are false positives, please report | ||
5579 | them to the maintainer, see CHECKPATCH in MAINTAINERS. | ||
5580 | EOM | ||
5581 | } | 5759 | } |
5582 | |||
5583 | return $clean; | 5760 | return $clean; |
5584 | } | 5761 | } |
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index d7016279ec2b..98bae869f6d0 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl | |||
@@ -42,6 +42,7 @@ my $output_multiline = 1; | |||
42 | my $output_separator = ", "; | 42 | my $output_separator = ", "; |
43 | my $output_roles = 0; | 43 | my $output_roles = 0; |
44 | my $output_rolestats = 1; | 44 | my $output_rolestats = 1; |
45 | my $output_section_maxlen = 50; | ||
45 | my $scm = 0; | 46 | my $scm = 0; |
46 | my $web = 0; | 47 | my $web = 0; |
47 | my $subsystem = 0; | 48 | my $subsystem = 0; |
@@ -186,6 +187,27 @@ if (-f $conf) { | |||
186 | unshift(@ARGV, @conf_args) if @conf_args; | 187 | unshift(@ARGV, @conf_args) if @conf_args; |
187 | } | 188 | } |
188 | 189 | ||
190 | my @ignore_emails = (); | ||
191 | my $ignore_file = which_conf(".get_maintainer.ignore"); | ||
192 | if (-f $ignore_file) { | ||
193 | open(my $ignore, '<', "$ignore_file") | ||
194 | or warn "$P: Can't find a readable .get_maintainer.ignore file $!\n"; | ||
195 | while (<$ignore>) { | ||
196 | my $line = $_; | ||
197 | |||
198 | $line =~ s/\s*\n?$//; | ||
199 | $line =~ s/^\s*//; | ||
200 | $line =~ s/\s+$//; | ||
201 | $line =~ s/#.*$//; | ||
202 | |||
203 | next if ($line =~ m/^\s*$/); | ||
204 | if (rfc822_valid($line)) { | ||
205 | push(@ignore_emails, $line); | ||
206 | } | ||
207 | } | ||
208 | close($ignore); | ||
209 | } | ||
210 | |||
189 | if (!GetOptions( | 211 | if (!GetOptions( |
190 | 'email!' => \$email, | 212 | 'email!' => \$email, |
191 | 'git!' => \$email_git, | 213 | 'git!' => \$email_git, |
@@ -283,7 +305,7 @@ open (my $maint, '<', "${lk_path}MAINTAINERS") | |||
283 | while (<$maint>) { | 305 | while (<$maint>) { |
284 | my $line = $_; | 306 | my $line = $_; |
285 | 307 | ||
286 | if ($line =~ m/^(\C):\s*(.*)/) { | 308 | if ($line =~ m/^([A-Z]):\s*(.*)/) { |
287 | my $type = $1; | 309 | my $type = $1; |
288 | my $value = $2; | 310 | my $value = $2; |
289 | 311 | ||
@@ -513,12 +535,22 @@ if ($web) { | |||
513 | 535 | ||
514 | exit($exit); | 536 | exit($exit); |
515 | 537 | ||
538 | sub ignore_email_address { | ||
539 | my ($address) = @_; | ||
540 | |||
541 | foreach my $ignore (@ignore_emails) { | ||
542 | return 1 if ($ignore eq $address); | ||
543 | } | ||
544 | |||
545 | return 0; | ||
546 | } | ||
547 | |||
516 | sub range_is_maintained { | 548 | sub range_is_maintained { |
517 | my ($start, $end) = @_; | 549 | my ($start, $end) = @_; |
518 | 550 | ||
519 | for (my $i = $start; $i < $end; $i++) { | 551 | for (my $i = $start; $i < $end; $i++) { |
520 | my $line = $typevalue[$i]; | 552 | my $line = $typevalue[$i]; |
521 | if ($line =~ m/^(\C):\s*(.*)/) { | 553 | if ($line =~ m/^([A-Z]):\s*(.*)/) { |
522 | my $type = $1; | 554 | my $type = $1; |
523 | my $value = $2; | 555 | my $value = $2; |
524 | if ($type eq 'S') { | 556 | if ($type eq 'S') { |
@@ -536,7 +568,7 @@ sub range_has_maintainer { | |||
536 | 568 | ||
537 | for (my $i = $start; $i < $end; $i++) { | 569 | for (my $i = $start; $i < $end; $i++) { |
538 | my $line = $typevalue[$i]; | 570 | my $line = $typevalue[$i]; |
539 | if ($line =~ m/^(\C):\s*(.*)/) { | 571 | if ($line =~ m/^([A-Z]):\s*(.*)/) { |
540 | my $type = $1; | 572 | my $type = $1; |
541 | my $value = $2; | 573 | my $value = $2; |
542 | if ($type eq 'M') { | 574 | if ($type eq 'M') { |
@@ -585,7 +617,7 @@ sub get_maintainers { | |||
585 | 617 | ||
586 | for ($i = $start; $i < $end; $i++) { | 618 | for ($i = $start; $i < $end; $i++) { |
587 | my $line = $typevalue[$i]; | 619 | my $line = $typevalue[$i]; |
588 | if ($line =~ m/^(\C):\s*(.*)/) { | 620 | if ($line =~ m/^([A-Z]):\s*(.*)/) { |
589 | my $type = $1; | 621 | my $type = $1; |
590 | my $value = $2; | 622 | my $value = $2; |
591 | if ($type eq 'X') { | 623 | if ($type eq 'X') { |
@@ -600,7 +632,7 @@ sub get_maintainers { | |||
600 | if (!$exclude) { | 632 | if (!$exclude) { |
601 | for ($i = $start; $i < $end; $i++) { | 633 | for ($i = $start; $i < $end; $i++) { |
602 | my $line = $typevalue[$i]; | 634 | my $line = $typevalue[$i]; |
603 | if ($line =~ m/^(\C):\s*(.*)/) { | 635 | if ($line =~ m/^([A-Z]):\s*(.*)/) { |
604 | my $type = $1; | 636 | my $type = $1; |
605 | my $value = $2; | 637 | my $value = $2; |
606 | if ($type eq 'F') { | 638 | if ($type eq 'F') { |
@@ -901,7 +933,7 @@ sub find_first_section { | |||
901 | 933 | ||
902 | while ($index < @typevalue) { | 934 | while ($index < @typevalue) { |
903 | my $tv = $typevalue[$index]; | 935 | my $tv = $typevalue[$index]; |
904 | if (($tv =~ m/^(\C):\s*(.*)/)) { | 936 | if (($tv =~ m/^([A-Z]):\s*(.*)/)) { |
905 | last; | 937 | last; |
906 | } | 938 | } |
907 | $index++; | 939 | $index++; |
@@ -915,7 +947,7 @@ sub find_starting_index { | |||
915 | 947 | ||
916 | while ($index > 0) { | 948 | while ($index > 0) { |
917 | my $tv = $typevalue[$index]; | 949 | my $tv = $typevalue[$index]; |
918 | if (!($tv =~ m/^(\C):\s*(.*)/)) { | 950 | if (!($tv =~ m/^([A-Z]):\s*(.*)/)) { |
919 | last; | 951 | last; |
920 | } | 952 | } |
921 | $index--; | 953 | $index--; |
@@ -929,7 +961,7 @@ sub find_ending_index { | |||
929 | 961 | ||
930 | while ($index < @typevalue) { | 962 | while ($index < @typevalue) { |
931 | my $tv = $typevalue[$index]; | 963 | my $tv = $typevalue[$index]; |
932 | if (!($tv =~ m/^(\C):\s*(.*)/)) { | 964 | if (!($tv =~ m/^([A-Z]):\s*(.*)/)) { |
933 | last; | 965 | last; |
934 | } | 966 | } |
935 | $index++; | 967 | $index++; |
@@ -947,15 +979,15 @@ sub get_maintainer_role { | |||
947 | 979 | ||
948 | my $role = "unknown"; | 980 | my $role = "unknown"; |
949 | my $subsystem = $typevalue[$start]; | 981 | my $subsystem = $typevalue[$start]; |
950 | if (length($subsystem) > 20) { | 982 | if ($output_section_maxlen && length($subsystem) > $output_section_maxlen) { |
951 | $subsystem = substr($subsystem, 0, 17); | 983 | $subsystem = substr($subsystem, 0, $output_section_maxlen - 3); |
952 | $subsystem =~ s/\s*$//; | 984 | $subsystem =~ s/\s*$//; |
953 | $subsystem = $subsystem . "..."; | 985 | $subsystem = $subsystem . "..."; |
954 | } | 986 | } |
955 | 987 | ||
956 | for ($i = $start + 1; $i < $end; $i++) { | 988 | for ($i = $start + 1; $i < $end; $i++) { |
957 | my $tv = $typevalue[$i]; | 989 | my $tv = $typevalue[$i]; |
958 | if ($tv =~ m/^(\C):\s*(.*)/) { | 990 | if ($tv =~ m/^([A-Z]):\s*(.*)/) { |
959 | my $ptype = $1; | 991 | my $ptype = $1; |
960 | my $pvalue = $2; | 992 | my $pvalue = $2; |
961 | if ($ptype eq "S") { | 993 | if ($ptype eq "S") { |
@@ -990,8 +1022,8 @@ sub get_list_role { | |||
990 | my $end = find_ending_index($index); | 1022 | my $end = find_ending_index($index); |
991 | 1023 | ||
992 | my $subsystem = $typevalue[$start]; | 1024 | my $subsystem = $typevalue[$start]; |
993 | if (length($subsystem) > 20) { | 1025 | if ($output_section_maxlen && length($subsystem) > $output_section_maxlen) { |
994 | $subsystem = substr($subsystem, 0, 17); | 1026 | $subsystem = substr($subsystem, 0, $output_section_maxlen - 3); |
995 | $subsystem =~ s/\s*$//; | 1027 | $subsystem =~ s/\s*$//; |
996 | $subsystem = $subsystem . "..."; | 1028 | $subsystem = $subsystem . "..."; |
997 | } | 1029 | } |
@@ -1014,7 +1046,7 @@ sub add_categories { | |||
1014 | 1046 | ||
1015 | for ($i = $start + 1; $i < $end; $i++) { | 1047 | for ($i = $start + 1; $i < $end; $i++) { |
1016 | my $tv = $typevalue[$i]; | 1048 | my $tv = $typevalue[$i]; |
1017 | if ($tv =~ m/^(\C):\s*(.*)/) { | 1049 | if ($tv =~ m/^([A-Z]):\s*(.*)/) { |
1018 | my $ptype = $1; | 1050 | my $ptype = $1; |
1019 | my $pvalue = $2; | 1051 | my $pvalue = $2; |
1020 | if ($ptype eq "L") { | 1052 | if ($ptype eq "L") { |
@@ -1056,7 +1088,7 @@ sub add_categories { | |||
1056 | if ($name eq "") { | 1088 | if ($name eq "") { |
1057 | if ($i > 0) { | 1089 | if ($i > 0) { |
1058 | my $tv = $typevalue[$i - 1]; | 1090 | my $tv = $typevalue[$i - 1]; |
1059 | if ($tv =~ m/^(\C):\s*(.*)/) { | 1091 | if ($tv =~ m/^([A-Z]):\s*(.*)/) { |
1060 | if ($1 eq "P") { | 1092 | if ($1 eq "P") { |
1061 | $name = $2; | 1093 | $name = $2; |
1062 | $pvalue = format_email($name, $address, $email_usename); | 1094 | $pvalue = format_email($name, $address, $email_usename); |
@@ -1073,7 +1105,7 @@ sub add_categories { | |||
1073 | if ($name eq "") { | 1105 | if ($name eq "") { |
1074 | if ($i > 0) { | 1106 | if ($i > 0) { |
1075 | my $tv = $typevalue[$i - 1]; | 1107 | my $tv = $typevalue[$i - 1]; |
1076 | if ($tv =~ m/^(\C):\s*(.*)/) { | 1108 | if ($tv =~ m/^([A-Z]):\s*(.*)/) { |
1077 | if ($1 eq "P") { | 1109 | if ($1 eq "P") { |
1078 | $name = $2; | 1110 | $name = $2; |
1079 | $pvalue = format_email($name, $address, $email_usename); | 1111 | $pvalue = format_email($name, $address, $email_usename); |
@@ -1868,6 +1900,7 @@ sub vcs_assign { | |||
1868 | my $percent = $sign_offs * 100 / $divisor; | 1900 | my $percent = $sign_offs * 100 / $divisor; |
1869 | 1901 | ||
1870 | $percent = 100 if ($percent > 100); | 1902 | $percent = 100 if ($percent > 100); |
1903 | next if (ignore_email_address($line)); | ||
1871 | $count++; | 1904 | $count++; |
1872 | last if ($sign_offs < $email_git_min_signatures || | 1905 | last if ($sign_offs < $email_git_min_signatures || |
1873 | $count > $email_git_max_maintainers || | 1906 | $count > $email_git_max_maintainers || |