diff options
author | Christoph Lameter <clameter@sgi.com> | 2008-02-14 15:05:41 -0500 |
---|---|---|
committer | Christoph Lameter <clameter@sgi.com> | 2008-02-14 15:05:41 -0500 |
commit | c5974932c1e8514d3478573bb52beebeb2c786dd (patch) | |
tree | a204156fbb0036fb76e89ceffa15a30e90bc3f75 | |
parent | 9e40ade04c45a46f6b3d647e0bdac1a32bfaa3a9 (diff) | |
parent | e760e716d47b48caf98da348368fd41b4a9b9e7e (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
144 files changed, 3141 insertions, 1303 deletions
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index 6a0ad4715e9f..300e1707893f 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ | 9 | DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ |
10 | kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ | 10 | kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ |
11 | procfs-guide.xml writing_usb_driver.xml \ | 11 | procfs-guide.xml writing_usb_driver.xml networking.xml \ |
12 | kernel-api.xml filesystems.xml lsm.xml usb.xml \ | 12 | kernel-api.xml filesystems.xml lsm.xml usb.xml \ |
13 | gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ | 13 | gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ |
14 | genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml | 14 | genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml |
diff --git a/Documentation/DocBook/filesystems.tmpl b/Documentation/DocBook/filesystems.tmpl index 5eaef87e8f1b..5e87ad58c0b5 100644 --- a/Documentation/DocBook/filesystems.tmpl +++ b/Documentation/DocBook/filesystems.tmpl | |||
@@ -398,4 +398,24 @@ an example. | |||
398 | 398 | ||
399 | </chapter> | 399 | </chapter> |
400 | 400 | ||
401 | <chapter id="splice"> | ||
402 | <title>splice API</title> | ||
403 | <para> | ||
404 | splice is a method for moving blocks of data around inside the | ||
405 | kernel, without continually transferring them between the kernel | ||
406 | and user space. | ||
407 | </para> | ||
408 | !Ffs/splice.c | ||
409 | </chapter> | ||
410 | |||
411 | <chapter id="pipes"> | ||
412 | <title>pipes API</title> | ||
413 | <para> | ||
414 | Pipe interfaces are all for in-kernel (builtin image) use. | ||
415 | They are not exported for use by modules. | ||
416 | </para> | ||
417 | !Iinclude/linux/pipe_fs_i.h | ||
418 | !Ffs/pipe.c | ||
419 | </chapter> | ||
420 | |||
401 | </book> | 421 | </book> |
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index 059aaf20951a..f31601e8bd89 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl | |||
@@ -204,65 +204,6 @@ X!Ilib/string.c | |||
204 | </sect1> | 204 | </sect1> |
205 | </chapter> | 205 | </chapter> |
206 | 206 | ||
207 | <chapter id="netcore"> | ||
208 | <title>Linux Networking</title> | ||
209 | <sect1><title>Networking Base Types</title> | ||
210 | !Iinclude/linux/net.h | ||
211 | </sect1> | ||
212 | <sect1><title>Socket Buffer Functions</title> | ||
213 | !Iinclude/linux/skbuff.h | ||
214 | !Iinclude/net/sock.h | ||
215 | !Enet/socket.c | ||
216 | !Enet/core/skbuff.c | ||
217 | !Enet/core/sock.c | ||
218 | !Enet/core/datagram.c | ||
219 | !Enet/core/stream.c | ||
220 | </sect1> | ||
221 | <sect1><title>Socket Filter</title> | ||
222 | !Enet/core/filter.c | ||
223 | </sect1> | ||
224 | <sect1><title>Generic Network Statistics</title> | ||
225 | !Iinclude/linux/gen_stats.h | ||
226 | !Enet/core/gen_stats.c | ||
227 | !Enet/core/gen_estimator.c | ||
228 | </sect1> | ||
229 | <sect1><title>SUN RPC subsystem</title> | ||
230 | <!-- The !D functionality is not perfect, garbage has to be protected by comments | ||
231 | !Dnet/sunrpc/sunrpc_syms.c | ||
232 | --> | ||
233 | !Enet/sunrpc/xdr.c | ||
234 | !Enet/sunrpc/svcsock.c | ||
235 | !Enet/sunrpc/sched.c | ||
236 | </sect1> | ||
237 | </chapter> | ||
238 | |||
239 | <chapter id="netdev"> | ||
240 | <title>Network device support</title> | ||
241 | <sect1><title>Driver Support</title> | ||
242 | !Enet/core/dev.c | ||
243 | !Enet/ethernet/eth.c | ||
244 | !Enet/sched/sch_generic.c | ||
245 | !Iinclude/linux/etherdevice.h | ||
246 | !Iinclude/linux/netdevice.h | ||
247 | </sect1> | ||
248 | <sect1><title>PHY Support</title> | ||
249 | !Edrivers/net/phy/phy.c | ||
250 | !Idrivers/net/phy/phy.c | ||
251 | !Edrivers/net/phy/phy_device.c | ||
252 | !Idrivers/net/phy/phy_device.c | ||
253 | !Edrivers/net/phy/mdio_bus.c | ||
254 | !Idrivers/net/phy/mdio_bus.c | ||
255 | </sect1> | ||
256 | <!-- FIXME: Removed for now since no structured comments in source | ||
257 | <sect1><title>Wireless</title> | ||
258 | X!Enet/core/wireless.c | ||
259 | </sect1> | ||
260 | --> | ||
261 | <sect1><title>Synchronous PPP</title> | ||
262 | !Edrivers/net/wan/syncppp.c | ||
263 | </sect1> | ||
264 | </chapter> | ||
265 | |||
266 | <chapter id="modload"> | 207 | <chapter id="modload"> |
267 | <title>Module Support</title> | 208 | <title>Module Support</title> |
268 | <sect1><title>Module Loading</title> | 209 | <sect1><title>Module Loading</title> |
@@ -508,11 +449,6 @@ X!Isound/sound_firmware.c | |||
508 | !Edrivers/serial/8250.c | 449 | !Edrivers/serial/8250.c |
509 | </chapter> | 450 | </chapter> |
510 | 451 | ||
511 | <chapter id="z85230"> | ||
512 | <title>Z85230 Support Library</title> | ||
513 | !Edrivers/net/wan/z85230.c | ||
514 | </chapter> | ||
515 | |||
516 | <chapter id="fbdev"> | 452 | <chapter id="fbdev"> |
517 | <title>Frame Buffer Library</title> | 453 | <title>Frame Buffer Library</title> |
518 | 454 | ||
@@ -712,24 +648,4 @@ X!Idrivers/video/console/fonts.c | |||
712 | !Edrivers/i2c/i2c-core.c | 648 | !Edrivers/i2c/i2c-core.c |
713 | </chapter> | 649 | </chapter> |
714 | 650 | ||
715 | <chapter id="splice"> | ||
716 | <title>splice API</title> | ||
717 | <para> | ||
718 | splice is a method for moving blocks of data around inside the | ||
719 | kernel, without continually transferring them between the kernel | ||
720 | and user space. | ||
721 | </para> | ||
722 | !Ffs/splice.c | ||
723 | </chapter> | ||
724 | |||
725 | <chapter id="pipes"> | ||
726 | <title>pipes API</title> | ||
727 | <para> | ||
728 | Pipe interfaces are all for in-kernel (builtin image) use. | ||
729 | They are not exported for use by modules. | ||
730 | </para> | ||
731 | !Iinclude/linux/pipe_fs_i.h | ||
732 | !Ffs/pipe.c | ||
733 | </chapter> | ||
734 | |||
735 | </book> | 651 | </book> |
diff --git a/Documentation/DocBook/networking.tmpl b/Documentation/DocBook/networking.tmpl new file mode 100644 index 000000000000..f24f9e85e4ae --- /dev/null +++ b/Documentation/DocBook/networking.tmpl | |||
@@ -0,0 +1,106 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" | ||
3 | "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> | ||
4 | |||
5 | <book id="LinuxNetworking"> | ||
6 | <bookinfo> | ||
7 | <title>Linux Networking and Network Devices APIs</title> | ||
8 | |||
9 | <legalnotice> | ||
10 | <para> | ||
11 | This documentation is free software; you can redistribute | ||
12 | it and/or modify it under the terms of the GNU General Public | ||
13 | License as published by the Free Software Foundation; either | ||
14 | version 2 of the License, or (at your option) any later | ||
15 | version. | ||
16 | </para> | ||
17 | |||
18 | <para> | ||
19 | This program is distributed in the hope that it will be | ||
20 | useful, but WITHOUT ANY WARRANTY; without even the implied | ||
21 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
22 | See the GNU General Public License for more details. | ||
23 | </para> | ||
24 | |||
25 | <para> | ||
26 | You should have received a copy of the GNU General Public | ||
27 | License along with this program; if not, write to the Free | ||
28 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
29 | MA 02111-1307 USA | ||
30 | </para> | ||
31 | |||
32 | <para> | ||
33 | For more details see the file COPYING in the source | ||
34 | distribution of Linux. | ||
35 | </para> | ||
36 | </legalnotice> | ||
37 | </bookinfo> | ||
38 | |||
39 | <toc></toc> | ||
40 | |||
41 | <chapter id="netcore"> | ||
42 | <title>Linux Networking</title> | ||
43 | <sect1><title>Networking Base Types</title> | ||
44 | !Iinclude/linux/net.h | ||
45 | </sect1> | ||
46 | <sect1><title>Socket Buffer Functions</title> | ||
47 | !Iinclude/linux/skbuff.h | ||
48 | !Iinclude/net/sock.h | ||
49 | !Enet/socket.c | ||
50 | !Enet/core/skbuff.c | ||
51 | !Enet/core/sock.c | ||
52 | !Enet/core/datagram.c | ||
53 | !Enet/core/stream.c | ||
54 | </sect1> | ||
55 | <sect1><title>Socket Filter</title> | ||
56 | !Enet/core/filter.c | ||
57 | </sect1> | ||
58 | <sect1><title>Generic Network Statistics</title> | ||
59 | !Iinclude/linux/gen_stats.h | ||
60 | !Enet/core/gen_stats.c | ||
61 | !Enet/core/gen_estimator.c | ||
62 | </sect1> | ||
63 | <sect1><title>SUN RPC subsystem</title> | ||
64 | <!-- The !D functionality is not perfect, garbage has to be protected by comments | ||
65 | !Dnet/sunrpc/sunrpc_syms.c | ||
66 | --> | ||
67 | !Enet/sunrpc/xdr.c | ||
68 | !Enet/sunrpc/svc_xprt.c | ||
69 | !Enet/sunrpc/xprt.c | ||
70 | !Enet/sunrpc/sched.c | ||
71 | !Enet/sunrpc/socklib.c | ||
72 | !Enet/sunrpc/stats.c | ||
73 | !Enet/sunrpc/rpc_pipe.c | ||
74 | !Enet/sunrpc/rpcb_clnt.c | ||
75 | !Enet/sunrpc/clnt.c | ||
76 | </sect1> | ||
77 | </chapter> | ||
78 | |||
79 | <chapter id="netdev"> | ||
80 | <title>Network device support</title> | ||
81 | <sect1><title>Driver Support</title> | ||
82 | !Enet/core/dev.c | ||
83 | !Enet/ethernet/eth.c | ||
84 | !Enet/sched/sch_generic.c | ||
85 | !Iinclude/linux/etherdevice.h | ||
86 | !Iinclude/linux/netdevice.h | ||
87 | </sect1> | ||
88 | <sect1><title>PHY Support</title> | ||
89 | !Edrivers/net/phy/phy.c | ||
90 | !Idrivers/net/phy/phy.c | ||
91 | !Edrivers/net/phy/phy_device.c | ||
92 | !Idrivers/net/phy/phy_device.c | ||
93 | !Edrivers/net/phy/mdio_bus.c | ||
94 | !Idrivers/net/phy/mdio_bus.c | ||
95 | </sect1> | ||
96 | <!-- FIXME: Removed for now since no structured comments in source | ||
97 | <sect1><title>Wireless</title> | ||
98 | X!Enet/core/wireless.c | ||
99 | </sect1> | ||
100 | --> | ||
101 | <sect1><title>Synchronous PPP</title> | ||
102 | !Edrivers/net/wan/syncppp.c | ||
103 | </sect1> | ||
104 | </chapter> | ||
105 | |||
106 | </book> | ||
diff --git a/Documentation/RCU/NMI-RCU.txt b/Documentation/RCU/NMI-RCU.txt index d0634a5c3445..c64158ecde43 100644 --- a/Documentation/RCU/NMI-RCU.txt +++ b/Documentation/RCU/NMI-RCU.txt | |||
@@ -25,7 +25,7 @@ the NMI handler to take the default machine-specific action. | |||
25 | This nmi_callback variable is a global function pointer to the current | 25 | This nmi_callback variable is a global function pointer to the current |
26 | NMI handler. | 26 | NMI handler. |
27 | 27 | ||
28 | fastcall void do_nmi(struct pt_regs * regs, long error_code) | 28 | void do_nmi(struct pt_regs * regs, long error_code) |
29 | { | 29 | { |
30 | int cpu; | 30 | int cpu; |
31 | 31 | ||
diff --git a/Documentation/SubmitChecklist b/Documentation/SubmitChecklist index 34e06d2f194f..da10e0714241 100644 --- a/Documentation/SubmitChecklist +++ b/Documentation/SubmitChecklist | |||
@@ -20,7 +20,11 @@ kernel patches. | |||
20 | 4: ppc64 is a good architecture for cross-compilation checking because it | 20 | 4: ppc64 is a good architecture for cross-compilation checking because it |
21 | tends to use `unsigned long' for 64-bit quantities. | 21 | tends to use `unsigned long' for 64-bit quantities. |
22 | 22 | ||
23 | 5: Matches kernel coding style(!) | 23 | 5: Check your patch for general style as detailed in |
24 | Documentation/CodingStyle. Check for trivial violations with the | ||
25 | patch style checker prior to submission (scripts/checkpatch.pl). | ||
26 | You should be able to justify all violations that remain in | ||
27 | your patch. | ||
24 | 28 | ||
25 | 6: Any new or modified CONFIG options don't muck up the config menu. | 29 | 6: Any new or modified CONFIG options don't muck up the config menu. |
26 | 30 | ||
@@ -79,13 +83,3 @@ kernel patches. | |||
79 | 23: Tested after it has been merged into the -mm patchset to make sure | 83 | 23: Tested after it has been merged into the -mm patchset to make sure |
80 | that it still works with all of the other queued patches and various | 84 | that it still works with all of the other queued patches and various |
81 | changes in the VM, VFS, and other subsystems. | 85 | changes in the VM, VFS, and other subsystems. |
82 | |||
83 | 24: Avoid whitespace damage such as indenting with spaces or whitespace | ||
84 | at the end of lines. You can test this by feeding the patch to | ||
85 | "git apply --check --whitespace=error-all" | ||
86 | |||
87 | 25: Check your patch for general style as detailed in | ||
88 | Documentation/CodingStyle. Check for trivial violations with the | ||
89 | patch style checker prior to submission (scripts/checkpatch.pl). | ||
90 | You should be able to justify all violations that remain in | ||
91 | your patch. | ||
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt index 30c101761d0d..83f515c2905a 100644 --- a/Documentation/kprobes.txt +++ b/Documentation/kprobes.txt | |||
@@ -92,9 +92,8 @@ handler has run. Up to MAX_STACK_SIZE bytes are copied -- e.g., | |||
92 | 64 bytes on i386. | 92 | 64 bytes on i386. |
93 | 93 | ||
94 | Note that the probed function's args may be passed on the stack | 94 | Note that the probed function's args may be passed on the stack |
95 | or in registers (e.g., for x86_64 or for an i386 fastcall function). | 95 | or in registers. The jprobe will work in either case, so long as the |
96 | The jprobe will work in either case, so long as the handler's | 96 | handler's prototype matches that of the probed function. |
97 | prototype matches that of the probed function. | ||
98 | 97 | ||
99 | 1.3 Return Probes | 98 | 1.3 Return Probes |
100 | 99 | ||
@@ -270,9 +269,9 @@ Kprobes runs the handler whose address is jp->entry. | |||
270 | The handler should have the same arg list and return type as the probed | 269 | The handler should have the same arg list and return type as the probed |
271 | function; and just before it returns, it must call jprobe_return(). | 270 | function; and just before it returns, it must call jprobe_return(). |
272 | (The handler never actually returns, since jprobe_return() returns | 271 | (The handler never actually returns, since jprobe_return() returns |
273 | control to Kprobes.) If the probed function is declared asmlinkage, | 272 | control to Kprobes.) If the probed function is declared asmlinkage |
274 | fastcall, or anything else that affects how args are passed, the | 273 | or anything else that affects how args are passed, the handler's |
275 | handler's declaration must match. | 274 | declaration must match. |
276 | 275 | ||
277 | register_jprobe() returns 0 on success, or a negative errno otherwise. | 276 | register_jprobe() returns 0 on success, or a negative errno otherwise. |
278 | 277 | ||
diff --git a/Documentation/sched-rt-group.txt b/Documentation/sched-rt-group.txt new file mode 100644 index 000000000000..1c6332f4543c --- /dev/null +++ b/Documentation/sched-rt-group.txt | |||
@@ -0,0 +1,59 @@ | |||
1 | |||
2 | |||
3 | Real-Time group scheduling. | ||
4 | |||
5 | The problem space: | ||
6 | |||
7 | In order to schedule multiple groups of realtime tasks each group must | ||
8 | be assigned a fixed portion of the CPU time available. Without a minimum | ||
9 | guarantee a realtime group can obviously fall short. A fuzzy upper limit | ||
10 | is of no use since it cannot be relied upon. Which leaves us with just | ||
11 | the single fixed portion. | ||
12 | |||
13 | CPU time is divided by means of specifying how much time can be spent | ||
14 | running in a given period. Say a frame fixed realtime renderer must | ||
15 | deliver 25 frames a second, which yields a period of 0.04s. Now say | ||
16 | it will also have to play some music and respond to input, leaving it | ||
17 | with around 80% for the graphics. We can then give this group a runtime | ||
18 | of 0.8 * 0.04s = 0.032s. | ||
19 | |||
20 | This way the graphics group will have a 0.04s period with a 0.032s runtime | ||
21 | limit. | ||
22 | |||
23 | Now if the audio thread needs to refill the DMA buffer every 0.005s, but | ||
24 | needs only about 3% CPU time to do so, it can do with a 0.03 * 0.005s | ||
25 | = 0.00015s. | ||
26 | |||
27 | |||
28 | The Interface: | ||
29 | |||
30 | system wide: | ||
31 | |||
32 | /proc/sys/kernel/sched_rt_period_ms | ||
33 | /proc/sys/kernel/sched_rt_runtime_us | ||
34 | |||
35 | CONFIG_FAIR_USER_SCHED | ||
36 | |||
37 | /sys/kernel/uids/<uid>/cpu_rt_runtime_us | ||
38 | |||
39 | or | ||
40 | |||
41 | CONFIG_FAIR_CGROUP_SCHED | ||
42 | |||
43 | /cgroup/<cgroup>/cpu.rt_runtime_us | ||
44 | |||
45 | [ time is specified in us because the interface is s32; this gives an | ||
46 | operating range of ~35m to 1us ] | ||
47 | |||
48 | The period takes values in [ 1, INT_MAX ], runtime in [ -1, INT_MAX - 1 ]. | ||
49 | |||
50 | A runtime of -1 specifies runtime == period, ie. no limit. | ||
51 | |||
52 | New groups get the period from /proc/sys/kernel/sched_rt_period_us and | ||
53 | a runtime of 0. | ||
54 | |||
55 | Settings are constrained to: | ||
56 | |||
57 | \Sum_{i} runtime_{i} / global_period <= global_runtime / global_period | ||
58 | |||
59 | in order to keep the configuration schedulable. | ||
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index dc8801d4e944..276a7e637822 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt | |||
@@ -29,7 +29,7 @@ show up in /proc/sys/kernel: | |||
29 | - java-interpreter [ binfmt_java, obsolete ] | 29 | - java-interpreter [ binfmt_java, obsolete ] |
30 | - kstack_depth_to_print [ X86 only ] | 30 | - kstack_depth_to_print [ X86 only ] |
31 | - l2cr [ PPC only ] | 31 | - l2cr [ PPC only ] |
32 | - modprobe ==> Documentation/kmod.txt | 32 | - modprobe ==> Documentation/debugging-modules.txt |
33 | - msgmax | 33 | - msgmax |
34 | - msgmnb | 34 | - msgmnb |
35 | - msgmni | 35 | - msgmni |
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 1dd50d07693c..75480cab0893 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c | |||
@@ -119,13 +119,8 @@ irqreturn_t timer_interrupt(int irq, void *dev) | |||
119 | state.partial_tick = delta & ((1UL << FIX_SHIFT) - 1); | 119 | state.partial_tick = delta & ((1UL << FIX_SHIFT) - 1); |
120 | nticks = delta >> FIX_SHIFT; | 120 | nticks = delta >> FIX_SHIFT; |
121 | 121 | ||
122 | while (nticks > 0) { | 122 | if (nticks) |
123 | do_timer(1); | 123 | do_timer(nticks); |
124 | #ifndef CONFIG_SMP | ||
125 | update_process_times(user_mode(get_irq_regs())); | ||
126 | #endif | ||
127 | nticks--; | ||
128 | } | ||
129 | 124 | ||
130 | /* | 125 | /* |
131 | * If we have an externally synchronized Linux clock, then update | 126 | * If we have an externally synchronized Linux clock, then update |
@@ -141,6 +136,12 @@ irqreturn_t timer_interrupt(int irq, void *dev) | |||
141 | } | 136 | } |
142 | 137 | ||
143 | write_sequnlock(&xtime_lock); | 138 | write_sequnlock(&xtime_lock); |
139 | |||
140 | #ifndef CONFIG_SMP | ||
141 | while (nticks--) | ||
142 | update_process_times(user_mode(get_irq_regs())); | ||
143 | #endif | ||
144 | |||
144 | return IRQ_HANDLED; | 145 | return IRQ_HANDLED; |
145 | } | 146 | } |
146 | 147 | ||
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c index 5bd64e341df3..9bdc8f99183a 100644 --- a/arch/blackfin/kernel/time.c +++ b/arch/blackfin/kernel/time.c | |||
@@ -137,9 +137,6 @@ irqreturn_t timer_interrupt(int irq, void *dummy) | |||
137 | 137 | ||
138 | do_timer(1); | 138 | do_timer(1); |
139 | 139 | ||
140 | #ifndef CONFIG_SMP | ||
141 | update_process_times(user_mode(get_irq_regs())); | ||
142 | #endif | ||
143 | profile_tick(CPU_PROFILING); | 140 | profile_tick(CPU_PROFILING); |
144 | 141 | ||
145 | /* | 142 | /* |
@@ -161,6 +158,11 @@ irqreturn_t timer_interrupt(int irq, void *dummy) | |||
161 | last_rtc_update = xtime.tv_sec - 600; | 158 | last_rtc_update = xtime.tv_sec - 600; |
162 | } | 159 | } |
163 | write_sequnlock(&xtime_lock); | 160 | write_sequnlock(&xtime_lock); |
161 | |||
162 | #ifndef CONFIG_SMP | ||
163 | update_process_times(user_mode(get_irq_regs())); | ||
164 | #endif | ||
165 | |||
164 | return IRQ_HANDLED; | 166 | return IRQ_HANDLED; |
165 | } | 167 | } |
166 | 168 | ||
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c index 925fb0199a0f..69f6a4ef5d61 100644 --- a/arch/frv/kernel/time.c +++ b/arch/frv/kernel/time.c | |||
@@ -63,6 +63,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy) | |||
63 | /* last time the cmos clock got updated */ | 63 | /* last time the cmos clock got updated */ |
64 | static long last_rtc_update = 0; | 64 | static long last_rtc_update = 0; |
65 | 65 | ||
66 | profile_tick(CPU_PROFILING); | ||
66 | /* | 67 | /* |
67 | * Here we are in the timer irq handler. We just have irqs locally | 68 | * Here we are in the timer irq handler. We just have irqs locally |
68 | * disabled but we don't know if the timer_bh is running on the other | 69 | * disabled but we don't know if the timer_bh is running on the other |
@@ -73,8 +74,6 @@ static irqreturn_t timer_interrupt(int irq, void *dummy) | |||
73 | write_seqlock(&xtime_lock); | 74 | write_seqlock(&xtime_lock); |
74 | 75 | ||
75 | do_timer(1); | 76 | do_timer(1); |
76 | update_process_times(user_mode(get_irq_regs())); | ||
77 | profile_tick(CPU_PROFILING); | ||
78 | 77 | ||
79 | /* | 78 | /* |
80 | * If we have an externally synchronized Linux clock, then update | 79 | * If we have an externally synchronized Linux clock, then update |
@@ -99,6 +98,9 @@ static irqreturn_t timer_interrupt(int irq, void *dummy) | |||
99 | #endif /* CONFIG_HEARTBEAT */ | 98 | #endif /* CONFIG_HEARTBEAT */ |
100 | 99 | ||
101 | write_sequnlock(&xtime_lock); | 100 | write_sequnlock(&xtime_lock); |
101 | |||
102 | update_process_times(user_mode(get_irq_regs())); | ||
103 | |||
102 | return IRQ_HANDLED; | 104 | return IRQ_HANDLED; |
103 | } | 105 | } |
104 | 106 | ||
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S index ef7527b8b0c7..17725a55aed8 100644 --- a/arch/frv/kernel/vmlinux.lds.S +++ b/arch/frv/kernel/vmlinux.lds.S | |||
@@ -105,11 +105,9 @@ SECTIONS | |||
105 | SCHED_TEXT | 105 | SCHED_TEXT |
106 | LOCK_TEXT | 106 | LOCK_TEXT |
107 | #ifdef CONFIG_DEBUG_INFO | 107 | #ifdef CONFIG_DEBUG_INFO |
108 | *( | ||
109 | INIT_TEXT | 108 | INIT_TEXT |
110 | EXIT_TEXT | 109 | EXIT_TEXT |
111 | .exitcall.exit | 110 | *(.exitcall.exit) |
112 | ) | ||
113 | #endif | 111 | #endif |
114 | *(.fixup) | 112 | *(.fixup) |
115 | *(.gnu.warning) | 113 | *(.gnu.warning) |
diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c index 89cdbcaeb45f..0ccfb2ad6380 100644 --- a/arch/m68knommu/kernel/time.c +++ b/arch/m68knommu/kernel/time.c | |||
@@ -42,14 +42,12 @@ irqreturn_t arch_timer_interrupt(int irq, void *dummy) | |||
42 | /* last time the cmos clock got updated */ | 42 | /* last time the cmos clock got updated */ |
43 | static long last_rtc_update=0; | 43 | static long last_rtc_update=0; |
44 | 44 | ||
45 | if (current->pid) | ||
46 | profile_tick(CPU_PROFILING); | ||
47 | |||
45 | write_seqlock(&xtime_lock); | 48 | write_seqlock(&xtime_lock); |
46 | 49 | ||
47 | do_timer(1); | 50 | do_timer(1); |
48 | #ifndef CONFIG_SMP | ||
49 | update_process_times(user_mode(get_irq_regs())); | ||
50 | #endif | ||
51 | if (current->pid) | ||
52 | profile_tick(CPU_PROFILING); | ||
53 | 51 | ||
54 | /* | 52 | /* |
55 | * If we have an externally synchronized Linux clock, then update | 53 | * If we have an externally synchronized Linux clock, then update |
@@ -67,6 +65,10 @@ irqreturn_t arch_timer_interrupt(int irq, void *dummy) | |||
67 | } | 65 | } |
68 | 66 | ||
69 | write_sequnlock(&xtime_lock); | 67 | write_sequnlock(&xtime_lock); |
68 | |||
69 | #ifndef CONFIG_SMP | ||
70 | update_process_times(user_mode(get_irq_regs())); | ||
71 | #endif | ||
70 | return(IRQ_HANDLED); | 72 | return(IRQ_HANDLED); |
71 | } | 73 | } |
72 | 74 | ||
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c index 2b1953f6f12e..01974f7776e1 100644 --- a/arch/powerpc/platforms/cell/spufs/sputrace.c +++ b/arch/powerpc/platforms/cell/spufs/sputrace.c | |||
@@ -146,34 +146,28 @@ static void sputrace_log_item(const char *name, struct spu_context *ctx, | |||
146 | wake_up(&sputrace_wait); | 146 | wake_up(&sputrace_wait); |
147 | } | 147 | } |
148 | 148 | ||
149 | static void spu_context_event(const struct marker *mdata, | 149 | static void spu_context_event(void *probe_private, void *call_data, |
150 | void *private, const char *format, ...) | 150 | const char *format, va_list *args) |
151 | { | 151 | { |
152 | struct spu_probe *p = mdata->private; | 152 | struct spu_probe *p = probe_private; |
153 | va_list ap; | ||
154 | struct spu_context *ctx; | 153 | struct spu_context *ctx; |
155 | struct spu *spu; | 154 | struct spu *spu; |
156 | 155 | ||
157 | va_start(ap, format); | 156 | ctx = va_arg(*args, struct spu_context *); |
158 | ctx = va_arg(ap, struct spu_context *); | 157 | spu = va_arg(*args, struct spu *); |
159 | spu = va_arg(ap, struct spu *); | ||
160 | 158 | ||
161 | sputrace_log_item(p->name, ctx, spu); | 159 | sputrace_log_item(p->name, ctx, spu); |
162 | va_end(ap); | ||
163 | } | 160 | } |
164 | 161 | ||
165 | static void spu_context_nospu_event(const struct marker *mdata, | 162 | static void spu_context_nospu_event(void *probe_private, void *call_data, |
166 | void *private, const char *format, ...) | 163 | const char *format, va_list *args) |
167 | { | 164 | { |
168 | struct spu_probe *p = mdata->private; | 165 | struct spu_probe *p = probe_private; |
169 | va_list ap; | ||
170 | struct spu_context *ctx; | 166 | struct spu_context *ctx; |
171 | 167 | ||
172 | va_start(ap, format); | 168 | ctx = va_arg(*args, struct spu_context *); |
173 | ctx = va_arg(ap, struct spu_context *); | ||
174 | 169 | ||
175 | sputrace_log_item(p->name, ctx, NULL); | 170 | sputrace_log_item(p->name, ctx, NULL); |
176 | va_end(ap); | ||
177 | } | 171 | } |
178 | 172 | ||
179 | struct spu_probe spu_probes[] = { | 173 | struct spu_probe spu_probes[] = { |
@@ -219,10 +213,6 @@ static int __init sputrace_init(void) | |||
219 | if (error) | 213 | if (error) |
220 | printk(KERN_INFO "Unable to register probe %s\n", | 214 | printk(KERN_INFO "Unable to register probe %s\n", |
221 | p->name); | 215 | p->name); |
222 | |||
223 | error = marker_arm(p->name); | ||
224 | if (error) | ||
225 | printk(KERN_INFO "Unable to arm probe %s\n", p->name); | ||
226 | } | 216 | } |
227 | 217 | ||
228 | return 0; | 218 | return 0; |
@@ -238,7 +228,8 @@ static void __exit sputrace_exit(void) | |||
238 | int i; | 228 | int i; |
239 | 229 | ||
240 | for (i = 0; i < ARRAY_SIZE(spu_probes); i++) | 230 | for (i = 0; i < ARRAY_SIZE(spu_probes); i++) |
241 | marker_probe_unregister(spu_probes[i].name); | 231 | marker_probe_unregister(spu_probes[i].name, |
232 | spu_probes[i].probe_func, &spu_probes[i]); | ||
242 | 233 | ||
243 | remove_proc_entry("sputrace", NULL); | 234 | remove_proc_entry("sputrace", NULL); |
244 | kfree(sputrace_log); | 235 | kfree(sputrace_log); |
diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c index 499e07beebe2..71312324b5de 100644 --- a/arch/sh/kernel/timers/timer-cmt.c +++ b/arch/sh/kernel/timers/timer-cmt.c | |||
@@ -100,16 +100,7 @@ static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id) | |||
100 | timer_status &= ~0x80; | 100 | timer_status &= ~0x80; |
101 | ctrl_outw(timer_status, CMT_CMCSR_0); | 101 | ctrl_outw(timer_status, CMT_CMCSR_0); |
102 | 102 | ||
103 | /* | ||
104 | * Here we are in the timer irq handler. We just have irqs locally | ||
105 | * disabled but we don't know if the timer_bh is running on the other | ||
106 | * CPU. We need to avoid to SMP race with it. NOTE: we don' t need | ||
107 | * the irq version of write_lock because as just said we have irq | ||
108 | * locally disabled. -arca | ||
109 | */ | ||
110 | write_seqlock(&xtime_lock); | ||
111 | handle_timer_tick(); | 103 | handle_timer_tick(); |
112 | write_sequnlock(&xtime_lock); | ||
113 | 104 | ||
114 | return IRQ_HANDLED; | 105 | return IRQ_HANDLED; |
115 | } | 106 | } |
diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c index b7499a2a9188..463cd08f9517 100644 --- a/arch/sh/kernel/timers/timer-mtu2.c +++ b/arch/sh/kernel/timers/timer-mtu2.c | |||
@@ -100,9 +100,7 @@ static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id) | |||
100 | ctrl_outb(timer_status, MTU2_TSR_1); | 100 | ctrl_outb(timer_status, MTU2_TSR_1); |
101 | 101 | ||
102 | /* Do timer tick */ | 102 | /* Do timer tick */ |
103 | write_seqlock(&xtime_lock); | ||
104 | handle_timer_tick(); | 103 | handle_timer_tick(); |
105 | write_sequnlock(&xtime_lock); | ||
106 | 104 | ||
107 | return IRQ_HANDLED; | 105 | return IRQ_HANDLED; |
108 | } | 106 | } |
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 4cd5d7818dc6..a6a6f9823370 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c | |||
@@ -713,10 +713,10 @@ static irqreturn_t pcic_timer_handler (int irq, void *h) | |||
713 | write_seqlock(&xtime_lock); /* Dummy, to show that we remember */ | 713 | write_seqlock(&xtime_lock); /* Dummy, to show that we remember */ |
714 | pcic_clear_clock_irq(); | 714 | pcic_clear_clock_irq(); |
715 | do_timer(1); | 715 | do_timer(1); |
716 | write_sequnlock(&xtime_lock); | ||
716 | #ifndef CONFIG_SMP | 717 | #ifndef CONFIG_SMP |
717 | update_process_times(user_mode(get_irq_regs())); | 718 | update_process_times(user_mode(get_irq_regs())); |
718 | #endif | 719 | #endif |
719 | write_sequnlock(&xtime_lock); | ||
720 | return IRQ_HANDLED; | 720 | return IRQ_HANDLED; |
721 | } | 721 | } |
722 | 722 | ||
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 00b393c3a4a0..cfaf22c05bc4 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c | |||
@@ -128,10 +128,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
128 | clear_clock_irq(); | 128 | clear_clock_irq(); |
129 | 129 | ||
130 | do_timer(1); | 130 | do_timer(1); |
131 | #ifndef CONFIG_SMP | ||
132 | update_process_times(user_mode(get_irq_regs())); | ||
133 | #endif | ||
134 | |||
135 | 131 | ||
136 | /* Determine when to update the Mostek clock. */ | 132 | /* Determine when to update the Mostek clock. */ |
137 | if (ntp_synced() && | 133 | if (ntp_synced() && |
@@ -145,6 +141,9 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
145 | } | 141 | } |
146 | write_sequnlock(&xtime_lock); | 142 | write_sequnlock(&xtime_lock); |
147 | 143 | ||
144 | #ifndef CONFIG_SMP | ||
145 | update_process_times(user_mode(get_irq_regs())); | ||
146 | #endif | ||
148 | return IRQ_HANDLED; | 147 | return IRQ_HANDLED; |
149 | } | 148 | } |
150 | 149 | ||
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c index 32dd62b36ff7..cbdf9bacc575 100644 --- a/arch/x86/kernel/efi.c +++ b/arch/x86/kernel/efi.c | |||
@@ -384,9 +384,6 @@ static void __init runtime_code_page_mkexec(void) | |||
384 | efi_memory_desc_t *md; | 384 | efi_memory_desc_t *md; |
385 | void *p; | 385 | void *p; |
386 | 386 | ||
387 | if (!(__supported_pte_mask & _PAGE_NX)) | ||
388 | return; | ||
389 | |||
390 | /* Make EFI runtime service code area executable */ | 387 | /* Make EFI runtime service code area executable */ |
391 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | 388 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
392 | md = p; | 389 | md = p; |
@@ -428,9 +425,6 @@ void __init efi_enter_virtual_mode(void) | |||
428 | else | 425 | else |
429 | va = efi_ioremap(md->phys_addr, size); | 426 | va = efi_ioremap(md->phys_addr, size); |
430 | 427 | ||
431 | if (md->attribute & EFI_MEMORY_WB) | ||
432 | set_memory_uc(md->virt_addr, size); | ||
433 | |||
434 | md->virt_addr = (u64) (unsigned long) va; | 428 | md->virt_addr = (u64) (unsigned long) va; |
435 | 429 | ||
436 | if (!va) { | 430 | if (!va) { |
@@ -439,6 +433,9 @@ void __init efi_enter_virtual_mode(void) | |||
439 | continue; | 433 | continue; |
440 | } | 434 | } |
441 | 435 | ||
436 | if (!(md->attribute & EFI_MEMORY_WB)) | ||
437 | set_memory_uc(md->virt_addr, size); | ||
438 | |||
442 | systab = (u64) (unsigned long) efi_phys.systab; | 439 | systab = (u64) (unsigned long) efi_phys.systab; |
443 | if (md->phys_addr <= systab && systab < end) { | 440 | if (md->phys_addr <= systab && systab < end) { |
444 | systab += md->virt_addr - md->phys_addr; | 441 | systab += md->virt_addr - md->phys_addr; |
@@ -476,7 +473,8 @@ void __init efi_enter_virtual_mode(void) | |||
476 | efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; | 473 | efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; |
477 | efi.reset_system = virt_efi_reset_system; | 474 | efi.reset_system = virt_efi_reset_system; |
478 | efi.set_virtual_address_map = virt_efi_set_virtual_address_map; | 475 | efi.set_virtual_address_map = virt_efi_set_virtual_address_map; |
479 | runtime_code_page_mkexec(); | 476 | if (__supported_pte_mask & _PAGE_NX) |
477 | runtime_code_page_mkexec(); | ||
480 | early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); | 478 | early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); |
481 | memmap.map = NULL; | 479 | memmap.map = NULL; |
482 | } | 480 | } |
diff --git a/arch/x86/kernel/efi_64.c b/arch/x86/kernel/efi_64.c index 09d5c2330934..d143a1e76b30 100644 --- a/arch/x86/kernel/efi_64.c +++ b/arch/x86/kernel/efi_64.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <asm/tlbflush.h> | 35 | #include <asm/tlbflush.h> |
36 | #include <asm/proto.h> | 36 | #include <asm/proto.h> |
37 | #include <asm/efi.h> | 37 | #include <asm/efi.h> |
38 | #include <asm/cacheflush.h> | ||
38 | 39 | ||
39 | static pgd_t save_pgd __initdata; | 40 | static pgd_t save_pgd __initdata; |
40 | static unsigned long efi_flags __initdata; | 41 | static unsigned long efi_flags __initdata; |
@@ -43,22 +44,15 @@ static void __init early_mapping_set_exec(unsigned long start, | |||
43 | unsigned long end, | 44 | unsigned long end, |
44 | int executable) | 45 | int executable) |
45 | { | 46 | { |
46 | pte_t *kpte; | 47 | unsigned long num_pages; |
47 | unsigned int level; | 48 | |
48 | 49 | start &= PMD_MASK; | |
49 | while (start < end) { | 50 | end = (end + PMD_SIZE - 1) & PMD_MASK; |
50 | kpte = lookup_address((unsigned long)__va(start), &level); | 51 | num_pages = (end - start) >> PAGE_SHIFT; |
51 | BUG_ON(!kpte); | 52 | if (executable) |
52 | if (executable) | 53 | set_memory_x((unsigned long)__va(start), num_pages); |
53 | set_pte(kpte, pte_mkexec(*kpte)); | 54 | else |
54 | else | 55 | set_memory_nx((unsigned long)__va(start), num_pages); |
55 | set_pte(kpte, __pte((pte_val(*kpte) | _PAGE_NX) & \ | ||
56 | __supported_pte_mask)); | ||
57 | if (level == PG_LEVEL_4K) | ||
58 | start = (start + PAGE_SIZE) & PAGE_MASK; | ||
59 | else | ||
60 | start = (start + PMD_SIZE) & PMD_MASK; | ||
61 | } | ||
62 | } | 56 | } |
63 | 57 | ||
64 | static void __init early_runtime_code_mapping_set_exec(int executable) | 58 | static void __init early_runtime_code_mapping_set_exec(int executable) |
@@ -74,7 +68,7 @@ static void __init early_runtime_code_mapping_set_exec(int executable) | |||
74 | md = p; | 68 | md = p; |
75 | if (md->type == EFI_RUNTIME_SERVICES_CODE) { | 69 | if (md->type == EFI_RUNTIME_SERVICES_CODE) { |
76 | unsigned long end; | 70 | unsigned long end; |
77 | end = md->phys_addr + (md->num_pages << PAGE_SHIFT); | 71 | end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT); |
78 | early_mapping_set_exec(md->phys_addr, end, executable); | 72 | early_mapping_set_exec(md->phys_addr, end, executable); |
79 | } | 73 | } |
80 | } | 74 | } |
@@ -84,8 +78,8 @@ void __init efi_call_phys_prelog(void) | |||
84 | { | 78 | { |
85 | unsigned long vaddress; | 79 | unsigned long vaddress; |
86 | 80 | ||
87 | local_irq_save(efi_flags); | ||
88 | early_runtime_code_mapping_set_exec(1); | 81 | early_runtime_code_mapping_set_exec(1); |
82 | local_irq_save(efi_flags); | ||
89 | vaddress = (unsigned long)__va(0x0UL); | 83 | vaddress = (unsigned long)__va(0x0UL); |
90 | save_pgd = *pgd_offset_k(0x0UL); | 84 | save_pgd = *pgd_offset_k(0x0UL); |
91 | set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress)); | 85 | set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress)); |
@@ -98,9 +92,9 @@ void __init efi_call_phys_epilog(void) | |||
98 | * After the lock is released, the original page table is restored. | 92 | * After the lock is released, the original page table is restored. |
99 | */ | 93 | */ |
100 | set_pgd(pgd_offset_k(0x0UL), save_pgd); | 94 | set_pgd(pgd_offset_k(0x0UL), save_pgd); |
101 | early_runtime_code_mapping_set_exec(0); | ||
102 | __flush_tlb_all(); | 95 | __flush_tlb_all(); |
103 | local_irq_restore(efi_flags); | 96 | local_irq_restore(efi_flags); |
97 | early_runtime_code_mapping_set_exec(0); | ||
104 | } | 98 | } |
105 | 99 | ||
106 | void __init efi_reserve_bootmem(void) | 100 | void __init efi_reserve_bootmem(void) |
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c index ef62b07b2b48..8540abe86ade 100644 --- a/arch/x86/kernel/i8253.c +++ b/arch/x86/kernel/i8253.c | |||
@@ -95,7 +95,7 @@ static int pit_next_event(unsigned long delta, struct clock_event_device *evt) | |||
95 | * registered. This mechanism replaces the previous #ifdef LOCAL_APIC - | 95 | * registered. This mechanism replaces the previous #ifdef LOCAL_APIC - |
96 | * !using_apic_timer decisions in do_timer_interrupt_hook() | 96 | * !using_apic_timer decisions in do_timer_interrupt_hook() |
97 | */ | 97 | */ |
98 | struct clock_event_device pit_clockevent = { | 98 | static struct clock_event_device pit_clockevent = { |
99 | .name = "pit", | 99 | .name = "pit", |
100 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 100 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
101 | .set_mode = init_pit_timer, | 101 | .set_mode = init_pit_timer, |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 5818dc28167d..7fd6ac43e4a1 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -326,7 +326,7 @@ static inline void kb_wait(void) | |||
326 | } | 326 | } |
327 | } | 327 | } |
328 | 328 | ||
329 | void machine_emergency_restart(void) | 329 | static void native_machine_emergency_restart(void) |
330 | { | 330 | { |
331 | int i; | 331 | int i; |
332 | 332 | ||
@@ -376,7 +376,7 @@ void machine_emergency_restart(void) | |||
376 | } | 376 | } |
377 | } | 377 | } |
378 | 378 | ||
379 | void machine_shutdown(void) | 379 | static void native_machine_shutdown(void) |
380 | { | 380 | { |
381 | /* Stop the cpus and apics */ | 381 | /* Stop the cpus and apics */ |
382 | #ifdef CONFIG_SMP | 382 | #ifdef CONFIG_SMP |
@@ -420,7 +420,7 @@ void machine_shutdown(void) | |||
420 | #endif | 420 | #endif |
421 | } | 421 | } |
422 | 422 | ||
423 | void machine_restart(char *__unused) | 423 | static void native_machine_restart(char *__unused) |
424 | { | 424 | { |
425 | printk("machine restart\n"); | 425 | printk("machine restart\n"); |
426 | 426 | ||
@@ -429,11 +429,11 @@ void machine_restart(char *__unused) | |||
429 | machine_emergency_restart(); | 429 | machine_emergency_restart(); |
430 | } | 430 | } |
431 | 431 | ||
432 | void machine_halt(void) | 432 | static void native_machine_halt(void) |
433 | { | 433 | { |
434 | } | 434 | } |
435 | 435 | ||
436 | void machine_power_off(void) | 436 | static void native_machine_power_off(void) |
437 | { | 437 | { |
438 | if (pm_power_off) { | 438 | if (pm_power_off) { |
439 | if (!reboot_force) | 439 | if (!reboot_force) |
@@ -443,9 +443,35 @@ void machine_power_off(void) | |||
443 | } | 443 | } |
444 | 444 | ||
445 | struct machine_ops machine_ops = { | 445 | struct machine_ops machine_ops = { |
446 | .power_off = machine_power_off, | 446 | .power_off = native_machine_power_off, |
447 | .shutdown = machine_shutdown, | 447 | .shutdown = native_machine_shutdown, |
448 | .emergency_restart = machine_emergency_restart, | 448 | .emergency_restart = native_machine_emergency_restart, |
449 | .restart = machine_restart, | 449 | .restart = native_machine_restart, |
450 | .halt = machine_halt | 450 | .halt = native_machine_halt |
451 | }; | 451 | }; |
452 | |||
453 | void machine_power_off(void) | ||
454 | { | ||
455 | machine_ops.power_off(); | ||
456 | } | ||
457 | |||
458 | void machine_shutdown(void) | ||
459 | { | ||
460 | machine_ops.shutdown(); | ||
461 | } | ||
462 | |||
463 | void machine_emergency_restart(void) | ||
464 | { | ||
465 | machine_ops.emergency_restart(); | ||
466 | } | ||
467 | |||
468 | void machine_restart(char *cmd) | ||
469 | { | ||
470 | machine_ops.restart(cmd); | ||
471 | } | ||
472 | |||
473 | void machine_halt(void) | ||
474 | { | ||
475 | machine_ops.halt(); | ||
476 | } | ||
477 | |||
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index a4897a85268a..9f42d7e9c158 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
@@ -265,7 +265,9 @@ static __initdata pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] | |||
265 | 265 | ||
266 | static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) | 266 | static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) |
267 | { | 267 | { |
268 | pgd_t *pgd = &swapper_pg_dir[pgd_index(addr)]; | 268 | /* Don't assume we're using swapper_pg_dir at this point */ |
269 | pgd_t *base = __va(read_cr3()); | ||
270 | pgd_t *pgd = &base[pgd_index(addr)]; | ||
269 | pud_t *pud = pud_offset(pgd, addr); | 271 | pud_t *pud = pud_offset(pgd, addr); |
270 | pmd_t *pmd = pmd_offset(pud, addr); | 272 | pmd_t *pmd = pmd_offset(pud, addr); |
271 | 273 | ||
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 440210a2277d..bd61ed13f9cf 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -275,8 +275,8 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, | |||
275 | break; | 275 | break; |
276 | #ifdef CONFIG_X86_64 | 276 | #ifdef CONFIG_X86_64 |
277 | case PG_LEVEL_1G: | 277 | case PG_LEVEL_1G: |
278 | psize = PMD_PAGE_SIZE; | 278 | psize = PUD_PAGE_SIZE; |
279 | pmask = PMD_PAGE_MASK; | 279 | pmask = PUD_PAGE_MASK; |
280 | break; | 280 | break; |
281 | #endif | 281 | #endif |
282 | default: | 282 | default: |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index de647bc6e74d..49e5358f481a 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -798,6 +798,10 @@ static __init void xen_pagetable_setup_start(pgd_t *base) | |||
798 | * added to the table can be prepared properly for Xen. | 798 | * added to the table can be prepared properly for Xen. |
799 | */ | 799 | */ |
800 | xen_write_cr3(__pa(base)); | 800 | xen_write_cr3(__pa(base)); |
801 | |||
802 | /* Unpin initial Xen pagetable */ | ||
803 | pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, | ||
804 | PFN_DOWN(__pa(xen_start_info->pt_base))); | ||
801 | } | 805 | } |
802 | 806 | ||
803 | static __init void xen_pagetable_setup_done(pgd_t *base) | 807 | static __init void xen_pagetable_setup_done(pgd_t *base) |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 34b3386dedca..15e602377655 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -623,7 +623,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) | |||
623 | 623 | ||
624 | acpi_status | 624 | acpi_status |
625 | acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, | 625 | acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, |
626 | void *value, u32 width) | 626 | u32 *value, u32 width) |
627 | { | 627 | { |
628 | int result, size; | 628 | int result, size; |
629 | 629 | ||
@@ -689,7 +689,6 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */ | |||
689 | acpi_status status; | 689 | acpi_status status; |
690 | unsigned long temp; | 690 | unsigned long temp; |
691 | acpi_object_type type; | 691 | acpi_object_type type; |
692 | u8 tu8; | ||
693 | 692 | ||
694 | acpi_get_parent(chandle, &handle); | 693 | acpi_get_parent(chandle, &handle); |
695 | if (handle != rhandle) { | 694 | if (handle != rhandle) { |
@@ -704,6 +703,7 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */ | |||
704 | acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, | 703 | acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, |
705 | &temp); | 704 | &temp); |
706 | if (ACPI_SUCCESS(status)) { | 705 | if (ACPI_SUCCESS(status)) { |
706 | u32 val; | ||
707 | pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp)); | 707 | pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp)); |
708 | pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp)); | 708 | pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp)); |
709 | 709 | ||
@@ -712,24 +712,24 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */ | |||
712 | 712 | ||
713 | /* any nicer way to get bus number of bridge ? */ | 713 | /* any nicer way to get bus number of bridge ? */ |
714 | status = | 714 | status = |
715 | acpi_os_read_pci_configuration(pci_id, 0x0e, &tu8, | 715 | acpi_os_read_pci_configuration(pci_id, 0x0e, &val, |
716 | 8); | 716 | 8); |
717 | if (ACPI_SUCCESS(status) | 717 | if (ACPI_SUCCESS(status) |
718 | && ((tu8 & 0x7f) == 1 || (tu8 & 0x7f) == 2)) { | 718 | && ((val & 0x7f) == 1 || (val & 0x7f) == 2)) { |
719 | status = | 719 | status = |
720 | acpi_os_read_pci_configuration(pci_id, 0x18, | 720 | acpi_os_read_pci_configuration(pci_id, 0x18, |
721 | &tu8, 8); | 721 | &val, 8); |
722 | if (!ACPI_SUCCESS(status)) { | 722 | if (!ACPI_SUCCESS(status)) { |
723 | /* Certainly broken... FIX ME */ | 723 | /* Certainly broken... FIX ME */ |
724 | return; | 724 | return; |
725 | } | 725 | } |
726 | *is_bridge = 1; | 726 | *is_bridge = 1; |
727 | pci_id->bus = tu8; | 727 | pci_id->bus = val; |
728 | status = | 728 | status = |
729 | acpi_os_read_pci_configuration(pci_id, 0x19, | 729 | acpi_os_read_pci_configuration(pci_id, 0x19, |
730 | &tu8, 8); | 730 | &val, 8); |
731 | if (ACPI_SUCCESS(status)) { | 731 | if (ACPI_SUCCESS(status)) { |
732 | *bus_number = tu8; | 732 | *bus_number = val; |
733 | } | 733 | } |
734 | } else | 734 | } else |
735 | *is_bridge = 0; | 735 | *is_bridge = 0; |
diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c index 457ed3d3f51c..efacc9f8bfe3 100644 --- a/drivers/acpi/wmi.c +++ b/drivers/acpi/wmi.c | |||
@@ -247,7 +247,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out) | |||
247 | block = &wblock->gblock; | 247 | block = &wblock->gblock; |
248 | handle = wblock->handle; | 248 | handle = wblock->handle; |
249 | 249 | ||
250 | if (!block->flags & ACPI_WMI_METHOD) | 250 | if (!(block->flags & ACPI_WMI_METHOD)) |
251 | return AE_BAD_DATA; | 251 | return AE_BAD_DATA; |
252 | 252 | ||
253 | if (block->instance_count < instance) | 253 | if (block->instance_count < instance) |
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c index 379cbdad4921..9df08105f4f3 100644 --- a/drivers/char/drm/i830_dma.c +++ b/drivers/char/drm/i830_dma.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include "i830_drm.h" | 36 | #include "i830_drm.h" |
37 | #include "i830_drv.h" | 37 | #include "i830_drv.h" |
38 | #include <linux/interrupt.h> /* For task queue support */ | 38 | #include <linux/interrupt.h> /* For task queue support */ |
39 | #include <linux/pagemap.h> /* For FASTCALL on unlock_page() */ | 39 | #include <linux/pagemap.h> |
40 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
41 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
42 | 42 | ||
diff --git a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig index 00b8a84b0319..ffa0efce0aed 100644 --- a/drivers/char/pcmcia/Kconfig +++ b/drivers/char/pcmcia/Kconfig | |||
@@ -45,7 +45,7 @@ config CARDMAN_4040 | |||
45 | 45 | ||
46 | config IPWIRELESS | 46 | config IPWIRELESS |
47 | tristate "IPWireless 3G UMTS PCMCIA card support" | 47 | tristate "IPWireless 3G UMTS PCMCIA card support" |
48 | depends on PCMCIA | 48 | depends on PCMCIA && NETDEVICES |
49 | select PPP | 49 | select PPP |
50 | help | 50 | help |
51 | This is a driver for 3G UMTS PCMCIA card from IPWireless company. In | 51 | This is a driver for 3G UMTS PCMCIA card from IPWireless company. In |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index edc057f5cdcc..2928ef228101 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -124,7 +124,7 @@ enum dm_raid1_error { | |||
124 | struct mirror { | 124 | struct mirror { |
125 | struct mirror_set *ms; | 125 | struct mirror_set *ms; |
126 | atomic_t error_count; | 126 | atomic_t error_count; |
127 | uint32_t error_type; | 127 | unsigned long error_type; |
128 | struct dm_dev *dev; | 128 | struct dm_dev *dev; |
129 | sector_t offset; | 129 | sector_t offset; |
130 | }; | 130 | }; |
diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c index f55b71a4337d..4fb24215bd95 100644 --- a/drivers/memstick/host/tifm_ms.c +++ b/drivers/memstick/host/tifm_ms.c | |||
@@ -282,7 +282,7 @@ static int tifm_ms_issue_cmd(struct tifm_ms *host) | |||
282 | 282 | ||
283 | writel(TIFM_MS_SYS_LATCH | 283 | writel(TIFM_MS_SYS_LATCH |
284 | | readl(sock->addr + SOCK_MS_SYSTEM), | 284 | | readl(sock->addr + SOCK_MS_SYSTEM), |
285 | sock + SOCK_MS_SYSTEM); | 285 | sock->addr + SOCK_MS_SYSTEM); |
286 | writel(0, sock->addr + SOCK_MS_DATA); | 286 | writel(0, sock->addr + SOCK_MS_DATA); |
287 | dev_dbg(&sock->dev, "writing %x\n", 0); | 287 | dev_dbg(&sock->dev, "writing %x\n", 0); |
288 | 288 | ||
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 425f60c21fdd..bfda731696f7 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -1470,9 +1470,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1470 | if (mpt_debug_level) | 1470 | if (mpt_debug_level) |
1471 | printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level); | 1471 | printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level); |
1472 | 1472 | ||
1473 | if (pci_enable_device(pdev)) | ||
1474 | return r; | ||
1475 | |||
1476 | ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); | 1473 | ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); |
1477 | if (ioc == NULL) { | 1474 | if (ioc == NULL) { |
1478 | printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); | 1475 | printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); |
@@ -1482,6 +1479,20 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1482 | ioc->id = mpt_ids++; | 1479 | ioc->id = mpt_ids++; |
1483 | sprintf(ioc->name, "ioc%d", ioc->id); | 1480 | sprintf(ioc->name, "ioc%d", ioc->id); |
1484 | 1481 | ||
1482 | ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
1483 | if (pci_enable_device_mem(pdev)) { | ||
1484 | kfree(ioc); | ||
1485 | printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() " | ||
1486 | "failed\n", ioc->name); | ||
1487 | return r; | ||
1488 | } | ||
1489 | if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) { | ||
1490 | kfree(ioc); | ||
1491 | printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with " | ||
1492 | "MEM failed\n", ioc->name); | ||
1493 | return r; | ||
1494 | } | ||
1495 | |||
1485 | dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name)); | 1496 | dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name)); |
1486 | 1497 | ||
1487 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { | 1498 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { |
@@ -1658,6 +1669,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1658 | ioc->active = 0; | 1669 | ioc->active = 0; |
1659 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); | 1670 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); |
1660 | 1671 | ||
1672 | /* Set IOC ptr in the pcidev's driver data. */ | ||
1673 | pci_set_drvdata(ioc->pcidev, ioc); | ||
1674 | |||
1661 | /* Set lookup ptr. */ | 1675 | /* Set lookup ptr. */ |
1662 | list_add_tail(&ioc->list, &ioc_list); | 1676 | list_add_tail(&ioc->list, &ioc_list); |
1663 | 1677 | ||
@@ -1791,6 +1805,7 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state) | |||
1791 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); | 1805 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); |
1792 | 1806 | ||
1793 | pci_disable_device(pdev); | 1807 | pci_disable_device(pdev); |
1808 | pci_release_selected_regions(pdev, ioc->bars); | ||
1794 | pci_set_power_state(pdev, device_state); | 1809 | pci_set_power_state(pdev, device_state); |
1795 | 1810 | ||
1796 | return 0; | 1811 | return 0; |
@@ -1807,7 +1822,6 @@ mpt_resume(struct pci_dev *pdev) | |||
1807 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); | 1822 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); |
1808 | u32 device_state = pdev->current_state; | 1823 | u32 device_state = pdev->current_state; |
1809 | int recovery_state; | 1824 | int recovery_state; |
1810 | int err; | ||
1811 | 1825 | ||
1812 | printk(MYIOC_s_INFO_FMT | 1826 | printk(MYIOC_s_INFO_FMT |
1813 | "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n", | 1827 | "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n", |
@@ -1815,9 +1829,18 @@ mpt_resume(struct pci_dev *pdev) | |||
1815 | 1829 | ||
1816 | pci_set_power_state(pdev, 0); | 1830 | pci_set_power_state(pdev, 0); |
1817 | pci_restore_state(pdev); | 1831 | pci_restore_state(pdev); |
1818 | err = pci_enable_device(pdev); | 1832 | if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) { |
1819 | if (err) | 1833 | ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM | |
1820 | return err; | 1834 | IORESOURCE_IO); |
1835 | if (pci_enable_device(pdev)) | ||
1836 | return 0; | ||
1837 | } else { | ||
1838 | ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
1839 | if (pci_enable_device_mem(pdev)) | ||
1840 | return 0; | ||
1841 | } | ||
1842 | if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) | ||
1843 | return 0; | ||
1821 | 1844 | ||
1822 | /* enable interrupts */ | 1845 | /* enable interrupts */ |
1823 | CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); | 1846 | CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); |
@@ -1878,6 +1901,7 @@ mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase) | |||
1878 | * -2 if READY but IOCFacts Failed | 1901 | * -2 if READY but IOCFacts Failed |
1879 | * -3 if READY but PrimeIOCFifos Failed | 1902 | * -3 if READY but PrimeIOCFifos Failed |
1880 | * -4 if READY but IOCInit Failed | 1903 | * -4 if READY but IOCInit Failed |
1904 | * -5 if failed to enable_device and/or request_selected_regions | ||
1881 | */ | 1905 | */ |
1882 | static int | 1906 | static int |
1883 | mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | 1907 | mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) |
@@ -1976,6 +2000,18 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | |||
1976 | } | 2000 | } |
1977 | } | 2001 | } |
1978 | 2002 | ||
2003 | if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) && | ||
2004 | (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) { | ||
2005 | pci_release_selected_regions(ioc->pcidev, ioc->bars); | ||
2006 | ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM | | ||
2007 | IORESOURCE_IO); | ||
2008 | if (pci_enable_device(ioc->pcidev)) | ||
2009 | return -5; | ||
2010 | if (pci_request_selected_regions(ioc->pcidev, ioc->bars, | ||
2011 | "mpt")) | ||
2012 | return -5; | ||
2013 | } | ||
2014 | |||
1979 | /* | 2015 | /* |
1980 | * Device is reset now. It must have de-asserted the interrupt line | 2016 | * Device is reset now. It must have de-asserted the interrupt line |
1981 | * (if it was asserted) and it should be safe to register for the | 2017 | * (if it was asserted) and it should be safe to register for the |
@@ -1999,7 +2035,6 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | |||
1999 | irq_allocated = 1; | 2035 | irq_allocated = 1; |
2000 | ioc->pci_irq = ioc->pcidev->irq; | 2036 | ioc->pci_irq = ioc->pcidev->irq; |
2001 | pci_set_master(ioc->pcidev); /* ?? */ | 2037 | pci_set_master(ioc->pcidev); /* ?? */ |
2002 | pci_set_drvdata(ioc->pcidev, ioc); | ||
2003 | dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt " | 2038 | dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt " |
2004 | "%d\n", ioc->name, ioc->pcidev->irq)); | 2039 | "%d\n", ioc->name, ioc->pcidev->irq)); |
2005 | } | 2040 | } |
@@ -2381,6 +2416,9 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) | |||
2381 | ioc->memmap = NULL; | 2416 | ioc->memmap = NULL; |
2382 | } | 2417 | } |
2383 | 2418 | ||
2419 | pci_disable_device(ioc->pcidev); | ||
2420 | pci_release_selected_regions(ioc->pcidev, ioc->bars); | ||
2421 | |||
2384 | #if defined(CONFIG_MTRR) && 0 | 2422 | #if defined(CONFIG_MTRR) && 0 |
2385 | if (ioc->mtrr_reg > 0) { | 2423 | if (ioc->mtrr_reg > 0) { |
2386 | mtrr_del(ioc->mtrr_reg, 0, 0); | 2424 | mtrr_del(ioc->mtrr_reg, 0, 0); |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index b49b706c0020..d83ea96fe135 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -629,6 +629,7 @@ typedef struct _MPT_ADAPTER | |||
629 | dma_addr_t HostPageBuffer_dma; | 629 | dma_addr_t HostPageBuffer_dma; |
630 | int mtrr_reg; | 630 | int mtrr_reg; |
631 | struct pci_dev *pcidev; /* struct pci_dev pointer */ | 631 | struct pci_dev *pcidev; /* struct pci_dev pointer */ |
632 | int bars; /* bitmask of BAR's that must be configured */ | ||
632 | u8 __iomem *memmap; /* mmap address */ | 633 | u8 __iomem *memmap; /* mmap address */ |
633 | struct Scsi_Host *sh; /* Scsi Host pointer */ | 634 | struct Scsi_Host *sh; /* Scsi Host pointer */ |
634 | SpiCfgData spi_data; /* Scsi config. data */ | 635 | SpiCfgData spi_data; /* Scsi config. data */ |
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 238628d3a854..d76d37bcb9cc 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -1768,7 +1768,7 @@ static int parport_PS2_supported(struct parport *pb) | |||
1768 | } | 1768 | } |
1769 | 1769 | ||
1770 | #ifdef CONFIG_PARPORT_PC_FIFO | 1770 | #ifdef CONFIG_PARPORT_PC_FIFO |
1771 | static int __devinit parport_ECP_supported(struct parport *pb) | 1771 | static int parport_ECP_supported(struct parport *pb) |
1772 | { | 1772 | { |
1773 | int i; | 1773 | int i; |
1774 | int config, configb; | 1774 | int config, configb; |
@@ -1992,7 +1992,7 @@ static int parport_ECPEPP_supported(struct parport *pb) | |||
1992 | /* Don't bother probing for modes we know we won't use. */ | 1992 | /* Don't bother probing for modes we know we won't use. */ |
1993 | static int __devinit parport_PS2_supported(struct parport *pb) { return 0; } | 1993 | static int __devinit parport_PS2_supported(struct parport *pb) { return 0; } |
1994 | #ifdef CONFIG_PARPORT_PC_FIFO | 1994 | #ifdef CONFIG_PARPORT_PC_FIFO |
1995 | static int __devinit parport_ECP_supported(struct parport *pb) { return 0; } | 1995 | static int parport_ECP_supported(struct parport *pb) { return 0; } |
1996 | #endif | 1996 | #endif |
1997 | static int __devinit parport_EPP_supported(struct parport *pb) { return 0; } | 1997 | static int __devinit parport_EPP_supported(struct parport *pb) { return 0; } |
1998 | static int __devinit parport_ECPEPP_supported(struct parport *pb){return 0;} | 1998 | static int __devinit parport_ECPEPP_supported(struct parport *pb){return 0;} |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a5f0aaaf0dd4..a7a0813b24cb 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -722,7 +722,7 @@ config SCSI_FD_MCS | |||
722 | 722 | ||
723 | config SCSI_GDTH | 723 | config SCSI_GDTH |
724 | tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support" | 724 | tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support" |
725 | depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API && PCI_LEGACY | 725 | depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API |
726 | ---help--- | 726 | ---help--- |
727 | Formerly called GDT SCSI Disk Array Controller Support. | 727 | Formerly called GDT SCSI Disk Array Controller Support. |
728 | 728 | ||
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index bfd0e64964ac..c05092fd3a9d 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -144,51 +144,77 @@ static char *aac_get_status_string(u32 status); | |||
144 | */ | 144 | */ |
145 | 145 | ||
146 | static int nondasd = -1; | 146 | static int nondasd = -1; |
147 | static int aac_cache = 0; | 147 | static int aac_cache; |
148 | static int dacmode = -1; | 148 | static int dacmode = -1; |
149 | 149 | int aac_msi; | |
150 | int aac_commit = -1; | 150 | int aac_commit = -1; |
151 | int startup_timeout = 180; | 151 | int startup_timeout = 180; |
152 | int aif_timeout = 120; | 152 | int aif_timeout = 120; |
153 | 153 | ||
154 | module_param(nondasd, int, S_IRUGO|S_IWUSR); | 154 | module_param(nondasd, int, S_IRUGO|S_IWUSR); |
155 | MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on"); | 155 | MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices." |
156 | " 0=off, 1=on"); | ||
156 | module_param_named(cache, aac_cache, int, S_IRUGO|S_IWUSR); | 157 | module_param_named(cache, aac_cache, int, S_IRUGO|S_IWUSR); |
157 | MODULE_PARM_DESC(cache, "Disable Queue Flush commands:\n\tbit 0 - Disable FUA in WRITE SCSI commands\n\tbit 1 - Disable SYNCHRONIZE_CACHE SCSI command\n\tbit 2 - Disable only if Battery not protecting Cache"); | 158 | MODULE_PARM_DESC(cache, "Disable Queue Flush commands:\n" |
159 | "\tbit 0 - Disable FUA in WRITE SCSI commands\n" | ||
160 | "\tbit 1 - Disable SYNCHRONIZE_CACHE SCSI command\n" | ||
161 | "\tbit 2 - Disable only if Battery not protecting Cache"); | ||
158 | module_param(dacmode, int, S_IRUGO|S_IWUSR); | 162 | module_param(dacmode, int, S_IRUGO|S_IWUSR); |
159 | MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on"); | 163 | MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC." |
164 | " 0=off, 1=on"); | ||
160 | module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR); | 165 | module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR); |
161 | MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on"); | 166 | MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the" |
167 | " adapter for foreign arrays.\n" | ||
168 | "This is typically needed in systems that do not have a BIOS." | ||
169 | " 0=off, 1=on"); | ||
170 | module_param_named(msi, aac_msi, int, S_IRUGO|S_IWUSR); | ||
171 | MODULE_PARM_DESC(msi, "IRQ handling." | ||
172 | " 0=PIC(default), 1=MSI, 2=MSI-X(unsupported, uses MSI)"); | ||
162 | module_param(startup_timeout, int, S_IRUGO|S_IWUSR); | 173 | module_param(startup_timeout, int, S_IRUGO|S_IWUSR); |
163 | MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for adapter to have it's kernel up and\nrunning. This is typically adjusted for large systems that do not have a BIOS."); | 174 | MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for" |
175 | " adapter to have it's kernel up and\n" | ||
176 | "running. This is typically adjusted for large systems that do not" | ||
177 | " have a BIOS."); | ||
164 | module_param(aif_timeout, int, S_IRUGO|S_IWUSR); | 178 | module_param(aif_timeout, int, S_IRUGO|S_IWUSR); |
165 | MODULE_PARM_DESC(aif_timeout, "The duration of time in seconds to wait for applications to pick up AIFs before\nderegistering them. This is typically adjusted for heavily burdened systems."); | 179 | MODULE_PARM_DESC(aif_timeout, "The duration of time in seconds to wait for" |
180 | " applications to pick up AIFs before\n" | ||
181 | "deregistering them. This is typically adjusted for heavily burdened" | ||
182 | " systems."); | ||
166 | 183 | ||
167 | int numacb = -1; | 184 | int numacb = -1; |
168 | module_param(numacb, int, S_IRUGO|S_IWUSR); | 185 | module_param(numacb, int, S_IRUGO|S_IWUSR); |
169 | MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control blocks (FIB) allocated. Valid values are 512 and down. Default is to use suggestion from Firmware."); | 186 | MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control" |
187 | " blocks (FIB) allocated. Valid values are 512 and down. Default is" | ||
188 | " to use suggestion from Firmware."); | ||
170 | 189 | ||
171 | int acbsize = -1; | 190 | int acbsize = -1; |
172 | module_param(acbsize, int, S_IRUGO|S_IWUSR); | 191 | module_param(acbsize, int, S_IRUGO|S_IWUSR); |
173 | MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512, 2048, 4096 and 8192. Default is to use suggestion from Firmware."); | 192 | MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB)" |
193 | " size. Valid values are 512, 2048, 4096 and 8192. Default is to use" | ||
194 | " suggestion from Firmware."); | ||
174 | 195 | ||
175 | int update_interval = 30 * 60; | 196 | int update_interval = 30 * 60; |
176 | module_param(update_interval, int, S_IRUGO|S_IWUSR); | 197 | module_param(update_interval, int, S_IRUGO|S_IWUSR); |
177 | MODULE_PARM_DESC(update_interval, "Interval in seconds between time sync updates issued to adapter."); | 198 | MODULE_PARM_DESC(update_interval, "Interval in seconds between time sync" |
199 | " updates issued to adapter."); | ||
178 | 200 | ||
179 | int check_interval = 24 * 60 * 60; | 201 | int check_interval = 24 * 60 * 60; |
180 | module_param(check_interval, int, S_IRUGO|S_IWUSR); | 202 | module_param(check_interval, int, S_IRUGO|S_IWUSR); |
181 | MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health checks."); | 203 | MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health" |
204 | " checks."); | ||
182 | 205 | ||
183 | int aac_check_reset = 1; | 206 | int aac_check_reset = 1; |
184 | module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR); | 207 | module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR); |
185 | MODULE_PARM_DESC(aac_check_reset, "If adapter fails health check, reset the adapter. a value of -1 forces the reset to adapters programmed to ignore it."); | 208 | MODULE_PARM_DESC(aac_check_reset, "If adapter fails health check, reset the" |
209 | " adapter. a value of -1 forces the reset to adapters programmed to" | ||
210 | " ignore it."); | ||
186 | 211 | ||
187 | int expose_physicals = -1; | 212 | int expose_physicals = -1; |
188 | module_param(expose_physicals, int, S_IRUGO|S_IWUSR); | 213 | module_param(expose_physicals, int, S_IRUGO|S_IWUSR); |
189 | MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on"); | 214 | MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays." |
215 | " -1=protect 0=off, 1=on"); | ||
190 | 216 | ||
191 | int aac_reset_devices = 0; | 217 | int aac_reset_devices; |
192 | module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR); | 218 | module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR); |
193 | MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization."); | 219 | MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization."); |
194 | 220 | ||
@@ -1315,7 +1341,7 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1315 | (int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid), | 1341 | (int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid), |
1316 | dev->supplement_adapter_info.VpdInfo.Tsid); | 1342 | dev->supplement_adapter_info.VpdInfo.Tsid); |
1317 | } | 1343 | } |
1318 | if (!aac_check_reset || ((aac_check_reset != 1) && | 1344 | if (!aac_check_reset || ((aac_check_reset == 1) && |
1319 | (dev->supplement_adapter_info.SupportedOptions2 & | 1345 | (dev->supplement_adapter_info.SupportedOptions2 & |
1320 | AAC_OPTION_IGNORE_RESET))) { | 1346 | AAC_OPTION_IGNORE_RESET))) { |
1321 | printk(KERN_INFO "%s%d: Reset Adapter Ignored\n", | 1347 | printk(KERN_INFO "%s%d: Reset Adapter Ignored\n", |
@@ -1353,13 +1379,14 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1353 | 1379 | ||
1354 | if (nondasd != -1) | 1380 | if (nondasd != -1) |
1355 | dev->nondasd_support = (nondasd!=0); | 1381 | dev->nondasd_support = (nondasd!=0); |
1356 | if(dev->nondasd_support != 0) { | 1382 | if (dev->nondasd_support && !dev->in_reset) |
1357 | printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id); | 1383 | printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id); |
1358 | } | ||
1359 | 1384 | ||
1360 | dev->dac_support = 0; | 1385 | dev->dac_support = 0; |
1361 | if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){ | 1386 | if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){ |
1362 | printk(KERN_INFO "%s%d: 64bit support enabled.\n", dev->name, dev->id); | 1387 | if (!dev->in_reset) |
1388 | printk(KERN_INFO "%s%d: 64bit support enabled.\n", | ||
1389 | dev->name, dev->id); | ||
1363 | dev->dac_support = 1; | 1390 | dev->dac_support = 1; |
1364 | } | 1391 | } |
1365 | 1392 | ||
@@ -1369,8 +1396,9 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1369 | if(dev->dac_support != 0) { | 1396 | if(dev->dac_support != 0) { |
1370 | if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) && | 1397 | if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) && |
1371 | !pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) { | 1398 | !pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) { |
1372 | printk(KERN_INFO"%s%d: 64 Bit DAC enabled\n", | 1399 | if (!dev->in_reset) |
1373 | dev->name, dev->id); | 1400 | printk(KERN_INFO"%s%d: 64 Bit DAC enabled\n", |
1401 | dev->name, dev->id); | ||
1374 | } else if (!pci_set_dma_mask(dev->pdev, DMA_32BIT_MASK) && | 1402 | } else if (!pci_set_dma_mask(dev->pdev, DMA_32BIT_MASK) && |
1375 | !pci_set_consistent_dma_mask(dev->pdev, DMA_32BIT_MASK)) { | 1403 | !pci_set_consistent_dma_mask(dev->pdev, DMA_32BIT_MASK)) { |
1376 | printk(KERN_INFO"%s%d: DMA mask set failed, 64 Bit DAC disabled\n", | 1404 | printk(KERN_INFO"%s%d: DMA mask set failed, 64 Bit DAC disabled\n", |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 3195d29f2177..ace0b751c131 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -1026,6 +1026,7 @@ struct aac_dev | |||
1026 | u8 raw_io_64; | 1026 | u8 raw_io_64; |
1027 | u8 printf_enabled; | 1027 | u8 printf_enabled; |
1028 | u8 in_reset; | 1028 | u8 in_reset; |
1029 | u8 msi; | ||
1029 | }; | 1030 | }; |
1030 | 1031 | ||
1031 | #define aac_adapter_interrupt(dev) \ | 1032 | #define aac_adapter_interrupt(dev) \ |
@@ -1881,6 +1882,7 @@ extern int startup_timeout; | |||
1881 | extern int aif_timeout; | 1882 | extern int aif_timeout; |
1882 | extern int expose_physicals; | 1883 | extern int expose_physicals; |
1883 | extern int aac_reset_devices; | 1884 | extern int aac_reset_devices; |
1885 | extern int aac_msi; | ||
1884 | extern int aac_commit; | 1886 | extern int aac_commit; |
1885 | extern int update_interval; | 1887 | extern int update_interval; |
1886 | extern int check_interval; | 1888 | extern int check_interval; |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 81b36923e0ef..47434499e82b 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -1458,7 +1458,7 @@ int aac_check_health(struct aac_dev * aac) | |||
1458 | 1458 | ||
1459 | printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED); | 1459 | printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED); |
1460 | 1460 | ||
1461 | if (!aac_check_reset || ((aac_check_reset != 1) && | 1461 | if (!aac_check_reset || ((aac_check_reset == 1) && |
1462 | (aac->supplement_adapter_info.SupportedOptions2 & | 1462 | (aac->supplement_adapter_info.SupportedOptions2 & |
1463 | AAC_OPTION_IGNORE_RESET))) | 1463 | AAC_OPTION_IGNORE_RESET))) |
1464 | goto out; | 1464 | goto out; |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index e80d2a0c46af..ae5f74fb62d5 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -275,9 +275,9 @@ static const char *aac_info(struct Scsi_Host *shost) | |||
275 | 275 | ||
276 | /** | 276 | /** |
277 | * aac_get_driver_ident | 277 | * aac_get_driver_ident |
278 | * @devtype: index into lookup table | 278 | * @devtype: index into lookup table |
279 | * | 279 | * |
280 | * Returns a pointer to the entry in the driver lookup table. | 280 | * Returns a pointer to the entry in the driver lookup table. |
281 | */ | 281 | */ |
282 | 282 | ||
283 | struct aac_driver_ident* aac_get_driver_ident(int devtype) | 283 | struct aac_driver_ident* aac_get_driver_ident(int devtype) |
@@ -494,13 +494,14 @@ static int aac_change_queue_depth(struct scsi_device *sdev, int depth) | |||
494 | 494 | ||
495 | static ssize_t aac_show_raid_level(struct device *dev, struct device_attribute *attr, char *buf) | 495 | static ssize_t aac_show_raid_level(struct device *dev, struct device_attribute *attr, char *buf) |
496 | { | 496 | { |
497 | struct scsi_device * sdev = to_scsi_device(dev); | 497 | struct scsi_device *sdev = to_scsi_device(dev); |
498 | struct aac_dev *aac = (struct aac_dev *)(sdev->host->hostdata); | ||
498 | if (sdev_channel(sdev) != CONTAINER_CHANNEL) | 499 | if (sdev_channel(sdev) != CONTAINER_CHANNEL) |
499 | return snprintf(buf, PAGE_SIZE, sdev->no_uld_attach | 500 | return snprintf(buf, PAGE_SIZE, sdev->no_uld_attach |
500 | ? "Hidden\n" : "JBOD"); | 501 | ? "Hidden\n" : |
502 | ((aac->jbod && (sdev->type == TYPE_DISK)) ? "JBOD\n" : "")); | ||
501 | return snprintf(buf, PAGE_SIZE, "%s\n", | 503 | return snprintf(buf, PAGE_SIZE, "%s\n", |
502 | get_container_type(((struct aac_dev *)(sdev->host->hostdata)) | 504 | get_container_type(aac->fsa_dev[sdev_id(sdev)].type)); |
503 | ->fsa_dev[sdev_id(sdev)].type)); | ||
504 | } | 505 | } |
505 | 506 | ||
506 | static struct device_attribute aac_raid_level_attr = { | 507 | static struct device_attribute aac_raid_level_attr = { |
@@ -641,7 +642,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) | |||
641 | AAC_OPTION_MU_RESET) && | 642 | AAC_OPTION_MU_RESET) && |
642 | aac_check_reset && | 643 | aac_check_reset && |
643 | ((aac_check_reset != 1) || | 644 | ((aac_check_reset != 1) || |
644 | (aac->supplement_adapter_info.SupportedOptions2 & | 645 | !(aac->supplement_adapter_info.SupportedOptions2 & |
645 | AAC_OPTION_IGNORE_RESET))) | 646 | AAC_OPTION_IGNORE_RESET))) |
646 | aac_reset_adapter(aac, 2); /* Bypass wait for command quiesce */ | 647 | aac_reset_adapter(aac, 2); /* Bypass wait for command quiesce */ |
647 | return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */ | 648 | return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */ |
@@ -860,8 +861,8 @@ ssize_t aac_show_serial_number(struct class_device *class_dev, char *buf) | |||
860 | le32_to_cpu(dev->adapter_info.serial[0])); | 861 | le32_to_cpu(dev->adapter_info.serial[0])); |
861 | if (len && | 862 | if (len && |
862 | !memcmp(&dev->supplement_adapter_info.MfgPcbaSerialNo[ | 863 | !memcmp(&dev->supplement_adapter_info.MfgPcbaSerialNo[ |
863 | sizeof(dev->supplement_adapter_info.MfgPcbaSerialNo)+2-len], | 864 | sizeof(dev->supplement_adapter_info.MfgPcbaSerialNo)-len], |
864 | buf, len)) | 865 | buf, len-1)) |
865 | len = snprintf(buf, PAGE_SIZE, "%.*s\n", | 866 | len = snprintf(buf, PAGE_SIZE, "%.*s\n", |
866 | (int)sizeof(dev->supplement_adapter_info.MfgPcbaSerialNo), | 867 | (int)sizeof(dev->supplement_adapter_info.MfgPcbaSerialNo), |
867 | dev->supplement_adapter_info.MfgPcbaSerialNo); | 868 | dev->supplement_adapter_info.MfgPcbaSerialNo); |
@@ -1004,32 +1005,32 @@ static const struct file_operations aac_cfg_fops = { | |||
1004 | 1005 | ||
1005 | static struct scsi_host_template aac_driver_template = { | 1006 | static struct scsi_host_template aac_driver_template = { |
1006 | .module = THIS_MODULE, | 1007 | .module = THIS_MODULE, |
1007 | .name = "AAC", | 1008 | .name = "AAC", |
1008 | .proc_name = AAC_DRIVERNAME, | 1009 | .proc_name = AAC_DRIVERNAME, |
1009 | .info = aac_info, | 1010 | .info = aac_info, |
1010 | .ioctl = aac_ioctl, | 1011 | .ioctl = aac_ioctl, |
1011 | #ifdef CONFIG_COMPAT | 1012 | #ifdef CONFIG_COMPAT |
1012 | .compat_ioctl = aac_compat_ioctl, | 1013 | .compat_ioctl = aac_compat_ioctl, |
1013 | #endif | 1014 | #endif |
1014 | .queuecommand = aac_queuecommand, | 1015 | .queuecommand = aac_queuecommand, |
1015 | .bios_param = aac_biosparm, | 1016 | .bios_param = aac_biosparm, |
1016 | .shost_attrs = aac_attrs, | 1017 | .shost_attrs = aac_attrs, |
1017 | .slave_configure = aac_slave_configure, | 1018 | .slave_configure = aac_slave_configure, |
1018 | .change_queue_depth = aac_change_queue_depth, | 1019 | .change_queue_depth = aac_change_queue_depth, |
1019 | .sdev_attrs = aac_dev_attrs, | 1020 | .sdev_attrs = aac_dev_attrs, |
1020 | .eh_abort_handler = aac_eh_abort, | 1021 | .eh_abort_handler = aac_eh_abort, |
1021 | .eh_host_reset_handler = aac_eh_reset, | 1022 | .eh_host_reset_handler = aac_eh_reset, |
1022 | .can_queue = AAC_NUM_IO_FIB, | 1023 | .can_queue = AAC_NUM_IO_FIB, |
1023 | .this_id = MAXIMUM_NUM_CONTAINERS, | 1024 | .this_id = MAXIMUM_NUM_CONTAINERS, |
1024 | .sg_tablesize = 16, | 1025 | .sg_tablesize = 16, |
1025 | .max_sectors = 128, | 1026 | .max_sectors = 128, |
1026 | #if (AAC_NUM_IO_FIB > 256) | 1027 | #if (AAC_NUM_IO_FIB > 256) |
1027 | .cmd_per_lun = 256, | 1028 | .cmd_per_lun = 256, |
1028 | #else | 1029 | #else |
1029 | .cmd_per_lun = AAC_NUM_IO_FIB, | 1030 | .cmd_per_lun = AAC_NUM_IO_FIB, |
1030 | #endif | 1031 | #endif |
1031 | .use_clustering = ENABLE_CLUSTERING, | 1032 | .use_clustering = ENABLE_CLUSTERING, |
1032 | .emulated = 1, | 1033 | .emulated = 1, |
1033 | }; | 1034 | }; |
1034 | 1035 | ||
1035 | static void __aac_shutdown(struct aac_dev * aac) | 1036 | static void __aac_shutdown(struct aac_dev * aac) |
@@ -1039,6 +1040,8 @@ static void __aac_shutdown(struct aac_dev * aac) | |||
1039 | aac_send_shutdown(aac); | 1040 | aac_send_shutdown(aac); |
1040 | aac_adapter_disable_int(aac); | 1041 | aac_adapter_disable_int(aac); |
1041 | free_irq(aac->pdev->irq, aac); | 1042 | free_irq(aac->pdev->irq, aac); |
1043 | if (aac->msi) | ||
1044 | pci_disable_msi(aac->pdev); | ||
1042 | } | 1045 | } |
1043 | 1046 | ||
1044 | static int __devinit aac_probe_one(struct pci_dev *pdev, | 1047 | static int __devinit aac_probe_one(struct pci_dev *pdev, |
@@ -1254,7 +1257,7 @@ static struct pci_driver aac_pci_driver = { | |||
1254 | .id_table = aac_pci_tbl, | 1257 | .id_table = aac_pci_tbl, |
1255 | .probe = aac_probe_one, | 1258 | .probe = aac_probe_one, |
1256 | .remove = __devexit_p(aac_remove_one), | 1259 | .remove = __devexit_p(aac_remove_one), |
1257 | .shutdown = aac_shutdown, | 1260 | .shutdown = aac_shutdown, |
1258 | }; | 1261 | }; |
1259 | 1262 | ||
1260 | static int __init aac_init(void) | 1263 | static int __init aac_init(void) |
@@ -1271,7 +1274,7 @@ static int __init aac_init(void) | |||
1271 | aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops); | 1274 | aac_cfg_major = register_chrdev( 0, "aac", &aac_cfg_fops); |
1272 | if (aac_cfg_major < 0) { | 1275 | if (aac_cfg_major < 0) { |
1273 | printk(KERN_WARNING | 1276 | printk(KERN_WARNING |
1274 | "aacraid: unable to register \"aac\" device.\n"); | 1277 | "aacraid: unable to register \"aac\" device.\n"); |
1275 | } | 1278 | } |
1276 | 1279 | ||
1277 | return 0; | 1280 | return 0; |
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index a08bbf1fd76c..1f18b83e1e02 100644 --- a/drivers/scsi/aacraid/rx.c +++ b/drivers/scsi/aacraid/rx.c | |||
@@ -625,8 +625,11 @@ int _aac_rx_init(struct aac_dev *dev) | |||
625 | if (aac_init_adapter(dev) == NULL) | 625 | if (aac_init_adapter(dev) == NULL) |
626 | goto error_iounmap; | 626 | goto error_iounmap; |
627 | aac_adapter_comm(dev, dev->comm_interface); | 627 | aac_adapter_comm(dev, dev->comm_interface); |
628 | if (request_irq(dev->scsi_host_ptr->irq, dev->a_ops.adapter_intr, | 628 | dev->msi = aac_msi && !pci_enable_msi(dev->pdev); |
629 | if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, | ||
629 | IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) { | 630 | IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) { |
631 | if (dev->msi) | ||
632 | pci_disable_msi(dev->pdev); | ||
630 | printk(KERN_ERR "%s%d: Interrupt unavailable.\n", | 633 | printk(KERN_ERR "%s%d: Interrupt unavailable.\n", |
631 | name, instance); | 634 | name, instance); |
632 | goto error_iounmap; | 635 | goto error_iounmap; |
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c index 85b91bc578c9..cfc3410ec073 100644 --- a/drivers/scsi/aacraid/sa.c +++ b/drivers/scsi/aacraid/sa.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/types.h> | 33 | #include <linux/types.h> |
34 | #include <linux/pci.h> | ||
34 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
35 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
36 | #include <linux/blkdev.h> | 37 | #include <linux/blkdev.h> |
@@ -385,7 +386,7 @@ int aac_sa_init(struct aac_dev *dev) | |||
385 | 386 | ||
386 | if(aac_init_adapter(dev) == NULL) | 387 | if(aac_init_adapter(dev) == NULL) |
387 | goto error_irq; | 388 | goto error_irq; |
388 | if (request_irq(dev->scsi_host_ptr->irq, dev->a_ops.adapter_intr, | 389 | if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, |
389 | IRQF_SHARED|IRQF_DISABLED, | 390 | IRQF_SHARED|IRQF_DISABLED, |
390 | "aacraid", (void *)dev ) < 0) { | 391 | "aacraid", (void *)dev ) < 0) { |
391 | printk(KERN_WARNING "%s%d: Interrupt unavailable.\n", | 392 | printk(KERN_WARNING "%s%d: Interrupt unavailable.\n", |
@@ -403,7 +404,7 @@ int aac_sa_init(struct aac_dev *dev) | |||
403 | 404 | ||
404 | error_irq: | 405 | error_irq: |
405 | aac_sa_disable_interrupt(dev); | 406 | aac_sa_disable_interrupt(dev); |
406 | free_irq(dev->scsi_host_ptr->irq, (void *)dev); | 407 | free_irq(dev->pdev->irq, (void *)dev); |
407 | 408 | ||
408 | error_iounmap: | 409 | error_iounmap: |
409 | 410 | ||
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index ccef891d642f..3c2d6888bb8c 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c | |||
@@ -566,7 +566,7 @@ typedef struct asc_dvc_var { | |||
566 | ASC_SCSI_BIT_ID_TYPE unit_not_ready; | 566 | ASC_SCSI_BIT_ID_TYPE unit_not_ready; |
567 | ASC_SCSI_BIT_ID_TYPE queue_full_or_busy; | 567 | ASC_SCSI_BIT_ID_TYPE queue_full_or_busy; |
568 | ASC_SCSI_BIT_ID_TYPE start_motor; | 568 | ASC_SCSI_BIT_ID_TYPE start_motor; |
569 | uchar overrun_buf[ASC_OVERRUN_BSIZE] __aligned(8); | 569 | uchar *overrun_buf; |
570 | dma_addr_t overrun_dma; | 570 | dma_addr_t overrun_dma; |
571 | uchar scsi_reset_wait; | 571 | uchar scsi_reset_wait; |
572 | uchar chip_no; | 572 | uchar chip_no; |
@@ -13833,6 +13833,12 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, | |||
13833 | */ | 13833 | */ |
13834 | if (ASC_NARROW_BOARD(boardp)) { | 13834 | if (ASC_NARROW_BOARD(boardp)) { |
13835 | ASC_DBG(2, "AscInitAsc1000Driver()\n"); | 13835 | ASC_DBG(2, "AscInitAsc1000Driver()\n"); |
13836 | |||
13837 | asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL); | ||
13838 | if (!asc_dvc_varp->overrun_buf) { | ||
13839 | ret = -ENOMEM; | ||
13840 | goto err_free_wide_mem; | ||
13841 | } | ||
13836 | warn_code = AscInitAsc1000Driver(asc_dvc_varp); | 13842 | warn_code = AscInitAsc1000Driver(asc_dvc_varp); |
13837 | 13843 | ||
13838 | if (warn_code || asc_dvc_varp->err_code) { | 13844 | if (warn_code || asc_dvc_varp->err_code) { |
@@ -13840,8 +13846,10 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, | |||
13840 | "warn 0x%x, error 0x%x\n", | 13846 | "warn 0x%x, error 0x%x\n", |
13841 | asc_dvc_varp->init_state, warn_code, | 13847 | asc_dvc_varp->init_state, warn_code, |
13842 | asc_dvc_varp->err_code); | 13848 | asc_dvc_varp->err_code); |
13843 | if (asc_dvc_varp->err_code) | 13849 | if (asc_dvc_varp->err_code) { |
13844 | ret = -ENODEV; | 13850 | ret = -ENODEV; |
13851 | kfree(asc_dvc_varp->overrun_buf); | ||
13852 | } | ||
13845 | } | 13853 | } |
13846 | } else { | 13854 | } else { |
13847 | if (advansys_wide_init_chip(shost)) | 13855 | if (advansys_wide_init_chip(shost)) |
@@ -13894,6 +13902,7 @@ static int advansys_release(struct Scsi_Host *shost) | |||
13894 | dma_unmap_single(board->dev, | 13902 | dma_unmap_single(board->dev, |
13895 | board->dvc_var.asc_dvc_var.overrun_dma, | 13903 | board->dvc_var.asc_dvc_var.overrun_dma, |
13896 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); | 13904 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); |
13905 | kfree(board->dvc_var.asc_dvc_var.overrun_buf); | ||
13897 | } else { | 13906 | } else { |
13898 | iounmap(board->ioremap_addr); | 13907 | iounmap(board->ioremap_addr); |
13899 | advansys_wide_free_mem(board); | 13908 | advansys_wide_free_mem(board); |
diff --git a/drivers/scsi/aic94xx/aic94xx_sas.h b/drivers/scsi/aic94xx/aic94xx_sas.h index fa7c5290257d..912e6b755f74 100644 --- a/drivers/scsi/aic94xx/aic94xx_sas.h +++ b/drivers/scsi/aic94xx/aic94xx_sas.h | |||
@@ -292,7 +292,7 @@ struct scb_header { | |||
292 | #define INITIATE_SSP_TASK 0x00 | 292 | #define INITIATE_SSP_TASK 0x00 |
293 | #define INITIATE_LONG_SSP_TASK 0x01 | 293 | #define INITIATE_LONG_SSP_TASK 0x01 |
294 | #define INITIATE_BIDIR_SSP_TASK 0x02 | 294 | #define INITIATE_BIDIR_SSP_TASK 0x02 |
295 | #define ABORT_TASK 0x03 | 295 | #define SCB_ABORT_TASK 0x03 |
296 | #define INITIATE_SSP_TMF 0x04 | 296 | #define INITIATE_SSP_TMF 0x04 |
297 | #define SSP_TARG_GET_DATA 0x05 | 297 | #define SSP_TARG_GET_DATA 0x05 |
298 | #define SSP_TARG_GET_DATA_GOOD 0x06 | 298 | #define SSP_TARG_GET_DATA_GOOD 0x06 |
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c index 87b2f6e6adfe..b52124f3d3ac 100644 --- a/drivers/scsi/aic94xx/aic94xx_tmf.c +++ b/drivers/scsi/aic94xx/aic94xx_tmf.c | |||
@@ -369,7 +369,7 @@ int asd_abort_task(struct sas_task *task) | |||
369 | return -ENOMEM; | 369 | return -ENOMEM; |
370 | scb = ascb->scb; | 370 | scb = ascb->scb; |
371 | 371 | ||
372 | scb->header.opcode = ABORT_TASK; | 372 | scb->header.opcode = SCB_ABORT_TASK; |
373 | 373 | ||
374 | switch (task->task_proto) { | 374 | switch (task->task_proto) { |
375 | case SAS_PROTOCOL_SATA: | 375 | case SAS_PROTOCOL_SATA: |
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index fb5f20284389..a715632e19d4 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c | |||
@@ -2018,6 +2018,7 @@ static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, | |||
2018 | * the upper layers to process. This would have been set | 2018 | * the upper layers to process. This would have been set |
2019 | * correctly by fas216_std_done. | 2019 | * correctly by fas216_std_done. |
2020 | */ | 2020 | */ |
2021 | scsi_eh_restore_cmnd(SCpnt, &info->ses); | ||
2021 | SCpnt->scsi_done(SCpnt); | 2022 | SCpnt->scsi_done(SCpnt); |
2022 | } | 2023 | } |
2023 | 2024 | ||
@@ -2103,23 +2104,12 @@ request_sense: | |||
2103 | if (SCpnt->cmnd[0] == REQUEST_SENSE) | 2104 | if (SCpnt->cmnd[0] == REQUEST_SENSE) |
2104 | goto done; | 2105 | goto done; |
2105 | 2106 | ||
2107 | scsi_eh_prep_cmnd(SCpnt, &info->ses, NULL, 0, ~0); | ||
2106 | fas216_log_target(info, LOG_CONNECT, SCpnt->device->id, | 2108 | fas216_log_target(info, LOG_CONNECT, SCpnt->device->id, |
2107 | "requesting sense"); | 2109 | "requesting sense"); |
2108 | memset(SCpnt->cmnd, 0, sizeof (SCpnt->cmnd)); | 2110 | init_SCp(SCpnt); |
2109 | SCpnt->cmnd[0] = REQUEST_SENSE; | ||
2110 | SCpnt->cmnd[1] = SCpnt->device->lun << 5; | ||
2111 | SCpnt->cmnd[4] = sizeof(SCpnt->sense_buffer); | ||
2112 | SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]); | ||
2113 | SCpnt->SCp.buffer = NULL; | ||
2114 | SCpnt->SCp.buffers_residual = 0; | ||
2115 | SCpnt->SCp.ptr = (char *)SCpnt->sense_buffer; | ||
2116 | SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer); | ||
2117 | SCpnt->SCp.phase = sizeof(SCpnt->sense_buffer); | ||
2118 | SCpnt->SCp.Message = 0; | 2111 | SCpnt->SCp.Message = 0; |
2119 | SCpnt->SCp.Status = 0; | 2112 | SCpnt->SCp.Status = 0; |
2120 | SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer); | ||
2121 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; | ||
2122 | SCpnt->use_sg = 0; | ||
2123 | SCpnt->tag = 0; | 2113 | SCpnt->tag = 0; |
2124 | SCpnt->host_scribble = (void *)fas216_rq_sns_done; | 2114 | SCpnt->host_scribble = (void *)fas216_rq_sns_done; |
2125 | 2115 | ||
diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h index 00e5f055afdc..3e73e264972e 100644 --- a/drivers/scsi/arm/fas216.h +++ b/drivers/scsi/arm/fas216.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #define NO_IRQ 255 | 16 | #define NO_IRQ 255 |
17 | #endif | 17 | #endif |
18 | 18 | ||
19 | #include <scsi/scsi_eh.h> | ||
20 | |||
19 | #include "queue.h" | 21 | #include "queue.h" |
20 | #include "msgqueue.h" | 22 | #include "msgqueue.h" |
21 | 23 | ||
@@ -311,6 +313,7 @@ typedef struct { | |||
311 | 313 | ||
312 | /* miscellaneous */ | 314 | /* miscellaneous */ |
313 | int internal_done; /* flag to indicate request done */ | 315 | int internal_done; /* flag to indicate request done */ |
316 | struct scsi_eh_save *ses; /* holds request sense restore info */ | ||
314 | unsigned long magic_end; | 317 | unsigned long magic_end; |
315 | } FAS216_Info; | 318 | } FAS216_Info; |
316 | 319 | ||
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index c82523908c2e..6d67f5c0eb8e 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -642,12 +642,15 @@ static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | |||
642 | *cnt, vendor, device)); | 642 | *cnt, vendor, device)); |
643 | 643 | ||
644 | pdev = NULL; | 644 | pdev = NULL; |
645 | while ((pdev = pci_find_device(vendor, device, pdev)) | 645 | while ((pdev = pci_get_device(vendor, device, pdev)) |
646 | != NULL) { | 646 | != NULL) { |
647 | if (pci_enable_device(pdev)) | 647 | if (pci_enable_device(pdev)) |
648 | continue; | 648 | continue; |
649 | if (*cnt >= MAXHA) | 649 | if (*cnt >= MAXHA) { |
650 | pci_dev_put(pdev); | ||
650 | return; | 651 | return; |
652 | } | ||
653 | |||
651 | /* GDT PCI controller found, resources are already in pdev */ | 654 | /* GDT PCI controller found, resources are already in pdev */ |
652 | pcistr[*cnt].pdev = pdev; | 655 | pcistr[*cnt].pdev = pdev; |
653 | pcistr[*cnt].irq = pdev->irq; | 656 | pcistr[*cnt].irq = pdev->irq; |
@@ -4836,6 +4839,9 @@ static int __init gdth_isa_probe_one(ulong32 isa_bios) | |||
4836 | if (error) | 4839 | if (error) |
4837 | goto out_free_coal_stat; | 4840 | goto out_free_coal_stat; |
4838 | list_add_tail(&ha->list, &gdth_instances); | 4841 | list_add_tail(&ha->list, &gdth_instances); |
4842 | |||
4843 | scsi_scan_host(shp); | ||
4844 | |||
4839 | return 0; | 4845 | return 0; |
4840 | 4846 | ||
4841 | out_free_coal_stat: | 4847 | out_free_coal_stat: |
@@ -4963,6 +4969,9 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot) | |||
4963 | if (error) | 4969 | if (error) |
4964 | goto out_free_coal_stat; | 4970 | goto out_free_coal_stat; |
4965 | list_add_tail(&ha->list, &gdth_instances); | 4971 | list_add_tail(&ha->list, &gdth_instances); |
4972 | |||
4973 | scsi_scan_host(shp); | ||
4974 | |||
4966 | return 0; | 4975 | return 0; |
4967 | 4976 | ||
4968 | out_free_ccb_phys: | 4977 | out_free_ccb_phys: |
@@ -5100,6 +5109,9 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | |||
5100 | if (error) | 5109 | if (error) |
5101 | goto out_free_coal_stat; | 5110 | goto out_free_coal_stat; |
5102 | list_add_tail(&ha->list, &gdth_instances); | 5111 | list_add_tail(&ha->list, &gdth_instances); |
5112 | |||
5113 | scsi_scan_host(shp); | ||
5114 | |||
5103 | return 0; | 5115 | return 0; |
5104 | 5116 | ||
5105 | out_free_coal_stat: | 5117 | out_free_coal_stat: |
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 83567b9755b4..2ab2d24dcc15 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -307,6 +307,7 @@ struct lpfc_vport { | |||
307 | 307 | ||
308 | uint32_t fc_nlp_cnt; /* outstanding NODELIST requests */ | 308 | uint32_t fc_nlp_cnt; /* outstanding NODELIST requests */ |
309 | uint32_t fc_rscn_id_cnt; /* count of RSCNs payloads in list */ | 309 | uint32_t fc_rscn_id_cnt; /* count of RSCNs payloads in list */ |
310 | uint32_t fc_rscn_flush; /* flag use of fc_rscn_id_list */ | ||
310 | struct lpfc_dmabuf *fc_rscn_id_list[FC_MAX_HOLD_RSCN]; | 311 | struct lpfc_dmabuf *fc_rscn_id_list[FC_MAX_HOLD_RSCN]; |
311 | struct lpfc_name fc_nodename; /* fc nodename */ | 312 | struct lpfc_name fc_nodename; /* fc nodename */ |
312 | struct lpfc_name fc_portname; /* fc portname */ | 313 | struct lpfc_name fc_portname; /* fc portname */ |
@@ -392,6 +393,13 @@ enum hba_temp_state { | |||
392 | HBA_OVER_TEMP | 393 | HBA_OVER_TEMP |
393 | }; | 394 | }; |
394 | 395 | ||
396 | enum intr_type_t { | ||
397 | NONE = 0, | ||
398 | INTx, | ||
399 | MSI, | ||
400 | MSIX, | ||
401 | }; | ||
402 | |||
395 | struct lpfc_hba { | 403 | struct lpfc_hba { |
396 | struct lpfc_sli sli; | 404 | struct lpfc_sli sli; |
397 | uint32_t sli_rev; /* SLI2 or SLI3 */ | 405 | uint32_t sli_rev; /* SLI2 or SLI3 */ |
@@ -409,7 +417,7 @@ struct lpfc_hba { | |||
409 | /* This flag is set while issuing */ | 417 | /* This flag is set while issuing */ |
410 | /* INIT_LINK mailbox command */ | 418 | /* INIT_LINK mailbox command */ |
411 | #define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */ | 419 | #define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */ |
412 | #define LS_IGNORE_ERATT 0x3 /* intr handler should ignore ERATT */ | 420 | #define LS_IGNORE_ERATT 0x4 /* intr handler should ignore ERATT */ |
413 | 421 | ||
414 | struct lpfc_sli2_slim *slim2p; | 422 | struct lpfc_sli2_slim *slim2p; |
415 | struct lpfc_dmabuf hbqslimp; | 423 | struct lpfc_dmabuf hbqslimp; |
@@ -487,6 +495,8 @@ struct lpfc_hba { | |||
487 | wait_queue_head_t *work_wait; | 495 | wait_queue_head_t *work_wait; |
488 | struct task_struct *worker_thread; | 496 | struct task_struct *worker_thread; |
489 | 497 | ||
498 | uint32_t hbq_in_use; /* HBQs in use flag */ | ||
499 | struct list_head hbqbuf_in_list; /* in-fly hbq buffer list */ | ||
490 | uint32_t hbq_count; /* Count of configured HBQs */ | 500 | uint32_t hbq_count; /* Count of configured HBQs */ |
491 | struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies */ | 501 | struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies */ |
492 | 502 | ||
@@ -555,7 +565,8 @@ struct lpfc_hba { | |||
555 | mempool_t *nlp_mem_pool; | 565 | mempool_t *nlp_mem_pool; |
556 | 566 | ||
557 | struct fc_host_statistics link_stats; | 567 | struct fc_host_statistics link_stats; |
558 | uint8_t using_msi; | 568 | enum intr_type_t intr_type; |
569 | struct msix_entry msix_entries[1]; | ||
559 | 570 | ||
560 | struct list_head port_list; | 571 | struct list_head port_list; |
561 | struct lpfc_vport *pport; /* physical lpfc_vport pointer */ | 572 | struct lpfc_vport *pport; /* physical lpfc_vport pointer */ |
@@ -595,6 +606,8 @@ struct lpfc_hba { | |||
595 | unsigned long last_completion_time; | 606 | unsigned long last_completion_time; |
596 | struct timer_list hb_tmofunc; | 607 | struct timer_list hb_tmofunc; |
597 | uint8_t hb_outstanding; | 608 | uint8_t hb_outstanding; |
609 | /* ndlp reference management */ | ||
610 | spinlock_t ndlp_lock; | ||
598 | /* | 611 | /* |
599 | * Following bit will be set for all buffer tags which are not | 612 | * Following bit will be set for all buffer tags which are not |
600 | * associated with any HBQ. | 613 | * associated with any HBQ. |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 4bae4a2ed2f1..b12a841703ca 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -1191,7 +1191,7 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport) | |||
1191 | shost = lpfc_shost_from_vport(vport); | 1191 | shost = lpfc_shost_from_vport(vport); |
1192 | spin_lock_irq(shost->host_lock); | 1192 | spin_lock_irq(shost->host_lock); |
1193 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) | 1193 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) |
1194 | if (ndlp->rport) | 1194 | if (NLP_CHK_NODE_ACT(ndlp) && ndlp->rport) |
1195 | ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo; | 1195 | ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo; |
1196 | spin_unlock_irq(shost->host_lock); | 1196 | spin_unlock_irq(shost->host_lock); |
1197 | } | 1197 | } |
@@ -1592,9 +1592,11 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255, | |||
1592 | # support this feature | 1592 | # support this feature |
1593 | # 0 = MSI disabled (default) | 1593 | # 0 = MSI disabled (default) |
1594 | # 1 = MSI enabled | 1594 | # 1 = MSI enabled |
1595 | # Value range is [0,1]. Default value is 0. | 1595 | # 2 = MSI-X enabled |
1596 | # Value range is [0,2]. Default value is 0. | ||
1596 | */ | 1597 | */ |
1597 | LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); | 1598 | LPFC_ATTR_R(use_msi, 0, 0, 2, "Use Message Signaled Interrupts (1) or " |
1599 | "MSI-X (2), if possible"); | ||
1598 | 1600 | ||
1599 | /* | 1601 | /* |
1600 | # lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware. | 1602 | # lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware. |
@@ -1946,11 +1948,13 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1946 | } | 1948 | } |
1947 | 1949 | ||
1948 | /* If HBA encountered an error attention, allow only DUMP | 1950 | /* If HBA encountered an error attention, allow only DUMP |
1949 | * mailbox command until the HBA is restarted. | 1951 | * or RESTART mailbox commands until the HBA is restarted. |
1950 | */ | 1952 | */ |
1951 | if ((phba->pport->stopped) && | 1953 | if ((phba->pport->stopped) && |
1952 | (phba->sysfs_mbox.mbox->mb.mbxCommand | 1954 | (phba->sysfs_mbox.mbox->mb.mbxCommand != |
1953 | != MBX_DUMP_MEMORY)) { | 1955 | MBX_DUMP_MEMORY && |
1956 | phba->sysfs_mbox.mbox->mb.mbxCommand != | ||
1957 | MBX_RESTART)) { | ||
1954 | sysfs_mbox_idle(phba); | 1958 | sysfs_mbox_idle(phba); |
1955 | spin_unlock_irq(&phba->hbalock); | 1959 | spin_unlock_irq(&phba->hbalock); |
1956 | return -EPERM; | 1960 | return -EPERM; |
@@ -2384,7 +2388,8 @@ lpfc_get_node_by_target(struct scsi_target *starget) | |||
2384 | spin_lock_irq(shost->host_lock); | 2388 | spin_lock_irq(shost->host_lock); |
2385 | /* Search for this, mapped, target ID */ | 2389 | /* Search for this, mapped, target ID */ |
2386 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { | 2390 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
2387 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && | 2391 | if (NLP_CHK_NODE_ACT(ndlp) && |
2392 | ndlp->nlp_state == NLP_STE_MAPPED_NODE && | ||
2388 | starget->id == ndlp->nlp_sid) { | 2393 | starget->id == ndlp->nlp_sid) { |
2389 | spin_unlock_irq(shost->host_lock); | 2394 | spin_unlock_irq(shost->host_lock); |
2390 | return ndlp; | 2395 | return ndlp; |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 50fcb7c930bc..848d97744b4d 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -53,7 +53,11 @@ void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *); | |||
53 | void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | 53 | void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); |
54 | void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | 54 | void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); |
55 | void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); | 55 | void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); |
56 | void lpfc_enqueue_node(struct lpfc_vport *, struct lpfc_nodelist *); | ||
56 | void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *); | 57 | void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *); |
58 | void lpfc_disable_node(struct lpfc_vport *, struct lpfc_nodelist *); | ||
59 | struct lpfc_nodelist *lpfc_enable_node(struct lpfc_vport *, | ||
60 | struct lpfc_nodelist *, int); | ||
57 | void lpfc_nlp_set_state(struct lpfc_vport *, struct lpfc_nodelist *, int); | 61 | void lpfc_nlp_set_state(struct lpfc_vport *, struct lpfc_nodelist *, int); |
58 | void lpfc_drop_node(struct lpfc_vport *, struct lpfc_nodelist *); | 62 | void lpfc_drop_node(struct lpfc_vport *, struct lpfc_nodelist *); |
59 | void lpfc_set_disctmo(struct lpfc_vport *); | 63 | void lpfc_set_disctmo(struct lpfc_vport *); |
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 92441ce610ed..3d0ccd9b341d 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -294,7 +294,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, | |||
294 | /* Save for completion so we can release these resources */ | 294 | /* Save for completion so we can release these resources */ |
295 | geniocb->context1 = (uint8_t *) inp; | 295 | geniocb->context1 = (uint8_t *) inp; |
296 | geniocb->context2 = (uint8_t *) outp; | 296 | geniocb->context2 = (uint8_t *) outp; |
297 | geniocb->context_un.ndlp = ndlp; | 297 | geniocb->context_un.ndlp = lpfc_nlp_get(ndlp); |
298 | 298 | ||
299 | /* Fill in payload, bp points to frame payload */ | 299 | /* Fill in payload, bp points to frame payload */ |
300 | icmd->ulpCommand = CMD_GEN_REQUEST64_CR; | 300 | icmd->ulpCommand = CMD_GEN_REQUEST64_CR; |
@@ -489,8 +489,10 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) | |||
489 | */ | 489 | */ |
490 | ndlp = lpfc_findnode_did(vport, | 490 | ndlp = lpfc_findnode_did(vport, |
491 | Did); | 491 | Did); |
492 | if (ndlp && (ndlp->nlp_type & | 492 | if (ndlp && |
493 | NLP_FCP_TARGET)) | 493 | NLP_CHK_NODE_ACT(ndlp) |
494 | && (ndlp->nlp_type & | ||
495 | NLP_FCP_TARGET)) | ||
494 | lpfc_setup_disc_node | 496 | lpfc_setup_disc_node |
495 | (vport, Did); | 497 | (vport, Did); |
496 | else if (lpfc_ns_cmd(vport, | 498 | else if (lpfc_ns_cmd(vport, |
@@ -773,7 +775,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
773 | "0267 NameServer GFF Rsp " | 775 | "0267 NameServer GFF Rsp " |
774 | "x%x Error (%d %d) Data: x%x x%x\n", | 776 | "x%x Error (%d %d) Data: x%x x%x\n", |
775 | did, irsp->ulpStatus, irsp->un.ulpWord[4], | 777 | did, irsp->ulpStatus, irsp->un.ulpWord[4], |
776 | vport->fc_flag, vport->fc_rscn_id_cnt) | 778 | vport->fc_flag, vport->fc_rscn_id_cnt); |
777 | } | 779 | } |
778 | 780 | ||
779 | /* This is a target port, unregistered port, or the GFF_ID failed */ | 781 | /* This is a target port, unregistered port, or the GFF_ID failed */ |
@@ -1064,7 +1066,8 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1064 | int rc = 0; | 1066 | int rc = 0; |
1065 | 1067 | ||
1066 | ndlp = lpfc_findnode_did(vport, NameServer_DID); | 1068 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
1067 | if (ndlp == NULL || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) { | 1069 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) |
1070 | || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) { | ||
1068 | rc=1; | 1071 | rc=1; |
1069 | goto ns_cmd_exit; | 1072 | goto ns_cmd_exit; |
1070 | } | 1073 | } |
@@ -1213,8 +1216,9 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1213 | cmpl = lpfc_cmpl_ct_cmd_rff_id; | 1216 | cmpl = lpfc_cmpl_ct_cmd_rff_id; |
1214 | break; | 1217 | break; |
1215 | } | 1218 | } |
1216 | lpfc_nlp_get(ndlp); | 1219 | /* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count |
1217 | 1220 | * to hold ndlp reference for the corresponding callback function. | |
1221 | */ | ||
1218 | if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) { | 1222 | if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) { |
1219 | /* On success, The cmpl function will free the buffers */ | 1223 | /* On success, The cmpl function will free the buffers */ |
1220 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, | 1224 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, |
@@ -1222,9 +1226,13 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1222 | cmdcode, ndlp->nlp_DID, 0); | 1226 | cmdcode, ndlp->nlp_DID, 0); |
1223 | return 0; | 1227 | return 0; |
1224 | } | 1228 | } |
1225 | |||
1226 | rc=6; | 1229 | rc=6; |
1230 | |||
1231 | /* Decrement ndlp reference count to release ndlp reference held | ||
1232 | * for the failed command's callback function. | ||
1233 | */ | ||
1227 | lpfc_nlp_put(ndlp); | 1234 | lpfc_nlp_put(ndlp); |
1235 | |||
1228 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | 1236 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); |
1229 | ns_cmd_free_bmp: | 1237 | ns_cmd_free_bmp: |
1230 | kfree(bmp); | 1238 | kfree(bmp); |
@@ -1271,6 +1279,9 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1271 | } | 1279 | } |
1272 | 1280 | ||
1273 | ndlp = lpfc_findnode_did(vport, FDMI_DID); | 1281 | ndlp = lpfc_findnode_did(vport, FDMI_DID); |
1282 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) | ||
1283 | goto fail_out; | ||
1284 | |||
1274 | if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { | 1285 | if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { |
1275 | /* FDMI rsp failed */ | 1286 | /* FDMI rsp failed */ |
1276 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 1287 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
@@ -1294,6 +1305,8 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1294 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA); | 1305 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA); |
1295 | break; | 1306 | break; |
1296 | } | 1307 | } |
1308 | |||
1309 | fail_out: | ||
1297 | lpfc_ct_free_iocb(phba, cmdiocb); | 1310 | lpfc_ct_free_iocb(phba, cmdiocb); |
1298 | return; | 1311 | return; |
1299 | } | 1312 | } |
@@ -1650,12 +1663,18 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode) | |||
1650 | bpl->tus.w = le32_to_cpu(bpl->tus.w); | 1663 | bpl->tus.w = le32_to_cpu(bpl->tus.w); |
1651 | 1664 | ||
1652 | cmpl = lpfc_cmpl_ct_cmd_fdmi; | 1665 | cmpl = lpfc_cmpl_ct_cmd_fdmi; |
1653 | lpfc_nlp_get(ndlp); | ||
1654 | 1666 | ||
1667 | /* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count | ||
1668 | * to hold ndlp reference for the corresponding callback function. | ||
1669 | */ | ||
1655 | if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP, 0)) | 1670 | if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP, 0)) |
1656 | return 0; | 1671 | return 0; |
1657 | 1672 | ||
1673 | /* Decrement ndlp reference count to release ndlp reference held | ||
1674 | * for the failed command's callback function. | ||
1675 | */ | ||
1658 | lpfc_nlp_put(ndlp); | 1676 | lpfc_nlp_put(ndlp); |
1677 | |||
1659 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | 1678 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); |
1660 | fdmi_cmd_free_bmp: | 1679 | fdmi_cmd_free_bmp: |
1661 | kfree(bmp); | 1680 | kfree(bmp); |
@@ -1698,7 +1717,7 @@ lpfc_fdmi_timeout_handler(struct lpfc_vport *vport) | |||
1698 | struct lpfc_nodelist *ndlp; | 1717 | struct lpfc_nodelist *ndlp; |
1699 | 1718 | ||
1700 | ndlp = lpfc_findnode_did(vport, FDMI_DID); | 1719 | ndlp = lpfc_findnode_did(vport, FDMI_DID); |
1701 | if (ndlp) { | 1720 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
1702 | if (init_utsname()->nodename[0] != '\0') | 1721 | if (init_utsname()->nodename[0] != '\0') |
1703 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); | 1722 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); |
1704 | else | 1723 | else |
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index cfe81c50529a..2db0b74b6fad 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -73,6 +73,12 @@ struct lpfc_nodelist { | |||
73 | uint8_t nlp_fcp_info; /* class info, bits 0-3 */ | 73 | uint8_t nlp_fcp_info; /* class info, bits 0-3 */ |
74 | #define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */ | 74 | #define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */ |
75 | 75 | ||
76 | uint16_t nlp_usg_map; /* ndlp management usage bitmap */ | ||
77 | #define NLP_USG_NODE_ACT_BIT 0x1 /* Indicate ndlp is actively used */ | ||
78 | #define NLP_USG_IACT_REQ_BIT 0x2 /* Request to inactivate ndlp */ | ||
79 | #define NLP_USG_FREE_REQ_BIT 0x4 /* Request to invoke ndlp memory free */ | ||
80 | #define NLP_USG_FREE_ACK_BIT 0x8 /* Indicate ndlp memory free invoked */ | ||
81 | |||
76 | struct timer_list nlp_delayfunc; /* Used for delayed ELS cmds */ | 82 | struct timer_list nlp_delayfunc; /* Used for delayed ELS cmds */ |
77 | struct fc_rport *rport; /* Corresponding FC transport | 83 | struct fc_rport *rport; /* Corresponding FC transport |
78 | port structure */ | 84 | port structure */ |
@@ -85,25 +91,51 @@ struct lpfc_nodelist { | |||
85 | }; | 91 | }; |
86 | 92 | ||
87 | /* Defines for nlp_flag (uint32) */ | 93 | /* Defines for nlp_flag (uint32) */ |
88 | #define NLP_PLOGI_SND 0x20 /* sent PLOGI request for this entry */ | 94 | #define NLP_PLOGI_SND 0x00000020 /* sent PLOGI request for this entry */ |
89 | #define NLP_PRLI_SND 0x40 /* sent PRLI request for this entry */ | 95 | #define NLP_PRLI_SND 0x00000040 /* sent PRLI request for this entry */ |
90 | #define NLP_ADISC_SND 0x80 /* sent ADISC request for this entry */ | 96 | #define NLP_ADISC_SND 0x00000080 /* sent ADISC request for this entry */ |
91 | #define NLP_LOGO_SND 0x100 /* sent LOGO request for this entry */ | 97 | #define NLP_LOGO_SND 0x00000100 /* sent LOGO request for this entry */ |
92 | #define NLP_RNID_SND 0x400 /* sent RNID request for this entry */ | 98 | #define NLP_RNID_SND 0x00000400 /* sent RNID request for this entry */ |
93 | #define NLP_ELS_SND_MASK 0x7e0 /* sent ELS request for this entry */ | 99 | #define NLP_ELS_SND_MASK 0x000007e0 /* sent ELS request for this entry */ |
94 | #define NLP_DEFER_RM 0x10000 /* Remove this ndlp if no longer used */ | 100 | #define NLP_DEFER_RM 0x00010000 /* Remove this ndlp if no longer used */ |
95 | #define NLP_DELAY_TMO 0x20000 /* delay timeout is running for node */ | 101 | #define NLP_DELAY_TMO 0x00020000 /* delay timeout is running for node */ |
96 | #define NLP_NPR_2B_DISC 0x40000 /* node is included in num_disc_nodes */ | 102 | #define NLP_NPR_2B_DISC 0x00040000 /* node is included in num_disc_nodes */ |
97 | #define NLP_RCV_PLOGI 0x80000 /* Rcv'ed PLOGI from remote system */ | 103 | #define NLP_RCV_PLOGI 0x00080000 /* Rcv'ed PLOGI from remote system */ |
98 | #define NLP_LOGO_ACC 0x100000 /* Process LOGO after ACC completes */ | 104 | #define NLP_LOGO_ACC 0x00100000 /* Process LOGO after ACC completes */ |
99 | #define NLP_TGT_NO_SCSIID 0x200000 /* good PRLI but no binding for scsid */ | 105 | #define NLP_TGT_NO_SCSIID 0x00200000 /* good PRLI but no binding for scsid */ |
100 | #define NLP_ACC_REGLOGIN 0x1000000 /* Issue Reg Login after successful | 106 | #define NLP_ACC_REGLOGIN 0x01000000 /* Issue Reg Login after successful |
101 | ACC */ | 107 | ACC */ |
102 | #define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from | 108 | #define NLP_NPR_ADISC 0x02000000 /* Issue ADISC when dq'ed from |
103 | NPR list */ | 109 | NPR list */ |
104 | #define NLP_RM_DFLT_RPI 0x4000000 /* need to remove leftover dflt RPI */ | 110 | #define NLP_RM_DFLT_RPI 0x04000000 /* need to remove leftover dflt RPI */ |
105 | #define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ | 111 | #define NLP_NODEV_REMOVE 0x08000000 /* Defer removal till discovery ends */ |
106 | #define NLP_TARGET_REMOVE 0x10000000 /* Target remove in process */ | 112 | #define NLP_TARGET_REMOVE 0x10000000 /* Target remove in process */ |
113 | #define NLP_SC_REQ 0x20000000 /* Target requires authentication */ | ||
114 | |||
115 | /* ndlp usage management macros */ | ||
116 | #define NLP_CHK_NODE_ACT(ndlp) (((ndlp)->nlp_usg_map \ | ||
117 | & NLP_USG_NODE_ACT_BIT) \ | ||
118 | && \ | ||
119 | !((ndlp)->nlp_usg_map \ | ||
120 | & NLP_USG_FREE_ACK_BIT)) | ||
121 | #define NLP_SET_NODE_ACT(ndlp) ((ndlp)->nlp_usg_map \ | ||
122 | |= NLP_USG_NODE_ACT_BIT) | ||
123 | #define NLP_INT_NODE_ACT(ndlp) ((ndlp)->nlp_usg_map \ | ||
124 | = NLP_USG_NODE_ACT_BIT) | ||
125 | #define NLP_CLR_NODE_ACT(ndlp) ((ndlp)->nlp_usg_map \ | ||
126 | &= ~NLP_USG_NODE_ACT_BIT) | ||
127 | #define NLP_CHK_IACT_REQ(ndlp) ((ndlp)->nlp_usg_map \ | ||
128 | & NLP_USG_IACT_REQ_BIT) | ||
129 | #define NLP_SET_IACT_REQ(ndlp) ((ndlp)->nlp_usg_map \ | ||
130 | |= NLP_USG_IACT_REQ_BIT) | ||
131 | #define NLP_CHK_FREE_REQ(ndlp) ((ndlp)->nlp_usg_map \ | ||
132 | & NLP_USG_FREE_REQ_BIT) | ||
133 | #define NLP_SET_FREE_REQ(ndlp) ((ndlp)->nlp_usg_map \ | ||
134 | |= NLP_USG_FREE_REQ_BIT) | ||
135 | #define NLP_CHK_FREE_ACK(ndlp) ((ndlp)->nlp_usg_map \ | ||
136 | & NLP_USG_FREE_ACK_BIT) | ||
137 | #define NLP_SET_FREE_ACK(ndlp) ((ndlp)->nlp_usg_map \ | ||
138 | |= NLP_USG_FREE_ACK_BIT) | ||
107 | 139 | ||
108 | /* There are 4 different double linked lists nodelist entries can reside on. | 140 | /* There are 4 different double linked lists nodelist entries can reside on. |
109 | * The Port Login (PLOGI) list and Address Discovery (ADISC) list are used | 141 | * The Port Login (PLOGI) list and Address Discovery (ADISC) list are used |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index c6b739dc6bc3..cbb68a942255 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -113,6 +113,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
113 | 113 | ||
114 | if (elsiocb == NULL) | 114 | if (elsiocb == NULL) |
115 | return NULL; | 115 | return NULL; |
116 | |||
116 | icmd = &elsiocb->iocb; | 117 | icmd = &elsiocb->iocb; |
117 | 118 | ||
118 | /* fill in BDEs for command */ | 119 | /* fill in BDEs for command */ |
@@ -134,9 +135,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
134 | if (!prsp || !prsp->virt) | 135 | if (!prsp || !prsp->virt) |
135 | goto els_iocb_free_prsp_exit; | 136 | goto els_iocb_free_prsp_exit; |
136 | INIT_LIST_HEAD(&prsp->list); | 137 | INIT_LIST_HEAD(&prsp->list); |
137 | } else { | 138 | } else |
138 | prsp = NULL; | 139 | prsp = NULL; |
139 | } | ||
140 | 140 | ||
141 | /* Allocate buffer for Buffer ptr list */ | 141 | /* Allocate buffer for Buffer ptr list */ |
142 | pbuflist = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | 142 | pbuflist = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); |
@@ -246,7 +246,7 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) | |||
246 | 246 | ||
247 | sp = &phba->fc_fabparam; | 247 | sp = &phba->fc_fabparam; |
248 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | 248 | ndlp = lpfc_findnode_did(vport, Fabric_DID); |
249 | if (!ndlp) { | 249 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { |
250 | err = 1; | 250 | err = 1; |
251 | goto fail; | 251 | goto fail; |
252 | } | 252 | } |
@@ -282,6 +282,9 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) | |||
282 | 282 | ||
283 | mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; | 283 | mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; |
284 | mbox->vport = vport; | 284 | mbox->vport = vport; |
285 | /* increment the reference count on ndlp to hold reference | ||
286 | * for the callback routine. | ||
287 | */ | ||
285 | mbox->context2 = lpfc_nlp_get(ndlp); | 288 | mbox->context2 = lpfc_nlp_get(ndlp); |
286 | 289 | ||
287 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 290 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
@@ -293,6 +296,9 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) | |||
293 | return 0; | 296 | return 0; |
294 | 297 | ||
295 | fail_issue_reg_login: | 298 | fail_issue_reg_login: |
299 | /* decrement the reference count on ndlp just incremented | ||
300 | * for the failed mbox command. | ||
301 | */ | ||
296 | lpfc_nlp_put(ndlp); | 302 | lpfc_nlp_put(ndlp); |
297 | mp = (struct lpfc_dmabuf *) mbox->context1; | 303 | mp = (struct lpfc_dmabuf *) mbox->context1; |
298 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 304 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
@@ -381,6 +387,8 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
381 | */ | 387 | */ |
382 | list_for_each_entry_safe(np, next_np, | 388 | list_for_each_entry_safe(np, next_np, |
383 | &vport->fc_nodes, nlp_listp) { | 389 | &vport->fc_nodes, nlp_listp) { |
390 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
391 | continue; | ||
384 | if ((np->nlp_state != NLP_STE_NPR_NODE) || | 392 | if ((np->nlp_state != NLP_STE_NPR_NODE) || |
385 | !(np->nlp_flag & NLP_NPR_ADISC)) | 393 | !(np->nlp_flag & NLP_NPR_ADISC)) |
386 | continue; | 394 | continue; |
@@ -456,6 +464,9 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
456 | mempool_free(mbox, phba->mbox_mem_pool); | 464 | mempool_free(mbox, phba->mbox_mem_pool); |
457 | goto fail; | 465 | goto fail; |
458 | } | 466 | } |
467 | /* Decrement ndlp reference count indicating that ndlp can be | ||
468 | * safely released when other references to it are done. | ||
469 | */ | ||
459 | lpfc_nlp_put(ndlp); | 470 | lpfc_nlp_put(ndlp); |
460 | 471 | ||
461 | ndlp = lpfc_findnode_did(vport, PT2PT_RemoteID); | 472 | ndlp = lpfc_findnode_did(vport, PT2PT_RemoteID); |
@@ -467,22 +478,29 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
467 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | 478 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
468 | if (!ndlp) | 479 | if (!ndlp) |
469 | goto fail; | 480 | goto fail; |
470 | |||
471 | lpfc_nlp_init(vport, ndlp, PT2PT_RemoteID); | 481 | lpfc_nlp_init(vport, ndlp, PT2PT_RemoteID); |
482 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { | ||
483 | ndlp = lpfc_enable_node(vport, ndlp, | ||
484 | NLP_STE_UNUSED_NODE); | ||
485 | if(!ndlp) | ||
486 | goto fail; | ||
472 | } | 487 | } |
473 | 488 | ||
474 | memcpy(&ndlp->nlp_portname, &sp->portName, | 489 | memcpy(&ndlp->nlp_portname, &sp->portName, |
475 | sizeof(struct lpfc_name)); | 490 | sizeof(struct lpfc_name)); |
476 | memcpy(&ndlp->nlp_nodename, &sp->nodeName, | 491 | memcpy(&ndlp->nlp_nodename, &sp->nodeName, |
477 | sizeof(struct lpfc_name)); | 492 | sizeof(struct lpfc_name)); |
493 | /* Set state will put ndlp onto node list if not already done */ | ||
478 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 494 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
479 | spin_lock_irq(shost->host_lock); | 495 | spin_lock_irq(shost->host_lock); |
480 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 496 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
481 | spin_unlock_irq(shost->host_lock); | 497 | spin_unlock_irq(shost->host_lock); |
482 | } else { | 498 | } else |
483 | /* This side will wait for the PLOGI */ | 499 | /* This side will wait for the PLOGI, decrement ndlp reference |
500 | * count indicating that ndlp can be released when other | ||
501 | * references to it are done. | ||
502 | */ | ||
484 | lpfc_nlp_put(ndlp); | 503 | lpfc_nlp_put(ndlp); |
485 | } | ||
486 | 504 | ||
487 | /* If we are pt2pt with another NPort, force NPIV off! */ | 505 | /* If we are pt2pt with another NPort, force NPIV off! */ |
488 | phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED; | 506 | phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED; |
@@ -728,16 +746,21 @@ lpfc_initial_flogi(struct lpfc_vport *vport) | |||
728 | if (!ndlp) | 746 | if (!ndlp) |
729 | return 0; | 747 | return 0; |
730 | lpfc_nlp_init(vport, ndlp, Fabric_DID); | 748 | lpfc_nlp_init(vport, ndlp, Fabric_DID); |
731 | } else { | 749 | /* Put ndlp onto node list */ |
732 | lpfc_dequeue_node(vport, ndlp); | 750 | lpfc_enqueue_node(vport, ndlp); |
751 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { | ||
752 | /* re-setup ndlp without removing from node list */ | ||
753 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); | ||
754 | if (!ndlp) | ||
755 | return 0; | ||
733 | } | 756 | } |
734 | 757 | ||
735 | if (lpfc_issue_els_flogi(vport, ndlp, 0)) { | 758 | if (lpfc_issue_els_flogi(vport, ndlp, 0)) |
736 | /* This decrement of reference count to node shall kick off | 759 | /* This decrement of reference count to node shall kick off |
737 | * the release of the node. | 760 | * the release of the node. |
738 | */ | 761 | */ |
739 | lpfc_nlp_put(ndlp); | 762 | lpfc_nlp_put(ndlp); |
740 | } | 763 | |
741 | return 1; | 764 | return 1; |
742 | } | 765 | } |
743 | 766 | ||
@@ -755,9 +778,15 @@ lpfc_initial_fdisc(struct lpfc_vport *vport) | |||
755 | if (!ndlp) | 778 | if (!ndlp) |
756 | return 0; | 779 | return 0; |
757 | lpfc_nlp_init(vport, ndlp, Fabric_DID); | 780 | lpfc_nlp_init(vport, ndlp, Fabric_DID); |
758 | } else { | 781 | /* Put ndlp onto node list */ |
759 | lpfc_dequeue_node(vport, ndlp); | 782 | lpfc_enqueue_node(vport, ndlp); |
783 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { | ||
784 | /* re-setup ndlp without removing from node list */ | ||
785 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); | ||
786 | if (!ndlp) | ||
787 | return 0; | ||
760 | } | 788 | } |
789 | |||
761 | if (lpfc_issue_els_fdisc(vport, ndlp, 0)) { | 790 | if (lpfc_issue_els_fdisc(vport, ndlp, 0)) { |
762 | /* decrement node reference count to trigger the release of | 791 | /* decrement node reference count to trigger the release of |
763 | * the node. | 792 | * the node. |
@@ -816,7 +845,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
816 | */ | 845 | */ |
817 | new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName); | 846 | new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName); |
818 | 847 | ||
819 | if (new_ndlp == ndlp) | 848 | if (new_ndlp == ndlp && NLP_CHK_NODE_ACT(new_ndlp)) |
820 | return ndlp; | 849 | return ndlp; |
821 | 850 | ||
822 | if (!new_ndlp) { | 851 | if (!new_ndlp) { |
@@ -827,8 +856,12 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
827 | new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); | 856 | new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); |
828 | if (!new_ndlp) | 857 | if (!new_ndlp) |
829 | return ndlp; | 858 | return ndlp; |
830 | |||
831 | lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID); | 859 | lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID); |
860 | } else if (!NLP_CHK_NODE_ACT(new_ndlp)) { | ||
861 | new_ndlp = lpfc_enable_node(vport, new_ndlp, | ||
862 | NLP_STE_UNUSED_NODE); | ||
863 | if (!new_ndlp) | ||
864 | return ndlp; | ||
832 | } | 865 | } |
833 | 866 | ||
834 | lpfc_unreg_rpi(vport, new_ndlp); | 867 | lpfc_unreg_rpi(vport, new_ndlp); |
@@ -839,6 +872,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
839 | new_ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 872 | new_ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
840 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 873 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
841 | 874 | ||
875 | /* Set state will put new_ndlp on to node list if not already done */ | ||
842 | lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state); | 876 | lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state); |
843 | 877 | ||
844 | /* Move this back to NPR state */ | 878 | /* Move this back to NPR state */ |
@@ -912,7 +946,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
912 | irsp->un.elsreq64.remoteID); | 946 | irsp->un.elsreq64.remoteID); |
913 | 947 | ||
914 | ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID); | 948 | ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID); |
915 | if (!ndlp) { | 949 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { |
916 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 950 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
917 | "0136 PLOGI completes to NPort x%x " | 951 | "0136 PLOGI completes to NPort x%x " |
918 | "with no ndlp. Data: x%x x%x x%x\n", | 952 | "with no ndlp. Data: x%x x%x x%x\n", |
@@ -962,12 +996,11 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
962 | } | 996 | } |
963 | /* PLOGI failed */ | 997 | /* PLOGI failed */ |
964 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 998 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
965 | if (lpfc_error_lost_link(irsp)) { | 999 | if (lpfc_error_lost_link(irsp)) |
966 | rc = NLP_STE_FREED_NODE; | 1000 | rc = NLP_STE_FREED_NODE; |
967 | } else { | 1001 | else |
968 | rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 1002 | rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
969 | NLP_EVT_CMPL_PLOGI); | 1003 | NLP_EVT_CMPL_PLOGI); |
970 | } | ||
971 | } else { | 1004 | } else { |
972 | /* Good status, call state machine */ | 1005 | /* Good status, call state machine */ |
973 | prsp = list_entry(((struct lpfc_dmabuf *) | 1006 | prsp = list_entry(((struct lpfc_dmabuf *) |
@@ -1015,8 +1048,10 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) | |||
1015 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 1048 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
1016 | 1049 | ||
1017 | ndlp = lpfc_findnode_did(vport, did); | 1050 | ndlp = lpfc_findnode_did(vport, did); |
1018 | /* If ndlp if not NULL, we will bump the reference count on it */ | 1051 | if (ndlp && !NLP_CHK_NODE_ACT(ndlp)) |
1052 | ndlp = NULL; | ||
1019 | 1053 | ||
1054 | /* If ndlp is not NULL, we will bump the reference count on it */ | ||
1020 | cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); | 1055 | cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); |
1021 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, | 1056 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, |
1022 | ELS_CMD_PLOGI); | 1057 | ELS_CMD_PLOGI); |
@@ -1097,18 +1132,15 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1097 | } | 1132 | } |
1098 | /* PRLI failed */ | 1133 | /* PRLI failed */ |
1099 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1134 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1100 | if (lpfc_error_lost_link(irsp)) { | 1135 | if (lpfc_error_lost_link(irsp)) |
1101 | goto out; | 1136 | goto out; |
1102 | } else { | 1137 | else |
1103 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 1138 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
1104 | NLP_EVT_CMPL_PRLI); | 1139 | NLP_EVT_CMPL_PRLI); |
1105 | } | 1140 | } else |
1106 | } else { | ||
1107 | /* Good status, call state machine */ | 1141 | /* Good status, call state machine */ |
1108 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 1142 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
1109 | NLP_EVT_CMPL_PRLI); | 1143 | NLP_EVT_CMPL_PRLI); |
1110 | } | ||
1111 | |||
1112 | out: | 1144 | out: |
1113 | lpfc_els_free_iocb(phba, cmdiocb); | 1145 | lpfc_els_free_iocb(phba, cmdiocb); |
1114 | return; | 1146 | return; |
@@ -1275,15 +1307,13 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1275 | } | 1307 | } |
1276 | /* ADISC failed */ | 1308 | /* ADISC failed */ |
1277 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1309 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1278 | if (!lpfc_error_lost_link(irsp)) { | 1310 | if (!lpfc_error_lost_link(irsp)) |
1279 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 1311 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
1280 | NLP_EVT_CMPL_ADISC); | 1312 | NLP_EVT_CMPL_ADISC); |
1281 | } | 1313 | } else |
1282 | } else { | ||
1283 | /* Good status, call state machine */ | 1314 | /* Good status, call state machine */ |
1284 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 1315 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
1285 | NLP_EVT_CMPL_ADISC); | 1316 | NLP_EVT_CMPL_ADISC); |
1286 | } | ||
1287 | 1317 | ||
1288 | if (disc && vport->num_disc_nodes) { | 1318 | if (disc && vport->num_disc_nodes) { |
1289 | /* Check to see if there are more ADISCs to be sent */ | 1319 | /* Check to see if there are more ADISCs to be sent */ |
@@ -1443,14 +1473,12 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1443 | else | 1473 | else |
1444 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 1474 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
1445 | NLP_EVT_CMPL_LOGO); | 1475 | NLP_EVT_CMPL_LOGO); |
1446 | } else { | 1476 | } else |
1447 | /* Good status, call state machine. | 1477 | /* Good status, call state machine. |
1448 | * This will unregister the rpi if needed. | 1478 | * This will unregister the rpi if needed. |
1449 | */ | 1479 | */ |
1450 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 1480 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
1451 | NLP_EVT_CMPL_LOGO); | 1481 | NLP_EVT_CMPL_LOGO); |
1452 | } | ||
1453 | |||
1454 | out: | 1482 | out: |
1455 | lpfc_els_free_iocb(phba, cmdiocb); | 1483 | lpfc_els_free_iocb(phba, cmdiocb); |
1456 | return; | 1484 | return; |
@@ -1556,11 +1584,19 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
1556 | psli = &phba->sli; | 1584 | psli = &phba->sli; |
1557 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 1585 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
1558 | cmdsize = (sizeof(uint32_t) + sizeof(SCR)); | 1586 | cmdsize = (sizeof(uint32_t) + sizeof(SCR)); |
1559 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | ||
1560 | if (!ndlp) | ||
1561 | return 1; | ||
1562 | 1587 | ||
1563 | lpfc_nlp_init(vport, ndlp, nportid); | 1588 | ndlp = lpfc_findnode_did(vport, nportid); |
1589 | if (!ndlp) { | ||
1590 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | ||
1591 | if (!ndlp) | ||
1592 | return 1; | ||
1593 | lpfc_nlp_init(vport, ndlp, nportid); | ||
1594 | lpfc_enqueue_node(vport, ndlp); | ||
1595 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { | ||
1596 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); | ||
1597 | if (!ndlp) | ||
1598 | return 1; | ||
1599 | } | ||
1564 | 1600 | ||
1565 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, | 1601 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, |
1566 | ndlp->nlp_DID, ELS_CMD_SCR); | 1602 | ndlp->nlp_DID, ELS_CMD_SCR); |
@@ -1623,11 +1659,19 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
1623 | psli = &phba->sli; | 1659 | psli = &phba->sli; |
1624 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 1660 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
1625 | cmdsize = (sizeof(uint32_t) + sizeof(FARP)); | 1661 | cmdsize = (sizeof(uint32_t) + sizeof(FARP)); |
1626 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | ||
1627 | if (!ndlp) | ||
1628 | return 1; | ||
1629 | 1662 | ||
1630 | lpfc_nlp_init(vport, ndlp, nportid); | 1663 | ndlp = lpfc_findnode_did(vport, nportid); |
1664 | if (!ndlp) { | ||
1665 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | ||
1666 | if (!ndlp) | ||
1667 | return 1; | ||
1668 | lpfc_nlp_init(vport, ndlp, nportid); | ||
1669 | lpfc_enqueue_node(vport, ndlp); | ||
1670 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { | ||
1671 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); | ||
1672 | if (!ndlp) | ||
1673 | return 1; | ||
1674 | } | ||
1631 | 1675 | ||
1632 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, | 1676 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, |
1633 | ndlp->nlp_DID, ELS_CMD_RNID); | 1677 | ndlp->nlp_DID, ELS_CMD_RNID); |
@@ -1657,7 +1701,7 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
1657 | memcpy(&fp->RportName, &vport->fc_portname, sizeof(struct lpfc_name)); | 1701 | memcpy(&fp->RportName, &vport->fc_portname, sizeof(struct lpfc_name)); |
1658 | memcpy(&fp->RnodeName, &vport->fc_nodename, sizeof(struct lpfc_name)); | 1702 | memcpy(&fp->RnodeName, &vport->fc_nodename, sizeof(struct lpfc_name)); |
1659 | ondlp = lpfc_findnode_did(vport, nportid); | 1703 | ondlp = lpfc_findnode_did(vport, nportid); |
1660 | if (ondlp) { | 1704 | if (ondlp && NLP_CHK_NODE_ACT(ondlp)) { |
1661 | memcpy(&fp->OportName, &ondlp->nlp_portname, | 1705 | memcpy(&fp->OportName, &ondlp->nlp_portname, |
1662 | sizeof(struct lpfc_name)); | 1706 | sizeof(struct lpfc_name)); |
1663 | memcpy(&fp->OnodeName, &ondlp->nlp_nodename, | 1707 | memcpy(&fp->OnodeName, &ondlp->nlp_nodename, |
@@ -1690,6 +1734,7 @@ void | |||
1690 | lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) | 1734 | lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) |
1691 | { | 1735 | { |
1692 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 1736 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1737 | struct lpfc_work_evt *evtp; | ||
1693 | 1738 | ||
1694 | spin_lock_irq(shost->host_lock); | 1739 | spin_lock_irq(shost->host_lock); |
1695 | nlp->nlp_flag &= ~NLP_DELAY_TMO; | 1740 | nlp->nlp_flag &= ~NLP_DELAY_TMO; |
@@ -1697,8 +1742,12 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) | |||
1697 | del_timer_sync(&nlp->nlp_delayfunc); | 1742 | del_timer_sync(&nlp->nlp_delayfunc); |
1698 | nlp->nlp_last_elscmd = 0; | 1743 | nlp->nlp_last_elscmd = 0; |
1699 | 1744 | ||
1700 | if (!list_empty(&nlp->els_retry_evt.evt_listp)) | 1745 | if (!list_empty(&nlp->els_retry_evt.evt_listp)) { |
1701 | list_del_init(&nlp->els_retry_evt.evt_listp); | 1746 | list_del_init(&nlp->els_retry_evt.evt_listp); |
1747 | /* Decrement nlp reference count held for the delayed retry */ | ||
1748 | evtp = &nlp->els_retry_evt; | ||
1749 | lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1); | ||
1750 | } | ||
1702 | 1751 | ||
1703 | if (nlp->nlp_flag & NLP_NPR_2B_DISC) { | 1752 | if (nlp->nlp_flag & NLP_NPR_2B_DISC) { |
1704 | spin_lock_irq(shost->host_lock); | 1753 | spin_lock_irq(shost->host_lock); |
@@ -1842,13 +1891,14 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1842 | cmd = *elscmd++; | 1891 | cmd = *elscmd++; |
1843 | } | 1892 | } |
1844 | 1893 | ||
1845 | if (ndlp) | 1894 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) |
1846 | did = ndlp->nlp_DID; | 1895 | did = ndlp->nlp_DID; |
1847 | else { | 1896 | else { |
1848 | /* We should only hit this case for retrying PLOGI */ | 1897 | /* We should only hit this case for retrying PLOGI */ |
1849 | did = irsp->un.elsreq64.remoteID; | 1898 | did = irsp->un.elsreq64.remoteID; |
1850 | ndlp = lpfc_findnode_did(vport, did); | 1899 | ndlp = lpfc_findnode_did(vport, did); |
1851 | if (!ndlp && (cmd != ELS_CMD_PLOGI)) | 1900 | if ((!ndlp || !NLP_CHK_NODE_ACT(ndlp)) |
1901 | && (cmd != ELS_CMD_PLOGI)) | ||
1852 | return 1; | 1902 | return 1; |
1853 | } | 1903 | } |
1854 | 1904 | ||
@@ -1870,18 +1920,15 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1870 | break; | 1920 | break; |
1871 | 1921 | ||
1872 | case IOERR_ILLEGAL_COMMAND: | 1922 | case IOERR_ILLEGAL_COMMAND: |
1873 | if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) && | 1923 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
1874 | (cmd == ELS_CMD_FDISC)) { | 1924 | "0124 Retry illegal cmd x%x " |
1875 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 1925 | "retry:x%x delay:x%x\n", |
1876 | "0124 FDISC failed (3/6) " | 1926 | cmd, cmdiocb->retry, delay); |
1877 | "retrying...\n"); | 1927 | retry = 1; |
1878 | lpfc_mbx_unreg_vpi(vport); | 1928 | /* All command's retry policy */ |
1879 | retry = 1; | 1929 | maxretry = 8; |
1880 | /* FDISC retry policy */ | 1930 | if (cmdiocb->retry > 2) |
1881 | maxretry = 48; | 1931 | delay = 1000; |
1882 | if (cmdiocb->retry >= 32) | ||
1883 | delay = 1000; | ||
1884 | } | ||
1885 | break; | 1932 | break; |
1886 | 1933 | ||
1887 | case IOERR_NO_RESOURCES: | 1934 | case IOERR_NO_RESOURCES: |
@@ -1967,6 +2014,17 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1967 | break; | 2014 | break; |
1968 | 2015 | ||
1969 | case LSRJT_LOGICAL_ERR: | 2016 | case LSRJT_LOGICAL_ERR: |
2017 | /* There are some cases where switches return this | ||
2018 | * error when they are not ready and should be returning | ||
2019 | * Logical Busy. We should delay every time. | ||
2020 | */ | ||
2021 | if (cmd == ELS_CMD_FDISC && | ||
2022 | stat.un.b.lsRjtRsnCodeExp == LSEXP_PORT_LOGIN_REQ) { | ||
2023 | maxretry = 3; | ||
2024 | delay = 1000; | ||
2025 | retry = 1; | ||
2026 | break; | ||
2027 | } | ||
1970 | case LSRJT_PROTOCOL_ERR: | 2028 | case LSRJT_PROTOCOL_ERR: |
1971 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && | 2029 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && |
1972 | (cmd == ELS_CMD_FDISC) && | 2030 | (cmd == ELS_CMD_FDISC) && |
@@ -1996,7 +2054,8 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1996 | retry = 1; | 2054 | retry = 1; |
1997 | 2055 | ||
1998 | if ((cmd == ELS_CMD_FLOGI) && | 2056 | if ((cmd == ELS_CMD_FLOGI) && |
1999 | (phba->fc_topology != TOPOLOGY_LOOP)) { | 2057 | (phba->fc_topology != TOPOLOGY_LOOP) && |
2058 | !lpfc_error_lost_link(irsp)) { | ||
2000 | /* FLOGI retry policy */ | 2059 | /* FLOGI retry policy */ |
2001 | retry = 1; | 2060 | retry = 1; |
2002 | maxretry = 48; | 2061 | maxretry = 48; |
@@ -2322,6 +2381,9 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2322 | if ((rspiocb->iocb.ulpStatus == 0) | 2381 | if ((rspiocb->iocb.ulpStatus == 0) |
2323 | && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { | 2382 | && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { |
2324 | lpfc_unreg_rpi(vport, ndlp); | 2383 | lpfc_unreg_rpi(vport, ndlp); |
2384 | /* Increment reference count to ndlp to hold the | ||
2385 | * reference to ndlp for the callback function. | ||
2386 | */ | ||
2325 | mbox->context2 = lpfc_nlp_get(ndlp); | 2387 | mbox->context2 = lpfc_nlp_get(ndlp); |
2326 | mbox->vport = vport; | 2388 | mbox->vport = vport; |
2327 | if (ndlp->nlp_flag & NLP_RM_DFLT_RPI) { | 2389 | if (ndlp->nlp_flag & NLP_RM_DFLT_RPI) { |
@@ -2335,9 +2397,13 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2335 | NLP_STE_REG_LOGIN_ISSUE); | 2397 | NLP_STE_REG_LOGIN_ISSUE); |
2336 | } | 2398 | } |
2337 | if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) | 2399 | if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) |
2338 | != MBX_NOT_FINISHED) { | 2400 | != MBX_NOT_FINISHED) |
2339 | goto out; | 2401 | goto out; |
2340 | } | 2402 | else |
2403 | /* Decrement the ndlp reference count we | ||
2404 | * set for this failed mailbox command. | ||
2405 | */ | ||
2406 | lpfc_nlp_put(ndlp); | ||
2341 | 2407 | ||
2342 | /* ELS rsp: Cannot issue reg_login for <NPortid> */ | 2408 | /* ELS rsp: Cannot issue reg_login for <NPortid> */ |
2343 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 2409 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
@@ -2796,6 +2862,8 @@ lpfc_els_disc_adisc(struct lpfc_vport *vport) | |||
2796 | 2862 | ||
2797 | /* go thru NPR nodes and issue any remaining ELS ADISCs */ | 2863 | /* go thru NPR nodes and issue any remaining ELS ADISCs */ |
2798 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { | 2864 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { |
2865 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
2866 | continue; | ||
2799 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && | 2867 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && |
2800 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && | 2868 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && |
2801 | (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) { | 2869 | (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) { |
@@ -2833,6 +2901,8 @@ lpfc_els_disc_plogi(struct lpfc_vport *vport) | |||
2833 | 2901 | ||
2834 | /* go thru NPR nodes and issue any remaining ELS PLOGIs */ | 2902 | /* go thru NPR nodes and issue any remaining ELS PLOGIs */ |
2835 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { | 2903 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { |
2904 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
2905 | continue; | ||
2836 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && | 2906 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && |
2837 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && | 2907 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && |
2838 | (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 && | 2908 | (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 && |
@@ -2869,6 +2939,16 @@ lpfc_els_flush_rscn(struct lpfc_vport *vport) | |||
2869 | struct lpfc_hba *phba = vport->phba; | 2939 | struct lpfc_hba *phba = vport->phba; |
2870 | int i; | 2940 | int i; |
2871 | 2941 | ||
2942 | spin_lock_irq(shost->host_lock); | ||
2943 | if (vport->fc_rscn_flush) { | ||
2944 | /* Another thread is walking fc_rscn_id_list on this vport */ | ||
2945 | spin_unlock_irq(shost->host_lock); | ||
2946 | return; | ||
2947 | } | ||
2948 | /* Indicate we are walking lpfc_els_flush_rscn on this vport */ | ||
2949 | vport->fc_rscn_flush = 1; | ||
2950 | spin_unlock_irq(shost->host_lock); | ||
2951 | |||
2872 | for (i = 0; i < vport->fc_rscn_id_cnt; i++) { | 2952 | for (i = 0; i < vport->fc_rscn_id_cnt; i++) { |
2873 | lpfc_in_buf_free(phba, vport->fc_rscn_id_list[i]); | 2953 | lpfc_in_buf_free(phba, vport->fc_rscn_id_list[i]); |
2874 | vport->fc_rscn_id_list[i] = NULL; | 2954 | vport->fc_rscn_id_list[i] = NULL; |
@@ -2878,6 +2958,8 @@ lpfc_els_flush_rscn(struct lpfc_vport *vport) | |||
2878 | vport->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY); | 2958 | vport->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY); |
2879 | spin_unlock_irq(shost->host_lock); | 2959 | spin_unlock_irq(shost->host_lock); |
2880 | lpfc_can_disctmo(vport); | 2960 | lpfc_can_disctmo(vport); |
2961 | /* Indicate we are done walking this fc_rscn_id_list */ | ||
2962 | vport->fc_rscn_flush = 0; | ||
2881 | } | 2963 | } |
2882 | 2964 | ||
2883 | int | 2965 | int |
@@ -2887,6 +2969,7 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) | |||
2887 | D_ID rscn_did; | 2969 | D_ID rscn_did; |
2888 | uint32_t *lp; | 2970 | uint32_t *lp; |
2889 | uint32_t payload_len, i; | 2971 | uint32_t payload_len, i; |
2972 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2890 | 2973 | ||
2891 | ns_did.un.word = did; | 2974 | ns_did.un.word = did; |
2892 | 2975 | ||
@@ -2898,6 +2981,15 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) | |||
2898 | if (vport->fc_flag & FC_RSCN_DISCOVERY) | 2981 | if (vport->fc_flag & FC_RSCN_DISCOVERY) |
2899 | return did; | 2982 | return did; |
2900 | 2983 | ||
2984 | spin_lock_irq(shost->host_lock); | ||
2985 | if (vport->fc_rscn_flush) { | ||
2986 | /* Another thread is walking fc_rscn_id_list on this vport */ | ||
2987 | spin_unlock_irq(shost->host_lock); | ||
2988 | return 0; | ||
2989 | } | ||
2990 | /* Indicate we are walking fc_rscn_id_list on this vport */ | ||
2991 | vport->fc_rscn_flush = 1; | ||
2992 | spin_unlock_irq(shost->host_lock); | ||
2901 | for (i = 0; i < vport->fc_rscn_id_cnt; i++) { | 2993 | for (i = 0; i < vport->fc_rscn_id_cnt; i++) { |
2902 | lp = vport->fc_rscn_id_list[i]->virt; | 2994 | lp = vport->fc_rscn_id_list[i]->virt; |
2903 | payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK); | 2995 | payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK); |
@@ -2908,16 +3000,16 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) | |||
2908 | switch (rscn_did.un.b.resv) { | 3000 | switch (rscn_did.un.b.resv) { |
2909 | case 0: /* Single N_Port ID effected */ | 3001 | case 0: /* Single N_Port ID effected */ |
2910 | if (ns_did.un.word == rscn_did.un.word) | 3002 | if (ns_did.un.word == rscn_did.un.word) |
2911 | return did; | 3003 | goto return_did_out; |
2912 | break; | 3004 | break; |
2913 | case 1: /* Whole N_Port Area effected */ | 3005 | case 1: /* Whole N_Port Area effected */ |
2914 | if ((ns_did.un.b.domain == rscn_did.un.b.domain) | 3006 | if ((ns_did.un.b.domain == rscn_did.un.b.domain) |
2915 | && (ns_did.un.b.area == rscn_did.un.b.area)) | 3007 | && (ns_did.un.b.area == rscn_did.un.b.area)) |
2916 | return did; | 3008 | goto return_did_out; |
2917 | break; | 3009 | break; |
2918 | case 2: /* Whole N_Port Domain effected */ | 3010 | case 2: /* Whole N_Port Domain effected */ |
2919 | if (ns_did.un.b.domain == rscn_did.un.b.domain) | 3011 | if (ns_did.un.b.domain == rscn_did.un.b.domain) |
2920 | return did; | 3012 | goto return_did_out; |
2921 | break; | 3013 | break; |
2922 | default: | 3014 | default: |
2923 | /* Unknown Identifier in RSCN node */ | 3015 | /* Unknown Identifier in RSCN node */ |
@@ -2926,11 +3018,17 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) | |||
2926 | "RSCN payload Data: x%x\n", | 3018 | "RSCN payload Data: x%x\n", |
2927 | rscn_did.un.word); | 3019 | rscn_did.un.word); |
2928 | case 3: /* Whole Fabric effected */ | 3020 | case 3: /* Whole Fabric effected */ |
2929 | return did; | 3021 | goto return_did_out; |
2930 | } | 3022 | } |
2931 | } | 3023 | } |
2932 | } | 3024 | } |
3025 | /* Indicate we are done with walking fc_rscn_id_list on this vport */ | ||
3026 | vport->fc_rscn_flush = 0; | ||
2933 | return 0; | 3027 | return 0; |
3028 | return_did_out: | ||
3029 | /* Indicate we are done with walking fc_rscn_id_list on this vport */ | ||
3030 | vport->fc_rscn_flush = 0; | ||
3031 | return did; | ||
2934 | } | 3032 | } |
2935 | 3033 | ||
2936 | static int | 3034 | static int |
@@ -2943,7 +3041,8 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport) | |||
2943 | */ | 3041 | */ |
2944 | 3042 | ||
2945 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { | 3043 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
2946 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE || | 3044 | if (!NLP_CHK_NODE_ACT(ndlp) || |
3045 | ndlp->nlp_state == NLP_STE_UNUSED_NODE || | ||
2947 | lpfc_rscn_payload_check(vport, ndlp->nlp_DID) == 0) | 3046 | lpfc_rscn_payload_check(vport, ndlp->nlp_DID) == 0) |
2948 | continue; | 3047 | continue; |
2949 | 3048 | ||
@@ -2971,7 +3070,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
2971 | uint32_t *lp, *datap; | 3070 | uint32_t *lp, *datap; |
2972 | IOCB_t *icmd; | 3071 | IOCB_t *icmd; |
2973 | uint32_t payload_len, length, nportid, *cmd; | 3072 | uint32_t payload_len, length, nportid, *cmd; |
2974 | int rscn_cnt = vport->fc_rscn_id_cnt; | 3073 | int rscn_cnt; |
2975 | int rscn_id = 0, hba_id = 0; | 3074 | int rscn_id = 0, hba_id = 0; |
2976 | int i; | 3075 | int i; |
2977 | 3076 | ||
@@ -2984,7 +3083,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
2984 | /* RSCN received */ | 3083 | /* RSCN received */ |
2985 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 3084 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
2986 | "0214 RSCN received Data: x%x x%x x%x x%x\n", | 3085 | "0214 RSCN received Data: x%x x%x x%x x%x\n", |
2987 | vport->fc_flag, payload_len, *lp, rscn_cnt); | 3086 | vport->fc_flag, payload_len, *lp, |
3087 | vport->fc_rscn_id_cnt); | ||
2988 | for (i = 0; i < payload_len/sizeof(uint32_t); i++) | 3088 | for (i = 0; i < payload_len/sizeof(uint32_t); i++) |
2989 | fc_host_post_event(shost, fc_get_event_number(), | 3089 | fc_host_post_event(shost, fc_get_event_number(), |
2990 | FCH_EVT_RSCN, lp[i]); | 3090 | FCH_EVT_RSCN, lp[i]); |
@@ -3022,7 +3122,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3022 | "0214 Ignore RSCN " | 3122 | "0214 Ignore RSCN " |
3023 | "Data: x%x x%x x%x x%x\n", | 3123 | "Data: x%x x%x x%x x%x\n", |
3024 | vport->fc_flag, payload_len, | 3124 | vport->fc_flag, payload_len, |
3025 | *lp, rscn_cnt); | 3125 | *lp, vport->fc_rscn_id_cnt); |
3026 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 3126 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
3027 | "RCV RSCN vport: did:x%x/ste:x%x flg:x%x", | 3127 | "RCV RSCN vport: did:x%x/ste:x%x flg:x%x", |
3028 | ndlp->nlp_DID, vport->port_state, | 3128 | ndlp->nlp_DID, vport->port_state, |
@@ -3034,6 +3134,18 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3034 | } | 3134 | } |
3035 | } | 3135 | } |
3036 | 3136 | ||
3137 | spin_lock_irq(shost->host_lock); | ||
3138 | if (vport->fc_rscn_flush) { | ||
3139 | /* Another thread is walking fc_rscn_id_list on this vport */ | ||
3140 | spin_unlock_irq(shost->host_lock); | ||
3141 | vport->fc_flag |= FC_RSCN_DISCOVERY; | ||
3142 | return 0; | ||
3143 | } | ||
3144 | /* Indicate we are walking fc_rscn_id_list on this vport */ | ||
3145 | vport->fc_rscn_flush = 1; | ||
3146 | spin_unlock_irq(shost->host_lock); | ||
3147 | /* Get the array count after sucessfully have the token */ | ||
3148 | rscn_cnt = vport->fc_rscn_id_cnt; | ||
3037 | /* If we are already processing an RSCN, save the received | 3149 | /* If we are already processing an RSCN, save the received |
3038 | * RSCN payload buffer, cmdiocb->context2 to process later. | 3150 | * RSCN payload buffer, cmdiocb->context2 to process later. |
3039 | */ | 3151 | */ |
@@ -3055,7 +3167,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3055 | if ((rscn_cnt) && | 3167 | if ((rscn_cnt) && |
3056 | (payload_len + length <= LPFC_BPL_SIZE)) { | 3168 | (payload_len + length <= LPFC_BPL_SIZE)) { |
3057 | *cmd &= ELS_CMD_MASK; | 3169 | *cmd &= ELS_CMD_MASK; |
3058 | *cmd |= be32_to_cpu(payload_len + length); | 3170 | *cmd |= cpu_to_be32(payload_len + length); |
3059 | memcpy(((uint8_t *)cmd) + length, lp, | 3171 | memcpy(((uint8_t *)cmd) + length, lp, |
3060 | payload_len); | 3172 | payload_len); |
3061 | } else { | 3173 | } else { |
@@ -3066,7 +3178,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3066 | */ | 3178 | */ |
3067 | cmdiocb->context2 = NULL; | 3179 | cmdiocb->context2 = NULL; |
3068 | } | 3180 | } |
3069 | |||
3070 | /* Deferred RSCN */ | 3181 | /* Deferred RSCN */ |
3071 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 3182 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
3072 | "0235 Deferred RSCN " | 3183 | "0235 Deferred RSCN " |
@@ -3083,9 +3194,10 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3083 | vport->fc_rscn_id_cnt, vport->fc_flag, | 3194 | vport->fc_rscn_id_cnt, vport->fc_flag, |
3084 | vport->port_state); | 3195 | vport->port_state); |
3085 | } | 3196 | } |
3197 | /* Indicate we are done walking fc_rscn_id_list on this vport */ | ||
3198 | vport->fc_rscn_flush = 0; | ||
3086 | /* Send back ACC */ | 3199 | /* Send back ACC */ |
3087 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); | 3200 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); |
3088 | |||
3089 | /* send RECOVERY event for ALL nodes that match RSCN payload */ | 3201 | /* send RECOVERY event for ALL nodes that match RSCN payload */ |
3090 | lpfc_rscn_recovery_check(vport); | 3202 | lpfc_rscn_recovery_check(vport); |
3091 | spin_lock_irq(shost->host_lock); | 3203 | spin_lock_irq(shost->host_lock); |
@@ -3093,7 +3205,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3093 | spin_unlock_irq(shost->host_lock); | 3205 | spin_unlock_irq(shost->host_lock); |
3094 | return 0; | 3206 | return 0; |
3095 | } | 3207 | } |
3096 | |||
3097 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 3208 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
3098 | "RCV RSCN: did:x%x/ste:x%x flg:x%x", | 3209 | "RCV RSCN: did:x%x/ste:x%x flg:x%x", |
3099 | ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); | 3210 | ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); |
@@ -3102,20 +3213,18 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3102 | vport->fc_flag |= FC_RSCN_MODE; | 3213 | vport->fc_flag |= FC_RSCN_MODE; |
3103 | spin_unlock_irq(shost->host_lock); | 3214 | spin_unlock_irq(shost->host_lock); |
3104 | vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd; | 3215 | vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd; |
3216 | /* Indicate we are done walking fc_rscn_id_list on this vport */ | ||
3217 | vport->fc_rscn_flush = 0; | ||
3105 | /* | 3218 | /* |
3106 | * If we zero, cmdiocb->context2, the calling routine will | 3219 | * If we zero, cmdiocb->context2, the calling routine will |
3107 | * not try to free it. | 3220 | * not try to free it. |
3108 | */ | 3221 | */ |
3109 | cmdiocb->context2 = NULL; | 3222 | cmdiocb->context2 = NULL; |
3110 | |||
3111 | lpfc_set_disctmo(vport); | 3223 | lpfc_set_disctmo(vport); |
3112 | |||
3113 | /* Send back ACC */ | 3224 | /* Send back ACC */ |
3114 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); | 3225 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); |
3115 | |||
3116 | /* send RECOVERY event for ALL nodes that match RSCN payload */ | 3226 | /* send RECOVERY event for ALL nodes that match RSCN payload */ |
3117 | lpfc_rscn_recovery_check(vport); | 3227 | lpfc_rscn_recovery_check(vport); |
3118 | |||
3119 | return lpfc_els_handle_rscn(vport); | 3228 | return lpfc_els_handle_rscn(vport); |
3120 | } | 3229 | } |
3121 | 3230 | ||
@@ -3145,7 +3254,8 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport) | |||
3145 | vport->num_disc_nodes = 0; | 3254 | vport->num_disc_nodes = 0; |
3146 | 3255 | ||
3147 | ndlp = lpfc_findnode_did(vport, NameServer_DID); | 3256 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
3148 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | 3257 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) |
3258 | && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | ||
3149 | /* Good ndlp, issue CT Request to NameServer */ | 3259 | /* Good ndlp, issue CT Request to NameServer */ |
3150 | if (lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 0, 0) == 0) | 3260 | if (lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 0, 0) == 0) |
3151 | /* Wait for NameServer query cmpl before we can | 3261 | /* Wait for NameServer query cmpl before we can |
@@ -3155,25 +3265,35 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport) | |||
3155 | /* If login to NameServer does not exist, issue one */ | 3265 | /* If login to NameServer does not exist, issue one */ |
3156 | /* Good status, issue PLOGI to NameServer */ | 3266 | /* Good status, issue PLOGI to NameServer */ |
3157 | ndlp = lpfc_findnode_did(vport, NameServer_DID); | 3267 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
3158 | if (ndlp) | 3268 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) |
3159 | /* Wait for NameServer login cmpl before we can | 3269 | /* Wait for NameServer login cmpl before we can |
3160 | continue */ | 3270 | continue */ |
3161 | return 1; | 3271 | return 1; |
3162 | 3272 | ||
3163 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | 3273 | if (ndlp) { |
3164 | if (!ndlp) { | 3274 | ndlp = lpfc_enable_node(vport, ndlp, |
3165 | lpfc_els_flush_rscn(vport); | 3275 | NLP_STE_PLOGI_ISSUE); |
3166 | return 0; | 3276 | if (!ndlp) { |
3277 | lpfc_els_flush_rscn(vport); | ||
3278 | return 0; | ||
3279 | } | ||
3280 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; | ||
3167 | } else { | 3281 | } else { |
3282 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | ||
3283 | if (!ndlp) { | ||
3284 | lpfc_els_flush_rscn(vport); | ||
3285 | return 0; | ||
3286 | } | ||
3168 | lpfc_nlp_init(vport, ndlp, NameServer_DID); | 3287 | lpfc_nlp_init(vport, ndlp, NameServer_DID); |
3169 | ndlp->nlp_type |= NLP_FABRIC; | ||
3170 | ndlp->nlp_prev_state = ndlp->nlp_state; | 3288 | ndlp->nlp_prev_state = ndlp->nlp_state; |
3171 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); | 3289 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
3172 | lpfc_issue_els_plogi(vport, NameServer_DID, 0); | ||
3173 | /* Wait for NameServer login cmpl before we can | ||
3174 | continue */ | ||
3175 | return 1; | ||
3176 | } | 3290 | } |
3291 | ndlp->nlp_type |= NLP_FABRIC; | ||
3292 | lpfc_issue_els_plogi(vport, NameServer_DID, 0); | ||
3293 | /* Wait for NameServer login cmpl before we can | ||
3294 | * continue | ||
3295 | */ | ||
3296 | return 1; | ||
3177 | } | 3297 | } |
3178 | 3298 | ||
3179 | lpfc_els_flush_rscn(vport); | 3299 | lpfc_els_flush_rscn(vport); |
@@ -3672,6 +3792,8 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3672 | 3792 | ||
3673 | list_for_each_entry_safe(ndlp, next_ndlp, | 3793 | list_for_each_entry_safe(ndlp, next_ndlp, |
3674 | &vport->fc_nodes, nlp_listp) { | 3794 | &vport->fc_nodes, nlp_listp) { |
3795 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
3796 | continue; | ||
3675 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) | 3797 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) |
3676 | continue; | 3798 | continue; |
3677 | if (ndlp->nlp_type & NLP_FABRIC) { | 3799 | if (ndlp->nlp_type & NLP_FABRIC) { |
@@ -3697,6 +3819,8 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3697 | */ | 3819 | */ |
3698 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, | 3820 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, |
3699 | nlp_listp) { | 3821 | nlp_listp) { |
3822 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
3823 | continue; | ||
3700 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) | 3824 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) |
3701 | continue; | 3825 | continue; |
3702 | 3826 | ||
@@ -3936,7 +4060,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3936 | uint32_t cmd, did, newnode, rjt_err = 0; | 4060 | uint32_t cmd, did, newnode, rjt_err = 0; |
3937 | IOCB_t *icmd = &elsiocb->iocb; | 4061 | IOCB_t *icmd = &elsiocb->iocb; |
3938 | 4062 | ||
3939 | if (vport == NULL || elsiocb->context2 == NULL) | 4063 | if (!vport || !(elsiocb->context2)) |
3940 | goto dropit; | 4064 | goto dropit; |
3941 | 4065 | ||
3942 | newnode = 0; | 4066 | newnode = 0; |
@@ -3971,14 +4095,20 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3971 | lpfc_nlp_init(vport, ndlp, did); | 4095 | lpfc_nlp_init(vport, ndlp, did); |
3972 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 4096 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
3973 | newnode = 1; | 4097 | newnode = 1; |
3974 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { | 4098 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) |
3975 | ndlp->nlp_type |= NLP_FABRIC; | 4099 | ndlp->nlp_type |= NLP_FABRIC; |
4100 | } else { | ||
4101 | if (!NLP_CHK_NODE_ACT(ndlp)) { | ||
4102 | ndlp = lpfc_enable_node(vport, ndlp, | ||
4103 | NLP_STE_UNUSED_NODE); | ||
4104 | if (!ndlp) | ||
4105 | goto dropit; | ||
3976 | } | 4106 | } |
3977 | } | ||
3978 | else { | ||
3979 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { | 4107 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { |
3980 | /* This is simular to the new node path */ | 4108 | /* This is simular to the new node path */ |
3981 | lpfc_nlp_get(ndlp); | 4109 | ndlp = lpfc_nlp_get(ndlp); |
4110 | if (!ndlp) | ||
4111 | goto dropit; | ||
3982 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 4112 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
3983 | newnode = 1; | 4113 | newnode = 1; |
3984 | } | 4114 | } |
@@ -3987,6 +4117,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3987 | phba->fc_stat.elsRcvFrame++; | 4117 | phba->fc_stat.elsRcvFrame++; |
3988 | if (elsiocb->context1) | 4118 | if (elsiocb->context1) |
3989 | lpfc_nlp_put(elsiocb->context1); | 4119 | lpfc_nlp_put(elsiocb->context1); |
4120 | |||
3990 | elsiocb->context1 = lpfc_nlp_get(ndlp); | 4121 | elsiocb->context1 = lpfc_nlp_get(ndlp); |
3991 | elsiocb->vport = vport; | 4122 | elsiocb->vport = vport; |
3992 | 4123 | ||
@@ -4007,8 +4138,15 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
4007 | ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); | 4138 | ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); |
4008 | 4139 | ||
4009 | if (vport->port_state < LPFC_DISC_AUTH) { | 4140 | if (vport->port_state < LPFC_DISC_AUTH) { |
4010 | rjt_err = LSRJT_UNABLE_TPC; | 4141 | if (!(phba->pport->fc_flag & FC_PT2PT) || |
4011 | break; | 4142 | (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { |
4143 | rjt_err = LSRJT_UNABLE_TPC; | ||
4144 | break; | ||
4145 | } | ||
4146 | /* We get here, and drop thru, if we are PT2PT with | ||
4147 | * another NPort and the other side has initiated | ||
4148 | * the PLOGI before responding to our FLOGI. | ||
4149 | */ | ||
4012 | } | 4150 | } |
4013 | 4151 | ||
4014 | shost = lpfc_shost_from_vport(vport); | 4152 | shost = lpfc_shost_from_vport(vport); |
@@ -4251,15 +4389,15 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
4251 | vport = lpfc_find_vport_by_vpid(phba, vpi); | 4389 | vport = lpfc_find_vport_by_vpid(phba, vpi); |
4252 | } | 4390 | } |
4253 | } | 4391 | } |
4254 | /* If there are no BDEs associated | 4392 | /* If there are no BDEs associated |
4255 | * with this IOCB, there is nothing to do. | 4393 | * with this IOCB, there is nothing to do. |
4256 | */ | 4394 | */ |
4257 | if (icmd->ulpBdeCount == 0) | 4395 | if (icmd->ulpBdeCount == 0) |
4258 | return; | 4396 | return; |
4259 | 4397 | ||
4260 | /* type of ELS cmd is first 32bit word | 4398 | /* type of ELS cmd is first 32bit word |
4261 | * in packet | 4399 | * in packet |
4262 | */ | 4400 | */ |
4263 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { | 4401 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { |
4264 | elsiocb->context2 = bdeBuf1; | 4402 | elsiocb->context2 = bdeBuf1; |
4265 | } else { | 4403 | } else { |
@@ -4314,6 +4452,18 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
4314 | } | 4452 | } |
4315 | lpfc_nlp_init(vport, ndlp, NameServer_DID); | 4453 | lpfc_nlp_init(vport, ndlp, NameServer_DID); |
4316 | ndlp->nlp_type |= NLP_FABRIC; | 4454 | ndlp->nlp_type |= NLP_FABRIC; |
4455 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { | ||
4456 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); | ||
4457 | if (!ndlp) { | ||
4458 | if (phba->fc_topology == TOPOLOGY_LOOP) { | ||
4459 | lpfc_disc_start(vport); | ||
4460 | return; | ||
4461 | } | ||
4462 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
4463 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
4464 | "0348 NameServer login: node freed\n"); | ||
4465 | return; | ||
4466 | } | ||
4317 | } | 4467 | } |
4318 | 4468 | ||
4319 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); | 4469 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
@@ -4360,6 +4510,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
4360 | switch (mb->mbxStatus) { | 4510 | switch (mb->mbxStatus) { |
4361 | case 0x11: /* unsupported feature */ | 4511 | case 0x11: /* unsupported feature */ |
4362 | case 0x9603: /* max_vpi exceeded */ | 4512 | case 0x9603: /* max_vpi exceeded */ |
4513 | case 0x9602: /* Link event since CLEAR_LA */ | ||
4363 | /* giving up on vport registration */ | 4514 | /* giving up on vport registration */ |
4364 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 4515 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
4365 | spin_lock_irq(shost->host_lock); | 4516 | spin_lock_irq(shost->host_lock); |
@@ -4373,7 +4524,10 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
4373 | spin_lock_irq(shost->host_lock); | 4524 | spin_lock_irq(shost->host_lock); |
4374 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 4525 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
4375 | spin_unlock_irq(shost->host_lock); | 4526 | spin_unlock_irq(shost->host_lock); |
4376 | lpfc_initial_fdisc(vport); | 4527 | if (vport->port_type == LPFC_PHYSICAL_PORT) |
4528 | lpfc_initial_flogi(vport); | ||
4529 | else | ||
4530 | lpfc_initial_fdisc(vport); | ||
4377 | break; | 4531 | break; |
4378 | } | 4532 | } |
4379 | 4533 | ||
@@ -4471,7 +4625,6 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4471 | irsp->ulpStatus, irsp->un.ulpWord[4]); | 4625 | irsp->ulpStatus, irsp->un.ulpWord[4]); |
4472 | if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING) | 4626 | if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING) |
4473 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 4627 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
4474 | |||
4475 | lpfc_nlp_put(ndlp); | 4628 | lpfc_nlp_put(ndlp); |
4476 | /* giving up on FDISC. Cancel discovery timer */ | 4629 | /* giving up on FDISC. Cancel discovery timer */ |
4477 | lpfc_can_disctmo(vport); | 4630 | lpfc_can_disctmo(vport); |
@@ -4492,8 +4645,9 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4492 | */ | 4645 | */ |
4493 | list_for_each_entry_safe(np, next_np, | 4646 | list_for_each_entry_safe(np, next_np, |
4494 | &vport->fc_nodes, nlp_listp) { | 4647 | &vport->fc_nodes, nlp_listp) { |
4495 | if (np->nlp_state != NLP_STE_NPR_NODE | 4648 | if (!NLP_CHK_NODE_ACT(ndlp) || |
4496 | || !(np->nlp_flag & NLP_NPR_ADISC)) | 4649 | (np->nlp_state != NLP_STE_NPR_NODE) || |
4650 | !(np->nlp_flag & NLP_NPR_ADISC)) | ||
4497 | continue; | 4651 | continue; |
4498 | spin_lock_irq(shost->host_lock); | 4652 | spin_lock_irq(shost->host_lock); |
4499 | np->nlp_flag &= ~NLP_NPR_ADISC; | 4653 | np->nlp_flag &= ~NLP_NPR_ADISC; |
@@ -4599,6 +4753,8 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4599 | { | 4753 | { |
4600 | struct lpfc_vport *vport = cmdiocb->vport; | 4754 | struct lpfc_vport *vport = cmdiocb->vport; |
4601 | IOCB_t *irsp; | 4755 | IOCB_t *irsp; |
4756 | struct lpfc_nodelist *ndlp; | ||
4757 | ndlp = (struct lpfc_nodelist *)cmdiocb->context1; | ||
4602 | 4758 | ||
4603 | irsp = &rspiocb->iocb; | 4759 | irsp = &rspiocb->iocb; |
4604 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | 4760 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, |
@@ -4607,6 +4763,9 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4607 | 4763 | ||
4608 | lpfc_els_free_iocb(phba, cmdiocb); | 4764 | lpfc_els_free_iocb(phba, cmdiocb); |
4609 | vport->unreg_vpi_cmpl = VPORT_ERROR; | 4765 | vport->unreg_vpi_cmpl = VPORT_ERROR; |
4766 | |||
4767 | /* Trigger the release of the ndlp after logo */ | ||
4768 | lpfc_nlp_put(ndlp); | ||
4610 | } | 4769 | } |
4611 | 4770 | ||
4612 | int | 4771 | int |
@@ -4686,11 +4845,12 @@ lpfc_resume_fabric_iocbs(struct lpfc_hba *phba) | |||
4686 | repeat: | 4845 | repeat: |
4687 | iocb = NULL; | 4846 | iocb = NULL; |
4688 | spin_lock_irqsave(&phba->hbalock, iflags); | 4847 | spin_lock_irqsave(&phba->hbalock, iflags); |
4689 | /* Post any pending iocb to the SLI layer */ | 4848 | /* Post any pending iocb to the SLI layer */ |
4690 | if (atomic_read(&phba->fabric_iocb_count) == 0) { | 4849 | if (atomic_read(&phba->fabric_iocb_count) == 0) { |
4691 | list_remove_head(&phba->fabric_iocb_list, iocb, typeof(*iocb), | 4850 | list_remove_head(&phba->fabric_iocb_list, iocb, typeof(*iocb), |
4692 | list); | 4851 | list); |
4693 | if (iocb) | 4852 | if (iocb) |
4853 | /* Increment fabric iocb count to hold the position */ | ||
4694 | atomic_inc(&phba->fabric_iocb_count); | 4854 | atomic_inc(&phba->fabric_iocb_count); |
4695 | } | 4855 | } |
4696 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 4856 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
@@ -4737,9 +4897,7 @@ lpfc_block_fabric_iocbs(struct lpfc_hba *phba) | |||
4737 | int blocked; | 4897 | int blocked; |
4738 | 4898 | ||
4739 | blocked = test_and_set_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags); | 4899 | blocked = test_and_set_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags); |
4740 | /* Start a timer to unblock fabric | 4900 | /* Start a timer to unblock fabric iocbs after 100ms */ |
4741 | * iocbs after 100ms | ||
4742 | */ | ||
4743 | if (!blocked) | 4901 | if (!blocked) |
4744 | mod_timer(&phba->fabric_block_timer, jiffies + HZ/10 ); | 4902 | mod_timer(&phba->fabric_block_timer, jiffies + HZ/10 ); |
4745 | 4903 | ||
@@ -4787,8 +4945,8 @@ lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4787 | 4945 | ||
4788 | atomic_dec(&phba->fabric_iocb_count); | 4946 | atomic_dec(&phba->fabric_iocb_count); |
4789 | if (!test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags)) { | 4947 | if (!test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags)) { |
4790 | /* Post any pending iocbs to HBA */ | 4948 | /* Post any pending iocbs to HBA */ |
4791 | lpfc_resume_fabric_iocbs(phba); | 4949 | lpfc_resume_fabric_iocbs(phba); |
4792 | } | 4950 | } |
4793 | } | 4951 | } |
4794 | 4952 | ||
@@ -4807,6 +4965,9 @@ lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) | |||
4807 | ready = atomic_read(&phba->fabric_iocb_count) == 0 && | 4965 | ready = atomic_read(&phba->fabric_iocb_count) == 0 && |
4808 | !test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags); | 4966 | !test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags); |
4809 | 4967 | ||
4968 | if (ready) | ||
4969 | /* Increment fabric iocb count to hold the position */ | ||
4970 | atomic_inc(&phba->fabric_iocb_count); | ||
4810 | spin_unlock_irqrestore(&phba->hbalock, iflags); | 4971 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
4811 | if (ready) { | 4972 | if (ready) { |
4812 | iocb->fabric_iocb_cmpl = iocb->iocb_cmpl; | 4973 | iocb->fabric_iocb_cmpl = iocb->iocb_cmpl; |
@@ -4817,7 +4978,6 @@ lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) | |||
4817 | "Fabric sched2: ste:x%x", | 4978 | "Fabric sched2: ste:x%x", |
4818 | iocb->vport->port_state, 0, 0); | 4979 | iocb->vport->port_state, 0, 0); |
4819 | 4980 | ||
4820 | atomic_inc(&phba->fabric_iocb_count); | ||
4821 | ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0); | 4981 | ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0); |
4822 | 4982 | ||
4823 | if (ret == IOCB_ERROR) { | 4983 | if (ret == IOCB_ERROR) { |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index dc042bd97baa..bd572d6b60af 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -272,9 +272,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
272 | if (!(vport->load_flag & FC_UNLOADING) && | 272 | if (!(vport->load_flag & FC_UNLOADING) && |
273 | !(ndlp->nlp_flag & NLP_DELAY_TMO) && | 273 | !(ndlp->nlp_flag & NLP_DELAY_TMO) && |
274 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && | 274 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
275 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) { | 275 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) |
276 | lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); | 276 | lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); |
277 | } | ||
278 | } | 277 | } |
279 | 278 | ||
280 | 279 | ||
@@ -566,9 +565,10 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) | |||
566 | int rc; | 565 | int rc; |
567 | 566 | ||
568 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { | 567 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { |
568 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
569 | continue; | ||
569 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 570 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) |
570 | continue; | 571 | continue; |
571 | |||
572 | if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) || | 572 | if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) || |
573 | ((vport->port_type == LPFC_NPIV_PORT) && | 573 | ((vport->port_type == LPFC_NPIV_PORT) && |
574 | (ndlp->nlp_DID == NameServer_DID))) | 574 | (ndlp->nlp_DID == NameServer_DID))) |
@@ -629,9 +629,8 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
629 | LPFC_MBOXQ_t *mb; | 629 | LPFC_MBOXQ_t *mb; |
630 | int i; | 630 | int i; |
631 | 631 | ||
632 | if (phba->link_state == LPFC_LINK_DOWN) { | 632 | if (phba->link_state == LPFC_LINK_DOWN) |
633 | return 0; | 633 | return 0; |
634 | } | ||
635 | spin_lock_irq(&phba->hbalock); | 634 | spin_lock_irq(&phba->hbalock); |
636 | if (phba->link_state > LPFC_LINK_DOWN) { | 635 | if (phba->link_state > LPFC_LINK_DOWN) { |
637 | phba->link_state = LPFC_LINK_DOWN; | 636 | phba->link_state = LPFC_LINK_DOWN; |
@@ -684,20 +683,21 @@ lpfc_linkup_cleanup_nodes(struct lpfc_vport *vport) | |||
684 | struct lpfc_nodelist *ndlp; | 683 | struct lpfc_nodelist *ndlp; |
685 | 684 | ||
686 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { | 685 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
686 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
687 | continue; | ||
687 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 688 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) |
688 | continue; | 689 | continue; |
689 | |||
690 | if (ndlp->nlp_type & NLP_FABRIC) { | 690 | if (ndlp->nlp_type & NLP_FABRIC) { |
691 | /* On Linkup its safe to clean up the ndlp | 691 | /* On Linkup its safe to clean up the ndlp |
692 | * from Fabric connections. | 692 | * from Fabric connections. |
693 | */ | 693 | */ |
694 | if (ndlp->nlp_DID != Fabric_DID) | 694 | if (ndlp->nlp_DID != Fabric_DID) |
695 | lpfc_unreg_rpi(vport, ndlp); | 695 | lpfc_unreg_rpi(vport, ndlp); |
696 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 696 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
697 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | 697 | } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { |
698 | /* Fail outstanding IO now since device is | 698 | /* Fail outstanding IO now since device is |
699 | * marked for PLOGI. | 699 | * marked for PLOGI. |
700 | */ | 700 | */ |
701 | lpfc_unreg_rpi(vport, ndlp); | 701 | lpfc_unreg_rpi(vport, ndlp); |
702 | } | 702 | } |
703 | } | 703 | } |
@@ -799,21 +799,9 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
799 | writel(control, phba->HCregaddr); | 799 | writel(control, phba->HCregaddr); |
800 | readl(phba->HCregaddr); /* flush */ | 800 | readl(phba->HCregaddr); /* flush */ |
801 | spin_unlock_irq(&phba->hbalock); | 801 | spin_unlock_irq(&phba->hbalock); |
802 | mempool_free(pmb, phba->mbox_mem_pool); | ||
802 | return; | 803 | return; |
803 | 804 | ||
804 | vport->num_disc_nodes = 0; | ||
805 | /* go thru NPR nodes and issue ELS PLOGIs */ | ||
806 | if (vport->fc_npr_cnt) | ||
807 | lpfc_els_disc_plogi(vport); | ||
808 | |||
809 | if (!vport->num_disc_nodes) { | ||
810 | spin_lock_irq(shost->host_lock); | ||
811 | vport->fc_flag &= ~FC_NDISC_ACTIVE; | ||
812 | spin_unlock_irq(shost->host_lock); | ||
813 | } | ||
814 | |||
815 | vport->port_state = LPFC_VPORT_READY; | ||
816 | |||
817 | out: | 805 | out: |
818 | /* Device Discovery completes */ | 806 | /* Device Discovery completes */ |
819 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 807 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
@@ -1133,7 +1121,7 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1133 | if (la->attType == AT_LINK_UP) { | 1121 | if (la->attType == AT_LINK_UP) { |
1134 | phba->fc_stat.LinkUp++; | 1122 | phba->fc_stat.LinkUp++; |
1135 | if (phba->link_flag & LS_LOOPBACK_MODE) { | 1123 | if (phba->link_flag & LS_LOOPBACK_MODE) { |
1136 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, | 1124 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, |
1137 | "1306 Link Up Event in loop back mode " | 1125 | "1306 Link Up Event in loop back mode " |
1138 | "x%x received Data: x%x x%x x%x x%x\n", | 1126 | "x%x received Data: x%x x%x x%x x%x\n", |
1139 | la->eventTag, phba->fc_eventTag, | 1127 | la->eventTag, phba->fc_eventTag, |
@@ -1150,11 +1138,21 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1150 | lpfc_mbx_process_link_up(phba, la); | 1138 | lpfc_mbx_process_link_up(phba, la); |
1151 | } else { | 1139 | } else { |
1152 | phba->fc_stat.LinkDown++; | 1140 | phba->fc_stat.LinkDown++; |
1153 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | 1141 | if (phba->link_flag & LS_LOOPBACK_MODE) { |
1142 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | ||
1143 | "1308 Link Down Event in loop back mode " | ||
1144 | "x%x received " | ||
1145 | "Data: x%x x%x x%x\n", | ||
1146 | la->eventTag, phba->fc_eventTag, | ||
1147 | phba->pport->port_state, vport->fc_flag); | ||
1148 | } | ||
1149 | else { | ||
1150 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | ||
1154 | "1305 Link Down Event x%x received " | 1151 | "1305 Link Down Event x%x received " |
1155 | "Data: x%x x%x x%x\n", | 1152 | "Data: x%x x%x x%x\n", |
1156 | la->eventTag, phba->fc_eventTag, | 1153 | la->eventTag, phba->fc_eventTag, |
1157 | phba->pport->port_state, vport->fc_flag); | 1154 | phba->pport->port_state, vport->fc_flag); |
1155 | } | ||
1158 | lpfc_mbx_issue_link_down(phba); | 1156 | lpfc_mbx_issue_link_down(phba); |
1159 | } | 1157 | } |
1160 | 1158 | ||
@@ -1305,7 +1303,6 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1305 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1303 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1306 | kfree(mp); | 1304 | kfree(mp); |
1307 | mempool_free(pmb, phba->mbox_mem_pool); | 1305 | mempool_free(pmb, phba->mbox_mem_pool); |
1308 | lpfc_nlp_put(ndlp); | ||
1309 | 1306 | ||
1310 | if (phba->fc_topology == TOPOLOGY_LOOP) { | 1307 | if (phba->fc_topology == TOPOLOGY_LOOP) { |
1311 | /* FLOGI failed, use loop map to make discovery list */ | 1308 | /* FLOGI failed, use loop map to make discovery list */ |
@@ -1313,6 +1310,10 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1313 | 1310 | ||
1314 | /* Start discovery */ | 1311 | /* Start discovery */ |
1315 | lpfc_disc_start(vport); | 1312 | lpfc_disc_start(vport); |
1313 | /* Decrement the reference count to ndlp after the | ||
1314 | * reference to the ndlp are done. | ||
1315 | */ | ||
1316 | lpfc_nlp_put(ndlp); | ||
1316 | return; | 1317 | return; |
1317 | } | 1318 | } |
1318 | 1319 | ||
@@ -1320,6 +1321,10 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1320 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 1321 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
1321 | "0258 Register Fabric login error: 0x%x\n", | 1322 | "0258 Register Fabric login error: 0x%x\n", |
1322 | mb->mbxStatus); | 1323 | mb->mbxStatus); |
1324 | /* Decrement the reference count to ndlp after the reference | ||
1325 | * to the ndlp are done. | ||
1326 | */ | ||
1327 | lpfc_nlp_put(ndlp); | ||
1323 | return; | 1328 | return; |
1324 | } | 1329 | } |
1325 | 1330 | ||
@@ -1327,8 +1332,6 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1327 | ndlp->nlp_type |= NLP_FABRIC; | 1332 | ndlp->nlp_type |= NLP_FABRIC; |
1328 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | 1333 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
1329 | 1334 | ||
1330 | lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */ | ||
1331 | |||
1332 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { | 1335 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { |
1333 | vports = lpfc_create_vport_work_array(phba); | 1336 | vports = lpfc_create_vport_work_array(phba); |
1334 | if (vports != NULL) | 1337 | if (vports != NULL) |
@@ -1356,6 +1359,11 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1356 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1359 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1357 | kfree(mp); | 1360 | kfree(mp); |
1358 | mempool_free(pmb, phba->mbox_mem_pool); | 1361 | mempool_free(pmb, phba->mbox_mem_pool); |
1362 | |||
1363 | /* Drop the reference count from the mbox at the end after | ||
1364 | * all the current reference to the ndlp have been done. | ||
1365 | */ | ||
1366 | lpfc_nlp_put(ndlp); | ||
1359 | return; | 1367 | return; |
1360 | } | 1368 | } |
1361 | 1369 | ||
@@ -1463,9 +1471,8 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
1463 | * registered the port. | 1471 | * registered the port. |
1464 | */ | 1472 | */ |
1465 | if (ndlp->rport && ndlp->rport->dd_data && | 1473 | if (ndlp->rport && ndlp->rport->dd_data && |
1466 | ((struct lpfc_rport_data *) ndlp->rport->dd_data)->pnode == ndlp) { | 1474 | ((struct lpfc_rport_data *) ndlp->rport->dd_data)->pnode == ndlp) |
1467 | lpfc_nlp_put(ndlp); | 1475 | lpfc_nlp_put(ndlp); |
1468 | } | ||
1469 | 1476 | ||
1470 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT, | 1477 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT, |
1471 | "rport add: did:x%x flg:x%x type x%x", | 1478 | "rport add: did:x%x flg:x%x type x%x", |
@@ -1660,6 +1667,18 @@ lpfc_nlp_set_state(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1660 | } | 1667 | } |
1661 | 1668 | ||
1662 | void | 1669 | void |
1670 | lpfc_enqueue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | ||
1671 | { | ||
1672 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1673 | |||
1674 | if (list_empty(&ndlp->nlp_listp)) { | ||
1675 | spin_lock_irq(shost->host_lock); | ||
1676 | list_add_tail(&ndlp->nlp_listp, &vport->fc_nodes); | ||
1677 | spin_unlock_irq(shost->host_lock); | ||
1678 | } | ||
1679 | } | ||
1680 | |||
1681 | void | ||
1663 | lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | 1682 | lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1664 | { | 1683 | { |
1665 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 1684 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
@@ -1672,7 +1691,80 @@ lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
1672 | list_del_init(&ndlp->nlp_listp); | 1691 | list_del_init(&ndlp->nlp_listp); |
1673 | spin_unlock_irq(shost->host_lock); | 1692 | spin_unlock_irq(shost->host_lock); |
1674 | lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state, | 1693 | lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state, |
1675 | NLP_STE_UNUSED_NODE); | 1694 | NLP_STE_UNUSED_NODE); |
1695 | } | ||
1696 | |||
1697 | void | ||
1698 | lpfc_disable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | ||
1699 | { | ||
1700 | if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) | ||
1701 | lpfc_cancel_retry_delay_tmo(vport, ndlp); | ||
1702 | if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) | ||
1703 | lpfc_nlp_counters(vport, ndlp->nlp_state, -1); | ||
1704 | lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state, | ||
1705 | NLP_STE_UNUSED_NODE); | ||
1706 | } | ||
1707 | |||
1708 | struct lpfc_nodelist * | ||
1709 | lpfc_enable_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | ||
1710 | int state) | ||
1711 | { | ||
1712 | struct lpfc_hba *phba = vport->phba; | ||
1713 | uint32_t did; | ||
1714 | unsigned long flags; | ||
1715 | |||
1716 | if (!ndlp) | ||
1717 | return NULL; | ||
1718 | |||
1719 | spin_lock_irqsave(&phba->ndlp_lock, flags); | ||
1720 | /* The ndlp should not be in memory free mode */ | ||
1721 | if (NLP_CHK_FREE_REQ(ndlp)) { | ||
1722 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); | ||
1723 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, | ||
1724 | "0277 lpfc_enable_node: ndlp:x%p " | ||
1725 | "usgmap:x%x refcnt:%d\n", | ||
1726 | (void *)ndlp, ndlp->nlp_usg_map, | ||
1727 | atomic_read(&ndlp->kref.refcount)); | ||
1728 | return NULL; | ||
1729 | } | ||
1730 | /* The ndlp should not already be in active mode */ | ||
1731 | if (NLP_CHK_NODE_ACT(ndlp)) { | ||
1732 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); | ||
1733 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, | ||
1734 | "0278 lpfc_enable_node: ndlp:x%p " | ||
1735 | "usgmap:x%x refcnt:%d\n", | ||
1736 | (void *)ndlp, ndlp->nlp_usg_map, | ||
1737 | atomic_read(&ndlp->kref.refcount)); | ||
1738 | return NULL; | ||
1739 | } | ||
1740 | |||
1741 | /* Keep the original DID */ | ||
1742 | did = ndlp->nlp_DID; | ||
1743 | |||
1744 | /* re-initialize ndlp except of ndlp linked list pointer */ | ||
1745 | memset((((char *)ndlp) + sizeof (struct list_head)), 0, | ||
1746 | sizeof (struct lpfc_nodelist) - sizeof (struct list_head)); | ||
1747 | INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); | ||
1748 | INIT_LIST_HEAD(&ndlp->dev_loss_evt.evt_listp); | ||
1749 | init_timer(&ndlp->nlp_delayfunc); | ||
1750 | ndlp->nlp_delayfunc.function = lpfc_els_retry_delay; | ||
1751 | ndlp->nlp_delayfunc.data = (unsigned long)ndlp; | ||
1752 | ndlp->nlp_DID = did; | ||
1753 | ndlp->vport = vport; | ||
1754 | ndlp->nlp_sid = NLP_NO_SID; | ||
1755 | /* ndlp management re-initialize */ | ||
1756 | kref_init(&ndlp->kref); | ||
1757 | NLP_INT_NODE_ACT(ndlp); | ||
1758 | |||
1759 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); | ||
1760 | |||
1761 | if (state != NLP_STE_UNUSED_NODE) | ||
1762 | lpfc_nlp_set_state(vport, ndlp, state); | ||
1763 | |||
1764 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE, | ||
1765 | "node enable: did:x%x", | ||
1766 | ndlp->nlp_DID, 0, 0); | ||
1767 | return ndlp; | ||
1676 | } | 1768 | } |
1677 | 1769 | ||
1678 | void | 1770 | void |
@@ -1972,7 +2064,21 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
1972 | "Data: x%x x%x x%x\n", | 2064 | "Data: x%x x%x x%x\n", |
1973 | ndlp->nlp_DID, ndlp->nlp_flag, | 2065 | ndlp->nlp_DID, ndlp->nlp_flag, |
1974 | ndlp->nlp_state, ndlp->nlp_rpi); | 2066 | ndlp->nlp_state, ndlp->nlp_rpi); |
1975 | lpfc_dequeue_node(vport, ndlp); | 2067 | if (NLP_CHK_FREE_REQ(ndlp)) { |
2068 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, | ||
2069 | "0280 lpfc_cleanup_node: ndlp:x%p " | ||
2070 | "usgmap:x%x refcnt:%d\n", | ||
2071 | (void *)ndlp, ndlp->nlp_usg_map, | ||
2072 | atomic_read(&ndlp->kref.refcount)); | ||
2073 | lpfc_dequeue_node(vport, ndlp); | ||
2074 | } else { | ||
2075 | lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, | ||
2076 | "0281 lpfc_cleanup_node: ndlp:x%p " | ||
2077 | "usgmap:x%x refcnt:%d\n", | ||
2078 | (void *)ndlp, ndlp->nlp_usg_map, | ||
2079 | atomic_read(&ndlp->kref.refcount)); | ||
2080 | lpfc_disable_node(vport, ndlp); | ||
2081 | } | ||
1976 | 2082 | ||
1977 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ | 2083 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ |
1978 | if ((mb = phba->sli.mbox_active)) { | 2084 | if ((mb = phba->sli.mbox_active)) { |
@@ -1994,12 +2100,16 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
1994 | } | 2100 | } |
1995 | list_del(&mb->list); | 2101 | list_del(&mb->list); |
1996 | mempool_free(mb, phba->mbox_mem_pool); | 2102 | mempool_free(mb, phba->mbox_mem_pool); |
1997 | lpfc_nlp_put(ndlp); | 2103 | /* We shall not invoke the lpfc_nlp_put to decrement |
2104 | * the ndlp reference count as we are in the process | ||
2105 | * of lpfc_nlp_release. | ||
2106 | */ | ||
1998 | } | 2107 | } |
1999 | } | 2108 | } |
2000 | spin_unlock_irq(&phba->hbalock); | 2109 | spin_unlock_irq(&phba->hbalock); |
2001 | 2110 | ||
2002 | lpfc_els_abort(phba,ndlp); | 2111 | lpfc_els_abort(phba, ndlp); |
2112 | |||
2003 | spin_lock_irq(shost->host_lock); | 2113 | spin_lock_irq(shost->host_lock); |
2004 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 2114 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; |
2005 | spin_unlock_irq(shost->host_lock); | 2115 | spin_unlock_irq(shost->host_lock); |
@@ -2057,7 +2167,6 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
2057 | } | 2167 | } |
2058 | } | 2168 | } |
2059 | } | 2169 | } |
2060 | |||
2061 | lpfc_cleanup_node(vport, ndlp); | 2170 | lpfc_cleanup_node(vport, ndlp); |
2062 | 2171 | ||
2063 | /* | 2172 | /* |
@@ -2182,7 +2291,16 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | |||
2182 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | 2291 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; |
2183 | spin_unlock_irq(shost->host_lock); | 2292 | spin_unlock_irq(shost->host_lock); |
2184 | return ndlp; | 2293 | return ndlp; |
2294 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { | ||
2295 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_NPR_NODE); | ||
2296 | if (!ndlp) | ||
2297 | return NULL; | ||
2298 | spin_lock_irq(shost->host_lock); | ||
2299 | ndlp->nlp_flag |= NLP_NPR_2B_DISC; | ||
2300 | spin_unlock_irq(shost->host_lock); | ||
2301 | return ndlp; | ||
2185 | } | 2302 | } |
2303 | |||
2186 | if (vport->fc_flag & FC_RSCN_MODE) { | 2304 | if (vport->fc_flag & FC_RSCN_MODE) { |
2187 | if (lpfc_rscn_payload_check(vport, did)) { | 2305 | if (lpfc_rscn_payload_check(vport, did)) { |
2188 | /* If we've already recieved a PLOGI from this NPort | 2306 | /* If we've already recieved a PLOGI from this NPort |
@@ -2363,6 +2481,7 @@ lpfc_disc_start(struct lpfc_vport *vport) | |||
2363 | * continue discovery. | 2481 | * continue discovery. |
2364 | */ | 2482 | */ |
2365 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && | 2483 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && |
2484 | !(vport->fc_flag & FC_PT2PT) && | ||
2366 | !(vport->fc_flag & FC_RSCN_MODE)) { | 2485 | !(vport->fc_flag & FC_RSCN_MODE)) { |
2367 | lpfc_issue_reg_vpi(phba, vport); | 2486 | lpfc_issue_reg_vpi(phba, vport); |
2368 | return; | 2487 | return; |
@@ -2485,6 +2604,8 @@ lpfc_disc_flush_list(struct lpfc_vport *vport) | |||
2485 | if (vport->fc_plogi_cnt || vport->fc_adisc_cnt) { | 2604 | if (vport->fc_plogi_cnt || vport->fc_adisc_cnt) { |
2486 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, | 2605 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, |
2487 | nlp_listp) { | 2606 | nlp_listp) { |
2607 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
2608 | continue; | ||
2488 | if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE || | 2609 | if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE || |
2489 | ndlp->nlp_state == NLP_STE_ADISC_ISSUE) { | 2610 | ndlp->nlp_state == NLP_STE_ADISC_ISSUE) { |
2490 | lpfc_free_tx(phba, ndlp); | 2611 | lpfc_free_tx(phba, ndlp); |
@@ -2572,6 +2693,8 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) | |||
2572 | /* Start discovery by sending FLOGI, clean up old rpis */ | 2693 | /* Start discovery by sending FLOGI, clean up old rpis */ |
2573 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, | 2694 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, |
2574 | nlp_listp) { | 2695 | nlp_listp) { |
2696 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
2697 | continue; | ||
2575 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) | 2698 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) |
2576 | continue; | 2699 | continue; |
2577 | if (ndlp->nlp_type & NLP_FABRIC) { | 2700 | if (ndlp->nlp_type & NLP_FABRIC) { |
@@ -2618,7 +2741,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport) | |||
2618 | "NameServer login\n"); | 2741 | "NameServer login\n"); |
2619 | /* Next look for NameServer ndlp */ | 2742 | /* Next look for NameServer ndlp */ |
2620 | ndlp = lpfc_findnode_did(vport, NameServer_DID); | 2743 | ndlp = lpfc_findnode_did(vport, NameServer_DID); |
2621 | if (ndlp) | 2744 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) |
2622 | lpfc_els_abort(phba, ndlp); | 2745 | lpfc_els_abort(phba, ndlp); |
2623 | 2746 | ||
2624 | /* ReStart discovery */ | 2747 | /* ReStart discovery */ |
@@ -2897,6 +3020,7 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
2897 | ndlp->nlp_sid = NLP_NO_SID; | 3020 | ndlp->nlp_sid = NLP_NO_SID; |
2898 | INIT_LIST_HEAD(&ndlp->nlp_listp); | 3021 | INIT_LIST_HEAD(&ndlp->nlp_listp); |
2899 | kref_init(&ndlp->kref); | 3022 | kref_init(&ndlp->kref); |
3023 | NLP_INT_NODE_ACT(ndlp); | ||
2900 | 3024 | ||
2901 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE, | 3025 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE, |
2902 | "node init: did:x%x", | 3026 | "node init: did:x%x", |
@@ -2911,6 +3035,8 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
2911 | static void | 3035 | static void |
2912 | lpfc_nlp_release(struct kref *kref) | 3036 | lpfc_nlp_release(struct kref *kref) |
2913 | { | 3037 | { |
3038 | struct lpfc_hba *phba; | ||
3039 | unsigned long flags; | ||
2914 | struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist, | 3040 | struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist, |
2915 | kref); | 3041 | kref); |
2916 | 3042 | ||
@@ -2918,8 +3044,24 @@ lpfc_nlp_release(struct kref *kref) | |||
2918 | "node release: did:x%x flg:x%x type:x%x", | 3044 | "node release: did:x%x flg:x%x type:x%x", |
2919 | ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); | 3045 | ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); |
2920 | 3046 | ||
3047 | lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, | ||
3048 | "0279 lpfc_nlp_release: ndlp:x%p " | ||
3049 | "usgmap:x%x refcnt:%d\n", | ||
3050 | (void *)ndlp, ndlp->nlp_usg_map, | ||
3051 | atomic_read(&ndlp->kref.refcount)); | ||
3052 | |||
3053 | /* remove ndlp from action. */ | ||
2921 | lpfc_nlp_remove(ndlp->vport, ndlp); | 3054 | lpfc_nlp_remove(ndlp->vport, ndlp); |
2922 | mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool); | 3055 | |
3056 | /* clear the ndlp active flag for all release cases */ | ||
3057 | phba = ndlp->vport->phba; | ||
3058 | spin_lock_irqsave(&phba->ndlp_lock, flags); | ||
3059 | NLP_CLR_NODE_ACT(ndlp); | ||
3060 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); | ||
3061 | |||
3062 | /* free ndlp memory for final ndlp release */ | ||
3063 | if (NLP_CHK_FREE_REQ(ndlp)) | ||
3064 | mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool); | ||
2923 | } | 3065 | } |
2924 | 3066 | ||
2925 | /* This routine bumps the reference count for a ndlp structure to ensure | 3067 | /* This routine bumps the reference count for a ndlp structure to ensure |
@@ -2929,37 +3071,108 @@ lpfc_nlp_release(struct kref *kref) | |||
2929 | struct lpfc_nodelist * | 3071 | struct lpfc_nodelist * |
2930 | lpfc_nlp_get(struct lpfc_nodelist *ndlp) | 3072 | lpfc_nlp_get(struct lpfc_nodelist *ndlp) |
2931 | { | 3073 | { |
3074 | struct lpfc_hba *phba; | ||
3075 | unsigned long flags; | ||
3076 | |||
2932 | if (ndlp) { | 3077 | if (ndlp) { |
2933 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, | 3078 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, |
2934 | "node get: did:x%x flg:x%x refcnt:x%x", | 3079 | "node get: did:x%x flg:x%x refcnt:x%x", |
2935 | ndlp->nlp_DID, ndlp->nlp_flag, | 3080 | ndlp->nlp_DID, ndlp->nlp_flag, |
2936 | atomic_read(&ndlp->kref.refcount)); | 3081 | atomic_read(&ndlp->kref.refcount)); |
2937 | kref_get(&ndlp->kref); | 3082 | /* The check of ndlp usage to prevent incrementing the |
3083 | * ndlp reference count that is in the process of being | ||
3084 | * released. | ||
3085 | */ | ||
3086 | phba = ndlp->vport->phba; | ||
3087 | spin_lock_irqsave(&phba->ndlp_lock, flags); | ||
3088 | if (!NLP_CHK_NODE_ACT(ndlp) || NLP_CHK_FREE_ACK(ndlp)) { | ||
3089 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); | ||
3090 | lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE, | ||
3091 | "0276 lpfc_nlp_get: ndlp:x%p " | ||
3092 | "usgmap:x%x refcnt:%d\n", | ||
3093 | (void *)ndlp, ndlp->nlp_usg_map, | ||
3094 | atomic_read(&ndlp->kref.refcount)); | ||
3095 | return NULL; | ||
3096 | } else | ||
3097 | kref_get(&ndlp->kref); | ||
3098 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); | ||
2938 | } | 3099 | } |
2939 | return ndlp; | 3100 | return ndlp; |
2940 | } | 3101 | } |
2941 | 3102 | ||
2942 | |||
2943 | /* This routine decrements the reference count for a ndlp structure. If the | 3103 | /* This routine decrements the reference count for a ndlp structure. If the |
2944 | * count goes to 0, this indicates the the associated nodelist should be freed. | 3104 | * count goes to 0, this indicates the the associated nodelist should be |
3105 | * freed. Returning 1 indicates the ndlp resource has been released; on the | ||
3106 | * other hand, returning 0 indicates the ndlp resource has not been released | ||
3107 | * yet. | ||
2945 | */ | 3108 | */ |
2946 | int | 3109 | int |
2947 | lpfc_nlp_put(struct lpfc_nodelist *ndlp) | 3110 | lpfc_nlp_put(struct lpfc_nodelist *ndlp) |
2948 | { | 3111 | { |
2949 | if (ndlp) { | 3112 | struct lpfc_hba *phba; |
2950 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, | 3113 | unsigned long flags; |
2951 | "node put: did:x%x flg:x%x refcnt:x%x", | 3114 | |
2952 | ndlp->nlp_DID, ndlp->nlp_flag, | 3115 | if (!ndlp) |
2953 | atomic_read(&ndlp->kref.refcount)); | 3116 | return 1; |
3117 | |||
3118 | lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE, | ||
3119 | "node put: did:x%x flg:x%x refcnt:x%x", | ||
3120 | ndlp->nlp_DID, ndlp->nlp_flag, | ||
3121 | atomic_read(&ndlp->kref.refcount)); | ||
3122 | phba = ndlp->vport->phba; | ||
3123 | spin_lock_irqsave(&phba->ndlp_lock, flags); | ||
3124 | /* Check the ndlp memory free acknowledge flag to avoid the | ||
3125 | * possible race condition that kref_put got invoked again | ||
3126 | * after previous one has done ndlp memory free. | ||
3127 | */ | ||
3128 | if (NLP_CHK_FREE_ACK(ndlp)) { | ||
3129 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); | ||
3130 | lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE, | ||
3131 | "0274 lpfc_nlp_put: ndlp:x%p " | ||
3132 | "usgmap:x%x refcnt:%d\n", | ||
3133 | (void *)ndlp, ndlp->nlp_usg_map, | ||
3134 | atomic_read(&ndlp->kref.refcount)); | ||
3135 | return 1; | ||
2954 | } | 3136 | } |
2955 | return ndlp ? kref_put(&ndlp->kref, lpfc_nlp_release) : 0; | 3137 | /* Check the ndlp inactivate log flag to avoid the possible |
3138 | * race condition that kref_put got invoked again after ndlp | ||
3139 | * is already in inactivating state. | ||
3140 | */ | ||
3141 | if (NLP_CHK_IACT_REQ(ndlp)) { | ||
3142 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); | ||
3143 | lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_NODE, | ||
3144 | "0275 lpfc_nlp_put: ndlp:x%p " | ||
3145 | "usgmap:x%x refcnt:%d\n", | ||
3146 | (void *)ndlp, ndlp->nlp_usg_map, | ||
3147 | atomic_read(&ndlp->kref.refcount)); | ||
3148 | return 1; | ||
3149 | } | ||
3150 | /* For last put, mark the ndlp usage flags to make sure no | ||
3151 | * other kref_get and kref_put on the same ndlp shall get | ||
3152 | * in between the process when the final kref_put has been | ||
3153 | * invoked on this ndlp. | ||
3154 | */ | ||
3155 | if (atomic_read(&ndlp->kref.refcount) == 1) { | ||
3156 | /* Indicate ndlp is put to inactive state. */ | ||
3157 | NLP_SET_IACT_REQ(ndlp); | ||
3158 | /* Acknowledge ndlp memory free has been seen. */ | ||
3159 | if (NLP_CHK_FREE_REQ(ndlp)) | ||
3160 | NLP_SET_FREE_ACK(ndlp); | ||
3161 | } | ||
3162 | spin_unlock_irqrestore(&phba->ndlp_lock, flags); | ||
3163 | /* Note, the kref_put returns 1 when decrementing a reference | ||
3164 | * count that was 1, it invokes the release callback function, | ||
3165 | * but it still left the reference count as 1 (not actually | ||
3166 | * performs the last decrementation). Otherwise, it actually | ||
3167 | * decrements the reference count and returns 0. | ||
3168 | */ | ||
3169 | return kref_put(&ndlp->kref, lpfc_nlp_release); | ||
2956 | } | 3170 | } |
2957 | 3171 | ||
2958 | /* This routine free's the specified nodelist if it is not in use | 3172 | /* This routine free's the specified nodelist if it is not in use |
2959 | * by any other discovery thread. This routine returns 1 if the ndlp | 3173 | * by any other discovery thread. This routine returns 1 if the |
2960 | * is not being used by anyone and has been freed. A return value of | 3174 | * ndlp has been freed. A return value of 0 indicates the ndlp is |
2961 | * 0 indicates it is being used by another discovery thread and the | 3175 | * not yet been released. |
2962 | * refcount is left unchanged. | ||
2963 | */ | 3176 | */ |
2964 | int | 3177 | int |
2965 | lpfc_nlp_not_used(struct lpfc_nodelist *ndlp) | 3178 | lpfc_nlp_not_used(struct lpfc_nodelist *ndlp) |
@@ -2968,11 +3181,8 @@ lpfc_nlp_not_used(struct lpfc_nodelist *ndlp) | |||
2968 | "node not used: did:x%x flg:x%x refcnt:x%x", | 3181 | "node not used: did:x%x flg:x%x refcnt:x%x", |
2969 | ndlp->nlp_DID, ndlp->nlp_flag, | 3182 | ndlp->nlp_DID, ndlp->nlp_flag, |
2970 | atomic_read(&ndlp->kref.refcount)); | 3183 | atomic_read(&ndlp->kref.refcount)); |
2971 | 3184 | if (atomic_read(&ndlp->kref.refcount) == 1) | |
2972 | if (atomic_read(&ndlp->kref.refcount) == 1) { | 3185 | if (lpfc_nlp_put(ndlp)) |
2973 | lpfc_nlp_put(ndlp); | 3186 | return 1; |
2974 | return 1; | ||
2975 | } | ||
2976 | return 0; | 3187 | return 0; |
2977 | } | 3188 | } |
2978 | |||
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 041f83e7634a..7773b949aa7c 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -581,6 +581,7 @@ struct ls_rjt { /* Structure is in Big Endian format */ | |||
581 | #define LSEXP_INVALID_O_SID 0x15 | 581 | #define LSEXP_INVALID_O_SID 0x15 |
582 | #define LSEXP_INVALID_OX_RX 0x17 | 582 | #define LSEXP_INVALID_OX_RX 0x17 |
583 | #define LSEXP_CMD_IN_PROGRESS 0x19 | 583 | #define LSEXP_CMD_IN_PROGRESS 0x19 |
584 | #define LSEXP_PORT_LOGIN_REQ 0x1E | ||
584 | #define LSEXP_INVALID_NPORT_ID 0x1F | 585 | #define LSEXP_INVALID_NPORT_ID 0x1F |
585 | #define LSEXP_INVALID_SEQ_ID 0x21 | 586 | #define LSEXP_INVALID_SEQ_ID 0x21 |
586 | #define LSEXP_INVALID_XCHG 0x23 | 587 | #define LSEXP_INVALID_XCHG 0x23 |
@@ -1376,11 +1377,26 @@ typedef struct { /* FireFly BIU registers */ | |||
1376 | #define CMD_QUE_XRI64_CX 0xB3 | 1377 | #define CMD_QUE_XRI64_CX 0xB3 |
1377 | #define CMD_IOCB_RCV_SEQ64_CX 0xB5 | 1378 | #define CMD_IOCB_RCV_SEQ64_CX 0xB5 |
1378 | #define CMD_IOCB_RCV_ELS64_CX 0xB7 | 1379 | #define CMD_IOCB_RCV_ELS64_CX 0xB7 |
1380 | #define CMD_IOCB_RET_XRI64_CX 0xB9 | ||
1379 | #define CMD_IOCB_RCV_CONT64_CX 0xBB | 1381 | #define CMD_IOCB_RCV_CONT64_CX 0xBB |
1380 | 1382 | ||
1381 | #define CMD_GEN_REQUEST64_CR 0xC2 | 1383 | #define CMD_GEN_REQUEST64_CR 0xC2 |
1382 | #define CMD_GEN_REQUEST64_CX 0xC3 | 1384 | #define CMD_GEN_REQUEST64_CX 0xC3 |
1383 | 1385 | ||
1386 | /* Unhandled SLI-3 Commands */ | ||
1387 | #define CMD_IOCB_XMIT_MSEQ64_CR 0xB0 | ||
1388 | #define CMD_IOCB_XMIT_MSEQ64_CX 0xB1 | ||
1389 | #define CMD_IOCB_RCV_SEQ_LIST64_CX 0xC1 | ||
1390 | #define CMD_IOCB_RCV_ELS_LIST64_CX 0xCD | ||
1391 | #define CMD_IOCB_CLOSE_EXTENDED_CN 0xB6 | ||
1392 | #define CMD_IOCB_ABORT_EXTENDED_CN 0xBA | ||
1393 | #define CMD_IOCB_RET_HBQE64_CN 0xCA | ||
1394 | #define CMD_IOCB_FCP_IBIDIR64_CR 0xAC | ||
1395 | #define CMD_IOCB_FCP_IBIDIR64_CX 0xAD | ||
1396 | #define CMD_IOCB_FCP_ITASKMGT64_CX 0xAF | ||
1397 | #define CMD_IOCB_LOGENTRY_CN 0x94 | ||
1398 | #define CMD_IOCB_LOGENTRY_ASYNC_CN 0x96 | ||
1399 | |||
1384 | #define CMD_MAX_IOCB_CMD 0xE6 | 1400 | #define CMD_MAX_IOCB_CMD 0xE6 |
1385 | #define CMD_IOCB_MASK 0xff | 1401 | #define CMD_IOCB_MASK 0xff |
1386 | 1402 | ||
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 6cfeba7454d4..22843751c2ca 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -461,11 +461,21 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |||
461 | int | 461 | int |
462 | lpfc_hba_down_prep(struct lpfc_hba *phba) | 462 | lpfc_hba_down_prep(struct lpfc_hba *phba) |
463 | { | 463 | { |
464 | struct lpfc_vport **vports; | ||
465 | int i; | ||
464 | /* Disable interrupts */ | 466 | /* Disable interrupts */ |
465 | writel(0, phba->HCregaddr); | 467 | writel(0, phba->HCregaddr); |
466 | readl(phba->HCregaddr); /* flush */ | 468 | readl(phba->HCregaddr); /* flush */ |
467 | 469 | ||
468 | lpfc_cleanup_discovery_resources(phba->pport); | 470 | if (phba->pport->load_flag & FC_UNLOADING) |
471 | lpfc_cleanup_discovery_resources(phba->pport); | ||
472 | else { | ||
473 | vports = lpfc_create_vport_work_array(phba); | ||
474 | if (vports != NULL) | ||
475 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) | ||
476 | lpfc_cleanup_discovery_resources(vports[i]); | ||
477 | lpfc_destroy_vport_work_array(phba, vports); | ||
478 | } | ||
469 | return 0; | 479 | return 0; |
470 | } | 480 | } |
471 | 481 | ||
@@ -1422,9 +1432,32 @@ lpfc_cleanup(struct lpfc_vport *vport) | |||
1422 | lpfc_port_link_failure(vport); | 1432 | lpfc_port_link_failure(vport); |
1423 | 1433 | ||
1424 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { | 1434 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { |
1435 | if (!NLP_CHK_NODE_ACT(ndlp)) { | ||
1436 | ndlp = lpfc_enable_node(vport, ndlp, | ||
1437 | NLP_STE_UNUSED_NODE); | ||
1438 | if (!ndlp) | ||
1439 | continue; | ||
1440 | spin_lock_irq(&phba->ndlp_lock); | ||
1441 | NLP_SET_FREE_REQ(ndlp); | ||
1442 | spin_unlock_irq(&phba->ndlp_lock); | ||
1443 | /* Trigger the release of the ndlp memory */ | ||
1444 | lpfc_nlp_put(ndlp); | ||
1445 | continue; | ||
1446 | } | ||
1447 | spin_lock_irq(&phba->ndlp_lock); | ||
1448 | if (NLP_CHK_FREE_REQ(ndlp)) { | ||
1449 | /* The ndlp should not be in memory free mode already */ | ||
1450 | spin_unlock_irq(&phba->ndlp_lock); | ||
1451 | continue; | ||
1452 | } else | ||
1453 | /* Indicate request for freeing ndlp memory */ | ||
1454 | NLP_SET_FREE_REQ(ndlp); | ||
1455 | spin_unlock_irq(&phba->ndlp_lock); | ||
1456 | |||
1425 | if (ndlp->nlp_type & NLP_FABRIC) | 1457 | if (ndlp->nlp_type & NLP_FABRIC) |
1426 | lpfc_disc_state_machine(vport, ndlp, NULL, | 1458 | lpfc_disc_state_machine(vport, ndlp, NULL, |
1427 | NLP_EVT_DEVICE_RECOVERY); | 1459 | NLP_EVT_DEVICE_RECOVERY); |
1460 | |||
1428 | lpfc_disc_state_machine(vport, ndlp, NULL, | 1461 | lpfc_disc_state_machine(vport, ndlp, NULL, |
1429 | NLP_EVT_DEVICE_RM); | 1462 | NLP_EVT_DEVICE_RM); |
1430 | } | 1463 | } |
@@ -1438,6 +1471,17 @@ lpfc_cleanup(struct lpfc_vport *vport) | |||
1438 | if (i++ > 3000) { | 1471 | if (i++ > 3000) { |
1439 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 1472 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
1440 | "0233 Nodelist not empty\n"); | 1473 | "0233 Nodelist not empty\n"); |
1474 | list_for_each_entry_safe(ndlp, next_ndlp, | ||
1475 | &vport->fc_nodes, nlp_listp) { | ||
1476 | lpfc_printf_vlog(ndlp->vport, KERN_ERR, | ||
1477 | LOG_NODE, | ||
1478 | "0282: did:x%x ndlp:x%p " | ||
1479 | "usgmap:x%x refcnt:%d\n", | ||
1480 | ndlp->nlp_DID, (void *)ndlp, | ||
1481 | ndlp->nlp_usg_map, | ||
1482 | atomic_read( | ||
1483 | &ndlp->kref.refcount)); | ||
1484 | } | ||
1441 | break; | 1485 | break; |
1442 | } | 1486 | } |
1443 | 1487 | ||
@@ -1586,6 +1630,8 @@ lpfc_offline_prep(struct lpfc_hba * phba) | |||
1586 | list_for_each_entry_safe(ndlp, next_ndlp, | 1630 | list_for_each_entry_safe(ndlp, next_ndlp, |
1587 | &vports[i]->fc_nodes, | 1631 | &vports[i]->fc_nodes, |
1588 | nlp_listp) { | 1632 | nlp_listp) { |
1633 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
1634 | continue; | ||
1589 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 1635 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) |
1590 | continue; | 1636 | continue; |
1591 | if (ndlp->nlp_type & NLP_FABRIC) { | 1637 | if (ndlp->nlp_type & NLP_FABRIC) { |
@@ -1695,9 +1741,9 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) | |||
1695 | 1741 | ||
1696 | vport = (struct lpfc_vport *) shost->hostdata; | 1742 | vport = (struct lpfc_vport *) shost->hostdata; |
1697 | vport->phba = phba; | 1743 | vport->phba = phba; |
1698 | |||
1699 | vport->load_flag |= FC_LOADING; | 1744 | vport->load_flag |= FC_LOADING; |
1700 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 1745 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
1746 | vport->fc_rscn_flush = 0; | ||
1701 | 1747 | ||
1702 | lpfc_get_vport_cfgparam(vport); | 1748 | lpfc_get_vport_cfgparam(vport); |
1703 | shost->unique_id = instance; | 1749 | shost->unique_id = instance; |
@@ -1879,6 +1925,42 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost) | |||
1879 | spin_unlock_irq(shost->host_lock); | 1925 | spin_unlock_irq(shost->host_lock); |
1880 | } | 1926 | } |
1881 | 1927 | ||
1928 | static int | ||
1929 | lpfc_enable_msix(struct lpfc_hba *phba) | ||
1930 | { | ||
1931 | int error; | ||
1932 | |||
1933 | phba->msix_entries[0].entry = 0; | ||
1934 | phba->msix_entries[0].vector = 0; | ||
1935 | |||
1936 | error = pci_enable_msix(phba->pcidev, phba->msix_entries, | ||
1937 | ARRAY_SIZE(phba->msix_entries)); | ||
1938 | if (error) { | ||
1939 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
1940 | "0420 Enable MSI-X failed (%d), continuing " | ||
1941 | "with MSI\n", error); | ||
1942 | pci_disable_msix(phba->pcidev); | ||
1943 | return error; | ||
1944 | } | ||
1945 | |||
1946 | error = request_irq(phba->msix_entries[0].vector, lpfc_intr_handler, 0, | ||
1947 | LPFC_DRIVER_NAME, phba); | ||
1948 | if (error) { | ||
1949 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1950 | "0421 MSI-X request_irq failed (%d), " | ||
1951 | "continuing with MSI\n", error); | ||
1952 | pci_disable_msix(phba->pcidev); | ||
1953 | } | ||
1954 | return error; | ||
1955 | } | ||
1956 | |||
1957 | static void | ||
1958 | lpfc_disable_msix(struct lpfc_hba *phba) | ||
1959 | { | ||
1960 | free_irq(phba->msix_entries[0].vector, phba); | ||
1961 | pci_disable_msix(phba->pcidev); | ||
1962 | } | ||
1963 | |||
1882 | static int __devinit | 1964 | static int __devinit |
1883 | lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | 1965 | lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) |
1884 | { | 1966 | { |
@@ -1905,6 +1987,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1905 | 1987 | ||
1906 | spin_lock_init(&phba->hbalock); | 1988 | spin_lock_init(&phba->hbalock); |
1907 | 1989 | ||
1990 | /* Initialize ndlp management spinlock */ | ||
1991 | spin_lock_init(&phba->ndlp_lock); | ||
1992 | |||
1908 | phba->pcidev = pdev; | 1993 | phba->pcidev = pdev; |
1909 | 1994 | ||
1910 | /* Assign an unused board number */ | 1995 | /* Assign an unused board number */ |
@@ -2002,6 +2087,8 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
2002 | 2087 | ||
2003 | memset(phba->hbqslimp.virt, 0, lpfc_sli_hbq_size()); | 2088 | memset(phba->hbqslimp.virt, 0, lpfc_sli_hbq_size()); |
2004 | 2089 | ||
2090 | INIT_LIST_HEAD(&phba->hbqbuf_in_list); | ||
2091 | |||
2005 | /* Initialize the SLI Layer to run with lpfc HBAs. */ | 2092 | /* Initialize the SLI Layer to run with lpfc HBAs. */ |
2006 | lpfc_sli_setup(phba); | 2093 | lpfc_sli_setup(phba); |
2007 | lpfc_sli_queue_setup(phba); | 2094 | lpfc_sli_queue_setup(phba); |
@@ -2077,24 +2164,36 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
2077 | lpfc_debugfs_initialize(vport); | 2164 | lpfc_debugfs_initialize(vport); |
2078 | 2165 | ||
2079 | pci_set_drvdata(pdev, shost); | 2166 | pci_set_drvdata(pdev, shost); |
2167 | phba->intr_type = NONE; | ||
2080 | 2168 | ||
2081 | if (phba->cfg_use_msi) { | 2169 | if (phba->cfg_use_msi == 2) { |
2170 | error = lpfc_enable_msix(phba); | ||
2171 | if (!error) | ||
2172 | phba->intr_type = MSIX; | ||
2173 | } | ||
2174 | |||
2175 | /* Fallback to MSI if MSI-X initialization failed */ | ||
2176 | if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) { | ||
2082 | retval = pci_enable_msi(phba->pcidev); | 2177 | retval = pci_enable_msi(phba->pcidev); |
2083 | if (!retval) | 2178 | if (!retval) |
2084 | phba->using_msi = 1; | 2179 | phba->intr_type = MSI; |
2085 | else | 2180 | else |
2086 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | 2181 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
2087 | "0452 Enable MSI failed, continuing " | 2182 | "0452 Enable MSI failed, continuing " |
2088 | "with IRQ\n"); | 2183 | "with IRQ\n"); |
2089 | } | 2184 | } |
2090 | 2185 | ||
2091 | retval = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, | 2186 | /* MSI-X is the only case the doesn't need to call request_irq */ |
2092 | LPFC_DRIVER_NAME, phba); | 2187 | if (phba->intr_type != MSIX) { |
2093 | if (retval) { | 2188 | retval = request_irq(phba->pcidev->irq, lpfc_intr_handler, |
2094 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 2189 | IRQF_SHARED, LPFC_DRIVER_NAME, phba); |
2095 | "0451 Enable interrupt handler failed\n"); | 2190 | if (retval) { |
2096 | error = retval; | 2191 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0451 Enable " |
2097 | goto out_disable_msi; | 2192 | "interrupt handler failed\n"); |
2193 | error = retval; | ||
2194 | goto out_disable_msi; | ||
2195 | } else if (phba->intr_type != MSI) | ||
2196 | phba->intr_type = INTx; | ||
2098 | } | 2197 | } |
2099 | 2198 | ||
2100 | phba->MBslimaddr = phba->slim_memmap_p; | 2199 | phba->MBslimaddr = phba->slim_memmap_p; |
@@ -2139,9 +2238,14 @@ out_remove_device: | |||
2139 | out_free_irq: | 2238 | out_free_irq: |
2140 | lpfc_stop_phba_timers(phba); | 2239 | lpfc_stop_phba_timers(phba); |
2141 | phba->pport->work_port_events = 0; | 2240 | phba->pport->work_port_events = 0; |
2142 | free_irq(phba->pcidev->irq, phba); | 2241 | |
2242 | if (phba->intr_type == MSIX) | ||
2243 | lpfc_disable_msix(phba); | ||
2244 | else | ||
2245 | free_irq(phba->pcidev->irq, phba); | ||
2246 | |||
2143 | out_disable_msi: | 2247 | out_disable_msi: |
2144 | if (phba->using_msi) | 2248 | if (phba->intr_type == MSI) |
2145 | pci_disable_msi(phba->pcidev); | 2249 | pci_disable_msi(phba->pcidev); |
2146 | destroy_port(vport); | 2250 | destroy_port(vport); |
2147 | out_kthread_stop: | 2251 | out_kthread_stop: |
@@ -2214,10 +2318,13 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
2214 | 2318 | ||
2215 | lpfc_debugfs_terminate(vport); | 2319 | lpfc_debugfs_terminate(vport); |
2216 | 2320 | ||
2217 | /* Release the irq reservation */ | 2321 | if (phba->intr_type == MSIX) |
2218 | free_irq(phba->pcidev->irq, phba); | 2322 | lpfc_disable_msix(phba); |
2219 | if (phba->using_msi) | 2323 | else { |
2220 | pci_disable_msi(phba->pcidev); | 2324 | free_irq(phba->pcidev->irq, phba); |
2325 | if (phba->intr_type == MSI) | ||
2326 | pci_disable_msi(phba->pcidev); | ||
2327 | } | ||
2221 | 2328 | ||
2222 | pci_set_drvdata(pdev, NULL); | 2329 | pci_set_drvdata(pdev, NULL); |
2223 | scsi_host_put(shost); | 2330 | scsi_host_put(shost); |
@@ -2276,10 +2383,13 @@ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev, | |||
2276 | pring = &psli->ring[psli->fcp_ring]; | 2383 | pring = &psli->ring[psli->fcp_ring]; |
2277 | lpfc_sli_abort_iocb_ring(phba, pring); | 2384 | lpfc_sli_abort_iocb_ring(phba, pring); |
2278 | 2385 | ||
2279 | /* Release the irq reservation */ | 2386 | if (phba->intr_type == MSIX) |
2280 | free_irq(phba->pcidev->irq, phba); | 2387 | lpfc_disable_msix(phba); |
2281 | if (phba->using_msi) | 2388 | else { |
2282 | pci_disable_msi(phba->pcidev); | 2389 | free_irq(phba->pcidev->irq, phba); |
2390 | if (phba->intr_type == MSI) | ||
2391 | pci_disable_msi(phba->pcidev); | ||
2392 | } | ||
2283 | 2393 | ||
2284 | /* Request a slot reset. */ | 2394 | /* Request a slot reset. */ |
2285 | return PCI_ERS_RESULT_NEED_RESET; | 2395 | return PCI_ERS_RESULT_NEED_RESET; |
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h index c5841d7565f7..39fd2b843bec 100644 --- a/drivers/scsi/lpfc/lpfc_logmsg.h +++ b/drivers/scsi/lpfc/lpfc_logmsg.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2005 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * * | 7 | * * |
@@ -35,11 +35,15 @@ | |||
35 | #define LOG_ALL_MSG 0xffff /* LOG all messages */ | 35 | #define LOG_ALL_MSG 0xffff /* LOG all messages */ |
36 | 36 | ||
37 | #define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ | 37 | #define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ |
38 | do { \ | ||
38 | { if (((mask) &(vport)->cfg_log_verbose) || (level[1] <= '3')) \ | 39 | { if (((mask) &(vport)->cfg_log_verbose) || (level[1] <= '3')) \ |
39 | dev_printk(level, &((vport)->phba->pcidev)->dev, "%d:(%d):" \ | 40 | dev_printk(level, &((vport)->phba->pcidev)->dev, "%d:(%d):" \ |
40 | fmt, (vport)->phba->brd_no, vport->vpi, ##arg); } | 41 | fmt, (vport)->phba->brd_no, vport->vpi, ##arg); } \ |
42 | } while (0) | ||
41 | 43 | ||
42 | #define lpfc_printf_log(phba, level, mask, fmt, arg...) \ | 44 | #define lpfc_printf_log(phba, level, mask, fmt, arg...) \ |
45 | do { \ | ||
43 | { if (((mask) &(phba)->pport->cfg_log_verbose) || (level[1] <= '3')) \ | 46 | { if (((mask) &(phba)->pport->cfg_log_verbose) || (level[1] <= '3')) \ |
44 | dev_printk(level, &((phba)->pcidev)->dev, "%d:" \ | 47 | dev_printk(level, &((phba)->pcidev)->dev, "%d:" \ |
45 | fmt, phba->brd_no, ##arg); } | 48 | fmt, phba->brd_no, ##arg); } \ |
49 | } while (0) | ||
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 6dc5ab8d6716..3c0cebc71800 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c | |||
@@ -264,19 +264,30 @@ void | |||
264 | lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp) | 264 | lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp) |
265 | { | 265 | { |
266 | struct hbq_dmabuf *hbq_entry; | 266 | struct hbq_dmabuf *hbq_entry; |
267 | unsigned long flags; | ||
268 | |||
269 | if (!mp) | ||
270 | return; | ||
267 | 271 | ||
268 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { | 272 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { |
273 | /* Check whether HBQ is still in use */ | ||
274 | spin_lock_irqsave(&phba->hbalock, flags); | ||
275 | if (!phba->hbq_in_use) { | ||
276 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
277 | return; | ||
278 | } | ||
269 | hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf); | 279 | hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf); |
280 | list_del(&hbq_entry->dbuf.list); | ||
270 | if (hbq_entry->tag == -1) { | 281 | if (hbq_entry->tag == -1) { |
271 | (phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer) | 282 | (phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer) |
272 | (phba, hbq_entry); | 283 | (phba, hbq_entry); |
273 | } else { | 284 | } else { |
274 | lpfc_sli_free_hbq(phba, hbq_entry); | 285 | lpfc_sli_free_hbq(phba, hbq_entry); |
275 | } | 286 | } |
287 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
276 | } else { | 288 | } else { |
277 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 289 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
278 | kfree(mp); | 290 | kfree(mp); |
279 | } | 291 | } |
280 | return; | 292 | return; |
281 | } | 293 | } |
282 | |||
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 4a0e3406e37a..d513813f6697 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -249,6 +249,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
249 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 249 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
250 | struct lpfc_hba *phba = vport->phba; | 250 | struct lpfc_hba *phba = vport->phba; |
251 | struct lpfc_dmabuf *pcmd; | 251 | struct lpfc_dmabuf *pcmd; |
252 | struct lpfc_work_evt *evtp; | ||
252 | uint32_t *lp; | 253 | uint32_t *lp; |
253 | IOCB_t *icmd; | 254 | IOCB_t *icmd; |
254 | struct serv_parm *sp; | 255 | struct serv_parm *sp; |
@@ -435,8 +436,14 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
435 | del_timer_sync(&ndlp->nlp_delayfunc); | 436 | del_timer_sync(&ndlp->nlp_delayfunc); |
436 | ndlp->nlp_last_elscmd = 0; | 437 | ndlp->nlp_last_elscmd = 0; |
437 | 438 | ||
438 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) | 439 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) { |
439 | list_del_init(&ndlp->els_retry_evt.evt_listp); | 440 | list_del_init(&ndlp->els_retry_evt.evt_listp); |
441 | /* Decrement ndlp reference count held for the | ||
442 | * delayed retry | ||
443 | */ | ||
444 | evtp = &ndlp->els_retry_evt; | ||
445 | lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1); | ||
446 | } | ||
440 | 447 | ||
441 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 448 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { |
442 | spin_lock_irq(shost->host_lock); | 449 | spin_lock_irq(shost->host_lock); |
@@ -638,13 +645,15 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
638 | return 0; | 645 | return 0; |
639 | } | 646 | } |
640 | 647 | ||
641 | /* Check config parameter use-adisc or FCP-2 */ | 648 | if (!(vport->fc_flag & FC_PT2PT)) { |
642 | if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) || | 649 | /* Check config parameter use-adisc or FCP-2 */ |
643 | ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) { | 650 | if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) || |
644 | spin_lock_irq(shost->host_lock); | 651 | ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) { |
645 | ndlp->nlp_flag |= NLP_NPR_ADISC; | 652 | spin_lock_irq(shost->host_lock); |
646 | spin_unlock_irq(shost->host_lock); | 653 | ndlp->nlp_flag |= NLP_NPR_ADISC; |
647 | return 1; | 654 | spin_unlock_irq(shost->host_lock); |
655 | return 1; | ||
656 | } | ||
648 | } | 657 | } |
649 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 658 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
650 | lpfc_unreg_rpi(vport, ndlp); | 659 | lpfc_unreg_rpi(vport, ndlp); |
@@ -656,7 +665,7 @@ lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
656 | void *arg, uint32_t evt) | 665 | void *arg, uint32_t evt) |
657 | { | 666 | { |
658 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 667 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
659 | "0253 Illegal State Transition: node x%x " | 668 | "0271 Illegal State Transition: node x%x " |
660 | "event x%x, state x%x Data: x%x x%x\n", | 669 | "event x%x, state x%x Data: x%x x%x\n", |
661 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, | 670 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, |
662 | ndlp->nlp_flag); | 671 | ndlp->nlp_flag); |
@@ -674,7 +683,7 @@ lpfc_cmpl_plogi_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
674 | */ | 683 | */ |
675 | if (!(ndlp->nlp_flag & NLP_RCV_PLOGI)) { | 684 | if (!(ndlp->nlp_flag & NLP_RCV_PLOGI)) { |
676 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 685 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
677 | "0253 Illegal State Transition: node x%x " | 686 | "0272 Illegal State Transition: node x%x " |
678 | "event x%x, state x%x Data: x%x x%x\n", | 687 | "event x%x, state x%x Data: x%x x%x\n", |
679 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, | 688 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, |
680 | ndlp->nlp_flag); | 689 | ndlp->nlp_flag); |
@@ -2144,8 +2153,11 @@ lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
2144 | uint32_t cur_state, rc; | 2153 | uint32_t cur_state, rc; |
2145 | uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *, | 2154 | uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *, |
2146 | uint32_t); | 2155 | uint32_t); |
2156 | uint32_t got_ndlp = 0; | ||
2157 | |||
2158 | if (lpfc_nlp_get(ndlp)) | ||
2159 | got_ndlp = 1; | ||
2147 | 2160 | ||
2148 | lpfc_nlp_get(ndlp); | ||
2149 | cur_state = ndlp->nlp_state; | 2161 | cur_state = ndlp->nlp_state; |
2150 | 2162 | ||
2151 | /* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */ | 2163 | /* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */ |
@@ -2162,15 +2174,24 @@ lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
2162 | rc = (func) (vport, ndlp, arg, evt); | 2174 | rc = (func) (vport, ndlp, arg, evt); |
2163 | 2175 | ||
2164 | /* DSM out state <rc> on NPort <nlp_DID> */ | 2176 | /* DSM out state <rc> on NPort <nlp_DID> */ |
2165 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 2177 | if (got_ndlp) { |
2178 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | ||
2166 | "0212 DSM out state %d on NPort x%x Data: x%x\n", | 2179 | "0212 DSM out state %d on NPort x%x Data: x%x\n", |
2167 | rc, ndlp->nlp_DID, ndlp->nlp_flag); | 2180 | rc, ndlp->nlp_DID, ndlp->nlp_flag); |
2168 | 2181 | ||
2169 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM, | 2182 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM, |
2170 | "DSM out: ste:%d did:x%x flg:x%x", | 2183 | "DSM out: ste:%d did:x%x flg:x%x", |
2171 | rc, ndlp->nlp_DID, ndlp->nlp_flag); | 2184 | rc, ndlp->nlp_DID, ndlp->nlp_flag); |
2185 | /* Decrement the ndlp reference count held for this function */ | ||
2186 | lpfc_nlp_put(ndlp); | ||
2187 | } else { | ||
2188 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | ||
2189 | "0212 DSM out state %d on NPort free\n", rc); | ||
2172 | 2190 | ||
2173 | lpfc_nlp_put(ndlp); | 2191 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM, |
2192 | "DSM out: ste:%d did:x%x flg:x%x", | ||
2193 | rc, 0, 0); | ||
2194 | } | ||
2174 | 2195 | ||
2175 | return rc; | 2196 | return rc; |
2176 | } | 2197 | } |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index fc5c3a42b05a..70255c11d3ad 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -1283,6 +1283,8 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) | |||
1283 | match = 0; | 1283 | match = 0; |
1284 | spin_lock_irq(shost->host_lock); | 1284 | spin_lock_irq(shost->host_lock); |
1285 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { | 1285 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
1286 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
1287 | continue; | ||
1286 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && | 1288 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && |
1287 | i == ndlp->nlp_sid && | 1289 | i == ndlp->nlp_sid && |
1288 | ndlp->rport) { | 1290 | ndlp->rport) { |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index fdd01e384e36..f53206411cd8 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2007 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -203,8 +203,25 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) | |||
203 | case CMD_IOCB_RCV_SEQ64_CX: | 203 | case CMD_IOCB_RCV_SEQ64_CX: |
204 | case CMD_IOCB_RCV_ELS64_CX: | 204 | case CMD_IOCB_RCV_ELS64_CX: |
205 | case CMD_IOCB_RCV_CONT64_CX: | 205 | case CMD_IOCB_RCV_CONT64_CX: |
206 | case CMD_IOCB_RET_XRI64_CX: | ||
206 | type = LPFC_UNSOL_IOCB; | 207 | type = LPFC_UNSOL_IOCB; |
207 | break; | 208 | break; |
209 | case CMD_IOCB_XMIT_MSEQ64_CR: | ||
210 | case CMD_IOCB_XMIT_MSEQ64_CX: | ||
211 | case CMD_IOCB_RCV_SEQ_LIST64_CX: | ||
212 | case CMD_IOCB_RCV_ELS_LIST64_CX: | ||
213 | case CMD_IOCB_CLOSE_EXTENDED_CN: | ||
214 | case CMD_IOCB_ABORT_EXTENDED_CN: | ||
215 | case CMD_IOCB_RET_HBQE64_CN: | ||
216 | case CMD_IOCB_FCP_IBIDIR64_CR: | ||
217 | case CMD_IOCB_FCP_IBIDIR64_CX: | ||
218 | case CMD_IOCB_FCP_ITASKMGT64_CX: | ||
219 | case CMD_IOCB_LOGENTRY_CN: | ||
220 | case CMD_IOCB_LOGENTRY_ASYNC_CN: | ||
221 | printk("%s - Unhandled SLI-3 Command x%x\n", | ||
222 | __FUNCTION__, iocb_cmnd); | ||
223 | type = LPFC_UNKNOWN_IOCB; | ||
224 | break; | ||
208 | default: | 225 | default: |
209 | type = LPFC_UNKNOWN_IOCB; | 226 | type = LPFC_UNKNOWN_IOCB; |
210 | break; | 227 | break; |
@@ -529,10 +546,13 @@ lpfc_sli_hbqbuf_free_all(struct lpfc_hba *phba) | |||
529 | { | 546 | { |
530 | struct lpfc_dmabuf *dmabuf, *next_dmabuf; | 547 | struct lpfc_dmabuf *dmabuf, *next_dmabuf; |
531 | struct hbq_dmabuf *hbq_buf; | 548 | struct hbq_dmabuf *hbq_buf; |
549 | unsigned long flags; | ||
532 | int i, hbq_count; | 550 | int i, hbq_count; |
551 | uint32_t hbqno; | ||
533 | 552 | ||
534 | hbq_count = lpfc_sli_hbq_count(); | 553 | hbq_count = lpfc_sli_hbq_count(); |
535 | /* Return all memory used by all HBQs */ | 554 | /* Return all memory used by all HBQs */ |
555 | spin_lock_irqsave(&phba->hbalock, flags); | ||
536 | for (i = 0; i < hbq_count; ++i) { | 556 | for (i = 0; i < hbq_count; ++i) { |
537 | list_for_each_entry_safe(dmabuf, next_dmabuf, | 557 | list_for_each_entry_safe(dmabuf, next_dmabuf, |
538 | &phba->hbqs[i].hbq_buffer_list, list) { | 558 | &phba->hbqs[i].hbq_buffer_list, list) { |
@@ -542,6 +562,28 @@ lpfc_sli_hbqbuf_free_all(struct lpfc_hba *phba) | |||
542 | } | 562 | } |
543 | phba->hbqs[i].buffer_count = 0; | 563 | phba->hbqs[i].buffer_count = 0; |
544 | } | 564 | } |
565 | /* Return all HBQ buffer that are in-fly */ | ||
566 | list_for_each_entry_safe(dmabuf, next_dmabuf, | ||
567 | &phba->hbqbuf_in_list, list) { | ||
568 | hbq_buf = container_of(dmabuf, struct hbq_dmabuf, dbuf); | ||
569 | list_del(&hbq_buf->dbuf.list); | ||
570 | if (hbq_buf->tag == -1) { | ||
571 | (phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer) | ||
572 | (phba, hbq_buf); | ||
573 | } else { | ||
574 | hbqno = hbq_buf->tag >> 16; | ||
575 | if (hbqno >= LPFC_MAX_HBQS) | ||
576 | (phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer) | ||
577 | (phba, hbq_buf); | ||
578 | else | ||
579 | (phba->hbqs[hbqno].hbq_free_buffer)(phba, | ||
580 | hbq_buf); | ||
581 | } | ||
582 | } | ||
583 | |||
584 | /* Mark the HBQs not in use */ | ||
585 | phba->hbq_in_use = 0; | ||
586 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
545 | } | 587 | } |
546 | 588 | ||
547 | static struct lpfc_hbq_entry * | 589 | static struct lpfc_hbq_entry * |
@@ -603,6 +645,7 @@ static int | |||
603 | lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) | 645 | lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) |
604 | { | 646 | { |
605 | uint32_t i, start, end; | 647 | uint32_t i, start, end; |
648 | unsigned long flags; | ||
606 | struct hbq_dmabuf *hbq_buffer; | 649 | struct hbq_dmabuf *hbq_buffer; |
607 | 650 | ||
608 | if (!phba->hbqs[hbqno].hbq_alloc_buffer) { | 651 | if (!phba->hbqs[hbqno].hbq_alloc_buffer) { |
@@ -615,6 +658,13 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) | |||
615 | end = lpfc_hbq_defs[hbqno]->entry_count; | 658 | end = lpfc_hbq_defs[hbqno]->entry_count; |
616 | } | 659 | } |
617 | 660 | ||
661 | /* Check whether HBQ is still in use */ | ||
662 | spin_lock_irqsave(&phba->hbalock, flags); | ||
663 | if (!phba->hbq_in_use) { | ||
664 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
665 | return 0; | ||
666 | } | ||
667 | |||
618 | /* Populate HBQ entries */ | 668 | /* Populate HBQ entries */ |
619 | for (i = start; i < end; i++) { | 669 | for (i = start; i < end; i++) { |
620 | hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); | 670 | hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); |
@@ -626,6 +676,8 @@ lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count) | |||
626 | else | 676 | else |
627 | (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); | 677 | (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer); |
628 | } | 678 | } |
679 | |||
680 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
629 | return 0; | 681 | return 0; |
630 | } | 682 | } |
631 | 683 | ||
@@ -910,16 +962,29 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag) | |||
910 | uint32_t hbqno; | 962 | uint32_t hbqno; |
911 | void *virt; /* virtual address ptr */ | 963 | void *virt; /* virtual address ptr */ |
912 | dma_addr_t phys; /* mapped address */ | 964 | dma_addr_t phys; /* mapped address */ |
965 | unsigned long flags; | ||
966 | |||
967 | /* Check whether HBQ is still in use */ | ||
968 | spin_lock_irqsave(&phba->hbalock, flags); | ||
969 | if (!phba->hbq_in_use) { | ||
970 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
971 | return NULL; | ||
972 | } | ||
913 | 973 | ||
914 | hbq_entry = lpfc_sli_hbqbuf_find(phba, tag); | 974 | hbq_entry = lpfc_sli_hbqbuf_find(phba, tag); |
915 | if (hbq_entry == NULL) | 975 | if (hbq_entry == NULL) { |
976 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
916 | return NULL; | 977 | return NULL; |
978 | } | ||
917 | list_del(&hbq_entry->dbuf.list); | 979 | list_del(&hbq_entry->dbuf.list); |
918 | 980 | ||
919 | hbqno = tag >> 16; | 981 | hbqno = tag >> 16; |
920 | new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); | 982 | new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); |
921 | if (new_hbq_entry == NULL) | 983 | if (new_hbq_entry == NULL) { |
984 | list_add_tail(&hbq_entry->dbuf.list, &phba->hbqbuf_in_list); | ||
985 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
922 | return &hbq_entry->dbuf; | 986 | return &hbq_entry->dbuf; |
987 | } | ||
923 | new_hbq_entry->tag = -1; | 988 | new_hbq_entry->tag = -1; |
924 | phys = new_hbq_entry->dbuf.phys; | 989 | phys = new_hbq_entry->dbuf.phys; |
925 | virt = new_hbq_entry->dbuf.virt; | 990 | virt = new_hbq_entry->dbuf.virt; |
@@ -928,6 +993,9 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag) | |||
928 | hbq_entry->dbuf.phys = phys; | 993 | hbq_entry->dbuf.phys = phys; |
929 | hbq_entry->dbuf.virt = virt; | 994 | hbq_entry->dbuf.virt = virt; |
930 | lpfc_sli_free_hbq(phba, hbq_entry); | 995 | lpfc_sli_free_hbq(phba, hbq_entry); |
996 | list_add_tail(&new_hbq_entry->dbuf.list, &phba->hbqbuf_in_list); | ||
997 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
998 | |||
931 | return &new_hbq_entry->dbuf; | 999 | return &new_hbq_entry->dbuf; |
932 | } | 1000 | } |
933 | 1001 | ||
@@ -951,6 +1019,7 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
951 | uint32_t Rctl, Type; | 1019 | uint32_t Rctl, Type; |
952 | uint32_t match, i; | 1020 | uint32_t match, i; |
953 | struct lpfc_iocbq *iocbq; | 1021 | struct lpfc_iocbq *iocbq; |
1022 | struct lpfc_dmabuf *dmzbuf; | ||
954 | 1023 | ||
955 | match = 0; | 1024 | match = 0; |
956 | irsp = &(saveq->iocb); | 1025 | irsp = &(saveq->iocb); |
@@ -972,6 +1041,29 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
972 | return 1; | 1041 | return 1; |
973 | } | 1042 | } |
974 | 1043 | ||
1044 | if ((irsp->ulpCommand == CMD_IOCB_RET_XRI64_CX) && | ||
1045 | (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) { | ||
1046 | if (irsp->ulpBdeCount > 0) { | ||
1047 | dmzbuf = lpfc_sli_get_buff(phba, pring, | ||
1048 | irsp->un.ulpWord[3]); | ||
1049 | lpfc_in_buf_free(phba, dmzbuf); | ||
1050 | } | ||
1051 | |||
1052 | if (irsp->ulpBdeCount > 1) { | ||
1053 | dmzbuf = lpfc_sli_get_buff(phba, pring, | ||
1054 | irsp->unsli3.sli3Words[3]); | ||
1055 | lpfc_in_buf_free(phba, dmzbuf); | ||
1056 | } | ||
1057 | |||
1058 | if (irsp->ulpBdeCount > 2) { | ||
1059 | dmzbuf = lpfc_sli_get_buff(phba, pring, | ||
1060 | irsp->unsli3.sli3Words[7]); | ||
1061 | lpfc_in_buf_free(phba, dmzbuf); | ||
1062 | } | ||
1063 | |||
1064 | return 1; | ||
1065 | } | ||
1066 | |||
975 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { | 1067 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { |
976 | if (irsp->ulpBdeCount != 0) { | 1068 | if (irsp->ulpBdeCount != 0) { |
977 | saveq->context2 = lpfc_sli_get_buff(phba, pring, | 1069 | saveq->context2 = lpfc_sli_get_buff(phba, pring, |
@@ -2293,6 +2385,7 @@ lpfc_sli_hbq_setup(struct lpfc_hba *phba) | |||
2293 | 2385 | ||
2294 | /* Initialize the struct lpfc_sli_hbq structure for each hbq */ | 2386 | /* Initialize the struct lpfc_sli_hbq structure for each hbq */ |
2295 | phba->link_state = LPFC_INIT_MBX_CMDS; | 2387 | phba->link_state = LPFC_INIT_MBX_CMDS; |
2388 | phba->hbq_in_use = 1; | ||
2296 | 2389 | ||
2297 | hbq_entry_index = 0; | 2390 | hbq_entry_index = 0; |
2298 | for (hbqno = 0; hbqno < hbq_count; ++hbqno) { | 2391 | for (hbqno = 0; hbqno < hbq_count; ++hbqno) { |
@@ -2404,9 +2497,7 @@ lpfc_do_config_port(struct lpfc_hba *phba, int sli_mode) | |||
2404 | if ((pmb->mb.un.varCfgPort.sli_mode == 3) && | 2497 | if ((pmb->mb.un.varCfgPort.sli_mode == 3) && |
2405 | (!pmb->mb.un.varCfgPort.cMA)) { | 2498 | (!pmb->mb.un.varCfgPort.cMA)) { |
2406 | rc = -ENXIO; | 2499 | rc = -ENXIO; |
2407 | goto do_prep_failed; | ||
2408 | } | 2500 | } |
2409 | return rc; | ||
2410 | 2501 | ||
2411 | do_prep_failed: | 2502 | do_prep_failed: |
2412 | mempool_free(pmb, phba->mbox_mem_pool); | 2503 | mempool_free(pmb, phba->mbox_mem_pool); |
@@ -2625,14 +2716,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2625 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2716 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2626 | 2717 | ||
2627 | /* Mbox command <mbxCommand> cannot issue */ | 2718 | /* Mbox command <mbxCommand> cannot issue */ |
2628 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag) | 2719 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2629 | return MBX_NOT_FINISHED; | 2720 | return MBX_NOT_FINISHED; |
2630 | } | 2721 | } |
2631 | 2722 | ||
2632 | if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && | 2723 | if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && |
2633 | !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { | 2724 | !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { |
2634 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2725 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2635 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag) | 2726 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2636 | return MBX_NOT_FINISHED; | 2727 | return MBX_NOT_FINISHED; |
2637 | } | 2728 | } |
2638 | 2729 | ||
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 4b633d39a82a..ca540d1d041e 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
@@ -18,7 +18,7 @@ | |||
18 | * included with this package. * | 18 | * included with this package. * |
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | #define LPFC_DRIVER_VERSION "8.2.4" | 21 | #define LPFC_DRIVER_VERSION "8.2.5" |
22 | 22 | ||
23 | #define LPFC_DRIVER_NAME "lpfc" | 23 | #define LPFC_DRIVER_NAME "lpfc" |
24 | 24 | ||
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 9fad7663c117..86d05beb00b8 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2006 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -327,7 +327,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable) | |||
327 | * up and ready to FDISC. | 327 | * up and ready to FDISC. |
328 | */ | 328 | */ |
329 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); | 329 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); |
330 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | 330 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
331 | ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | ||
331 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) { | 332 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) { |
332 | lpfc_set_disctmo(vport); | 333 | lpfc_set_disctmo(vport); |
333 | lpfc_initial_fdisc(vport); | 334 | lpfc_initial_fdisc(vport); |
@@ -358,7 +359,8 @@ disable_vport(struct fc_vport *fc_vport) | |||
358 | long timeout; | 359 | long timeout; |
359 | 360 | ||
360 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | 361 | ndlp = lpfc_findnode_did(vport, Fabric_DID); |
361 | if (ndlp && phba->link_state >= LPFC_LINK_UP) { | 362 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) |
363 | && phba->link_state >= LPFC_LINK_UP) { | ||
362 | vport->unreg_vpi_cmpl = VPORT_INVAL; | 364 | vport->unreg_vpi_cmpl = VPORT_INVAL; |
363 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); | 365 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); |
364 | if (!lpfc_issue_els_npiv_logo(vport, ndlp)) | 366 | if (!lpfc_issue_els_npiv_logo(vport, ndlp)) |
@@ -372,6 +374,8 @@ disable_vport(struct fc_vport *fc_vport) | |||
372 | * calling lpfc_cleanup_rpis(vport, 1) | 374 | * calling lpfc_cleanup_rpis(vport, 1) |
373 | */ | 375 | */ |
374 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { | 376 | list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { |
377 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
378 | continue; | ||
375 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 379 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) |
376 | continue; | 380 | continue; |
377 | lpfc_disc_state_machine(vport, ndlp, NULL, | 381 | lpfc_disc_state_machine(vport, ndlp, NULL, |
@@ -414,7 +418,8 @@ enable_vport(struct fc_vport *fc_vport) | |||
414 | * up and ready to FDISC. | 418 | * up and ready to FDISC. |
415 | */ | 419 | */ |
416 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); | 420 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); |
417 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | 421 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) |
422 | && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | ||
418 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) { | 423 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) { |
419 | lpfc_set_disctmo(vport); | 424 | lpfc_set_disctmo(vport); |
420 | lpfc_initial_fdisc(vport); | 425 | lpfc_initial_fdisc(vport); |
@@ -498,7 +503,41 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
498 | scsi_remove_host(lpfc_shost_from_vport(vport)); | 503 | scsi_remove_host(lpfc_shost_from_vport(vport)); |
499 | 504 | ||
500 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); | 505 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); |
501 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && | 506 | |
507 | /* In case of driver unload, we shall not perform fabric logo as the | ||
508 | * worker thread already stopped at this stage and, in this case, we | ||
509 | * can safely skip the fabric logo. | ||
510 | */ | ||
511 | if (phba->pport->load_flag & FC_UNLOADING) { | ||
512 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && | ||
513 | ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && | ||
514 | phba->link_state >= LPFC_LINK_UP) { | ||
515 | /* First look for the Fabric ndlp */ | ||
516 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | ||
517 | if (!ndlp) | ||
518 | goto skip_logo; | ||
519 | else if (!NLP_CHK_NODE_ACT(ndlp)) { | ||
520 | ndlp = lpfc_enable_node(vport, ndlp, | ||
521 | NLP_STE_UNUSED_NODE); | ||
522 | if (!ndlp) | ||
523 | goto skip_logo; | ||
524 | } | ||
525 | /* Remove ndlp from vport npld list */ | ||
526 | lpfc_dequeue_node(vport, ndlp); | ||
527 | |||
528 | /* Indicate free memory when release */ | ||
529 | spin_lock_irq(&phba->ndlp_lock); | ||
530 | NLP_SET_FREE_REQ(ndlp); | ||
531 | spin_unlock_irq(&phba->ndlp_lock); | ||
532 | /* Kick off release ndlp when it can be safely done */ | ||
533 | lpfc_nlp_put(ndlp); | ||
534 | } | ||
535 | goto skip_logo; | ||
536 | } | ||
537 | |||
538 | /* Otherwise, we will perform fabric logo as needed */ | ||
539 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && | ||
540 | ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && | ||
502 | phba->link_state >= LPFC_LINK_UP) { | 541 | phba->link_state >= LPFC_LINK_UP) { |
503 | if (vport->cfg_enable_da_id) { | 542 | if (vport->cfg_enable_da_id) { |
504 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); | 543 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); |
@@ -519,8 +558,27 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
519 | if (!ndlp) | 558 | if (!ndlp) |
520 | goto skip_logo; | 559 | goto skip_logo; |
521 | lpfc_nlp_init(vport, ndlp, Fabric_DID); | 560 | lpfc_nlp_init(vport, ndlp, Fabric_DID); |
561 | /* Indicate free memory when release */ | ||
562 | NLP_SET_FREE_REQ(ndlp); | ||
522 | } else { | 563 | } else { |
564 | if (!NLP_CHK_NODE_ACT(ndlp)) | ||
565 | ndlp = lpfc_enable_node(vport, ndlp, | ||
566 | NLP_STE_UNUSED_NODE); | ||
567 | if (!ndlp) | ||
568 | goto skip_logo; | ||
569 | |||
570 | /* Remove ndlp from vport npld list */ | ||
523 | lpfc_dequeue_node(vport, ndlp); | 571 | lpfc_dequeue_node(vport, ndlp); |
572 | spin_lock_irq(&phba->ndlp_lock); | ||
573 | if (!NLP_CHK_FREE_REQ(ndlp)) | ||
574 | /* Indicate free memory when release */ | ||
575 | NLP_SET_FREE_REQ(ndlp); | ||
576 | else { | ||
577 | /* Skip this if ndlp is already in free mode */ | ||
578 | spin_unlock_irq(&phba->ndlp_lock); | ||
579 | goto skip_logo; | ||
580 | } | ||
581 | spin_unlock_irq(&phba->ndlp_lock); | ||
524 | } | 582 | } |
525 | vport->unreg_vpi_cmpl = VPORT_INVAL; | 583 | vport->unreg_vpi_cmpl = VPORT_INVAL; |
526 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); | 584 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); |
@@ -534,9 +592,9 @@ skip_logo: | |||
534 | lpfc_sli_host_down(vport); | 592 | lpfc_sli_host_down(vport); |
535 | 593 | ||
536 | lpfc_stop_vport_timers(vport); | 594 | lpfc_stop_vport_timers(vport); |
537 | lpfc_unreg_all_rpis(vport); | ||
538 | 595 | ||
539 | if (!(phba->pport->load_flag & FC_UNLOADING)) { | 596 | if (!(phba->pport->load_flag & FC_UNLOADING)) { |
597 | lpfc_unreg_all_rpis(vport); | ||
540 | lpfc_unreg_default_rpis(vport); | 598 | lpfc_unreg_default_rpis(vport); |
541 | /* | 599 | /* |
542 | * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi) | 600 | * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi) |
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index b6587a6d8486..0ad215e27b83 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c | |||
@@ -59,7 +59,6 @@ EXPORT_SYMBOL(mraid_mm_register_adp); | |||
59 | EXPORT_SYMBOL(mraid_mm_unregister_adp); | 59 | EXPORT_SYMBOL(mraid_mm_unregister_adp); |
60 | EXPORT_SYMBOL(mraid_mm_adapter_app_handle); | 60 | EXPORT_SYMBOL(mraid_mm_adapter_app_handle); |
61 | 61 | ||
62 | static int majorno; | ||
63 | static uint32_t drvr_ver = 0x02200207; | 62 | static uint32_t drvr_ver = 0x02200207; |
64 | 63 | ||
65 | static int adapters_count_g; | 64 | static int adapters_count_g; |
@@ -76,6 +75,12 @@ static const struct file_operations lsi_fops = { | |||
76 | .owner = THIS_MODULE, | 75 | .owner = THIS_MODULE, |
77 | }; | 76 | }; |
78 | 77 | ||
78 | static struct miscdevice megaraid_mm_dev = { | ||
79 | .minor = MISC_DYNAMIC_MINOR, | ||
80 | .name = "megadev0", | ||
81 | .fops = &lsi_fops, | ||
82 | }; | ||
83 | |||
79 | /** | 84 | /** |
80 | * mraid_mm_open - open routine for char node interface | 85 | * mraid_mm_open - open routine for char node interface |
81 | * @inode : unused | 86 | * @inode : unused |
@@ -1184,15 +1189,16 @@ mraid_mm_teardown_dma_pools(mraid_mmadp_t *adp) | |||
1184 | static int __init | 1189 | static int __init |
1185 | mraid_mm_init(void) | 1190 | mraid_mm_init(void) |
1186 | { | 1191 | { |
1192 | int err; | ||
1193 | |||
1187 | // Announce the driver version | 1194 | // Announce the driver version |
1188 | con_log(CL_ANN, (KERN_INFO "megaraid cmm: %s %s\n", | 1195 | con_log(CL_ANN, (KERN_INFO "megaraid cmm: %s %s\n", |
1189 | LSI_COMMON_MOD_VERSION, LSI_COMMON_MOD_EXT_VERSION)); | 1196 | LSI_COMMON_MOD_VERSION, LSI_COMMON_MOD_EXT_VERSION)); |
1190 | 1197 | ||
1191 | majorno = register_chrdev(0, "megadev", &lsi_fops); | 1198 | err = misc_register(&megaraid_mm_dev); |
1192 | 1199 | if (err < 0) { | |
1193 | if (majorno < 0) { | 1200 | con_log(CL_ANN, ("megaraid cmm: cannot register misc device\n")); |
1194 | con_log(CL_ANN, ("megaraid cmm: cannot get major\n")); | 1201 | return err; |
1195 | return majorno; | ||
1196 | } | 1202 | } |
1197 | 1203 | ||
1198 | init_waitqueue_head(&wait_q); | 1204 | init_waitqueue_head(&wait_q); |
@@ -1230,7 +1236,7 @@ mraid_mm_exit(void) | |||
1230 | { | 1236 | { |
1231 | con_log(CL_DLEVEL1 , ("exiting common mod\n")); | 1237 | con_log(CL_DLEVEL1 , ("exiting common mod\n")); |
1232 | 1238 | ||
1233 | unregister_chrdev(majorno, "megadev"); | 1239 | misc_deregister(&megaraid_mm_dev); |
1234 | } | 1240 | } |
1235 | 1241 | ||
1236 | module_init(mraid_mm_init); | 1242 | module_init(mraid_mm_init); |
diff --git a/drivers/scsi/megaraid/megaraid_mm.h b/drivers/scsi/megaraid/megaraid_mm.h index c8762b2b8ed1..55b425c0a654 100644 --- a/drivers/scsi/megaraid/megaraid_mm.h +++ b/drivers/scsi/megaraid/megaraid_mm.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/moduleparam.h> | 22 | #include <linux/moduleparam.h> |
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
25 | #include <linux/miscdevice.h> | ||
25 | 26 | ||
26 | #include "mbox_defs.h" | 27 | #include "mbox_defs.h" |
27 | #include "megaraid_ioctl.h" | 28 | #include "megaraid_ioctl.h" |
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 2a6e4f472eaa..a57fed47b39d 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c | |||
@@ -416,11 +416,11 @@ static int ses_intf_add(struct class_device *cdev, | |||
416 | int i, j, types, len, components = 0; | 416 | int i, j, types, len, components = 0; |
417 | int err = -ENOMEM; | 417 | int err = -ENOMEM; |
418 | struct enclosure_device *edev; | 418 | struct enclosure_device *edev; |
419 | struct ses_component *scomp; | 419 | struct ses_component *scomp = NULL; |
420 | 420 | ||
421 | if (!scsi_device_enclosure(sdev)) { | 421 | if (!scsi_device_enclosure(sdev)) { |
422 | /* not an enclosure, but might be in one */ | 422 | /* not an enclosure, but might be in one */ |
423 | edev = enclosure_find(&sdev->host->shost_gendev); | 423 | edev = enclosure_find(&sdev->host->shost_gendev); |
424 | if (edev) { | 424 | if (edev) { |
425 | ses_match_to_enclosure(edev, sdev); | 425 | ses_match_to_enclosure(edev, sdev); |
426 | class_device_put(&edev->cdev); | 426 | class_device_put(&edev->cdev); |
@@ -456,9 +456,6 @@ static int ses_intf_add(struct class_device *cdev, | |||
456 | if (!buf) | 456 | if (!buf) |
457 | goto err_free; | 457 | goto err_free; |
458 | 458 | ||
459 | ses_dev->page1 = buf; | ||
460 | ses_dev->page1_len = len; | ||
461 | |||
462 | result = ses_recv_diag(sdev, 1, buf, len); | 459 | result = ses_recv_diag(sdev, 1, buf, len); |
463 | if (result) | 460 | if (result) |
464 | goto recv_failed; | 461 | goto recv_failed; |
@@ -473,6 +470,9 @@ static int ses_intf_add(struct class_device *cdev, | |||
473 | type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) | 470 | type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) |
474 | components += type_ptr[1]; | 471 | components += type_ptr[1]; |
475 | } | 472 | } |
473 | ses_dev->page1 = buf; | ||
474 | ses_dev->page1_len = len; | ||
475 | buf = NULL; | ||
476 | 476 | ||
477 | result = ses_recv_diag(sdev, 2, hdr_buf, INIT_ALLOC_SIZE); | 477 | result = ses_recv_diag(sdev, 2, hdr_buf, INIT_ALLOC_SIZE); |
478 | if (result) | 478 | if (result) |
@@ -489,6 +489,7 @@ static int ses_intf_add(struct class_device *cdev, | |||
489 | goto recv_failed; | 489 | goto recv_failed; |
490 | ses_dev->page2 = buf; | 490 | ses_dev->page2 = buf; |
491 | ses_dev->page2_len = len; | 491 | ses_dev->page2_len = len; |
492 | buf = NULL; | ||
492 | 493 | ||
493 | /* The additional information page --- allows us | 494 | /* The additional information page --- allows us |
494 | * to match up the devices */ | 495 | * to match up the devices */ |
@@ -506,11 +507,12 @@ static int ses_intf_add(struct class_device *cdev, | |||
506 | goto recv_failed; | 507 | goto recv_failed; |
507 | ses_dev->page10 = buf; | 508 | ses_dev->page10 = buf; |
508 | ses_dev->page10_len = len; | 509 | ses_dev->page10_len = len; |
510 | buf = NULL; | ||
509 | 511 | ||
510 | no_page10: | 512 | no_page10: |
511 | scomp = kmalloc(sizeof(struct ses_component) * components, GFP_KERNEL); | 513 | scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL); |
512 | if (!scomp) | 514 | if (!scomp) |
513 | goto err_free; | 515 | goto err_free; |
514 | 516 | ||
515 | edev = enclosure_register(cdev->dev, sdev->sdev_gendev.bus_id, | 517 | edev = enclosure_register(cdev->dev, sdev->sdev_gendev.bus_id, |
516 | components, &ses_enclosure_callbacks); | 518 | components, &ses_enclosure_callbacks); |
@@ -521,10 +523,9 @@ static int ses_intf_add(struct class_device *cdev, | |||
521 | 523 | ||
522 | edev->scratch = ses_dev; | 524 | edev->scratch = ses_dev; |
523 | for (i = 0; i < components; i++) | 525 | for (i = 0; i < components; i++) |
524 | edev->component[i].scratch = scomp++; | 526 | edev->component[i].scratch = scomp + i; |
525 | 527 | ||
526 | /* Page 7 for the descriptors is optional */ | 528 | /* Page 7 for the descriptors is optional */ |
527 | buf = NULL; | ||
528 | result = ses_recv_diag(sdev, 7, hdr_buf, INIT_ALLOC_SIZE); | 529 | result = ses_recv_diag(sdev, 7, hdr_buf, INIT_ALLOC_SIZE); |
529 | if (result) | 530 | if (result) |
530 | goto simple_populate; | 531 | goto simple_populate; |
@@ -532,6 +533,8 @@ static int ses_intf_add(struct class_device *cdev, | |||
532 | len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; | 533 | len = (hdr_buf[2] << 8) + hdr_buf[3] + 4; |
533 | /* add 1 for trailing '\0' we'll use */ | 534 | /* add 1 for trailing '\0' we'll use */ |
534 | buf = kzalloc(len + 1, GFP_KERNEL); | 535 | buf = kzalloc(len + 1, GFP_KERNEL); |
536 | if (!buf) | ||
537 | goto simple_populate; | ||
535 | result = ses_recv_diag(sdev, 7, buf, len); | 538 | result = ses_recv_diag(sdev, 7, buf, len); |
536 | if (result) { | 539 | if (result) { |
537 | simple_populate: | 540 | simple_populate: |
@@ -598,6 +601,7 @@ static int ses_intf_add(struct class_device *cdev, | |||
598 | err = -ENODEV; | 601 | err = -ENODEV; |
599 | err_free: | 602 | err_free: |
600 | kfree(buf); | 603 | kfree(buf); |
604 | kfree(scomp); | ||
601 | kfree(ses_dev->page10); | 605 | kfree(ses_dev->page10); |
602 | kfree(ses_dev->page2); | 606 | kfree(ses_dev->page2); |
603 | kfree(ses_dev->page1); | 607 | kfree(ses_dev->page1); |
@@ -630,6 +634,7 @@ static void ses_intf_remove(struct class_device *cdev, | |||
630 | ses_dev = edev->scratch; | 634 | ses_dev = edev->scratch; |
631 | edev->scratch = NULL; | 635 | edev->scratch = NULL; |
632 | 636 | ||
637 | kfree(ses_dev->page10); | ||
633 | kfree(ses_dev->page1); | 638 | kfree(ses_dev->page1); |
634 | kfree(ses_dev->page2); | 639 | kfree(ses_dev->page2); |
635 | kfree(ses_dev); | 640 | kfree(ses_dev); |
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c index 6325901e5093..f7d279542fa5 100644 --- a/drivers/scsi/sym53c416.c +++ b/drivers/scsi/sym53c416.c | |||
@@ -187,10 +187,10 @@ | |||
187 | #define sym53c416_base_2 sym53c416_2 | 187 | #define sym53c416_base_2 sym53c416_2 |
188 | #define sym53c416_base_3 sym53c416_3 | 188 | #define sym53c416_base_3 sym53c416_3 |
189 | 189 | ||
190 | static unsigned int sym53c416_base[2] = {0,0}; | 190 | static unsigned int sym53c416_base[2]; |
191 | static unsigned int sym53c416_base_1[2] = {0,0}; | 191 | static unsigned int sym53c416_base_1[2]; |
192 | static unsigned int sym53c416_base_2[2] = {0,0}; | 192 | static unsigned int sym53c416_base_2[2]; |
193 | static unsigned int sym53c416_base_3[2] = {0,0}; | 193 | static unsigned int sym53c416_base_3[2]; |
194 | 194 | ||
195 | #endif | 195 | #endif |
196 | 196 | ||
@@ -621,25 +621,25 @@ int __init sym53c416_detect(struct scsi_host_template *tpnt) | |||
621 | int ints[3]; | 621 | int ints[3]; |
622 | 622 | ||
623 | ints[0] = 2; | 623 | ints[0] = 2; |
624 | if(sym53c416_base) | 624 | if(sym53c416_base[0]) |
625 | { | 625 | { |
626 | ints[1] = sym53c416_base[0]; | 626 | ints[1] = sym53c416_base[0]; |
627 | ints[2] = sym53c416_base[1]; | 627 | ints[2] = sym53c416_base[1]; |
628 | sym53c416_setup(NULL, ints); | 628 | sym53c416_setup(NULL, ints); |
629 | } | 629 | } |
630 | if(sym53c416_base_1) | 630 | if(sym53c416_base_1[0]) |
631 | { | 631 | { |
632 | ints[1] = sym53c416_base_1[0]; | 632 | ints[1] = sym53c416_base_1[0]; |
633 | ints[2] = sym53c416_base_1[1]; | 633 | ints[2] = sym53c416_base_1[1]; |
634 | sym53c416_setup(NULL, ints); | 634 | sym53c416_setup(NULL, ints); |
635 | } | 635 | } |
636 | if(sym53c416_base_2) | 636 | if(sym53c416_base_2[0]) |
637 | { | 637 | { |
638 | ints[1] = sym53c416_base_2[0]; | 638 | ints[1] = sym53c416_base_2[0]; |
639 | ints[2] = sym53c416_base_2[1]; | 639 | ints[2] = sym53c416_base_2[1]; |
640 | sym53c416_setup(NULL, ints); | 640 | sym53c416_setup(NULL, ints); |
641 | } | 641 | } |
642 | if(sym53c416_base_3) | 642 | if(sym53c416_base_3[0]) |
643 | { | 643 | { |
644 | ints[1] = sym53c416_base_3[0]; | 644 | ints[1] = sym53c416_base_3[0]; |
645 | ints[2] = sym53c416_base_3[1]; | 645 | ints[2] = sym53c416_base_3[1]; |
@@ -171,7 +171,7 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe, | |||
171 | * | 171 | * |
172 | * Description: | 172 | * Description: |
173 | * This function returns a kernel virtual address mapping for the | 173 | * This function returns a kernel virtual address mapping for the |
174 | * passed in @pipe_buffer. If @atomic is set, an atomic map is provided | 174 | * pipe_buffer passed in @buf. If @atomic is set, an atomic map is provided |
175 | * and the caller has to be careful not to fault before calling | 175 | * and the caller has to be careful not to fault before calling |
176 | * the unmap function. | 176 | * the unmap function. |
177 | * | 177 | * |
@@ -208,15 +208,15 @@ void generic_pipe_buf_unmap(struct pipe_inode_info *pipe, | |||
208 | } | 208 | } |
209 | 209 | ||
210 | /** | 210 | /** |
211 | * generic_pipe_buf_steal - attempt to take ownership of a @pipe_buffer | 211 | * generic_pipe_buf_steal - attempt to take ownership of a &pipe_buffer |
212 | * @pipe: the pipe that the buffer belongs to | 212 | * @pipe: the pipe that the buffer belongs to |
213 | * @buf: the buffer to attempt to steal | 213 | * @buf: the buffer to attempt to steal |
214 | * | 214 | * |
215 | * Description: | 215 | * Description: |
216 | * This function attempts to steal the @struct page attached to | 216 | * This function attempts to steal the &struct page attached to |
217 | * @buf. If successful, this function returns 0 and returns with | 217 | * @buf. If successful, this function returns 0 and returns with |
218 | * the page locked. The caller may then reuse the page for whatever | 218 | * the page locked. The caller may then reuse the page for whatever |
219 | * he wishes, the typical use is insertion into a different file | 219 | * he wishes; the typical use is insertion into a different file |
220 | * page cache. | 220 | * page cache. |
221 | */ | 221 | */ |
222 | int generic_pipe_buf_steal(struct pipe_inode_info *pipe, | 222 | int generic_pipe_buf_steal(struct pipe_inode_info *pipe, |
@@ -238,7 +238,7 @@ int generic_pipe_buf_steal(struct pipe_inode_info *pipe, | |||
238 | } | 238 | } |
239 | 239 | ||
240 | /** | 240 | /** |
241 | * generic_pipe_buf_get - get a reference to a @struct pipe_buffer | 241 | * generic_pipe_buf_get - get a reference to a &struct pipe_buffer |
242 | * @pipe: the pipe that the buffer belongs to | 242 | * @pipe: the pipe that the buffer belongs to |
243 | * @buf: the buffer to get a reference to | 243 | * @buf: the buffer to get a reference to |
244 | * | 244 | * |
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 4e5c22ca802e..376ef3ee6ed7 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c | |||
@@ -505,7 +505,7 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
505 | if (warn_count < 5) { | 505 | if (warn_count < 5) { |
506 | warn_count++; | 506 | warn_count++; |
507 | printk(KERN_EMERG "smbfs is deprecated and will be removed" | 507 | printk(KERN_EMERG "smbfs is deprecated and will be removed" |
508 | "from the 2.6.27 kernel. Please migrate to cifs\n"); | 508 | " from the 2.6.27 kernel. Please migrate to cifs\n"); |
509 | } | 509 | } |
510 | 510 | ||
511 | if (!raw_data) | 511 | if (!raw_data) |
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index d721a1af1972..f855dcbbdfb8 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
@@ -145,7 +145,7 @@ static bool udf_add_free_space(struct udf_sb_info *sbi, | |||
145 | { | 145 | { |
146 | struct logicalVolIntegrityDesc *lvid; | 146 | struct logicalVolIntegrityDesc *lvid; |
147 | 147 | ||
148 | if (sbi->s_lvid_bh) | 148 | if (sbi->s_lvid_bh == NULL) |
149 | return false; | 149 | return false; |
150 | 150 | ||
151 | lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; | 151 | lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; |
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index 4b44e23caa12..8d8643ada199 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -43,13 +43,13 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
43 | struct fileIdentDesc *fi = NULL; | 43 | struct fileIdentDesc *fi = NULL; |
44 | struct fileIdentDesc cfi; | 44 | struct fileIdentDesc cfi; |
45 | int block, iblock; | 45 | int block, iblock; |
46 | loff_t nf_pos = filp->f_pos - 1; | 46 | loff_t nf_pos = (filp->f_pos - 1) << 2; |
47 | int flen; | 47 | int flen; |
48 | char fname[UDF_NAME_LEN]; | 48 | char fname[UDF_NAME_LEN]; |
49 | char *nameptr; | 49 | char *nameptr; |
50 | uint16_t liu; | 50 | uint16_t liu; |
51 | uint8_t lfi; | 51 | uint8_t lfi; |
52 | loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; | 52 | loff_t size = udf_ext0_offset(dir) + dir->i_size; |
53 | struct buffer_head *tmp, *bha[16]; | 53 | struct buffer_head *tmp, *bha[16]; |
54 | kernel_lb_addr eloc; | 54 | kernel_lb_addr eloc; |
55 | uint32_t elen; | 55 | uint32_t elen; |
@@ -63,13 +63,13 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
63 | return 0; | 63 | return 0; |
64 | 64 | ||
65 | if (nf_pos == 0) | 65 | if (nf_pos == 0) |
66 | nf_pos = (udf_ext0_offset(dir) >> 2); | 66 | nf_pos = udf_ext0_offset(dir); |
67 | 67 | ||
68 | fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; | 68 | fibh.soffset = fibh.eoffset = nf_pos & (dir->i_sb->s_blocksize - 1); |
69 | iinfo = UDF_I(dir); | 69 | iinfo = UDF_I(dir); |
70 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 70 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
71 | fibh.sbh = fibh.ebh = NULL; | 71 | fibh.sbh = fibh.ebh = NULL; |
72 | } else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2), | 72 | } else if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits, |
73 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) { | 73 | &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) { |
74 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); | 74 | block = udf_get_lb_pblock(dir->i_sb, eloc, offset); |
75 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { | 75 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { |
@@ -111,7 +111,7 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
111 | } | 111 | } |
112 | 112 | ||
113 | while (nf_pos < size) { | 113 | while (nf_pos < size) { |
114 | filp->f_pos = nf_pos + 1; | 114 | filp->f_pos = (nf_pos >> 2) + 1; |
115 | 115 | ||
116 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, | 116 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, |
117 | &elen, &offset); | 117 | &elen, &offset); |
@@ -178,7 +178,7 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
178 | } | 178 | } |
179 | } /* end while */ | 179 | } /* end while */ |
180 | 180 | ||
181 | filp->f_pos = nf_pos + 1; | 181 | filp->f_pos = (nf_pos >> 2) + 1; |
182 | 182 | ||
183 | if (fibh.sbh != fibh.ebh) | 183 | if (fibh.sbh != fibh.ebh) |
184 | brelse(fibh.ebh); | 184 | brelse(fibh.ebh); |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 35582fe9d648..1f3da5b8657b 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -1648,14 +1648,14 @@ xfs_qm_quotacheck_dqadjust( | |||
1648 | * Adjust the inode count and the block count to reflect this inode's | 1648 | * Adjust the inode count and the block count to reflect this inode's |
1649 | * resource usage. | 1649 | * resource usage. |
1650 | */ | 1650 | */ |
1651 | be64_add(&dqp->q_core.d_icount, 1); | 1651 | be64_add_cpu(&dqp->q_core.d_icount, 1); |
1652 | dqp->q_res_icount++; | 1652 | dqp->q_res_icount++; |
1653 | if (nblks) { | 1653 | if (nblks) { |
1654 | be64_add(&dqp->q_core.d_bcount, nblks); | 1654 | be64_add_cpu(&dqp->q_core.d_bcount, nblks); |
1655 | dqp->q_res_bcount += nblks; | 1655 | dqp->q_res_bcount += nblks; |
1656 | } | 1656 | } |
1657 | if (rtblks) { | 1657 | if (rtblks) { |
1658 | be64_add(&dqp->q_core.d_rtbcount, rtblks); | 1658 | be64_add_cpu(&dqp->q_core.d_rtbcount, rtblks); |
1659 | dqp->q_res_rtbcount += rtblks; | 1659 | dqp->q_res_rtbcount += rtblks; |
1660 | } | 1660 | } |
1661 | 1661 | ||
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 7de6874bf1b8..f441f836ca8b 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c | |||
@@ -421,13 +421,13 @@ xfs_trans_apply_dquot_deltas( | |||
421 | (xfs_qcnt_t) -qtrx->qt_icount_delta); | 421 | (xfs_qcnt_t) -qtrx->qt_icount_delta); |
422 | #endif | 422 | #endif |
423 | if (totalbdelta) | 423 | if (totalbdelta) |
424 | be64_add(&d->d_bcount, (xfs_qcnt_t)totalbdelta); | 424 | be64_add_cpu(&d->d_bcount, (xfs_qcnt_t)totalbdelta); |
425 | 425 | ||
426 | if (qtrx->qt_icount_delta) | 426 | if (qtrx->qt_icount_delta) |
427 | be64_add(&d->d_icount, (xfs_qcnt_t)qtrx->qt_icount_delta); | 427 | be64_add_cpu(&d->d_icount, (xfs_qcnt_t)qtrx->qt_icount_delta); |
428 | 428 | ||
429 | if (totalrtbdelta) | 429 | if (totalrtbdelta) |
430 | be64_add(&d->d_rtbcount, (xfs_qcnt_t)totalrtbdelta); | 430 | be64_add_cpu(&d->d_rtbcount, (xfs_qcnt_t)totalrtbdelta); |
431 | 431 | ||
432 | /* | 432 | /* |
433 | * Get any default limits in use. | 433 | * Get any default limits in use. |
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index ea6aa60ace06..bdbfbbee4959 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -592,7 +592,7 @@ xfs_alloc_ag_vextent( | |||
592 | if (!(args->wasfromfl)) { | 592 | if (!(args->wasfromfl)) { |
593 | 593 | ||
594 | agf = XFS_BUF_TO_AGF(args->agbp); | 594 | agf = XFS_BUF_TO_AGF(args->agbp); |
595 | be32_add(&agf->agf_freeblks, -(args->len)); | 595 | be32_add_cpu(&agf->agf_freeblks, -(args->len)); |
596 | xfs_trans_agblocks_delta(args->tp, | 596 | xfs_trans_agblocks_delta(args->tp, |
597 | -((long)(args->len))); | 597 | -((long)(args->len))); |
598 | args->pag->pagf_freeblks -= args->len; | 598 | args->pag->pagf_freeblks -= args->len; |
@@ -1720,7 +1720,7 @@ xfs_free_ag_extent( | |||
1720 | 1720 | ||
1721 | agf = XFS_BUF_TO_AGF(agbp); | 1721 | agf = XFS_BUF_TO_AGF(agbp); |
1722 | pag = &mp->m_perag[agno]; | 1722 | pag = &mp->m_perag[agno]; |
1723 | be32_add(&agf->agf_freeblks, len); | 1723 | be32_add_cpu(&agf->agf_freeblks, len); |
1724 | xfs_trans_agblocks_delta(tp, len); | 1724 | xfs_trans_agblocks_delta(tp, len); |
1725 | pag->pagf_freeblks += len; | 1725 | pag->pagf_freeblks += len; |
1726 | XFS_WANT_CORRUPTED_GOTO( | 1726 | XFS_WANT_CORRUPTED_GOTO( |
@@ -2008,18 +2008,18 @@ xfs_alloc_get_freelist( | |||
2008 | * Get the block number and update the data structures. | 2008 | * Get the block number and update the data structures. |
2009 | */ | 2009 | */ |
2010 | bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]); | 2010 | bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]); |
2011 | be32_add(&agf->agf_flfirst, 1); | 2011 | be32_add_cpu(&agf->agf_flfirst, 1); |
2012 | xfs_trans_brelse(tp, agflbp); | 2012 | xfs_trans_brelse(tp, agflbp); |
2013 | if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp)) | 2013 | if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp)) |
2014 | agf->agf_flfirst = 0; | 2014 | agf->agf_flfirst = 0; |
2015 | pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)]; | 2015 | pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)]; |
2016 | be32_add(&agf->agf_flcount, -1); | 2016 | be32_add_cpu(&agf->agf_flcount, -1); |
2017 | xfs_trans_agflist_delta(tp, -1); | 2017 | xfs_trans_agflist_delta(tp, -1); |
2018 | pag->pagf_flcount--; | 2018 | pag->pagf_flcount--; |
2019 | 2019 | ||
2020 | logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT; | 2020 | logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT; |
2021 | if (btreeblk) { | 2021 | if (btreeblk) { |
2022 | be32_add(&agf->agf_btreeblks, 1); | 2022 | be32_add_cpu(&agf->agf_btreeblks, 1); |
2023 | pag->pagf_btreeblks++; | 2023 | pag->pagf_btreeblks++; |
2024 | logflags |= XFS_AGF_BTREEBLKS; | 2024 | logflags |= XFS_AGF_BTREEBLKS; |
2025 | } | 2025 | } |
@@ -2117,17 +2117,17 @@ xfs_alloc_put_freelist( | |||
2117 | be32_to_cpu(agf->agf_seqno), &agflbp))) | 2117 | be32_to_cpu(agf->agf_seqno), &agflbp))) |
2118 | return error; | 2118 | return error; |
2119 | agfl = XFS_BUF_TO_AGFL(agflbp); | 2119 | agfl = XFS_BUF_TO_AGFL(agflbp); |
2120 | be32_add(&agf->agf_fllast, 1); | 2120 | be32_add_cpu(&agf->agf_fllast, 1); |
2121 | if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp)) | 2121 | if (be32_to_cpu(agf->agf_fllast) == XFS_AGFL_SIZE(mp)) |
2122 | agf->agf_fllast = 0; | 2122 | agf->agf_fllast = 0; |
2123 | pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)]; | 2123 | pag = &mp->m_perag[be32_to_cpu(agf->agf_seqno)]; |
2124 | be32_add(&agf->agf_flcount, 1); | 2124 | be32_add_cpu(&agf->agf_flcount, 1); |
2125 | xfs_trans_agflist_delta(tp, 1); | 2125 | xfs_trans_agflist_delta(tp, 1); |
2126 | pag->pagf_flcount++; | 2126 | pag->pagf_flcount++; |
2127 | 2127 | ||
2128 | logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT; | 2128 | logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT; |
2129 | if (btreeblk) { | 2129 | if (btreeblk) { |
2130 | be32_add(&agf->agf_btreeblks, -1); | 2130 | be32_add_cpu(&agf->agf_btreeblks, -1); |
2131 | pag->pagf_btreeblks--; | 2131 | pag->pagf_btreeblks--; |
2132 | logflags |= XFS_AGF_BTREEBLKS; | 2132 | logflags |= XFS_AGF_BTREEBLKS; |
2133 | } | 2133 | } |
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index 1603ce595853..3ce2645508ae 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c | |||
@@ -221,7 +221,7 @@ xfs_alloc_delrec( | |||
221 | */ | 221 | */ |
222 | bno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]); | 222 | bno = be32_to_cpu(agf->agf_roots[cur->bc_btnum]); |
223 | agf->agf_roots[cur->bc_btnum] = *lpp; | 223 | agf->agf_roots[cur->bc_btnum] = *lpp; |
224 | be32_add(&agf->agf_levels[cur->bc_btnum], -1); | 224 | be32_add_cpu(&agf->agf_levels[cur->bc_btnum], -1); |
225 | mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_levels[cur->bc_btnum]--; | 225 | mp->m_perag[be32_to_cpu(agf->agf_seqno)].pagf_levels[cur->bc_btnum]--; |
226 | /* | 226 | /* |
227 | * Put this buffer/block on the ag's freelist. | 227 | * Put this buffer/block on the ag's freelist. |
@@ -1256,9 +1256,9 @@ xfs_alloc_lshift( | |||
1256 | /* | 1256 | /* |
1257 | * Bump and log left's numrecs, decrement and log right's numrecs. | 1257 | * Bump and log left's numrecs, decrement and log right's numrecs. |
1258 | */ | 1258 | */ |
1259 | be16_add(&left->bb_numrecs, 1); | 1259 | be16_add_cpu(&left->bb_numrecs, 1); |
1260 | xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS); | 1260 | xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS); |
1261 | be16_add(&right->bb_numrecs, -1); | 1261 | be16_add_cpu(&right->bb_numrecs, -1); |
1262 | xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS); | 1262 | xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS); |
1263 | /* | 1263 | /* |
1264 | * Slide the contents of right down one entry. | 1264 | * Slide the contents of right down one entry. |
@@ -1346,7 +1346,7 @@ xfs_alloc_newroot( | |||
1346 | 1346 | ||
1347 | agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); | 1347 | agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); |
1348 | agf->agf_roots[cur->bc_btnum] = cpu_to_be32(nbno); | 1348 | agf->agf_roots[cur->bc_btnum] = cpu_to_be32(nbno); |
1349 | be32_add(&agf->agf_levels[cur->bc_btnum], 1); | 1349 | be32_add_cpu(&agf->agf_levels[cur->bc_btnum], 1); |
1350 | seqno = be32_to_cpu(agf->agf_seqno); | 1350 | seqno = be32_to_cpu(agf->agf_seqno); |
1351 | mp->m_perag[seqno].pagf_levels[cur->bc_btnum]++; | 1351 | mp->m_perag[seqno].pagf_levels[cur->bc_btnum]++; |
1352 | xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, | 1352 | xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, |
@@ -1558,9 +1558,9 @@ xfs_alloc_rshift( | |||
1558 | /* | 1558 | /* |
1559 | * Decrement and log left's numrecs, bump and log right's numrecs. | 1559 | * Decrement and log left's numrecs, bump and log right's numrecs. |
1560 | */ | 1560 | */ |
1561 | be16_add(&left->bb_numrecs, -1); | 1561 | be16_add_cpu(&left->bb_numrecs, -1); |
1562 | xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS); | 1562 | xfs_alloc_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS); |
1563 | be16_add(&right->bb_numrecs, 1); | 1563 | be16_add_cpu(&right->bb_numrecs, 1); |
1564 | xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS); | 1564 | xfs_alloc_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS); |
1565 | /* | 1565 | /* |
1566 | * Using a temporary cursor, update the parent key values of the | 1566 | * Using a temporary cursor, update the parent key values of the |
@@ -1643,7 +1643,7 @@ xfs_alloc_split( | |||
1643 | */ | 1643 | */ |
1644 | if ((be16_to_cpu(left->bb_numrecs) & 1) && | 1644 | if ((be16_to_cpu(left->bb_numrecs) & 1) && |
1645 | cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1) | 1645 | cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1) |
1646 | be16_add(&right->bb_numrecs, 1); | 1646 | be16_add_cpu(&right->bb_numrecs, 1); |
1647 | i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1; | 1647 | i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1; |
1648 | /* | 1648 | /* |
1649 | * For non-leaf blocks, copy keys and addresses over to the new block. | 1649 | * For non-leaf blocks, copy keys and addresses over to the new block. |
@@ -1689,7 +1689,7 @@ xfs_alloc_split( | |||
1689 | * Adjust numrecs, sibling pointers. | 1689 | * Adjust numrecs, sibling pointers. |
1690 | */ | 1690 | */ |
1691 | lbno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(lbp)); | 1691 | lbno = XFS_DADDR_TO_AGBNO(cur->bc_mp, XFS_BUF_ADDR(lbp)); |
1692 | be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); | 1692 | be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); |
1693 | right->bb_rightsib = left->bb_rightsib; | 1693 | right->bb_rightsib = left->bb_rightsib; |
1694 | left->bb_rightsib = cpu_to_be32(rbno); | 1694 | left->bb_rightsib = cpu_to_be32(rbno); |
1695 | right->bb_leftsib = cpu_to_be32(lbno); | 1695 | right->bb_leftsib = cpu_to_be32(lbno); |
diff --git a/fs/xfs/xfs_arch.h b/fs/xfs/xfs_arch.h index c4836890b726..f9472a2076d4 100644 --- a/fs/xfs/xfs_arch.h +++ b/fs/xfs/xfs_arch.h | |||
@@ -170,21 +170,6 @@ | |||
170 | } \ | 170 | } \ |
171 | } | 171 | } |
172 | 172 | ||
173 | static inline void be16_add(__be16 *a, __s16 b) | ||
174 | { | ||
175 | *a = cpu_to_be16(be16_to_cpu(*a) + b); | ||
176 | } | ||
177 | |||
178 | static inline void be32_add(__be32 *a, __s32 b) | ||
179 | { | ||
180 | *a = cpu_to_be32(be32_to_cpu(*a) + b); | ||
181 | } | ||
182 | |||
183 | static inline void be64_add(__be64 *a, __s64 b) | ||
184 | { | ||
185 | *a = cpu_to_be64(be64_to_cpu(*a) + b); | ||
186 | } | ||
187 | |||
188 | /* | 173 | /* |
189 | * In directories inode numbers are stored as unaligned arrays of unsigned | 174 | * In directories inode numbers are stored as unaligned arrays of unsigned |
190 | * 8bit integers on disk. | 175 | * 8bit integers on disk. |
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index eb3815ebb7aa..b08e2a2a8add 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
@@ -317,7 +317,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) | |||
317 | memcpy(sfe->nameval, args->name, args->namelen); | 317 | memcpy(sfe->nameval, args->name, args->namelen); |
318 | memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen); | 318 | memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen); |
319 | sf->hdr.count++; | 319 | sf->hdr.count++; |
320 | be16_add(&sf->hdr.totsize, size); | 320 | be16_add_cpu(&sf->hdr.totsize, size); |
321 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); | 321 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA); |
322 | 322 | ||
323 | xfs_sbversion_add_attr2(mp, args->trans); | 323 | xfs_sbversion_add_attr2(mp, args->trans); |
@@ -363,7 +363,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) | |||
363 | if (end != totsize) | 363 | if (end != totsize) |
364 | memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end); | 364 | memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end); |
365 | sf->hdr.count--; | 365 | sf->hdr.count--; |
366 | be16_add(&sf->hdr.totsize, -size); | 366 | be16_add_cpu(&sf->hdr.totsize, -size); |
367 | 367 | ||
368 | /* | 368 | /* |
369 | * Fix up the start offset of the attribute fork | 369 | * Fix up the start offset of the attribute fork |
@@ -1133,7 +1133,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) | |||
1133 | xfs_da_log_buf(args->trans, bp, | 1133 | xfs_da_log_buf(args->trans, bp, |
1134 | XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); | 1134 | XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); |
1135 | } | 1135 | } |
1136 | be16_add(&hdr->count, 1); | 1136 | be16_add_cpu(&hdr->count, 1); |
1137 | 1137 | ||
1138 | /* | 1138 | /* |
1139 | * Allocate space for the new string (at the end of the run). | 1139 | * Allocate space for the new string (at the end of the run). |
@@ -1147,7 +1147,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) | |||
1147 | mp->m_sb.sb_blocksize, NULL)); | 1147 | mp->m_sb.sb_blocksize, NULL)); |
1148 | ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); | 1148 | ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); |
1149 | ASSERT((be16_to_cpu(map->size) & 0x3) == 0); | 1149 | ASSERT((be16_to_cpu(map->size) & 0x3) == 0); |
1150 | be16_add(&map->size, | 1150 | be16_add_cpu(&map->size, |
1151 | -xfs_attr_leaf_newentsize(args->namelen, args->valuelen, | 1151 | -xfs_attr_leaf_newentsize(args->namelen, args->valuelen, |
1152 | mp->m_sb.sb_blocksize, &tmp)); | 1152 | mp->m_sb.sb_blocksize, &tmp)); |
1153 | entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) + | 1153 | entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) + |
@@ -1214,12 +1214,12 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) | |||
1214 | map = &hdr->freemap[0]; | 1214 | map = &hdr->freemap[0]; |
1215 | for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) { | 1215 | for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; map++, i++) { |
1216 | if (be16_to_cpu(map->base) == tmp) { | 1216 | if (be16_to_cpu(map->base) == tmp) { |
1217 | be16_add(&map->base, sizeof(xfs_attr_leaf_entry_t)); | 1217 | be16_add_cpu(&map->base, sizeof(xfs_attr_leaf_entry_t)); |
1218 | be16_add(&map->size, | 1218 | be16_add_cpu(&map->size, |
1219 | -((int)sizeof(xfs_attr_leaf_entry_t))); | 1219 | -((int)sizeof(xfs_attr_leaf_entry_t))); |
1220 | } | 1220 | } |
1221 | } | 1221 | } |
1222 | be16_add(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index)); | 1222 | be16_add_cpu(&hdr->usedbytes, xfs_attr_leaf_entsize(leaf, args->index)); |
1223 | xfs_da_log_buf(args->trans, bp, | 1223 | xfs_da_log_buf(args->trans, bp, |
1224 | XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); | 1224 | XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); |
1225 | return(0); | 1225 | return(0); |
@@ -1727,9 +1727,9 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1727 | ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); | 1727 | ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); |
1728 | ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); | 1728 | ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); |
1729 | if (be16_to_cpu(map->base) == tablesize) { | 1729 | if (be16_to_cpu(map->base) == tablesize) { |
1730 | be16_add(&map->base, | 1730 | be16_add_cpu(&map->base, |
1731 | -((int)sizeof(xfs_attr_leaf_entry_t))); | 1731 | -((int)sizeof(xfs_attr_leaf_entry_t))); |
1732 | be16_add(&map->size, sizeof(xfs_attr_leaf_entry_t)); | 1732 | be16_add_cpu(&map->size, sizeof(xfs_attr_leaf_entry_t)); |
1733 | } | 1733 | } |
1734 | 1734 | ||
1735 | if ((be16_to_cpu(map->base) + be16_to_cpu(map->size)) | 1735 | if ((be16_to_cpu(map->base) + be16_to_cpu(map->size)) |
@@ -1751,19 +1751,19 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1751 | if ((before >= 0) || (after >= 0)) { | 1751 | if ((before >= 0) || (after >= 0)) { |
1752 | if ((before >= 0) && (after >= 0)) { | 1752 | if ((before >= 0) && (after >= 0)) { |
1753 | map = &hdr->freemap[before]; | 1753 | map = &hdr->freemap[before]; |
1754 | be16_add(&map->size, entsize); | 1754 | be16_add_cpu(&map->size, entsize); |
1755 | be16_add(&map->size, | 1755 | be16_add_cpu(&map->size, |
1756 | be16_to_cpu(hdr->freemap[after].size)); | 1756 | be16_to_cpu(hdr->freemap[after].size)); |
1757 | hdr->freemap[after].base = 0; | 1757 | hdr->freemap[after].base = 0; |
1758 | hdr->freemap[after].size = 0; | 1758 | hdr->freemap[after].size = 0; |
1759 | } else if (before >= 0) { | 1759 | } else if (before >= 0) { |
1760 | map = &hdr->freemap[before]; | 1760 | map = &hdr->freemap[before]; |
1761 | be16_add(&map->size, entsize); | 1761 | be16_add_cpu(&map->size, entsize); |
1762 | } else { | 1762 | } else { |
1763 | map = &hdr->freemap[after]; | 1763 | map = &hdr->freemap[after]; |
1764 | /* both on-disk, don't endian flip twice */ | 1764 | /* both on-disk, don't endian flip twice */ |
1765 | map->base = entry->nameidx; | 1765 | map->base = entry->nameidx; |
1766 | be16_add(&map->size, entsize); | 1766 | be16_add_cpu(&map->size, entsize); |
1767 | } | 1767 | } |
1768 | } else { | 1768 | } else { |
1769 | /* | 1769 | /* |
@@ -1788,7 +1788,7 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1788 | * Compress the remaining entries and zero out the removed stuff. | 1788 | * Compress the remaining entries and zero out the removed stuff. |
1789 | */ | 1789 | */ |
1790 | memset(XFS_ATTR_LEAF_NAME(leaf, args->index), 0, entsize); | 1790 | memset(XFS_ATTR_LEAF_NAME(leaf, args->index), 0, entsize); |
1791 | be16_add(&hdr->usedbytes, -entsize); | 1791 | be16_add_cpu(&hdr->usedbytes, -entsize); |
1792 | xfs_da_log_buf(args->trans, bp, | 1792 | xfs_da_log_buf(args->trans, bp, |
1793 | XFS_DA_LOGRANGE(leaf, XFS_ATTR_LEAF_NAME(leaf, args->index), | 1793 | XFS_DA_LOGRANGE(leaf, XFS_ATTR_LEAF_NAME(leaf, args->index), |
1794 | entsize)); | 1794 | entsize)); |
@@ -1796,7 +1796,7 @@ xfs_attr_leaf_remove(xfs_dabuf_t *bp, xfs_da_args_t *args) | |||
1796 | tmp = (be16_to_cpu(hdr->count) - args->index) | 1796 | tmp = (be16_to_cpu(hdr->count) - args->index) |
1797 | * sizeof(xfs_attr_leaf_entry_t); | 1797 | * sizeof(xfs_attr_leaf_entry_t); |
1798 | memmove((char *)entry, (char *)(entry+1), tmp); | 1798 | memmove((char *)entry, (char *)(entry+1), tmp); |
1799 | be16_add(&hdr->count, -1); | 1799 | be16_add_cpu(&hdr->count, -1); |
1800 | xfs_da_log_buf(args->trans, bp, | 1800 | xfs_da_log_buf(args->trans, bp, |
1801 | XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); | 1801 | XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry))); |
1802 | entry = &leaf->entries[be16_to_cpu(hdr->count)]; | 1802 | entry = &leaf->entries[be16_to_cpu(hdr->count)]; |
@@ -2182,15 +2182,15 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, | |||
2182 | */ | 2182 | */ |
2183 | if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */ | 2183 | if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */ |
2184 | memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp); | 2184 | memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp); |
2185 | be16_add(&hdr_s->usedbytes, -tmp); | 2185 | be16_add_cpu(&hdr_s->usedbytes, -tmp); |
2186 | be16_add(&hdr_s->count, -1); | 2186 | be16_add_cpu(&hdr_s->count, -1); |
2187 | entry_d--; /* to compensate for ++ in loop hdr */ | 2187 | entry_d--; /* to compensate for ++ in loop hdr */ |
2188 | desti--; | 2188 | desti--; |
2189 | if ((start_s + i) < offset) | 2189 | if ((start_s + i) < offset) |
2190 | result++; /* insertion index adjustment */ | 2190 | result++; /* insertion index adjustment */ |
2191 | } else { | 2191 | } else { |
2192 | #endif /* GROT */ | 2192 | #endif /* GROT */ |
2193 | be16_add(&hdr_d->firstused, -tmp); | 2193 | be16_add_cpu(&hdr_d->firstused, -tmp); |
2194 | /* both on-disk, don't endian flip twice */ | 2194 | /* both on-disk, don't endian flip twice */ |
2195 | entry_d->hashval = entry_s->hashval; | 2195 | entry_d->hashval = entry_s->hashval; |
2196 | /* both on-disk, don't endian flip twice */ | 2196 | /* both on-disk, don't endian flip twice */ |
@@ -2203,10 +2203,10 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, | |||
2203 | ASSERT(be16_to_cpu(entry_s->nameidx) + tmp | 2203 | ASSERT(be16_to_cpu(entry_s->nameidx) + tmp |
2204 | <= XFS_LBSIZE(mp)); | 2204 | <= XFS_LBSIZE(mp)); |
2205 | memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp); | 2205 | memset(XFS_ATTR_LEAF_NAME(leaf_s, start_s + i), 0, tmp); |
2206 | be16_add(&hdr_s->usedbytes, -tmp); | 2206 | be16_add_cpu(&hdr_s->usedbytes, -tmp); |
2207 | be16_add(&hdr_d->usedbytes, tmp); | 2207 | be16_add_cpu(&hdr_d->usedbytes, tmp); |
2208 | be16_add(&hdr_s->count, -1); | 2208 | be16_add_cpu(&hdr_s->count, -1); |
2209 | be16_add(&hdr_d->count, 1); | 2209 | be16_add_cpu(&hdr_d->count, 1); |
2210 | tmp = be16_to_cpu(hdr_d->count) | 2210 | tmp = be16_to_cpu(hdr_d->count) |
2211 | * sizeof(xfs_attr_leaf_entry_t) | 2211 | * sizeof(xfs_attr_leaf_entry_t) |
2212 | + sizeof(xfs_attr_leaf_hdr_t); | 2212 | + sizeof(xfs_attr_leaf_hdr_t); |
@@ -2247,7 +2247,7 @@ xfs_attr_leaf_moveents(xfs_attr_leafblock_t *leaf_s, int start_s, | |||
2247 | * Fill in the freemap information | 2247 | * Fill in the freemap information |
2248 | */ | 2248 | */ |
2249 | hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); | 2249 | hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_attr_leaf_hdr_t)); |
2250 | be16_add(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) * | 2250 | be16_add_cpu(&hdr_d->freemap[0].base, be16_to_cpu(hdr_d->count) * |
2251 | sizeof(xfs_attr_leaf_entry_t)); | 2251 | sizeof(xfs_attr_leaf_entry_t)); |
2252 | hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) | 2252 | hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) |
2253 | - be16_to_cpu(hdr_d->freemap[0].base)); | 2253 | - be16_to_cpu(hdr_d->freemap[0].base)); |
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index c4181d85605c..bd18987326a3 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -631,7 +631,7 @@ xfs_bmbt_delrec( | |||
631 | memcpy(lrp, rrp, numrrecs * sizeof(*lrp)); | 631 | memcpy(lrp, rrp, numrrecs * sizeof(*lrp)); |
632 | xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs); | 632 | xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs); |
633 | } | 633 | } |
634 | be16_add(&left->bb_numrecs, numrrecs); | 634 | be16_add_cpu(&left->bb_numrecs, numrrecs); |
635 | left->bb_rightsib = right->bb_rightsib; | 635 | left->bb_rightsib = right->bb_rightsib; |
636 | xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS); | 636 | xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS); |
637 | if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) { | 637 | if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) { |
@@ -924,7 +924,7 @@ xfs_bmbt_killroot( | |||
924 | xfs_iroot_realloc(ip, i, cur->bc_private.b.whichfork); | 924 | xfs_iroot_realloc(ip, i, cur->bc_private.b.whichfork); |
925 | block = ifp->if_broot; | 925 | block = ifp->if_broot; |
926 | } | 926 | } |
927 | be16_add(&block->bb_numrecs, i); | 927 | be16_add_cpu(&block->bb_numrecs, i); |
928 | ASSERT(block->bb_numrecs == cblock->bb_numrecs); | 928 | ASSERT(block->bb_numrecs == cblock->bb_numrecs); |
929 | kp = XFS_BMAP_KEY_IADDR(block, 1, cur); | 929 | kp = XFS_BMAP_KEY_IADDR(block, 1, cur); |
930 | ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur); | 930 | ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur); |
@@ -947,7 +947,7 @@ xfs_bmbt_killroot( | |||
947 | XFS_TRANS_DQ_BCOUNT, -1L); | 947 | XFS_TRANS_DQ_BCOUNT, -1L); |
948 | xfs_trans_binval(cur->bc_tp, cbp); | 948 | xfs_trans_binval(cur->bc_tp, cbp); |
949 | cur->bc_bufs[level - 1] = NULL; | 949 | cur->bc_bufs[level - 1] = NULL; |
950 | be16_add(&block->bb_level, -1); | 950 | be16_add_cpu(&block->bb_level, -1); |
951 | xfs_trans_log_inode(cur->bc_tp, ip, | 951 | xfs_trans_log_inode(cur->bc_tp, ip, |
952 | XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork)); | 952 | XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork)); |
953 | cur->bc_nlevels--; | 953 | cur->bc_nlevels--; |
@@ -1401,9 +1401,9 @@ xfs_bmbt_rshift( | |||
1401 | key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp)); | 1401 | key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp)); |
1402 | rkp = &key; | 1402 | rkp = &key; |
1403 | } | 1403 | } |
1404 | be16_add(&left->bb_numrecs, -1); | 1404 | be16_add_cpu(&left->bb_numrecs, -1); |
1405 | xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS); | 1405 | xfs_bmbt_log_block(cur, lbp, XFS_BB_NUMRECS); |
1406 | be16_add(&right->bb_numrecs, 1); | 1406 | be16_add_cpu(&right->bb_numrecs, 1); |
1407 | #ifdef DEBUG | 1407 | #ifdef DEBUG |
1408 | if (level > 0) | 1408 | if (level > 0) |
1409 | xfs_btree_check_key(XFS_BTNUM_BMAP, rkp, rkp + 1); | 1409 | xfs_btree_check_key(XFS_BTNUM_BMAP, rkp, rkp + 1); |
@@ -1535,7 +1535,7 @@ xfs_bmbt_split( | |||
1535 | right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2); | 1535 | right->bb_numrecs = cpu_to_be16(be16_to_cpu(left->bb_numrecs) / 2); |
1536 | if ((be16_to_cpu(left->bb_numrecs) & 1) && | 1536 | if ((be16_to_cpu(left->bb_numrecs) & 1) && |
1537 | cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1) | 1537 | cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1) |
1538 | be16_add(&right->bb_numrecs, 1); | 1538 | be16_add_cpu(&right->bb_numrecs, 1); |
1539 | i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1; | 1539 | i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1; |
1540 | if (level > 0) { | 1540 | if (level > 0) { |
1541 | lkp = XFS_BMAP_KEY_IADDR(left, i, cur); | 1541 | lkp = XFS_BMAP_KEY_IADDR(left, i, cur); |
@@ -1562,7 +1562,7 @@ xfs_bmbt_split( | |||
1562 | xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); | 1562 | xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); |
1563 | *startoff = xfs_bmbt_disk_get_startoff(rrp); | 1563 | *startoff = xfs_bmbt_disk_get_startoff(rrp); |
1564 | } | 1564 | } |
1565 | be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); | 1565 | be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); |
1566 | right->bb_rightsib = left->bb_rightsib; | 1566 | right->bb_rightsib = left->bb_rightsib; |
1567 | left->bb_rightsib = cpu_to_be64(args.fsbno); | 1567 | left->bb_rightsib = cpu_to_be64(args.fsbno); |
1568 | right->bb_leftsib = cpu_to_be64(lbno); | 1568 | right->bb_leftsib = cpu_to_be64(lbno); |
@@ -2240,7 +2240,7 @@ xfs_bmbt_newroot( | |||
2240 | bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0); | 2240 | bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0); |
2241 | cblock = XFS_BUF_TO_BMBT_BLOCK(bp); | 2241 | cblock = XFS_BUF_TO_BMBT_BLOCK(bp); |
2242 | *cblock = *block; | 2242 | *cblock = *block; |
2243 | be16_add(&block->bb_level, 1); | 2243 | be16_add_cpu(&block->bb_level, 1); |
2244 | block->bb_numrecs = cpu_to_be16(1); | 2244 | block->bb_numrecs = cpu_to_be16(1); |
2245 | cur->bc_nlevels++; | 2245 | cur->bc_nlevels++; |
2246 | cur->bc_ptrs[level + 1] = 1; | 2246 | cur->bc_ptrs[level + 1] = 1; |
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 1b446849fb3d..021a8f7e563f 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
@@ -511,12 +511,12 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
511 | * Move the req'd B-tree elements from high in node1 to | 511 | * Move the req'd B-tree elements from high in node1 to |
512 | * low in node2. | 512 | * low in node2. |
513 | */ | 513 | */ |
514 | be16_add(&node2->hdr.count, count); | 514 | be16_add_cpu(&node2->hdr.count, count); |
515 | tmp = count * (uint)sizeof(xfs_da_node_entry_t); | 515 | tmp = count * (uint)sizeof(xfs_da_node_entry_t); |
516 | btree_s = &node1->btree[be16_to_cpu(node1->hdr.count) - count]; | 516 | btree_s = &node1->btree[be16_to_cpu(node1->hdr.count) - count]; |
517 | btree_d = &node2->btree[0]; | 517 | btree_d = &node2->btree[0]; |
518 | memcpy(btree_d, btree_s, tmp); | 518 | memcpy(btree_d, btree_s, tmp); |
519 | be16_add(&node1->hdr.count, -count); | 519 | be16_add_cpu(&node1->hdr.count, -count); |
520 | } else { | 520 | } else { |
521 | /* | 521 | /* |
522 | * Move the req'd B-tree elements from low in node2 to | 522 | * Move the req'd B-tree elements from low in node2 to |
@@ -527,7 +527,7 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
527 | btree_s = &node2->btree[0]; | 527 | btree_s = &node2->btree[0]; |
528 | btree_d = &node1->btree[be16_to_cpu(node1->hdr.count)]; | 528 | btree_d = &node1->btree[be16_to_cpu(node1->hdr.count)]; |
529 | memcpy(btree_d, btree_s, tmp); | 529 | memcpy(btree_d, btree_s, tmp); |
530 | be16_add(&node1->hdr.count, count); | 530 | be16_add_cpu(&node1->hdr.count, count); |
531 | xfs_da_log_buf(tp, blk1->bp, | 531 | xfs_da_log_buf(tp, blk1->bp, |
532 | XFS_DA_LOGRANGE(node1, btree_d, tmp)); | 532 | XFS_DA_LOGRANGE(node1, btree_d, tmp)); |
533 | 533 | ||
@@ -539,7 +539,7 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
539 | btree_s = &node2->btree[count]; | 539 | btree_s = &node2->btree[count]; |
540 | btree_d = &node2->btree[0]; | 540 | btree_d = &node2->btree[0]; |
541 | memmove(btree_d, btree_s, tmp); | 541 | memmove(btree_d, btree_s, tmp); |
542 | be16_add(&node2->hdr.count, -count); | 542 | be16_add_cpu(&node2->hdr.count, -count); |
543 | } | 543 | } |
544 | 544 | ||
545 | /* | 545 | /* |
@@ -604,7 +604,7 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, | |||
604 | btree->before = cpu_to_be32(newblk->blkno); | 604 | btree->before = cpu_to_be32(newblk->blkno); |
605 | xfs_da_log_buf(state->args->trans, oldblk->bp, | 605 | xfs_da_log_buf(state->args->trans, oldblk->bp, |
606 | XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree))); | 606 | XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree))); |
607 | be16_add(&node->hdr.count, 1); | 607 | be16_add_cpu(&node->hdr.count, 1); |
608 | xfs_da_log_buf(state->args->trans, oldblk->bp, | 608 | xfs_da_log_buf(state->args->trans, oldblk->bp, |
609 | XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); | 609 | XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); |
610 | 610 | ||
@@ -959,7 +959,7 @@ xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk) | |||
959 | memset((char *)btree, 0, sizeof(xfs_da_node_entry_t)); | 959 | memset((char *)btree, 0, sizeof(xfs_da_node_entry_t)); |
960 | xfs_da_log_buf(state->args->trans, drop_blk->bp, | 960 | xfs_da_log_buf(state->args->trans, drop_blk->bp, |
961 | XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); | 961 | XFS_DA_LOGRANGE(node, btree, sizeof(*btree))); |
962 | be16_add(&node->hdr.count, -1); | 962 | be16_add_cpu(&node->hdr.count, -1); |
963 | xfs_da_log_buf(state->args->trans, drop_blk->bp, | 963 | xfs_da_log_buf(state->args->trans, drop_blk->bp, |
964 | XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); | 964 | XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); |
965 | 965 | ||
@@ -1018,7 +1018,7 @@ xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1018 | */ | 1018 | */ |
1019 | tmp = be16_to_cpu(drop_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t); | 1019 | tmp = be16_to_cpu(drop_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t); |
1020 | memcpy(btree, &drop_node->btree[0], tmp); | 1020 | memcpy(btree, &drop_node->btree[0], tmp); |
1021 | be16_add(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count)); | 1021 | be16_add_cpu(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count)); |
1022 | 1022 | ||
1023 | xfs_da_log_buf(tp, save_blk->bp, | 1023 | xfs_da_log_buf(tp, save_blk->bp, |
1024 | XFS_DA_LOGRANGE(save_node, &save_node->hdr, | 1024 | XFS_DA_LOGRANGE(save_node, &save_node->hdr, |
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index a5f4f4fb8868..fb5a556725b3 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c | |||
@@ -271,7 +271,7 @@ xfs_dir2_block_addname( | |||
271 | } | 271 | } |
272 | lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1); | 272 | lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1); |
273 | lfloghigh -= be32_to_cpu(btp->stale) - 1; | 273 | lfloghigh -= be32_to_cpu(btp->stale) - 1; |
274 | be32_add(&btp->count, -(be32_to_cpu(btp->stale) - 1)); | 274 | be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1)); |
275 | xfs_dir2_data_make_free(tp, bp, | 275 | xfs_dir2_data_make_free(tp, bp, |
276 | (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), | 276 | (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), |
277 | (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)), | 277 | (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)), |
@@ -326,7 +326,7 @@ xfs_dir2_block_addname( | |||
326 | /* | 326 | /* |
327 | * Update the tail (entry count). | 327 | * Update the tail (entry count). |
328 | */ | 328 | */ |
329 | be32_add(&btp->count, 1); | 329 | be32_add_cpu(&btp->count, 1); |
330 | /* | 330 | /* |
331 | * If we now need to rebuild the bestfree map, do so. | 331 | * If we now need to rebuild the bestfree map, do so. |
332 | * This needs to happen before the next call to use_free. | 332 | * This needs to happen before the next call to use_free. |
@@ -387,7 +387,7 @@ xfs_dir2_block_addname( | |||
387 | lfloglow = MIN(mid, lfloglow); | 387 | lfloglow = MIN(mid, lfloglow); |
388 | lfloghigh = MAX(highstale, lfloghigh); | 388 | lfloghigh = MAX(highstale, lfloghigh); |
389 | } | 389 | } |
390 | be32_add(&btp->stale, -1); | 390 | be32_add_cpu(&btp->stale, -1); |
391 | } | 391 | } |
392 | /* | 392 | /* |
393 | * Point to the new data entry. | 393 | * Point to the new data entry. |
@@ -767,7 +767,7 @@ xfs_dir2_block_removename( | |||
767 | /* | 767 | /* |
768 | * Fix up the block tail. | 768 | * Fix up the block tail. |
769 | */ | 769 | */ |
770 | be32_add(&btp->stale, 1); | 770 | be32_add_cpu(&btp->stale, 1); |
771 | xfs_dir2_block_log_tail(tp, bp); | 771 | xfs_dir2_block_log_tail(tp, bp); |
772 | /* | 772 | /* |
773 | * Remove the leaf entry by marking it stale. | 773 | * Remove the leaf entry by marking it stale. |
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c index d2452699e9b1..fb8c9e08b23d 100644 --- a/fs/xfs/xfs_dir2_data.c +++ b/fs/xfs/xfs_dir2_data.c | |||
@@ -587,7 +587,7 @@ xfs_dir2_data_make_free( | |||
587 | /* | 587 | /* |
588 | * Fix up the new big freespace. | 588 | * Fix up the new big freespace. |
589 | */ | 589 | */ |
590 | be16_add(&prevdup->length, len + be16_to_cpu(postdup->length)); | 590 | be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length)); |
591 | *xfs_dir2_data_unused_tag_p(prevdup) = | 591 | *xfs_dir2_data_unused_tag_p(prevdup) = |
592 | cpu_to_be16((char *)prevdup - (char *)d); | 592 | cpu_to_be16((char *)prevdup - (char *)d); |
593 | xfs_dir2_data_log_unused(tp, bp, prevdup); | 593 | xfs_dir2_data_log_unused(tp, bp, prevdup); |
@@ -621,7 +621,7 @@ xfs_dir2_data_make_free( | |||
621 | */ | 621 | */ |
622 | else if (prevdup) { | 622 | else if (prevdup) { |
623 | dfp = xfs_dir2_data_freefind(d, prevdup); | 623 | dfp = xfs_dir2_data_freefind(d, prevdup); |
624 | be16_add(&prevdup->length, len); | 624 | be16_add_cpu(&prevdup->length, len); |
625 | *xfs_dir2_data_unused_tag_p(prevdup) = | 625 | *xfs_dir2_data_unused_tag_p(prevdup) = |
626 | cpu_to_be16((char *)prevdup - (char *)d); | 626 | cpu_to_be16((char *)prevdup - (char *)d); |
627 | xfs_dir2_data_log_unused(tp, bp, prevdup); | 627 | xfs_dir2_data_log_unused(tp, bp, prevdup); |
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 0ca0020ba09f..bc52b803d79b 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c | |||
@@ -359,7 +359,7 @@ xfs_dir2_leaf_addname( | |||
359 | bestsp--; | 359 | bestsp--; |
360 | memmove(&bestsp[0], &bestsp[1], | 360 | memmove(&bestsp[0], &bestsp[1], |
361 | be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0])); | 361 | be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0])); |
362 | be32_add(<p->bestcount, 1); | 362 | be32_add_cpu(<p->bestcount, 1); |
363 | xfs_dir2_leaf_log_tail(tp, lbp); | 363 | xfs_dir2_leaf_log_tail(tp, lbp); |
364 | xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); | 364 | xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); |
365 | } | 365 | } |
@@ -445,7 +445,7 @@ xfs_dir2_leaf_addname( | |||
445 | */ | 445 | */ |
446 | lfloglow = index; | 446 | lfloglow = index; |
447 | lfloghigh = be16_to_cpu(leaf->hdr.count); | 447 | lfloghigh = be16_to_cpu(leaf->hdr.count); |
448 | be16_add(&leaf->hdr.count, 1); | 448 | be16_add_cpu(&leaf->hdr.count, 1); |
449 | } | 449 | } |
450 | /* | 450 | /* |
451 | * There are stale entries. | 451 | * There are stale entries. |
@@ -523,7 +523,7 @@ xfs_dir2_leaf_addname( | |||
523 | lfloglow = MIN(index, lfloglow); | 523 | lfloglow = MIN(index, lfloglow); |
524 | lfloghigh = MAX(highstale, lfloghigh); | 524 | lfloghigh = MAX(highstale, lfloghigh); |
525 | } | 525 | } |
526 | be16_add(&leaf->hdr.stale, -1); | 526 | be16_add_cpu(&leaf->hdr.stale, -1); |
527 | } | 527 | } |
528 | /* | 528 | /* |
529 | * Fill in the new leaf entry. | 529 | * Fill in the new leaf entry. |
@@ -626,7 +626,7 @@ xfs_dir2_leaf_compact( | |||
626 | * Update and log the header, log the leaf entries. | 626 | * Update and log the header, log the leaf entries. |
627 | */ | 627 | */ |
628 | ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to); | 628 | ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to); |
629 | be16_add(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale))); | 629 | be16_add_cpu(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale))); |
630 | leaf->hdr.stale = 0; | 630 | leaf->hdr.stale = 0; |
631 | xfs_dir2_leaf_log_header(args->trans, bp); | 631 | xfs_dir2_leaf_log_header(args->trans, bp); |
632 | if (loglow != -1) | 632 | if (loglow != -1) |
@@ -728,7 +728,7 @@ xfs_dir2_leaf_compact_x1( | |||
728 | /* | 728 | /* |
729 | * Adjust the leaf header values. | 729 | * Adjust the leaf header values. |
730 | */ | 730 | */ |
731 | be16_add(&leaf->hdr.count, -(from - to)); | 731 | be16_add_cpu(&leaf->hdr.count, -(from - to)); |
732 | leaf->hdr.stale = cpu_to_be16(1); | 732 | leaf->hdr.stale = cpu_to_be16(1); |
733 | /* | 733 | /* |
734 | * Remember the low/high stale value only in the "right" | 734 | * Remember the low/high stale value only in the "right" |
@@ -1470,7 +1470,7 @@ xfs_dir2_leaf_removename( | |||
1470 | /* | 1470 | /* |
1471 | * We just mark the leaf entry stale by putting a null in it. | 1471 | * We just mark the leaf entry stale by putting a null in it. |
1472 | */ | 1472 | */ |
1473 | be16_add(&leaf->hdr.stale, 1); | 1473 | be16_add_cpu(&leaf->hdr.stale, 1); |
1474 | xfs_dir2_leaf_log_header(tp, lbp); | 1474 | xfs_dir2_leaf_log_header(tp, lbp); |
1475 | lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); | 1475 | lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); |
1476 | xfs_dir2_leaf_log_ents(tp, lbp, index, index); | 1476 | xfs_dir2_leaf_log_ents(tp, lbp, index, index); |
@@ -1531,7 +1531,7 @@ xfs_dir2_leaf_removename( | |||
1531 | */ | 1531 | */ |
1532 | memmove(&bestsp[db - i], bestsp, | 1532 | memmove(&bestsp[db - i], bestsp, |
1533 | (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp)); | 1533 | (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp)); |
1534 | be32_add(<p->bestcount, -(db - i)); | 1534 | be32_add_cpu(<p->bestcount, -(db - i)); |
1535 | xfs_dir2_leaf_log_tail(tp, lbp); | 1535 | xfs_dir2_leaf_log_tail(tp, lbp); |
1536 | xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); | 1536 | xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); |
1537 | } else | 1537 | } else |
@@ -1712,7 +1712,7 @@ xfs_dir2_leaf_trim_data( | |||
1712 | * Eliminate the last bests entry from the table. | 1712 | * Eliminate the last bests entry from the table. |
1713 | */ | 1713 | */ |
1714 | bestsp = xfs_dir2_leaf_bests_p(ltp); | 1714 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
1715 | be32_add(<p->bestcount, -1); | 1715 | be32_add_cpu(<p->bestcount, -1); |
1716 | memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp)); | 1716 | memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp)); |
1717 | xfs_dir2_leaf_log_tail(tp, lbp); | 1717 | xfs_dir2_leaf_log_tail(tp, lbp); |
1718 | xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); | 1718 | xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); |
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index eb18e399e836..8dade711f099 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c | |||
@@ -254,7 +254,7 @@ xfs_dir2_leafn_add( | |||
254 | (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); | 254 | (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); |
255 | lfloglow = index; | 255 | lfloglow = index; |
256 | lfloghigh = be16_to_cpu(leaf->hdr.count); | 256 | lfloghigh = be16_to_cpu(leaf->hdr.count); |
257 | be16_add(&leaf->hdr.count, 1); | 257 | be16_add_cpu(&leaf->hdr.count, 1); |
258 | } | 258 | } |
259 | /* | 259 | /* |
260 | * There are stale entries. We'll use one for the new entry. | 260 | * There are stale entries. We'll use one for the new entry. |
@@ -322,7 +322,7 @@ xfs_dir2_leafn_add( | |||
322 | lfloglow = MIN(index, lfloglow); | 322 | lfloglow = MIN(index, lfloglow); |
323 | lfloghigh = MAX(highstale, lfloghigh); | 323 | lfloghigh = MAX(highstale, lfloghigh); |
324 | } | 324 | } |
325 | be16_add(&leaf->hdr.stale, -1); | 325 | be16_add_cpu(&leaf->hdr.stale, -1); |
326 | } | 326 | } |
327 | /* | 327 | /* |
328 | * Insert the new entry, log everything. | 328 | * Insert the new entry, log everything. |
@@ -697,10 +697,10 @@ xfs_dir2_leafn_moveents( | |||
697 | /* | 697 | /* |
698 | * Update the headers and log them. | 698 | * Update the headers and log them. |
699 | */ | 699 | */ |
700 | be16_add(&leaf_s->hdr.count, -(count)); | 700 | be16_add_cpu(&leaf_s->hdr.count, -(count)); |
701 | be16_add(&leaf_s->hdr.stale, -(stale)); | 701 | be16_add_cpu(&leaf_s->hdr.stale, -(stale)); |
702 | be16_add(&leaf_d->hdr.count, count); | 702 | be16_add_cpu(&leaf_d->hdr.count, count); |
703 | be16_add(&leaf_d->hdr.stale, stale); | 703 | be16_add_cpu(&leaf_d->hdr.stale, stale); |
704 | xfs_dir2_leaf_log_header(tp, bp_s); | 704 | xfs_dir2_leaf_log_header(tp, bp_s); |
705 | xfs_dir2_leaf_log_header(tp, bp_d); | 705 | xfs_dir2_leaf_log_header(tp, bp_d); |
706 | xfs_dir2_leafn_check(args->dp, bp_s); | 706 | xfs_dir2_leafn_check(args->dp, bp_s); |
@@ -885,7 +885,7 @@ xfs_dir2_leafn_remove( | |||
885 | * Kill the leaf entry by marking it stale. | 885 | * Kill the leaf entry by marking it stale. |
886 | * Log the leaf block changes. | 886 | * Log the leaf block changes. |
887 | */ | 887 | */ |
888 | be16_add(&leaf->hdr.stale, 1); | 888 | be16_add_cpu(&leaf->hdr.stale, 1); |
889 | xfs_dir2_leaf_log_header(tp, bp); | 889 | xfs_dir2_leaf_log_header(tp, bp); |
890 | lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); | 890 | lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); |
891 | xfs_dir2_leaf_log_ents(tp, bp, index, index); | 891 | xfs_dir2_leaf_log_ents(tp, bp, index, index); |
@@ -971,7 +971,7 @@ xfs_dir2_leafn_remove( | |||
971 | /* | 971 | /* |
972 | * One less used entry in the free table. | 972 | * One less used entry in the free table. |
973 | */ | 973 | */ |
974 | be32_add(&free->hdr.nused, -1); | 974 | be32_add_cpu(&free->hdr.nused, -1); |
975 | xfs_dir2_free_log_header(tp, fbp); | 975 | xfs_dir2_free_log_header(tp, fbp); |
976 | /* | 976 | /* |
977 | * If this was the last entry in the table, we can | 977 | * If this was the last entry in the table, we can |
@@ -1642,7 +1642,7 @@ xfs_dir2_node_addname_int( | |||
1642 | * (this should always be true) then update the header. | 1642 | * (this should always be true) then update the header. |
1643 | */ | 1643 | */ |
1644 | if (be16_to_cpu(free->bests[findex]) == NULLDATAOFF) { | 1644 | if (be16_to_cpu(free->bests[findex]) == NULLDATAOFF) { |
1645 | be32_add(&free->hdr.nused, 1); | 1645 | be32_add_cpu(&free->hdr.nused, 1); |
1646 | xfs_dir2_free_log_header(tp, fbp); | 1646 | xfs_dir2_free_log_header(tp, fbp); |
1647 | } | 1647 | } |
1648 | /* | 1648 | /* |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index b8de7f3cc17e..eadc1591c795 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -318,7 +318,7 @@ xfs_growfs_data_private( | |||
318 | } | 318 | } |
319 | ASSERT(bp); | 319 | ASSERT(bp); |
320 | agi = XFS_BUF_TO_AGI(bp); | 320 | agi = XFS_BUF_TO_AGI(bp); |
321 | be32_add(&agi->agi_length, new); | 321 | be32_add_cpu(&agi->agi_length, new); |
322 | ASSERT(nagcount == oagcount || | 322 | ASSERT(nagcount == oagcount || |
323 | be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks); | 323 | be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks); |
324 | xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH); | 324 | xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH); |
@@ -331,7 +331,7 @@ xfs_growfs_data_private( | |||
331 | } | 331 | } |
332 | ASSERT(bp); | 332 | ASSERT(bp); |
333 | agf = XFS_BUF_TO_AGF(bp); | 333 | agf = XFS_BUF_TO_AGF(bp); |
334 | be32_add(&agf->agf_length, new); | 334 | be32_add_cpu(&agf->agf_length, new); |
335 | ASSERT(be32_to_cpu(agf->agf_length) == | 335 | ASSERT(be32_to_cpu(agf->agf_length) == |
336 | be32_to_cpu(agi->agi_length)); | 336 | be32_to_cpu(agi->agi_length)); |
337 | xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH); | 337 | xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH); |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 1409c2d61c11..c5836b951d0c 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -301,8 +301,8 @@ xfs_ialloc_ag_alloc( | |||
301 | } | 301 | } |
302 | xfs_trans_inode_alloc_buf(tp, fbuf); | 302 | xfs_trans_inode_alloc_buf(tp, fbuf); |
303 | } | 303 | } |
304 | be32_add(&agi->agi_count, newlen); | 304 | be32_add_cpu(&agi->agi_count, newlen); |
305 | be32_add(&agi->agi_freecount, newlen); | 305 | be32_add_cpu(&agi->agi_freecount, newlen); |
306 | agno = be32_to_cpu(agi->agi_seqno); | 306 | agno = be32_to_cpu(agi->agi_seqno); |
307 | down_read(&args.mp->m_peraglock); | 307 | down_read(&args.mp->m_peraglock); |
308 | args.mp->m_perag[agno].pagi_freecount += newlen; | 308 | args.mp->m_perag[agno].pagi_freecount += newlen; |
@@ -885,7 +885,7 @@ nextag: | |||
885 | if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount, | 885 | if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount, |
886 | rec.ir_free))) | 886 | rec.ir_free))) |
887 | goto error0; | 887 | goto error0; |
888 | be32_add(&agi->agi_freecount, -1); | 888 | be32_add_cpu(&agi->agi_freecount, -1); |
889 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); | 889 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); |
890 | down_read(&mp->m_peraglock); | 890 | down_read(&mp->m_peraglock); |
891 | mp->m_perag[tagno].pagi_freecount--; | 891 | mp->m_perag[tagno].pagi_freecount--; |
@@ -1065,8 +1065,8 @@ xfs_difree( | |||
1065 | * to be freed when the transaction is committed. | 1065 | * to be freed when the transaction is committed. |
1066 | */ | 1066 | */ |
1067 | ilen = XFS_IALLOC_INODES(mp); | 1067 | ilen = XFS_IALLOC_INODES(mp); |
1068 | be32_add(&agi->agi_count, -ilen); | 1068 | be32_add_cpu(&agi->agi_count, -ilen); |
1069 | be32_add(&agi->agi_freecount, -(ilen - 1)); | 1069 | be32_add_cpu(&agi->agi_freecount, -(ilen - 1)); |
1070 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT); | 1070 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT); |
1071 | down_read(&mp->m_peraglock); | 1071 | down_read(&mp->m_peraglock); |
1072 | mp->m_perag[agno].pagi_freecount -= ilen - 1; | 1072 | mp->m_perag[agno].pagi_freecount -= ilen - 1; |
@@ -1095,7 +1095,7 @@ xfs_difree( | |||
1095 | /* | 1095 | /* |
1096 | * Change the inode free counts and log the ag/sb changes. | 1096 | * Change the inode free counts and log the ag/sb changes. |
1097 | */ | 1097 | */ |
1098 | be32_add(&agi->agi_freecount, 1); | 1098 | be32_add_cpu(&agi->agi_freecount, 1); |
1099 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); | 1099 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); |
1100 | down_read(&mp->m_peraglock); | 1100 | down_read(&mp->m_peraglock); |
1101 | mp->m_perag[agno].pagi_freecount++; | 1101 | mp->m_perag[agno].pagi_freecount++; |
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c index 8cdeeaf8632b..e5310c90e50f 100644 --- a/fs/xfs/xfs_ialloc_btree.c +++ b/fs/xfs/xfs_ialloc_btree.c | |||
@@ -189,7 +189,7 @@ xfs_inobt_delrec( | |||
189 | */ | 189 | */ |
190 | bno = be32_to_cpu(agi->agi_root); | 190 | bno = be32_to_cpu(agi->agi_root); |
191 | agi->agi_root = *pp; | 191 | agi->agi_root = *pp; |
192 | be32_add(&agi->agi_level, -1); | 192 | be32_add_cpu(&agi->agi_level, -1); |
193 | /* | 193 | /* |
194 | * Free the block. | 194 | * Free the block. |
195 | */ | 195 | */ |
@@ -1132,7 +1132,7 @@ xfs_inobt_lshift( | |||
1132 | /* | 1132 | /* |
1133 | * Bump and log left's numrecs, decrement and log right's numrecs. | 1133 | * Bump and log left's numrecs, decrement and log right's numrecs. |
1134 | */ | 1134 | */ |
1135 | be16_add(&left->bb_numrecs, 1); | 1135 | be16_add_cpu(&left->bb_numrecs, 1); |
1136 | xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS); | 1136 | xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS); |
1137 | #ifdef DEBUG | 1137 | #ifdef DEBUG |
1138 | if (level > 0) | 1138 | if (level > 0) |
@@ -1140,7 +1140,7 @@ xfs_inobt_lshift( | |||
1140 | else | 1140 | else |
1141 | xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp); | 1141 | xfs_btree_check_rec(cur->bc_btnum, lrp - 1, lrp); |
1142 | #endif | 1142 | #endif |
1143 | be16_add(&right->bb_numrecs, -1); | 1143 | be16_add_cpu(&right->bb_numrecs, -1); |
1144 | xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS); | 1144 | xfs_inobt_log_block(cur->bc_tp, rbp, XFS_BB_NUMRECS); |
1145 | /* | 1145 | /* |
1146 | * Slide the contents of right down one entry. | 1146 | * Slide the contents of right down one entry. |
@@ -1232,7 +1232,7 @@ xfs_inobt_newroot( | |||
1232 | * Set the root data in the a.g. inode structure. | 1232 | * Set the root data in the a.g. inode structure. |
1233 | */ | 1233 | */ |
1234 | agi->agi_root = cpu_to_be32(args.agbno); | 1234 | agi->agi_root = cpu_to_be32(args.agbno); |
1235 | be32_add(&agi->agi_level, 1); | 1235 | be32_add_cpu(&agi->agi_level, 1); |
1236 | xfs_ialloc_log_agi(args.tp, cur->bc_private.i.agbp, | 1236 | xfs_ialloc_log_agi(args.tp, cur->bc_private.i.agbp, |
1237 | XFS_AGI_ROOT | XFS_AGI_LEVEL); | 1237 | XFS_AGI_ROOT | XFS_AGI_LEVEL); |
1238 | /* | 1238 | /* |
@@ -1426,9 +1426,9 @@ xfs_inobt_rshift( | |||
1426 | /* | 1426 | /* |
1427 | * Decrement and log left's numrecs, bump and log right's numrecs. | 1427 | * Decrement and log left's numrecs, bump and log right's numrecs. |
1428 | */ | 1428 | */ |
1429 | be16_add(&left->bb_numrecs, -1); | 1429 | be16_add_cpu(&left->bb_numrecs, -1); |
1430 | xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS); | 1430 | xfs_inobt_log_block(cur->bc_tp, lbp, XFS_BB_NUMRECS); |
1431 | be16_add(&right->bb_numrecs, 1); | 1431 | be16_add_cpu(&right->bb_numrecs, 1); |
1432 | #ifdef DEBUG | 1432 | #ifdef DEBUG |
1433 | if (level > 0) | 1433 | if (level > 0) |
1434 | xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1); | 1434 | xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1); |
@@ -1529,7 +1529,7 @@ xfs_inobt_split( | |||
1529 | */ | 1529 | */ |
1530 | if ((be16_to_cpu(left->bb_numrecs) & 1) && | 1530 | if ((be16_to_cpu(left->bb_numrecs) & 1) && |
1531 | cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1) | 1531 | cur->bc_ptrs[level] <= be16_to_cpu(right->bb_numrecs) + 1) |
1532 | be16_add(&right->bb_numrecs, 1); | 1532 | be16_add_cpu(&right->bb_numrecs, 1); |
1533 | i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1; | 1533 | i = be16_to_cpu(left->bb_numrecs) - be16_to_cpu(right->bb_numrecs) + 1; |
1534 | /* | 1534 | /* |
1535 | * For non-leaf blocks, copy keys and addresses over to the new block. | 1535 | * For non-leaf blocks, copy keys and addresses over to the new block. |
@@ -1565,7 +1565,7 @@ xfs_inobt_split( | |||
1565 | * Find the left block number by looking in the buffer. | 1565 | * Find the left block number by looking in the buffer. |
1566 | * Adjust numrecs, sibling pointers. | 1566 | * Adjust numrecs, sibling pointers. |
1567 | */ | 1567 | */ |
1568 | be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); | 1568 | be16_add_cpu(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); |
1569 | right->bb_rightsib = left->bb_rightsib; | 1569 | right->bb_rightsib = left->bb_rightsib; |
1570 | left->bb_rightsib = cpu_to_be32(args.agbno); | 1570 | left->bb_rightsib = cpu_to_be32(args.agbno); |
1571 | right->bb_leftsib = cpu_to_be32(lbno); | 1571 | right->bb_leftsib = cpu_to_be32(lbno); |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index b3ac3805d3c4..a75edca1860f 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -1509,9 +1509,9 @@ xlog_sync(xlog_t *log, | |||
1509 | * case, though. | 1509 | * case, though. |
1510 | */ | 1510 | */ |
1511 | for (i = 0; i < split; i += BBSIZE) { | 1511 | for (i = 0; i < split; i += BBSIZE) { |
1512 | be32_add((__be32 *)dptr, 1); | 1512 | be32_add_cpu((__be32 *)dptr, 1); |
1513 | if (be32_to_cpu(*(__be32 *)dptr) == XLOG_HEADER_MAGIC_NUM) | 1513 | if (be32_to_cpu(*(__be32 *)dptr) == XLOG_HEADER_MAGIC_NUM) |
1514 | be32_add((__be32 *)dptr, 1); | 1514 | be32_add_cpu((__be32 *)dptr, 1); |
1515 | dptr += BBSIZE; | 1515 | dptr += BBSIZE; |
1516 | } | 1516 | } |
1517 | 1517 | ||
@@ -1600,7 +1600,7 @@ xlog_state_finish_copy(xlog_t *log, | |||
1600 | { | 1600 | { |
1601 | spin_lock(&log->l_icloglock); | 1601 | spin_lock(&log->l_icloglock); |
1602 | 1602 | ||
1603 | be32_add(&iclog->ic_header.h_num_logops, record_cnt); | 1603 | be32_add_cpu(&iclog->ic_header.h_num_logops, record_cnt); |
1604 | iclog->ic_offset += copy_bytes; | 1604 | iclog->ic_offset += copy_bytes; |
1605 | 1605 | ||
1606 | spin_unlock(&log->l_icloglock); | 1606 | spin_unlock(&log->l_icloglock); |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 71e4c8dcc69b..140386434aa3 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -567,26 +567,26 @@ xfs_trans_apply_sb_deltas( | |||
567 | */ | 567 | */ |
568 | if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) { | 568 | if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) { |
569 | if (tp->t_icount_delta) | 569 | if (tp->t_icount_delta) |
570 | be64_add(&sbp->sb_icount, tp->t_icount_delta); | 570 | be64_add_cpu(&sbp->sb_icount, tp->t_icount_delta); |
571 | if (tp->t_ifree_delta) | 571 | if (tp->t_ifree_delta) |
572 | be64_add(&sbp->sb_ifree, tp->t_ifree_delta); | 572 | be64_add_cpu(&sbp->sb_ifree, tp->t_ifree_delta); |
573 | if (tp->t_fdblocks_delta) | 573 | if (tp->t_fdblocks_delta) |
574 | be64_add(&sbp->sb_fdblocks, tp->t_fdblocks_delta); | 574 | be64_add_cpu(&sbp->sb_fdblocks, tp->t_fdblocks_delta); |
575 | if (tp->t_res_fdblocks_delta) | 575 | if (tp->t_res_fdblocks_delta) |
576 | be64_add(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta); | 576 | be64_add_cpu(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta); |
577 | } | 577 | } |
578 | 578 | ||
579 | if (tp->t_frextents_delta) | 579 | if (tp->t_frextents_delta) |
580 | be64_add(&sbp->sb_frextents, tp->t_frextents_delta); | 580 | be64_add_cpu(&sbp->sb_frextents, tp->t_frextents_delta); |
581 | if (tp->t_res_frextents_delta) | 581 | if (tp->t_res_frextents_delta) |
582 | be64_add(&sbp->sb_frextents, tp->t_res_frextents_delta); | 582 | be64_add_cpu(&sbp->sb_frextents, tp->t_res_frextents_delta); |
583 | 583 | ||
584 | if (tp->t_dblocks_delta) { | 584 | if (tp->t_dblocks_delta) { |
585 | be64_add(&sbp->sb_dblocks, tp->t_dblocks_delta); | 585 | be64_add_cpu(&sbp->sb_dblocks, tp->t_dblocks_delta); |
586 | whole = 1; | 586 | whole = 1; |
587 | } | 587 | } |
588 | if (tp->t_agcount_delta) { | 588 | if (tp->t_agcount_delta) { |
589 | be32_add(&sbp->sb_agcount, tp->t_agcount_delta); | 589 | be32_add_cpu(&sbp->sb_agcount, tp->t_agcount_delta); |
590 | whole = 1; | 590 | whole = 1; |
591 | } | 591 | } |
592 | if (tp->t_imaxpct_delta) { | 592 | if (tp->t_imaxpct_delta) { |
@@ -594,19 +594,19 @@ xfs_trans_apply_sb_deltas( | |||
594 | whole = 1; | 594 | whole = 1; |
595 | } | 595 | } |
596 | if (tp->t_rextsize_delta) { | 596 | if (tp->t_rextsize_delta) { |
597 | be32_add(&sbp->sb_rextsize, tp->t_rextsize_delta); | 597 | be32_add_cpu(&sbp->sb_rextsize, tp->t_rextsize_delta); |
598 | whole = 1; | 598 | whole = 1; |
599 | } | 599 | } |
600 | if (tp->t_rbmblocks_delta) { | 600 | if (tp->t_rbmblocks_delta) { |
601 | be32_add(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta); | 601 | be32_add_cpu(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta); |
602 | whole = 1; | 602 | whole = 1; |
603 | } | 603 | } |
604 | if (tp->t_rblocks_delta) { | 604 | if (tp->t_rblocks_delta) { |
605 | be64_add(&sbp->sb_rblocks, tp->t_rblocks_delta); | 605 | be64_add_cpu(&sbp->sb_rblocks, tp->t_rblocks_delta); |
606 | whole = 1; | 606 | whole = 1; |
607 | } | 607 | } |
608 | if (tp->t_rextents_delta) { | 608 | if (tp->t_rextents_delta) { |
609 | be64_add(&sbp->sb_rextents, tp->t_rextents_delta); | 609 | be64_add_cpu(&sbp->sb_rextents, tp->t_rextents_delta); |
610 | whole = 1; | 610 | whole = 1; |
611 | } | 611 | } |
612 | if (tp->t_rextslog_delta) { | 612 | if (tp->t_rextslog_delta) { |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 022a5fd80c8e..4839f2af94c3 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
@@ -222,7 +222,7 @@ acpi_os_write_memory(acpi_physical_address address, u32 value, u32 width); | |||
222 | */ | 222 | */ |
223 | acpi_status | 223 | acpi_status |
224 | acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id, | 224 | acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id, |
225 | u32 reg, void *value, u32 width); | 225 | u32 reg, u32 *value, u32 width); |
226 | 226 | ||
227 | acpi_status | 227 | acpi_status |
228 | acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id, | 228 | acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id, |
diff --git a/include/asm-mn10300/highmem.h b/include/asm-mn10300/highmem.h index 383c0c42982e..5256854c0453 100644 --- a/include/asm-mn10300/highmem.h +++ b/include/asm-mn10300/highmem.h | |||
@@ -42,8 +42,8 @@ extern void __init kmap_init(void); | |||
42 | #define PKMAP_NR(virt) ((virt - PKMAP_BASE) >> PAGE_SHIFT) | 42 | #define PKMAP_NR(virt) ((virt - PKMAP_BASE) >> PAGE_SHIFT) |
43 | #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) | 43 | #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) |
44 | 44 | ||
45 | extern unsigned long __fastcall kmap_high(struct page *page); | 45 | extern unsigned long kmap_high(struct page *page); |
46 | extern void __fastcall kunmap_high(struct page *page); | 46 | extern void kunmap_high(struct page *page); |
47 | 47 | ||
48 | static inline unsigned long kmap(struct page *page) | 48 | static inline unsigned long kmap(struct page *page) |
49 | { | 49 | { |
diff --git a/include/asm-mn10300/linkage.h b/include/asm-mn10300/linkage.h index 29a32e467523..dda3002a5dfa 100644 --- a/include/asm-mn10300/linkage.h +++ b/include/asm-mn10300/linkage.h | |||
@@ -13,8 +13,6 @@ | |||
13 | 13 | ||
14 | /* don't override anything */ | 14 | /* don't override anything */ |
15 | #define asmlinkage | 15 | #define asmlinkage |
16 | #define FASTCALL(x) x | ||
17 | #define fastcall | ||
18 | 16 | ||
19 | #define __ALIGN .align 4,0xcb | 17 | #define __ALIGN .align 4,0xcb |
20 | #define __ALIGN_STR ".align 4,0xcb" | 18 | #define __ALIGN_STR ".align 4,0xcb" |
diff --git a/include/asm-x86/sigcontext.h b/include/asm-x86/sigcontext.h index 681deade5f00..d743947f4c77 100644 --- a/include/asm-x86/sigcontext.h +++ b/include/asm-x86/sigcontext.h | |||
@@ -58,6 +58,7 @@ struct _fpstate { | |||
58 | 58 | ||
59 | #define X86_FXSR_MAGIC 0x0000 | 59 | #define X86_FXSR_MAGIC 0x0000 |
60 | 60 | ||
61 | #ifdef __KERNEL__ | ||
61 | struct sigcontext { | 62 | struct sigcontext { |
62 | unsigned short gs, __gsh; | 63 | unsigned short gs, __gsh; |
63 | unsigned short fs, __fsh; | 64 | unsigned short fs, __fsh; |
@@ -82,6 +83,35 @@ struct sigcontext { | |||
82 | unsigned long oldmask; | 83 | unsigned long oldmask; |
83 | unsigned long cr2; | 84 | unsigned long cr2; |
84 | }; | 85 | }; |
86 | #else /* __KERNEL__ */ | ||
87 | /* | ||
88 | * User-space might still rely on the old definition: | ||
89 | */ | ||
90 | struct sigcontext { | ||
91 | unsigned short gs, __gsh; | ||
92 | unsigned short fs, __fsh; | ||
93 | unsigned short es, __esh; | ||
94 | unsigned short ds, __dsh; | ||
95 | unsigned long edi; | ||
96 | unsigned long esi; | ||
97 | unsigned long ebp; | ||
98 | unsigned long esp; | ||
99 | unsigned long ebx; | ||
100 | unsigned long edx; | ||
101 | unsigned long ecx; | ||
102 | unsigned long eax; | ||
103 | unsigned long trapno; | ||
104 | unsigned long err; | ||
105 | unsigned long eip; | ||
106 | unsigned short cs, __csh; | ||
107 | unsigned long eflags; | ||
108 | unsigned long esp_at_signal; | ||
109 | unsigned short ss, __ssh; | ||
110 | struct _fpstate __user * fpstate; | ||
111 | unsigned long oldmask; | ||
112 | unsigned long cr2; | ||
113 | }; | ||
114 | #endif /* !__KERNEL__ */ | ||
85 | 115 | ||
86 | #else /* __i386__ */ | 116 | #else /* __i386__ */ |
87 | 117 | ||
@@ -102,6 +132,7 @@ struct _fpstate { | |||
102 | __u32 reserved2[24]; | 132 | __u32 reserved2[24]; |
103 | }; | 133 | }; |
104 | 134 | ||
135 | #ifdef __KERNEL__ | ||
105 | struct sigcontext { | 136 | struct sigcontext { |
106 | unsigned long r8; | 137 | unsigned long r8; |
107 | unsigned long r9; | 138 | unsigned long r9; |
@@ -132,6 +163,41 @@ struct sigcontext { | |||
132 | struct _fpstate __user *fpstate; /* zero when no FPU context */ | 163 | struct _fpstate __user *fpstate; /* zero when no FPU context */ |
133 | unsigned long reserved1[8]; | 164 | unsigned long reserved1[8]; |
134 | }; | 165 | }; |
166 | #else /* __KERNEL__ */ | ||
167 | /* | ||
168 | * User-space might still rely on the old definition: | ||
169 | */ | ||
170 | struct sigcontext { | ||
171 | unsigned long r8; | ||
172 | unsigned long r9; | ||
173 | unsigned long r10; | ||
174 | unsigned long r11; | ||
175 | unsigned long r12; | ||
176 | unsigned long r13; | ||
177 | unsigned long r14; | ||
178 | unsigned long r15; | ||
179 | unsigned long rdi; | ||
180 | unsigned long rsi; | ||
181 | unsigned long rbp; | ||
182 | unsigned long rbx; | ||
183 | unsigned long rdx; | ||
184 | unsigned long rax; | ||
185 | unsigned long rcx; | ||
186 | unsigned long rsp; | ||
187 | unsigned long rip; | ||
188 | unsigned long eflags; /* RFLAGS */ | ||
189 | unsigned short cs; | ||
190 | unsigned short gs; | ||
191 | unsigned short fs; | ||
192 | unsigned short __pad0; | ||
193 | unsigned long err; | ||
194 | unsigned long trapno; | ||
195 | unsigned long oldmask; | ||
196 | unsigned long cr2; | ||
197 | struct _fpstate __user *fpstate; /* zero when no FPU context */ | ||
198 | unsigned long reserved1[8]; | ||
199 | }; | ||
200 | #endif /* !__KERNEL__ */ | ||
135 | 201 | ||
136 | #endif /* !__i386__ */ | 202 | #endif /* !__i386__ */ |
137 | 203 | ||
diff --git a/include/linux/aio.h b/include/linux/aio.h index 7ef8de662001..a9931e2e5624 100644 --- a/include/linux/aio.h +++ b/include/linux/aio.h | |||
@@ -206,21 +206,21 @@ struct kioctx { | |||
206 | /* prototypes */ | 206 | /* prototypes */ |
207 | extern unsigned aio_max_size; | 207 | extern unsigned aio_max_size; |
208 | 208 | ||
209 | extern ssize_t FASTCALL(wait_on_sync_kiocb(struct kiocb *iocb)); | 209 | extern ssize_t wait_on_sync_kiocb(struct kiocb *iocb); |
210 | extern int FASTCALL(aio_put_req(struct kiocb *iocb)); | 210 | extern int aio_put_req(struct kiocb *iocb); |
211 | extern void FASTCALL(kick_iocb(struct kiocb *iocb)); | 211 | extern void kick_iocb(struct kiocb *iocb); |
212 | extern int FASTCALL(aio_complete(struct kiocb *iocb, long res, long res2)); | 212 | extern int aio_complete(struct kiocb *iocb, long res, long res2); |
213 | extern void FASTCALL(__put_ioctx(struct kioctx *ctx)); | 213 | extern void __put_ioctx(struct kioctx *ctx); |
214 | struct mm_struct; | 214 | struct mm_struct; |
215 | extern void FASTCALL(exit_aio(struct mm_struct *mm)); | 215 | extern void exit_aio(struct mm_struct *mm); |
216 | extern struct kioctx *lookup_ioctx(unsigned long ctx_id); | 216 | extern struct kioctx *lookup_ioctx(unsigned long ctx_id); |
217 | extern int FASTCALL(io_submit_one(struct kioctx *ctx, | 217 | extern int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, |
218 | struct iocb __user *user_iocb, struct iocb *iocb)); | 218 | struct iocb *iocb); |
219 | 219 | ||
220 | /* semi private, but used by the 32bit emulations: */ | 220 | /* semi private, but used by the 32bit emulations: */ |
221 | struct kioctx *lookup_ioctx(unsigned long ctx_id); | 221 | struct kioctx *lookup_ioctx(unsigned long ctx_id); |
222 | int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | 222 | int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, |
223 | struct iocb *iocb)); | 223 | struct iocb *iocb); |
224 | 224 | ||
225 | #define get_ioctx(kioctx) do { \ | 225 | #define get_ioctx(kioctx) do { \ |
226 | BUG_ON(atomic_read(&(kioctx)->users) <= 0); \ | 226 | BUG_ON(atomic_read(&(kioctx)->users) <= 0); \ |
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index e98801f06dcc..932eb02a2753 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h | |||
@@ -144,7 +144,7 @@ BUFFER_FNS(Unwritten, unwritten) | |||
144 | * Declarations | 144 | * Declarations |
145 | */ | 145 | */ |
146 | 146 | ||
147 | void FASTCALL(mark_buffer_dirty(struct buffer_head *bh)); | 147 | void mark_buffer_dirty(struct buffer_head *bh); |
148 | void init_buffer(struct buffer_head *, bh_end_io_t *, void *); | 148 | void init_buffer(struct buffer_head *, bh_end_io_t *, void *); |
149 | void set_bh_page(struct buffer_head *bh, | 149 | void set_bh_page(struct buffer_head *bh, |
150 | struct page *page, unsigned long offset); | 150 | struct page *page, unsigned long offset); |
@@ -185,8 +185,8 @@ struct buffer_head *__bread(struct block_device *, sector_t block, unsigned size | |||
185 | void invalidate_bh_lrus(void); | 185 | void invalidate_bh_lrus(void); |
186 | struct buffer_head *alloc_buffer_head(gfp_t gfp_flags); | 186 | struct buffer_head *alloc_buffer_head(gfp_t gfp_flags); |
187 | void free_buffer_head(struct buffer_head * bh); | 187 | void free_buffer_head(struct buffer_head * bh); |
188 | void FASTCALL(unlock_buffer(struct buffer_head *bh)); | 188 | void unlock_buffer(struct buffer_head *bh); |
189 | void FASTCALL(__lock_buffer(struct buffer_head *bh)); | 189 | void __lock_buffer(struct buffer_head *bh); |
190 | void ll_rw_block(int, int, struct buffer_head * bh[]); | 190 | void ll_rw_block(int, int, struct buffer_head * bh[]); |
191 | int sync_dirty_buffer(struct buffer_head *bh); | 191 | int sync_dirty_buffer(struct buffer_head *bh); |
192 | int submit_bh(int, struct buffer_head *); | 192 | int submit_bh(int, struct buffer_head *); |
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h index 228235c5ae53..ac6aad98b607 100644 --- a/include/linux/cgroup_subsys.h +++ b/include/linux/cgroup_subsys.h | |||
@@ -25,7 +25,7 @@ SUBSYS(ns) | |||
25 | 25 | ||
26 | /* */ | 26 | /* */ |
27 | 27 | ||
28 | #ifdef CONFIG_FAIR_CGROUP_SCHED | 28 | #ifdef CONFIG_CGROUP_SCHED |
29 | SUBSYS(cpu_cgroup) | 29 | SUBSYS(cpu_cgroup) |
30 | #endif | 30 | #endif |
31 | 31 | ||
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index b7558ec81ed5..25d62e6e3290 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
@@ -70,8 +70,7 @@ static inline int is_multicast_ether_addr(const u8 *addr) | |||
70 | } | 70 | } |
71 | 71 | ||
72 | /** | 72 | /** |
73 | * is_local_ether_addr - Determine if the Ethernet address is locally-assigned | 73 | * is_local_ether_addr - Determine if the Ethernet address is locally-assigned one (IEEE 802). |
74 | * one (IEEE 802). | ||
75 | * @addr: Pointer to a six-byte array containing the Ethernet address | 74 | * @addr: Pointer to a six-byte array containing the Ethernet address |
76 | * | 75 | * |
77 | * Return true if the address is a local address. | 76 | * Return true if the address is a local address. |
diff --git a/include/linux/file.h b/include/linux/file.h index 56023c74e9fd..7239baac81a9 100644 --- a/include/linux/file.h +++ b/include/linux/file.h | |||
@@ -59,8 +59,8 @@ struct files_struct { | |||
59 | 59 | ||
60 | extern struct kmem_cache *filp_cachep; | 60 | extern struct kmem_cache *filp_cachep; |
61 | 61 | ||
62 | extern void FASTCALL(__fput(struct file *)); | 62 | extern void __fput(struct file *); |
63 | extern void FASTCALL(fput(struct file *)); | 63 | extern void fput(struct file *); |
64 | 64 | ||
65 | struct file_operations; | 65 | struct file_operations; |
66 | struct vfsmount; | 66 | struct vfsmount; |
@@ -77,13 +77,13 @@ static inline void fput_light(struct file *file, int fput_needed) | |||
77 | fput(file); | 77 | fput(file); |
78 | } | 78 | } |
79 | 79 | ||
80 | extern struct file * FASTCALL(fget(unsigned int fd)); | 80 | extern struct file *fget(unsigned int fd); |
81 | extern struct file * FASTCALL(fget_light(unsigned int fd, int *fput_needed)); | 81 | extern struct file *fget_light(unsigned int fd, int *fput_needed); |
82 | extern void FASTCALL(set_close_on_exec(unsigned int fd, int flag)); | 82 | extern void set_close_on_exec(unsigned int fd, int flag); |
83 | extern void put_filp(struct file *); | 83 | extern void put_filp(struct file *); |
84 | extern int get_unused_fd(void); | 84 | extern int get_unused_fd(void); |
85 | extern int get_unused_fd_flags(int flags); | 85 | extern int get_unused_fd_flags(int flags); |
86 | extern void FASTCALL(put_unused_fd(unsigned int fd)); | 86 | extern void put_unused_fd(unsigned int fd); |
87 | struct kmem_cache; | 87 | struct kmem_cache; |
88 | 88 | ||
89 | extern int expand_files(struct files_struct *, int nr); | 89 | extern int expand_files(struct files_struct *, int nr); |
@@ -110,12 +110,12 @@ static inline struct file * fcheck_files(struct files_struct *files, unsigned in | |||
110 | */ | 110 | */ |
111 | #define fcheck(fd) fcheck_files(current->files, fd) | 111 | #define fcheck(fd) fcheck_files(current->files, fd) |
112 | 112 | ||
113 | extern void FASTCALL(fd_install(unsigned int fd, struct file * file)); | 113 | extern void fd_install(unsigned int fd, struct file *file); |
114 | 114 | ||
115 | struct task_struct; | 115 | struct task_struct; |
116 | 116 | ||
117 | struct files_struct *get_files_struct(struct task_struct *); | 117 | struct files_struct *get_files_struct(struct task_struct *); |
118 | void FASTCALL(put_files_struct(struct files_struct *fs)); | 118 | void put_files_struct(struct files_struct *fs); |
119 | void reset_files_struct(struct task_struct *, struct files_struct *); | 119 | void reset_files_struct(struct task_struct *, struct files_struct *); |
120 | 120 | ||
121 | extern struct kmem_cache *files_cachep; | 121 | extern struct kmem_cache *files_cachep; |
diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 0c6ce515185d..164be9da3c1b 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h | |||
@@ -172,8 +172,7 @@ static inline void arch_free_page(struct page *page, int order) { } | |||
172 | static inline void arch_alloc_page(struct page *page, int order) { } | 172 | static inline void arch_alloc_page(struct page *page, int order) { } |
173 | #endif | 173 | #endif |
174 | 174 | ||
175 | extern struct page * | 175 | extern struct page *__alloc_pages(gfp_t, unsigned int, struct zonelist *); |
176 | FASTCALL(__alloc_pages(gfp_t, unsigned int, struct zonelist *)); | ||
177 | 176 | ||
178 | static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, | 177 | static inline struct page *alloc_pages_node(int nid, gfp_t gfp_mask, |
179 | unsigned int order) | 178 | unsigned int order) |
@@ -209,8 +208,8 @@ extern struct page *alloc_page_vma(gfp_t gfp_mask, | |||
209 | #endif | 208 | #endif |
210 | #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) | 209 | #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) |
211 | 210 | ||
212 | extern unsigned long FASTCALL(__get_free_pages(gfp_t gfp_mask, unsigned int order)); | 211 | extern unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order); |
213 | extern unsigned long FASTCALL(get_zeroed_page(gfp_t gfp_mask)); | 212 | extern unsigned long get_zeroed_page(gfp_t gfp_mask); |
214 | 213 | ||
215 | #define __get_free_page(gfp_mask) \ | 214 | #define __get_free_page(gfp_mask) \ |
216 | __get_free_pages((gfp_mask),0) | 215 | __get_free_pages((gfp_mask),0) |
@@ -218,10 +217,10 @@ extern unsigned long FASTCALL(get_zeroed_page(gfp_t gfp_mask)); | |||
218 | #define __get_dma_pages(gfp_mask, order) \ | 217 | #define __get_dma_pages(gfp_mask, order) \ |
219 | __get_free_pages((gfp_mask) | GFP_DMA,(order)) | 218 | __get_free_pages((gfp_mask) | GFP_DMA,(order)) |
220 | 219 | ||
221 | extern void FASTCALL(__free_pages(struct page *page, unsigned int order)); | 220 | extern void __free_pages(struct page *page, unsigned int order); |
222 | extern void FASTCALL(free_pages(unsigned long addr, unsigned int order)); | 221 | extern void free_pages(unsigned long addr, unsigned int order); |
223 | extern void FASTCALL(free_hot_page(struct page *page)); | 222 | extern void free_hot_page(struct page *page); |
224 | extern void FASTCALL(free_cold_page(struct page *page)); | 223 | extern void free_cold_page(struct page *page); |
225 | 224 | ||
226 | #define __free_page(page) __free_pages((page), 0) | 225 | #define __free_page(page) __free_pages((page), 0) |
227 | #define free_page(addr) free_pages((addr),0) | 226 | #define free_page(addr) free_pages((addr),0) |
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 7ca198b379af..addca4cd4f11 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h | |||
@@ -33,8 +33,8 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to); | |||
33 | void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed); | 33 | void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed); |
34 | 34 | ||
35 | extern unsigned long max_huge_pages; | 35 | extern unsigned long max_huge_pages; |
36 | extern unsigned long sysctl_overcommit_huge_pages; | ||
36 | extern unsigned long hugepages_treat_as_movable; | 37 | extern unsigned long hugepages_treat_as_movable; |
37 | extern unsigned long nr_overcommit_huge_pages; | ||
38 | extern const unsigned long hugetlb_zero, hugetlb_infinity; | 38 | extern const unsigned long hugetlb_zero, hugetlb_infinity; |
39 | extern int sysctl_hugetlb_shm_group; | 39 | extern int sysctl_hugetlb_shm_group; |
40 | 40 | ||
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index dea7598aeff4..f8ab4ce70564 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -273,8 +273,8 @@ asmlinkage void do_softirq(void); | |||
273 | extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data); | 273 | extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data); |
274 | extern void softirq_init(void); | 274 | extern void softirq_init(void); |
275 | #define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0) | 275 | #define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0) |
276 | extern void FASTCALL(raise_softirq_irqoff(unsigned int nr)); | 276 | extern void raise_softirq_irqoff(unsigned int nr); |
277 | extern void FASTCALL(raise_softirq(unsigned int nr)); | 277 | extern void raise_softirq(unsigned int nr); |
278 | 278 | ||
279 | 279 | ||
280 | /* Tasklets --- multithreaded analogue of BHs. | 280 | /* Tasklets --- multithreaded analogue of BHs. |
@@ -341,7 +341,7 @@ static inline void tasklet_unlock_wait(struct tasklet_struct *t) | |||
341 | #define tasklet_unlock(t) do { } while (0) | 341 | #define tasklet_unlock(t) do { } while (0) |
342 | #endif | 342 | #endif |
343 | 343 | ||
344 | extern void FASTCALL(__tasklet_schedule(struct tasklet_struct *t)); | 344 | extern void __tasklet_schedule(struct tasklet_struct *t); |
345 | 345 | ||
346 | static inline void tasklet_schedule(struct tasklet_struct *t) | 346 | static inline void tasklet_schedule(struct tasklet_struct *t) |
347 | { | 347 | { |
@@ -349,7 +349,7 @@ static inline void tasklet_schedule(struct tasklet_struct *t) | |||
349 | __tasklet_schedule(t); | 349 | __tasklet_schedule(t); |
350 | } | 350 | } |
351 | 351 | ||
352 | extern void FASTCALL(__tasklet_hi_schedule(struct tasklet_struct *t)); | 352 | extern void __tasklet_hi_schedule(struct tasklet_struct *t); |
353 | 353 | ||
354 | static inline void tasklet_hi_schedule(struct tasklet_struct *t) | 354 | static inline void tasklet_hi_schedule(struct tasklet_struct *t) |
355 | { | 355 | { |
diff --git a/include/linux/irq.h b/include/linux/irq.h index bfd9efb5cb49..176e5e790a44 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -285,7 +285,6 @@ extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc); | |||
285 | 285 | ||
286 | /* | 286 | /* |
287 | * Monolithic do_IRQ implementation. | 287 | * Monolithic do_IRQ implementation. |
288 | * (is an explicit fastcall, because i386 4KSTACKS calls it from assembly) | ||
289 | */ | 288 | */ |
290 | #ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ | 289 | #ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ |
291 | extern unsigned int __do_IRQ(unsigned int irq); | 290 | extern unsigned int __do_IRQ(unsigned int irq); |
diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 3faf599ea58e..0592936344c4 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h | |||
@@ -73,9 +73,4 @@ | |||
73 | #define ATTRIB_NORET __attribute__((noreturn)) | 73 | #define ATTRIB_NORET __attribute__((noreturn)) |
74 | #define NORET_AND noreturn, | 74 | #define NORET_AND noreturn, |
75 | 75 | ||
76 | #ifndef FASTCALL | ||
77 | #define FASTCALL(x) x | ||
78 | #define fastcall | ||
79 | #endif | ||
80 | |||
81 | #endif | 76 | #endif |
diff --git a/include/linux/marker.h b/include/linux/marker.h index 5f36cf946bcb..5df879dc3776 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h | |||
@@ -19,16 +19,23 @@ struct marker; | |||
19 | 19 | ||
20 | /** | 20 | /** |
21 | * marker_probe_func - Type of a marker probe function | 21 | * marker_probe_func - Type of a marker probe function |
22 | * @mdata: pointer of type struct marker | 22 | * @probe_private: probe private data |
23 | * @private_data: caller site private data | 23 | * @call_private: call site private data |
24 | * @fmt: format string | 24 | * @fmt: format string |
25 | * @...: variable argument list | 25 | * @args: variable argument list pointer. Use a pointer to overcome C's |
26 | * inability to pass this around as a pointer in a portable manner in | ||
27 | * the callee otherwise. | ||
26 | * | 28 | * |
27 | * Type of marker probe functions. They receive the mdata and need to parse the | 29 | * Type of marker probe functions. They receive the mdata and need to parse the |
28 | * format string to recover the variable argument list. | 30 | * format string to recover the variable argument list. |
29 | */ | 31 | */ |
30 | typedef void marker_probe_func(const struct marker *mdata, | 32 | typedef void marker_probe_func(void *probe_private, void *call_private, |
31 | void *private_data, const char *fmt, ...); | 33 | const char *fmt, va_list *args); |
34 | |||
35 | struct marker_probe_closure { | ||
36 | marker_probe_func *func; /* Callback */ | ||
37 | void *probe_private; /* Private probe data */ | ||
38 | }; | ||
32 | 39 | ||
33 | struct marker { | 40 | struct marker { |
34 | const char *name; /* Marker name */ | 41 | const char *name; /* Marker name */ |
@@ -36,8 +43,11 @@ struct marker { | |||
36 | * variable argument list. | 43 | * variable argument list. |
37 | */ | 44 | */ |
38 | char state; /* Marker state. */ | 45 | char state; /* Marker state. */ |
39 | marker_probe_func *call;/* Probe handler function pointer */ | 46 | char ptype; /* probe type : 0 : single, 1 : multi */ |
40 | void *private; /* Private probe data */ | 47 | void (*call)(const struct marker *mdata, /* Probe wrapper */ |
48 | void *call_private, const char *fmt, ...); | ||
49 | struct marker_probe_closure single; | ||
50 | struct marker_probe_closure *multi; | ||
41 | } __attribute__((aligned(8))); | 51 | } __attribute__((aligned(8))); |
42 | 52 | ||
43 | #ifdef CONFIG_MARKERS | 53 | #ifdef CONFIG_MARKERS |
@@ -49,35 +59,31 @@ struct marker { | |||
49 | * not add unwanted padding between the beginning of the section and the | 59 | * not add unwanted padding between the beginning of the section and the |
50 | * structure. Force alignment to the same alignment as the section start. | 60 | * structure. Force alignment to the same alignment as the section start. |
51 | */ | 61 | */ |
52 | #define __trace_mark(name, call_data, format, args...) \ | 62 | #define __trace_mark(name, call_private, format, args...) \ |
53 | do { \ | 63 | do { \ |
54 | static const char __mstrtab_name_##name[] \ | 64 | static const char __mstrtab_##name[] \ |
55 | __attribute__((section("__markers_strings"))) \ | ||
56 | = #name; \ | ||
57 | static const char __mstrtab_format_##name[] \ | ||
58 | __attribute__((section("__markers_strings"))) \ | 65 | __attribute__((section("__markers_strings"))) \ |
59 | = format; \ | 66 | = #name "\0" format; \ |
60 | static struct marker __mark_##name \ | 67 | static struct marker __mark_##name \ |
61 | __attribute__((section("__markers"), aligned(8))) = \ | 68 | __attribute__((section("__markers"), aligned(8))) = \ |
62 | { __mstrtab_name_##name, __mstrtab_format_##name, \ | 69 | { __mstrtab_##name, &__mstrtab_##name[sizeof(#name)], \ |
63 | 0, __mark_empty_function, NULL }; \ | 70 | 0, 0, marker_probe_cb, \ |
71 | { __mark_empty_function, NULL}, NULL }; \ | ||
64 | __mark_check_format(format, ## args); \ | 72 | __mark_check_format(format, ## args); \ |
65 | if (unlikely(__mark_##name.state)) { \ | 73 | if (unlikely(__mark_##name.state)) { \ |
66 | preempt_disable(); \ | ||
67 | (*__mark_##name.call) \ | 74 | (*__mark_##name.call) \ |
68 | (&__mark_##name, call_data, \ | 75 | (&__mark_##name, call_private, \ |
69 | format, ## args); \ | 76 | format, ## args); \ |
70 | preempt_enable(); \ | ||
71 | } \ | 77 | } \ |
72 | } while (0) | 78 | } while (0) |
73 | 79 | ||
74 | extern void marker_update_probe_range(struct marker *begin, | 80 | extern void marker_update_probe_range(struct marker *begin, |
75 | struct marker *end, struct module *probe_module, int *refcount); | 81 | struct marker *end); |
76 | #else /* !CONFIG_MARKERS */ | 82 | #else /* !CONFIG_MARKERS */ |
77 | #define __trace_mark(name, call_data, format, args...) \ | 83 | #define __trace_mark(name, call_private, format, args...) \ |
78 | __mark_check_format(format, ## args) | 84 | __mark_check_format(format, ## args) |
79 | static inline void marker_update_probe_range(struct marker *begin, | 85 | static inline void marker_update_probe_range(struct marker *begin, |
80 | struct marker *end, struct module *probe_module, int *refcount) | 86 | struct marker *end) |
81 | { } | 87 | { } |
82 | #endif /* CONFIG_MARKERS */ | 88 | #endif /* CONFIG_MARKERS */ |
83 | 89 | ||
@@ -92,8 +98,6 @@ static inline void marker_update_probe_range(struct marker *begin, | |||
92 | #define trace_mark(name, format, args...) \ | 98 | #define trace_mark(name, format, args...) \ |
93 | __trace_mark(name, NULL, format, ## args) | 99 | __trace_mark(name, NULL, format, ## args) |
94 | 100 | ||
95 | #define MARK_MAX_FORMAT_LEN 1024 | ||
96 | |||
97 | /** | 101 | /** |
98 | * MARK_NOARGS - Format string for a marker with no argument. | 102 | * MARK_NOARGS - Format string for a marker with no argument. |
99 | */ | 103 | */ |
@@ -106,24 +110,30 @@ static inline void __printf(1, 2) __mark_check_format(const char *fmt, ...) | |||
106 | 110 | ||
107 | extern marker_probe_func __mark_empty_function; | 111 | extern marker_probe_func __mark_empty_function; |
108 | 112 | ||
113 | extern void marker_probe_cb(const struct marker *mdata, | ||
114 | void *call_private, const char *fmt, ...); | ||
115 | extern void marker_probe_cb_noarg(const struct marker *mdata, | ||
116 | void *call_private, const char *fmt, ...); | ||
117 | |||
109 | /* | 118 | /* |
110 | * Connect a probe to a marker. | 119 | * Connect a probe to a marker. |
111 | * private data pointer must be a valid allocated memory address, or NULL. | 120 | * private data pointer must be a valid allocated memory address, or NULL. |
112 | */ | 121 | */ |
113 | extern int marker_probe_register(const char *name, const char *format, | 122 | extern int marker_probe_register(const char *name, const char *format, |
114 | marker_probe_func *probe, void *private); | 123 | marker_probe_func *probe, void *probe_private); |
115 | 124 | ||
116 | /* | 125 | /* |
117 | * Returns the private data given to marker_probe_register. | 126 | * Returns the private data given to marker_probe_register. |
118 | */ | 127 | */ |
119 | extern void *marker_probe_unregister(const char *name); | 128 | extern int marker_probe_unregister(const char *name, |
129 | marker_probe_func *probe, void *probe_private); | ||
120 | /* | 130 | /* |
121 | * Unregister a marker by providing the registered private data. | 131 | * Unregister a marker by providing the registered private data. |
122 | */ | 132 | */ |
123 | extern void *marker_probe_unregister_private_data(void *private); | 133 | extern int marker_probe_unregister_private_data(marker_probe_func *probe, |
134 | void *probe_private); | ||
124 | 135 | ||
125 | extern int marker_arm(const char *name); | 136 | extern void *marker_get_private_data(const char *name, marker_probe_func *probe, |
126 | extern int marker_disarm(const char *name); | 137 | int num); |
127 | extern void *marker_get_private_data(const char *name); | ||
128 | 138 | ||
129 | #endif | 139 | #endif |
diff --git a/include/linux/mm.h b/include/linux/mm.h index e8abb3814209..26c7124b841a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -786,7 +786,7 @@ int __set_page_dirty_nobuffers(struct page *page); | |||
786 | int __set_page_dirty_no_writeback(struct page *page); | 786 | int __set_page_dirty_no_writeback(struct page *page); |
787 | int redirty_page_for_writepage(struct writeback_control *wbc, | 787 | int redirty_page_for_writepage(struct writeback_control *wbc, |
788 | struct page *page); | 788 | struct page *page); |
789 | int FASTCALL(set_page_dirty(struct page *page)); | 789 | int set_page_dirty(struct page *page); |
790 | int set_page_dirty_lock(struct page *page); | 790 | int set_page_dirty_lock(struct page *page); |
791 | int clear_page_dirty_for_io(struct page *page); | 791 | int clear_page_dirty_for_io(struct page *page); |
792 | 792 | ||
@@ -829,7 +829,7 @@ extern void unregister_shrinker(struct shrinker *); | |||
829 | 829 | ||
830 | int vma_wants_writenotify(struct vm_area_struct *vma); | 830 | int vma_wants_writenotify(struct vm_area_struct *vma); |
831 | 831 | ||
832 | extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl)); | 832 | extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl); |
833 | 833 | ||
834 | #ifdef __PAGETABLE_PUD_FOLDED | 834 | #ifdef __PAGETABLE_PUD_FOLDED |
835 | static inline int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, | 835 | static inline int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, |
diff --git a/include/linux/module.h b/include/linux/module.h index ac28e8761e84..330bec08c2c4 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -465,7 +465,7 @@ int unregister_module_notifier(struct notifier_block * nb); | |||
465 | 465 | ||
466 | extern void print_modules(void); | 466 | extern void print_modules(void); |
467 | 467 | ||
468 | extern void module_update_markers(struct module *probe_module, int *refcount); | 468 | extern void module_update_markers(void); |
469 | 469 | ||
470 | #else /* !CONFIG_MODULES... */ | 470 | #else /* !CONFIG_MODULES... */ |
471 | #define EXPORT_SYMBOL(sym) | 471 | #define EXPORT_SYMBOL(sym) |
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 8126e55c5bdc..ec624381c844 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h | |||
@@ -62,6 +62,16 @@ struct kparam_array | |||
62 | void *elem; | 62 | void *elem; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | /* On alpha, ia64 and ppc64 relocations to global data cannot go into | ||
66 | read-only sections (which is part of respective UNIX ABI on these | ||
67 | platforms). So 'const' makes no sense and even causes compile failures | ||
68 | with some compilers. */ | ||
69 | #if defined(CONFIG_ALPHA) || defined(CONFIG_IA64) || defined(CONFIG_PPC64) | ||
70 | #define __moduleparam_const | ||
71 | #else | ||
72 | #define __moduleparam_const const | ||
73 | #endif | ||
74 | |||
65 | /* This is the fundamental function for registering boot/module | 75 | /* This is the fundamental function for registering boot/module |
66 | parameters. perm sets the visibility in sysfs: 000 means it's | 76 | parameters. perm sets the visibility in sysfs: 000 means it's |
67 | not there, read bits mean it's readable, write bits mean it's | 77 | not there, read bits mean it's readable, write bits mean it's |
@@ -71,7 +81,7 @@ struct kparam_array | |||
71 | static int __param_perm_check_##name __attribute__((unused)) = \ | 81 | static int __param_perm_check_##name __attribute__((unused)) = \ |
72 | BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \ | 82 | BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \ |
73 | static const char __param_str_##name[] = prefix #name; \ | 83 | static const char __param_str_##name[] = prefix #name; \ |
74 | static struct kernel_param const __param_##name \ | 84 | static struct kernel_param __moduleparam_const __param_##name \ |
75 | __used \ | 85 | __used \ |
76 | __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ | 86 | __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ |
77 | = { __param_str_##name, perm, set, get, { arg } } | 87 | = { __param_str_##name, perm, set, get, { arg } } |
diff --git a/include/linux/mutex-debug.h b/include/linux/mutex-debug.h index 2537285e1064..731d77d6e155 100644 --- a/include/linux/mutex-debug.h +++ b/include/linux/mutex-debug.h | |||
@@ -18,6 +18,6 @@ do { \ | |||
18 | __mutex_init((mutex), #mutex, &__key); \ | 18 | __mutex_init((mutex), #mutex, &__key); \ |
19 | } while (0) | 19 | } while (0) |
20 | 20 | ||
21 | extern void FASTCALL(mutex_destroy(struct mutex *lock)); | 21 | extern void mutex_destroy(struct mutex *lock); |
22 | 22 | ||
23 | #endif | 23 | #endif |
diff --git a/include/linux/namei.h b/include/linux/namei.h index 4cb4f8d2f78d..c13e411491f4 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h | |||
@@ -62,13 +62,13 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; | |||
62 | #define LOOKUP_ACCESS (0x0400) | 62 | #define LOOKUP_ACCESS (0x0400) |
63 | #define LOOKUP_CHDIR (0x0800) | 63 | #define LOOKUP_CHDIR (0x0800) |
64 | 64 | ||
65 | extern int FASTCALL(__user_walk(const char __user *, unsigned, struct nameidata *)); | 65 | extern int __user_walk(const char __user *, unsigned, struct nameidata *); |
66 | extern int FASTCALL(__user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *)); | 66 | extern int __user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *); |
67 | #define user_path_walk(name,nd) \ | 67 | #define user_path_walk(name,nd) \ |
68 | __user_walk_fd(AT_FDCWD, name, LOOKUP_FOLLOW, nd) | 68 | __user_walk_fd(AT_FDCWD, name, LOOKUP_FOLLOW, nd) |
69 | #define user_path_walk_link(name,nd) \ | 69 | #define user_path_walk_link(name,nd) \ |
70 | __user_walk_fd(AT_FDCWD, name, 0, nd) | 70 | __user_walk_fd(AT_FDCWD, name, 0, nd) |
71 | extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *)); | 71 | extern int path_lookup(const char *, unsigned, struct nameidata *); |
72 | extern int vfs_path_lookup(struct dentry *, struct vfsmount *, | 72 | extern int vfs_path_lookup(struct dentry *, struct vfsmount *, |
73 | const char *, unsigned int, struct nameidata *); | 73 | const char *, unsigned int, struct nameidata *); |
74 | extern void path_release(struct nameidata *); | 74 | extern void path_release(struct nameidata *); |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 047d432bde55..7128a02f1d37 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -322,7 +322,7 @@ enum | |||
322 | NAPI_STATE_DISABLE, /* Disable pending */ | 322 | NAPI_STATE_DISABLE, /* Disable pending */ |
323 | }; | 323 | }; |
324 | 324 | ||
325 | extern void FASTCALL(__napi_schedule(struct napi_struct *n)); | 325 | extern void __napi_schedule(struct napi_struct *n); |
326 | 326 | ||
327 | static inline int napi_disable_pending(struct napi_struct *n) | 327 | static inline int napi_disable_pending(struct napi_struct *n) |
328 | { | 328 | { |
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 4b62a105622b..d2fca802f809 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h | |||
@@ -156,10 +156,10 @@ static inline pgoff_t linear_page_index(struct vm_area_struct *vma, | |||
156 | return pgoff >> (PAGE_CACHE_SHIFT - PAGE_SHIFT); | 156 | return pgoff >> (PAGE_CACHE_SHIFT - PAGE_SHIFT); |
157 | } | 157 | } |
158 | 158 | ||
159 | extern void FASTCALL(__lock_page(struct page *page)); | 159 | extern void __lock_page(struct page *page); |
160 | extern int FASTCALL(__lock_page_killable(struct page *page)); | 160 | extern int __lock_page_killable(struct page *page); |
161 | extern void FASTCALL(__lock_page_nosync(struct page *page)); | 161 | extern void __lock_page_nosync(struct page *page); |
162 | extern void FASTCALL(unlock_page(struct page *page)); | 162 | extern void unlock_page(struct page *page); |
163 | 163 | ||
164 | /* | 164 | /* |
165 | * lock_page may only be called if we have the page's inode pinned. | 165 | * lock_page may only be called if we have the page's inode pinned. |
@@ -199,7 +199,7 @@ static inline void lock_page_nosync(struct page *page) | |||
199 | * This is exported only for wait_on_page_locked/wait_on_page_writeback. | 199 | * This is exported only for wait_on_page_locked/wait_on_page_writeback. |
200 | * Never use this directly! | 200 | * Never use this directly! |
201 | */ | 201 | */ |
202 | extern void FASTCALL(wait_on_page_bit(struct page *page, int bit_nr)); | 202 | extern void wait_on_page_bit(struct page *page, int bit_nr); |
203 | 203 | ||
204 | /* | 204 | /* |
205 | * Wait for a page to be unlocked. | 205 | * Wait for a page to be unlocked. |
diff --git a/include/linux/pid.h b/include/linux/pid.h index f84d532b5d23..c7980810eb09 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h | |||
@@ -79,10 +79,9 @@ static inline struct pid *get_pid(struct pid *pid) | |||
79 | return pid; | 79 | return pid; |
80 | } | 80 | } |
81 | 81 | ||
82 | extern void FASTCALL(put_pid(struct pid *pid)); | 82 | extern void put_pid(struct pid *pid); |
83 | extern struct task_struct *FASTCALL(pid_task(struct pid *pid, enum pid_type)); | 83 | extern struct task_struct *pid_task(struct pid *pid, enum pid_type); |
84 | extern struct task_struct *FASTCALL(get_pid_task(struct pid *pid, | 84 | extern struct task_struct *get_pid_task(struct pid *pid, enum pid_type); |
85 | enum pid_type)); | ||
86 | 85 | ||
87 | extern struct pid *get_task_pid(struct task_struct *task, enum pid_type type); | 86 | extern struct pid *get_task_pid(struct task_struct *task, enum pid_type type); |
88 | 87 | ||
@@ -90,11 +89,11 @@ extern struct pid *get_task_pid(struct task_struct *task, enum pid_type type); | |||
90 | * attach_pid() and detach_pid() must be called with the tasklist_lock | 89 | * attach_pid() and detach_pid() must be called with the tasklist_lock |
91 | * write-held. | 90 | * write-held. |
92 | */ | 91 | */ |
93 | extern int FASTCALL(attach_pid(struct task_struct *task, | 92 | extern int attach_pid(struct task_struct *task, enum pid_type type, |
94 | enum pid_type type, struct pid *pid)); | 93 | struct pid *pid); |
95 | extern void FASTCALL(detach_pid(struct task_struct *task, enum pid_type)); | 94 | extern void detach_pid(struct task_struct *task, enum pid_type); |
96 | extern void FASTCALL(transfer_pid(struct task_struct *old, | 95 | extern void transfer_pid(struct task_struct *old, struct task_struct *new, |
97 | struct task_struct *new, enum pid_type)); | 96 | enum pid_type); |
98 | 97 | ||
99 | struct pid_namespace; | 98 | struct pid_namespace; |
100 | extern struct pid_namespace init_pid_ns; | 99 | extern struct pid_namespace init_pid_ns; |
@@ -109,7 +108,7 @@ extern struct pid_namespace init_pid_ns; | |||
109 | * | 108 | * |
110 | * see also find_task_by_pid() set in include/linux/sched.h | 109 | * see also find_task_by_pid() set in include/linux/sched.h |
111 | */ | 110 | */ |
112 | extern struct pid *FASTCALL(find_pid_ns(int nr, struct pid_namespace *ns)); | 111 | extern struct pid *find_pid_ns(int nr, struct pid_namespace *ns); |
113 | extern struct pid *find_vpid(int nr); | 112 | extern struct pid *find_vpid(int nr); |
114 | extern struct pid *find_pid(int nr); | 113 | extern struct pid *find_pid(int nr); |
115 | 114 | ||
@@ -121,7 +120,7 @@ extern struct pid *find_ge_pid(int nr, struct pid_namespace *); | |||
121 | int next_pidmap(struct pid_namespace *pid_ns, int last); | 120 | int next_pidmap(struct pid_namespace *pid_ns, int last); |
122 | 121 | ||
123 | extern struct pid *alloc_pid(struct pid_namespace *ns); | 122 | extern struct pid *alloc_pid(struct pid_namespace *ns); |
124 | extern void FASTCALL(free_pid(struct pid *pid)); | 123 | extern void free_pid(struct pid *pid); |
125 | 124 | ||
126 | /* | 125 | /* |
127 | * the helpers to get the pid's id seen from different namespaces | 126 | * the helpers to get the pid's id seen from different namespaces |
diff --git a/include/linux/rwsem-spinlock.h b/include/linux/rwsem-spinlock.h index 813cee13da0d..6c3c0f6c261f 100644 --- a/include/linux/rwsem-spinlock.h +++ b/include/linux/rwsem-spinlock.h | |||
@@ -60,14 +60,14 @@ do { \ | |||
60 | __init_rwsem((sem), #sem, &__key); \ | 60 | __init_rwsem((sem), #sem, &__key); \ |
61 | } while (0) | 61 | } while (0) |
62 | 62 | ||
63 | extern void FASTCALL(__down_read(struct rw_semaphore *sem)); | 63 | extern void __down_read(struct rw_semaphore *sem); |
64 | extern int FASTCALL(__down_read_trylock(struct rw_semaphore *sem)); | 64 | extern int __down_read_trylock(struct rw_semaphore *sem); |
65 | extern void FASTCALL(__down_write(struct rw_semaphore *sem)); | 65 | extern void __down_write(struct rw_semaphore *sem); |
66 | extern void FASTCALL(__down_write_nested(struct rw_semaphore *sem, int subclass)); | 66 | extern void __down_write_nested(struct rw_semaphore *sem, int subclass); |
67 | extern int FASTCALL(__down_write_trylock(struct rw_semaphore *sem)); | 67 | extern int __down_write_trylock(struct rw_semaphore *sem); |
68 | extern void FASTCALL(__up_read(struct rw_semaphore *sem)); | 68 | extern void __up_read(struct rw_semaphore *sem); |
69 | extern void FASTCALL(__up_write(struct rw_semaphore *sem)); | 69 | extern void __up_write(struct rw_semaphore *sem); |
70 | extern void FASTCALL(__downgrade_write(struct rw_semaphore *sem)); | 70 | extern void __downgrade_write(struct rw_semaphore *sem); |
71 | 71 | ||
72 | static inline int rwsem_is_locked(struct rw_semaphore *sem) | 72 | static inline int rwsem_is_locked(struct rw_semaphore *sem) |
73 | { | 73 | { |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 00e144117326..e217d188a102 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -323,7 +323,7 @@ extern char __sched_text_start[], __sched_text_end[]; | |||
323 | extern int in_sched_functions(unsigned long addr); | 323 | extern int in_sched_functions(unsigned long addr); |
324 | 324 | ||
325 | #define MAX_SCHEDULE_TIMEOUT LONG_MAX | 325 | #define MAX_SCHEDULE_TIMEOUT LONG_MAX |
326 | extern signed long FASTCALL(schedule_timeout(signed long timeout)); | 326 | extern signed long schedule_timeout(signed long timeout); |
327 | extern signed long schedule_timeout_interruptible(signed long timeout); | 327 | extern signed long schedule_timeout_interruptible(signed long timeout); |
328 | extern signed long schedule_timeout_killable(signed long timeout); | 328 | extern signed long schedule_timeout_killable(signed long timeout); |
329 | extern signed long schedule_timeout_uninterruptible(signed long timeout); | 329 | extern signed long schedule_timeout_uninterruptible(signed long timeout); |
@@ -590,7 +590,7 @@ struct user_struct { | |||
590 | struct hlist_node uidhash_node; | 590 | struct hlist_node uidhash_node; |
591 | uid_t uid; | 591 | uid_t uid; |
592 | 592 | ||
593 | #ifdef CONFIG_FAIR_USER_SCHED | 593 | #ifdef CONFIG_USER_SCHED |
594 | struct task_group *tg; | 594 | struct task_group *tg; |
595 | #ifdef CONFIG_SYSFS | 595 | #ifdef CONFIG_SYSFS |
596 | struct kobject kobj; | 596 | struct kobject kobj; |
@@ -973,7 +973,7 @@ struct sched_rt_entity { | |||
973 | unsigned long timeout; | 973 | unsigned long timeout; |
974 | int nr_cpus_allowed; | 974 | int nr_cpus_allowed; |
975 | 975 | ||
976 | #ifdef CONFIG_FAIR_GROUP_SCHED | 976 | #ifdef CONFIG_RT_GROUP_SCHED |
977 | struct sched_rt_entity *parent; | 977 | struct sched_rt_entity *parent; |
978 | /* rq on which this entity is (to be) queued: */ | 978 | /* rq on which this entity is (to be) queued: */ |
979 | struct rt_rq *rt_rq; | 979 | struct rt_rq *rt_rq; |
@@ -1541,8 +1541,6 @@ extern unsigned int sysctl_sched_child_runs_first; | |||
1541 | extern unsigned int sysctl_sched_features; | 1541 | extern unsigned int sysctl_sched_features; |
1542 | extern unsigned int sysctl_sched_migration_cost; | 1542 | extern unsigned int sysctl_sched_migration_cost; |
1543 | extern unsigned int sysctl_sched_nr_migrate; | 1543 | extern unsigned int sysctl_sched_nr_migrate; |
1544 | extern unsigned int sysctl_sched_rt_period; | ||
1545 | extern unsigned int sysctl_sched_rt_ratio; | ||
1546 | #if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) | 1544 | #if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) |
1547 | extern unsigned int sysctl_sched_min_bal_int_shares; | 1545 | extern unsigned int sysctl_sched_min_bal_int_shares; |
1548 | extern unsigned int sysctl_sched_max_bal_int_shares; | 1546 | extern unsigned int sysctl_sched_max_bal_int_shares; |
@@ -1552,6 +1550,8 @@ int sched_nr_latency_handler(struct ctl_table *table, int write, | |||
1552 | struct file *file, void __user *buffer, size_t *length, | 1550 | struct file *file, void __user *buffer, size_t *length, |
1553 | loff_t *ppos); | 1551 | loff_t *ppos); |
1554 | #endif | 1552 | #endif |
1553 | extern unsigned int sysctl_sched_rt_period; | ||
1554 | extern int sysctl_sched_rt_runtime; | ||
1555 | 1555 | ||
1556 | extern unsigned int sysctl_sched_compat_yield; | 1556 | extern unsigned int sysctl_sched_compat_yield; |
1557 | 1557 | ||
@@ -1648,10 +1648,10 @@ extern void release_uids(struct user_namespace *ns); | |||
1648 | 1648 | ||
1649 | extern void do_timer(unsigned long ticks); | 1649 | extern void do_timer(unsigned long ticks); |
1650 | 1650 | ||
1651 | extern int FASTCALL(wake_up_state(struct task_struct * tsk, unsigned int state)); | 1651 | extern int wake_up_state(struct task_struct *tsk, unsigned int state); |
1652 | extern int FASTCALL(wake_up_process(struct task_struct * tsk)); | 1652 | extern int wake_up_process(struct task_struct *tsk); |
1653 | extern void FASTCALL(wake_up_new_task(struct task_struct * tsk, | 1653 | extern void wake_up_new_task(struct task_struct *tsk, |
1654 | unsigned long clone_flags)); | 1654 | unsigned long clone_flags); |
1655 | #ifdef CONFIG_SMP | 1655 | #ifdef CONFIG_SMP |
1656 | extern void kick_process(struct task_struct *tsk); | 1656 | extern void kick_process(struct task_struct *tsk); |
1657 | #else | 1657 | #else |
@@ -1741,7 +1741,7 @@ static inline int sas_ss_flags(unsigned long sp) | |||
1741 | extern struct mm_struct * mm_alloc(void); | 1741 | extern struct mm_struct * mm_alloc(void); |
1742 | 1742 | ||
1743 | /* mmdrop drops the mm and the page tables */ | 1743 | /* mmdrop drops the mm and the page tables */ |
1744 | extern void FASTCALL(__mmdrop(struct mm_struct *)); | 1744 | extern void __mmdrop(struct mm_struct *); |
1745 | static inline void mmdrop(struct mm_struct * mm) | 1745 | static inline void mmdrop(struct mm_struct * mm) |
1746 | { | 1746 | { |
1747 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) | 1747 | if (unlikely(atomic_dec_and_test(&mm->mm_count))) |
@@ -1925,7 +1925,7 @@ static inline int signal_pending(struct task_struct *p) | |||
1925 | return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING)); | 1925 | return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING)); |
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | extern int FASTCALL(__fatal_signal_pending(struct task_struct *p)); | 1928 | extern int __fatal_signal_pending(struct task_struct *p); |
1929 | 1929 | ||
1930 | static inline int fatal_signal_pending(struct task_struct *p) | 1930 | static inline int fatal_signal_pending(struct task_struct *p) |
1931 | { | 1931 | { |
@@ -2027,16 +2027,22 @@ extern int sched_mc_power_savings, sched_smt_power_savings; | |||
2027 | 2027 | ||
2028 | extern void normalize_rt_tasks(void); | 2028 | extern void normalize_rt_tasks(void); |
2029 | 2029 | ||
2030 | #ifdef CONFIG_FAIR_GROUP_SCHED | 2030 | #ifdef CONFIG_GROUP_SCHED |
2031 | 2031 | ||
2032 | extern struct task_group init_task_group; | 2032 | extern struct task_group init_task_group; |
2033 | 2033 | ||
2034 | extern struct task_group *sched_create_group(void); | 2034 | extern struct task_group *sched_create_group(void); |
2035 | extern void sched_destroy_group(struct task_group *tg); | 2035 | extern void sched_destroy_group(struct task_group *tg); |
2036 | extern void sched_move_task(struct task_struct *tsk); | 2036 | extern void sched_move_task(struct task_struct *tsk); |
2037 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
2037 | extern int sched_group_set_shares(struct task_group *tg, unsigned long shares); | 2038 | extern int sched_group_set_shares(struct task_group *tg, unsigned long shares); |
2038 | extern unsigned long sched_group_shares(struct task_group *tg); | 2039 | extern unsigned long sched_group_shares(struct task_group *tg); |
2039 | 2040 | #endif | |
2041 | #ifdef CONFIG_RT_GROUP_SCHED | ||
2042 | extern int sched_group_set_rt_runtime(struct task_group *tg, | ||
2043 | long rt_runtime_us); | ||
2044 | extern long sched_group_rt_runtime(struct task_group *tg); | ||
2045 | #endif | ||
2040 | #endif | 2046 | #endif |
2041 | 2047 | ||
2042 | #ifdef CONFIG_TASK_XACCT | 2048 | #ifdef CONFIG_TASK_XACCT |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 1a0b6cf83ff1..289942fc6655 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -149,6 +149,8 @@ | |||
149 | /* Freescale ColdFire */ | 149 | /* Freescale ColdFire */ |
150 | #define PORT_MCF 78 | 150 | #define PORT_MCF 78 |
151 | 151 | ||
152 | #define PORT_SC26XX 79 | ||
153 | |||
152 | 154 | ||
153 | /* MN10300 on-chip UART numbers */ | 155 | /* MN10300 on-chip UART numbers */ |
154 | #define PORT_MN10300 80 | 156 | #define PORT_MN10300 80 |
diff --git a/include/linux/swap.h b/include/linux/swap.h index 3ca5c4bd6d3f..878459ae0454 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
@@ -171,10 +171,10 @@ extern unsigned int nr_free_pagecache_pages(void); | |||
171 | 171 | ||
172 | 172 | ||
173 | /* linux/mm/swap.c */ | 173 | /* linux/mm/swap.c */ |
174 | extern void FASTCALL(lru_cache_add(struct page *)); | 174 | extern void lru_cache_add(struct page *); |
175 | extern void FASTCALL(lru_cache_add_active(struct page *)); | 175 | extern void lru_cache_add_active(struct page *); |
176 | extern void FASTCALL(activate_page(struct page *)); | 176 | extern void activate_page(struct page *); |
177 | extern void FASTCALL(mark_page_accessed(struct page *)); | 177 | extern void mark_page_accessed(struct page *); |
178 | extern void lru_add_drain(void); | 178 | extern void lru_add_drain(void); |
179 | extern int lru_add_drain_all(void); | 179 | extern int lru_add_drain_all(void); |
180 | extern int rotate_reclaimable_page(struct page *page); | 180 | extern int rotate_reclaimable_page(struct page *page); |
diff --git a/include/linux/wait.h b/include/linux/wait.h index 33a2aa9e02f2..0081147a9fe8 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h | |||
@@ -117,9 +117,9 @@ static inline int waitqueue_active(wait_queue_head_t *q) | |||
117 | */ | 117 | */ |
118 | #define is_sync_wait(wait) (!(wait) || ((wait)->private)) | 118 | #define is_sync_wait(wait) (!(wait) || ((wait)->private)) |
119 | 119 | ||
120 | extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)); | 120 | extern void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait); |
121 | extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait)); | 121 | extern void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait); |
122 | extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)); | 122 | extern void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait); |
123 | 123 | ||
124 | static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new) | 124 | static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new) |
125 | { | 125 | { |
@@ -141,16 +141,16 @@ static inline void __remove_wait_queue(wait_queue_head_t *head, | |||
141 | list_del(&old->task_list); | 141 | list_del(&old->task_list); |
142 | } | 142 | } |
143 | 143 | ||
144 | void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key)); | 144 | void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key); |
145 | extern void FASTCALL(__wake_up_locked(wait_queue_head_t *q, unsigned int mode)); | 145 | extern void __wake_up_locked(wait_queue_head_t *q, unsigned int mode); |
146 | extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr)); | 146 | extern void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr); |
147 | void FASTCALL(__wake_up_bit(wait_queue_head_t *, void *, int)); | 147 | void __wake_up_bit(wait_queue_head_t *, void *, int); |
148 | int FASTCALL(__wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned)); | 148 | int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned); |
149 | int FASTCALL(__wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned)); | 149 | int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned); |
150 | void FASTCALL(wake_up_bit(void *, int)); | 150 | void wake_up_bit(void *, int); |
151 | int FASTCALL(out_of_line_wait_on_bit(void *, int, int (*)(void *), unsigned)); | 151 | int out_of_line_wait_on_bit(void *, int, int (*)(void *), unsigned); |
152 | int FASTCALL(out_of_line_wait_on_bit_lock(void *, int, int (*)(void *), unsigned)); | 152 | int out_of_line_wait_on_bit_lock(void *, int, int (*)(void *), unsigned); |
153 | wait_queue_head_t *FASTCALL(bit_waitqueue(void *, int)); | 153 | wait_queue_head_t *bit_waitqueue(void *, int); |
154 | 154 | ||
155 | #define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL) | 155 | #define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL) |
156 | #define wake_up_nr(x, nr) __wake_up(x, TASK_NORMAL, nr, NULL) | 156 | #define wake_up_nr(x, nr) __wake_up(x, TASK_NORMAL, nr, NULL) |
@@ -437,11 +437,9 @@ extern long interruptible_sleep_on_timeout(wait_queue_head_t *q, | |||
437 | /* | 437 | /* |
438 | * Waitqueues which are removed from the waitqueue_head at wakeup time | 438 | * Waitqueues which are removed from the waitqueue_head at wakeup time |
439 | */ | 439 | */ |
440 | void FASTCALL(prepare_to_wait(wait_queue_head_t *q, | 440 | void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state); |
441 | wait_queue_t *wait, int state)); | 441 | void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state); |
442 | void FASTCALL(prepare_to_wait_exclusive(wait_queue_head_t *q, | 442 | void finish_wait(wait_queue_head_t *q, wait_queue_t *wait); |
443 | wait_queue_t *wait, int state)); | ||
444 | void FASTCALL(finish_wait(wait_queue_head_t *q, wait_queue_t *wait)); | ||
445 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); | 443 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); |
446 | int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key); | 444 | int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key); |
447 | 445 | ||
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 7f28c32d9aca..542526c6e8ef 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
@@ -178,18 +178,17 @@ __create_workqueue_key(const char *name, int singlethread, | |||
178 | 178 | ||
179 | extern void destroy_workqueue(struct workqueue_struct *wq); | 179 | extern void destroy_workqueue(struct workqueue_struct *wq); |
180 | 180 | ||
181 | extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work)); | 181 | extern int queue_work(struct workqueue_struct *wq, struct work_struct *work); |
182 | extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, | 182 | extern int queue_delayed_work(struct workqueue_struct *wq, |
183 | struct delayed_work *work, unsigned long delay)); | 183 | struct delayed_work *work, unsigned long delay); |
184 | extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, | 184 | extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, |
185 | struct delayed_work *work, unsigned long delay); | 185 | struct delayed_work *work, unsigned long delay); |
186 | 186 | ||
187 | extern void FASTCALL(flush_workqueue(struct workqueue_struct *wq)); | 187 | extern void flush_workqueue(struct workqueue_struct *wq); |
188 | extern void flush_scheduled_work(void); | 188 | extern void flush_scheduled_work(void); |
189 | 189 | ||
190 | extern int FASTCALL(schedule_work(struct work_struct *work)); | 190 | extern int schedule_work(struct work_struct *work); |
191 | extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, | 191 | extern int schedule_delayed_work(struct delayed_work *work, unsigned long delay); |
192 | unsigned long delay)); | ||
193 | extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, | 192 | extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, |
194 | unsigned long delay); | 193 | unsigned long delay); |
195 | extern int schedule_on_each_cpu(work_func_t func); | 194 | extern int schedule_on_each_cpu(work_func_t func); |
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index d1299e999723..530ff4c553f8 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
7 | #include <linux/workqueue.h> | 7 | #include <linux/workqueue.h> |
8 | #include <linux/mutex.h> | 8 | #include <linux/mutex.h> |
9 | #include <scsi/scsi.h> | ||
9 | 10 | ||
10 | struct request_queue; | 11 | struct request_queue; |
11 | struct block_device; | 12 | struct block_device; |
@@ -25,12 +26,15 @@ struct blk_queue_tags; | |||
25 | * NONE: Self evident. Host adapter is not capable of scatter-gather. | 26 | * NONE: Self evident. Host adapter is not capable of scatter-gather. |
26 | * ALL: Means that the host adapter module can do scatter-gather, | 27 | * ALL: Means that the host adapter module can do scatter-gather, |
27 | * and that there is no limit to the size of the table to which | 28 | * and that there is no limit to the size of the table to which |
28 | * we scatter/gather data. | 29 | * we scatter/gather data. The value we set here is the maximum |
30 | * single element sglist. To use chained sglists, the adapter | ||
31 | * has to set a value beyond ALL (and correctly use the chain | ||
32 | * handling API. | ||
29 | * Anything else: Indicates the maximum number of chains that can be | 33 | * Anything else: Indicates the maximum number of chains that can be |
30 | * used in one scatter-gather request. | 34 | * used in one scatter-gather request. |
31 | */ | 35 | */ |
32 | #define SG_NONE 0 | 36 | #define SG_NONE 0 |
33 | #define SG_ALL 0xff | 37 | #define SG_ALL SCSI_MAX_SG_SEGMENTS |
34 | 38 | ||
35 | #define MODE_UNKNOWN 0x00 | 39 | #define MODE_UNKNOWN 0x00 |
36 | #define MODE_INITIATOR 0x01 | 40 | #define MODE_INITIATOR 0x01 |
diff --git a/init/Kconfig b/init/Kconfig index 824d48cb67bf..dcef8b55011a 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -311,25 +311,36 @@ config CPUSETS | |||
311 | 311 | ||
312 | Say N if unsure. | 312 | Say N if unsure. |
313 | 313 | ||
314 | config FAIR_GROUP_SCHED | 314 | config GROUP_SCHED |
315 | bool "Fair group CPU scheduler" | 315 | bool "Group CPU scheduler" |
316 | default y | 316 | default y |
317 | help | 317 | help |
318 | This feature lets CPU scheduler recognize task groups and control CPU | 318 | This feature lets CPU scheduler recognize task groups and control CPU |
319 | bandwidth allocation to such task groups. | 319 | bandwidth allocation to such task groups. |
320 | 320 | ||
321 | config FAIR_GROUP_SCHED | ||
322 | bool "Group scheduling for SCHED_OTHER" | ||
323 | depends on GROUP_SCHED | ||
324 | default y | ||
325 | |||
326 | config RT_GROUP_SCHED | ||
327 | bool "Group scheduling for SCHED_RR/FIFO" | ||
328 | depends on EXPERIMENTAL | ||
329 | depends on GROUP_SCHED | ||
330 | default n | ||
331 | |||
321 | choice | 332 | choice |
322 | depends on FAIR_GROUP_SCHED | 333 | depends on GROUP_SCHED |
323 | prompt "Basis for grouping tasks" | 334 | prompt "Basis for grouping tasks" |
324 | default FAIR_USER_SCHED | 335 | default USER_SCHED |
325 | 336 | ||
326 | config FAIR_USER_SCHED | 337 | config USER_SCHED |
327 | bool "user id" | 338 | bool "user id" |
328 | help | 339 | help |
329 | This option will choose userid as the basis for grouping | 340 | This option will choose userid as the basis for grouping |
330 | tasks, thus providing equal CPU bandwidth to each user. | 341 | tasks, thus providing equal CPU bandwidth to each user. |
331 | 342 | ||
332 | config FAIR_CGROUP_SCHED | 343 | config CGROUP_SCHED |
333 | bool "Control groups" | 344 | bool "Control groups" |
334 | depends on CGROUPS | 345 | depends on CGROUPS |
335 | help | 346 | help |
diff --git a/kernel/marker.c b/kernel/marker.c index 5323cfaedbce..c4c2cd8b61f5 100644 --- a/kernel/marker.c +++ b/kernel/marker.c | |||
@@ -27,35 +27,42 @@ | |||
27 | extern struct marker __start___markers[]; | 27 | extern struct marker __start___markers[]; |
28 | extern struct marker __stop___markers[]; | 28 | extern struct marker __stop___markers[]; |
29 | 29 | ||
30 | /* Set to 1 to enable marker debug output */ | ||
31 | const int marker_debug; | ||
32 | |||
30 | /* | 33 | /* |
31 | * markers_mutex nests inside module_mutex. Markers mutex protects the builtin | 34 | * markers_mutex nests inside module_mutex. Markers mutex protects the builtin |
32 | * and module markers, the hash table and deferred_sync. | 35 | * and module markers and the hash table. |
33 | */ | 36 | */ |
34 | static DEFINE_MUTEX(markers_mutex); | 37 | static DEFINE_MUTEX(markers_mutex); |
35 | 38 | ||
36 | /* | 39 | /* |
37 | * Marker deferred synchronization. | ||
38 | * Upon marker probe_unregister, we delay call to synchronize_sched() to | ||
39 | * accelerate mass unregistration (only when there is no more reference to a | ||
40 | * given module do we call synchronize_sched()). However, we need to make sure | ||
41 | * every critical region has ended before we re-arm a marker that has been | ||
42 | * unregistered and then registered back with a different probe data. | ||
43 | */ | ||
44 | static int deferred_sync; | ||
45 | |||
46 | /* | ||
47 | * Marker hash table, containing the active markers. | 40 | * Marker hash table, containing the active markers. |
48 | * Protected by module_mutex. | 41 | * Protected by module_mutex. |
49 | */ | 42 | */ |
50 | #define MARKER_HASH_BITS 6 | 43 | #define MARKER_HASH_BITS 6 |
51 | #define MARKER_TABLE_SIZE (1 << MARKER_HASH_BITS) | 44 | #define MARKER_TABLE_SIZE (1 << MARKER_HASH_BITS) |
52 | 45 | ||
46 | /* | ||
47 | * Note about RCU : | ||
48 | * It is used to make sure every handler has finished using its private data | ||
49 | * between two consecutive operation (add or remove) on a given marker. It is | ||
50 | * also used to delay the free of multiple probes array until a quiescent state | ||
51 | * is reached. | ||
52 | * marker entries modifications are protected by the markers_mutex. | ||
53 | */ | ||
53 | struct marker_entry { | 54 | struct marker_entry { |
54 | struct hlist_node hlist; | 55 | struct hlist_node hlist; |
55 | char *format; | 56 | char *format; |
56 | marker_probe_func *probe; | 57 | void (*call)(const struct marker *mdata, /* Probe wrapper */ |
57 | void *private; | 58 | void *call_private, const char *fmt, ...); |
59 | struct marker_probe_closure single; | ||
60 | struct marker_probe_closure *multi; | ||
58 | int refcount; /* Number of times armed. 0 if disarmed. */ | 61 | int refcount; /* Number of times armed. 0 if disarmed. */ |
62 | struct rcu_head rcu; | ||
63 | void *oldptr; | ||
64 | char rcu_pending:1; | ||
65 | char ptype:1; | ||
59 | char name[0]; /* Contains name'\0'format'\0' */ | 66 | char name[0]; /* Contains name'\0'format'\0' */ |
60 | }; | 67 | }; |
61 | 68 | ||
@@ -63,7 +70,8 @@ static struct hlist_head marker_table[MARKER_TABLE_SIZE]; | |||
63 | 70 | ||
64 | /** | 71 | /** |
65 | * __mark_empty_function - Empty probe callback | 72 | * __mark_empty_function - Empty probe callback |
66 | * @mdata: pointer of type const struct marker | 73 | * @probe_private: probe private data |
74 | * @call_private: call site private data | ||
67 | * @fmt: format string | 75 | * @fmt: format string |
68 | * @...: variable argument list | 76 | * @...: variable argument list |
69 | * | 77 | * |
@@ -72,13 +80,267 @@ static struct hlist_head marker_table[MARKER_TABLE_SIZE]; | |||
72 | * though the function pointer change and the marker enabling are two distinct | 80 | * though the function pointer change and the marker enabling are two distinct |
73 | * operations that modifies the execution flow of preemptible code. | 81 | * operations that modifies the execution flow of preemptible code. |
74 | */ | 82 | */ |
75 | void __mark_empty_function(const struct marker *mdata, void *private, | 83 | void __mark_empty_function(void *probe_private, void *call_private, |
76 | const char *fmt, ...) | 84 | const char *fmt, va_list *args) |
77 | { | 85 | { |
78 | } | 86 | } |
79 | EXPORT_SYMBOL_GPL(__mark_empty_function); | 87 | EXPORT_SYMBOL_GPL(__mark_empty_function); |
80 | 88 | ||
81 | /* | 89 | /* |
90 | * marker_probe_cb Callback that prepares the variable argument list for probes. | ||
91 | * @mdata: pointer of type struct marker | ||
92 | * @call_private: caller site private data | ||
93 | * @fmt: format string | ||
94 | * @...: Variable argument list. | ||
95 | * | ||
96 | * Since we do not use "typical" pointer based RCU in the 1 argument case, we | ||
97 | * need to put a full smp_rmb() in this branch. This is why we do not use | ||
98 | * rcu_dereference() for the pointer read. | ||
99 | */ | ||
100 | void marker_probe_cb(const struct marker *mdata, void *call_private, | ||
101 | const char *fmt, ...) | ||
102 | { | ||
103 | va_list args; | ||
104 | char ptype; | ||
105 | |||
106 | /* | ||
107 | * disabling preemption to make sure the teardown of the callbacks can | ||
108 | * be done correctly when they are in modules and they insure RCU read | ||
109 | * coherency. | ||
110 | */ | ||
111 | preempt_disable(); | ||
112 | ptype = ACCESS_ONCE(mdata->ptype); | ||
113 | if (likely(!ptype)) { | ||
114 | marker_probe_func *func; | ||
115 | /* Must read the ptype before ptr. They are not data dependant, | ||
116 | * so we put an explicit smp_rmb() here. */ | ||
117 | smp_rmb(); | ||
118 | func = ACCESS_ONCE(mdata->single.func); | ||
119 | /* Must read the ptr before private data. They are not data | ||
120 | * dependant, so we put an explicit smp_rmb() here. */ | ||
121 | smp_rmb(); | ||
122 | va_start(args, fmt); | ||
123 | func(mdata->single.probe_private, call_private, fmt, &args); | ||
124 | va_end(args); | ||
125 | } else { | ||
126 | struct marker_probe_closure *multi; | ||
127 | int i; | ||
128 | /* | ||
129 | * multi points to an array, therefore accessing the array | ||
130 | * depends on reading multi. However, even in this case, | ||
131 | * we must insure that the pointer is read _before_ the array | ||
132 | * data. Same as rcu_dereference, but we need a full smp_rmb() | ||
133 | * in the fast path, so put the explicit barrier here. | ||
134 | */ | ||
135 | smp_read_barrier_depends(); | ||
136 | multi = ACCESS_ONCE(mdata->multi); | ||
137 | for (i = 0; multi[i].func; i++) { | ||
138 | va_start(args, fmt); | ||
139 | multi[i].func(multi[i].probe_private, call_private, fmt, | ||
140 | &args); | ||
141 | va_end(args); | ||
142 | } | ||
143 | } | ||
144 | preempt_enable(); | ||
145 | } | ||
146 | EXPORT_SYMBOL_GPL(marker_probe_cb); | ||
147 | |||
148 | /* | ||
149 | * marker_probe_cb Callback that does not prepare the variable argument list. | ||
150 | * @mdata: pointer of type struct marker | ||
151 | * @call_private: caller site private data | ||
152 | * @fmt: format string | ||
153 | * @...: Variable argument list. | ||
154 | * | ||
155 | * Should be connected to markers "MARK_NOARGS". | ||
156 | */ | ||
157 | void marker_probe_cb_noarg(const struct marker *mdata, | ||
158 | void *call_private, const char *fmt, ...) | ||
159 | { | ||
160 | va_list args; /* not initialized */ | ||
161 | char ptype; | ||
162 | |||
163 | preempt_disable(); | ||
164 | ptype = ACCESS_ONCE(mdata->ptype); | ||
165 | if (likely(!ptype)) { | ||
166 | marker_probe_func *func; | ||
167 | /* Must read the ptype before ptr. They are not data dependant, | ||
168 | * so we put an explicit smp_rmb() here. */ | ||
169 | smp_rmb(); | ||
170 | func = ACCESS_ONCE(mdata->single.func); | ||
171 | /* Must read the ptr before private data. They are not data | ||
172 | * dependant, so we put an explicit smp_rmb() here. */ | ||
173 | smp_rmb(); | ||
174 | func(mdata->single.probe_private, call_private, fmt, &args); | ||
175 | } else { | ||
176 | struct marker_probe_closure *multi; | ||
177 | int i; | ||
178 | /* | ||
179 | * multi points to an array, therefore accessing the array | ||
180 | * depends on reading multi. However, even in this case, | ||
181 | * we must insure that the pointer is read _before_ the array | ||
182 | * data. Same as rcu_dereference, but we need a full smp_rmb() | ||
183 | * in the fast path, so put the explicit barrier here. | ||
184 | */ | ||
185 | smp_read_barrier_depends(); | ||
186 | multi = ACCESS_ONCE(mdata->multi); | ||
187 | for (i = 0; multi[i].func; i++) | ||
188 | multi[i].func(multi[i].probe_private, call_private, fmt, | ||
189 | &args); | ||
190 | } | ||
191 | preempt_enable(); | ||
192 | } | ||
193 | EXPORT_SYMBOL_GPL(marker_probe_cb_noarg); | ||
194 | |||
195 | static void free_old_closure(struct rcu_head *head) | ||
196 | { | ||
197 | struct marker_entry *entry = container_of(head, | ||
198 | struct marker_entry, rcu); | ||
199 | kfree(entry->oldptr); | ||
200 | /* Make sure we free the data before setting the pending flag to 0 */ | ||
201 | smp_wmb(); | ||
202 | entry->rcu_pending = 0; | ||
203 | } | ||
204 | |||
205 | static void debug_print_probes(struct marker_entry *entry) | ||
206 | { | ||
207 | int i; | ||
208 | |||
209 | if (!marker_debug) | ||
210 | return; | ||
211 | |||
212 | if (!entry->ptype) { | ||
213 | printk(KERN_DEBUG "Single probe : %p %p\n", | ||
214 | entry->single.func, | ||
215 | entry->single.probe_private); | ||
216 | } else { | ||
217 | for (i = 0; entry->multi[i].func; i++) | ||
218 | printk(KERN_DEBUG "Multi probe %d : %p %p\n", i, | ||
219 | entry->multi[i].func, | ||
220 | entry->multi[i].probe_private); | ||
221 | } | ||
222 | } | ||
223 | |||
224 | static struct marker_probe_closure * | ||
225 | marker_entry_add_probe(struct marker_entry *entry, | ||
226 | marker_probe_func *probe, void *probe_private) | ||
227 | { | ||
228 | int nr_probes = 0; | ||
229 | struct marker_probe_closure *old, *new; | ||
230 | |||
231 | WARN_ON(!probe); | ||
232 | |||
233 | debug_print_probes(entry); | ||
234 | old = entry->multi; | ||
235 | if (!entry->ptype) { | ||
236 | if (entry->single.func == probe && | ||
237 | entry->single.probe_private == probe_private) | ||
238 | return ERR_PTR(-EBUSY); | ||
239 | if (entry->single.func == __mark_empty_function) { | ||
240 | /* 0 -> 1 probes */ | ||
241 | entry->single.func = probe; | ||
242 | entry->single.probe_private = probe_private; | ||
243 | entry->refcount = 1; | ||
244 | entry->ptype = 0; | ||
245 | debug_print_probes(entry); | ||
246 | return NULL; | ||
247 | } else { | ||
248 | /* 1 -> 2 probes */ | ||
249 | nr_probes = 1; | ||
250 | old = NULL; | ||
251 | } | ||
252 | } else { | ||
253 | /* (N -> N+1), (N != 0, 1) probes */ | ||
254 | for (nr_probes = 0; old[nr_probes].func; nr_probes++) | ||
255 | if (old[nr_probes].func == probe | ||
256 | && old[nr_probes].probe_private | ||
257 | == probe_private) | ||
258 | return ERR_PTR(-EBUSY); | ||
259 | } | ||
260 | /* + 2 : one for new probe, one for NULL func */ | ||
261 | new = kzalloc((nr_probes + 2) * sizeof(struct marker_probe_closure), | ||
262 | GFP_KERNEL); | ||
263 | if (new == NULL) | ||
264 | return ERR_PTR(-ENOMEM); | ||
265 | if (!old) | ||
266 | new[0] = entry->single; | ||
267 | else | ||
268 | memcpy(new, old, | ||
269 | nr_probes * sizeof(struct marker_probe_closure)); | ||
270 | new[nr_probes].func = probe; | ||
271 | new[nr_probes].probe_private = probe_private; | ||
272 | entry->refcount = nr_probes + 1; | ||
273 | entry->multi = new; | ||
274 | entry->ptype = 1; | ||
275 | debug_print_probes(entry); | ||
276 | return old; | ||
277 | } | ||
278 | |||
279 | static struct marker_probe_closure * | ||
280 | marker_entry_remove_probe(struct marker_entry *entry, | ||
281 | marker_probe_func *probe, void *probe_private) | ||
282 | { | ||
283 | int nr_probes = 0, nr_del = 0, i; | ||
284 | struct marker_probe_closure *old, *new; | ||
285 | |||
286 | old = entry->multi; | ||
287 | |||
288 | debug_print_probes(entry); | ||
289 | if (!entry->ptype) { | ||
290 | /* 0 -> N is an error */ | ||
291 | WARN_ON(entry->single.func == __mark_empty_function); | ||
292 | /* 1 -> 0 probes */ | ||
293 | WARN_ON(probe && entry->single.func != probe); | ||
294 | WARN_ON(entry->single.probe_private != probe_private); | ||
295 | entry->single.func = __mark_empty_function; | ||
296 | entry->refcount = 0; | ||
297 | entry->ptype = 0; | ||
298 | debug_print_probes(entry); | ||
299 | return NULL; | ||
300 | } else { | ||
301 | /* (N -> M), (N > 1, M >= 0) probes */ | ||
302 | for (nr_probes = 0; old[nr_probes].func; nr_probes++) { | ||
303 | if ((!probe || old[nr_probes].func == probe) | ||
304 | && old[nr_probes].probe_private | ||
305 | == probe_private) | ||
306 | nr_del++; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | if (nr_probes - nr_del == 0) { | ||
311 | /* N -> 0, (N > 1) */ | ||
312 | entry->single.func = __mark_empty_function; | ||
313 | entry->refcount = 0; | ||
314 | entry->ptype = 0; | ||
315 | } else if (nr_probes - nr_del == 1) { | ||
316 | /* N -> 1, (N > 1) */ | ||
317 | for (i = 0; old[i].func; i++) | ||
318 | if ((probe && old[i].func != probe) || | ||
319 | old[i].probe_private != probe_private) | ||
320 | entry->single = old[i]; | ||
321 | entry->refcount = 1; | ||
322 | entry->ptype = 0; | ||
323 | } else { | ||
324 | int j = 0; | ||
325 | /* N -> M, (N > 1, M > 1) */ | ||
326 | /* + 1 for NULL */ | ||
327 | new = kzalloc((nr_probes - nr_del + 1) | ||
328 | * sizeof(struct marker_probe_closure), GFP_KERNEL); | ||
329 | if (new == NULL) | ||
330 | return ERR_PTR(-ENOMEM); | ||
331 | for (i = 0; old[i].func; i++) | ||
332 | if ((probe && old[i].func != probe) || | ||
333 | old[i].probe_private != probe_private) | ||
334 | new[j++] = old[i]; | ||
335 | entry->refcount = nr_probes - nr_del; | ||
336 | entry->ptype = 1; | ||
337 | entry->multi = new; | ||
338 | } | ||
339 | debug_print_probes(entry); | ||
340 | return old; | ||
341 | } | ||
342 | |||
343 | /* | ||
82 | * Get marker if the marker is present in the marker hash table. | 344 | * Get marker if the marker is present in the marker hash table. |
83 | * Must be called with markers_mutex held. | 345 | * Must be called with markers_mutex held. |
84 | * Returns NULL if not present. | 346 | * Returns NULL if not present. |
@@ -102,8 +364,7 @@ static struct marker_entry *get_marker(const char *name) | |||
102 | * Add the marker to the marker hash table. Must be called with markers_mutex | 364 | * Add the marker to the marker hash table. Must be called with markers_mutex |
103 | * held. | 365 | * held. |
104 | */ | 366 | */ |
105 | static int add_marker(const char *name, const char *format, | 367 | static struct marker_entry *add_marker(const char *name, const char *format) |
106 | marker_probe_func *probe, void *private) | ||
107 | { | 368 | { |
108 | struct hlist_head *head; | 369 | struct hlist_head *head; |
109 | struct hlist_node *node; | 370 | struct hlist_node *node; |
@@ -118,9 +379,8 @@ static int add_marker(const char *name, const char *format, | |||
118 | hlist_for_each_entry(e, node, head, hlist) { | 379 | hlist_for_each_entry(e, node, head, hlist) { |
119 | if (!strcmp(name, e->name)) { | 380 | if (!strcmp(name, e->name)) { |
120 | printk(KERN_NOTICE | 381 | printk(KERN_NOTICE |
121 | "Marker %s busy, probe %p already installed\n", | 382 | "Marker %s busy\n", name); |
122 | name, e->probe); | 383 | return ERR_PTR(-EBUSY); /* Already there */ |
123 | return -EBUSY; /* Already there */ | ||
124 | } | 384 | } |
125 | } | 385 | } |
126 | /* | 386 | /* |
@@ -130,34 +390,42 @@ static int add_marker(const char *name, const char *format, | |||
130 | e = kmalloc(sizeof(struct marker_entry) + name_len + format_len, | 390 | e = kmalloc(sizeof(struct marker_entry) + name_len + format_len, |
131 | GFP_KERNEL); | 391 | GFP_KERNEL); |
132 | if (!e) | 392 | if (!e) |
133 | return -ENOMEM; | 393 | return ERR_PTR(-ENOMEM); |
134 | memcpy(&e->name[0], name, name_len); | 394 | memcpy(&e->name[0], name, name_len); |
135 | if (format) { | 395 | if (format) { |
136 | e->format = &e->name[name_len]; | 396 | e->format = &e->name[name_len]; |
137 | memcpy(e->format, format, format_len); | 397 | memcpy(e->format, format, format_len); |
398 | if (strcmp(e->format, MARK_NOARGS) == 0) | ||
399 | e->call = marker_probe_cb_noarg; | ||
400 | else | ||
401 | e->call = marker_probe_cb; | ||
138 | trace_mark(core_marker_format, "name %s format %s", | 402 | trace_mark(core_marker_format, "name %s format %s", |
139 | e->name, e->format); | 403 | e->name, e->format); |
140 | } else | 404 | } else { |
141 | e->format = NULL; | 405 | e->format = NULL; |
142 | e->probe = probe; | 406 | e->call = marker_probe_cb; |
143 | e->private = private; | 407 | } |
408 | e->single.func = __mark_empty_function; | ||
409 | e->single.probe_private = NULL; | ||
410 | e->multi = NULL; | ||
411 | e->ptype = 0; | ||
144 | e->refcount = 0; | 412 | e->refcount = 0; |
413 | e->rcu_pending = 0; | ||
145 | hlist_add_head(&e->hlist, head); | 414 | hlist_add_head(&e->hlist, head); |
146 | return 0; | 415 | return e; |
147 | } | 416 | } |
148 | 417 | ||
149 | /* | 418 | /* |
150 | * Remove the marker from the marker hash table. Must be called with mutex_lock | 419 | * Remove the marker from the marker hash table. Must be called with mutex_lock |
151 | * held. | 420 | * held. |
152 | */ | 421 | */ |
153 | static void *remove_marker(const char *name) | 422 | static int remove_marker(const char *name) |
154 | { | 423 | { |
155 | struct hlist_head *head; | 424 | struct hlist_head *head; |
156 | struct hlist_node *node; | 425 | struct hlist_node *node; |
157 | struct marker_entry *e; | 426 | struct marker_entry *e; |
158 | int found = 0; | 427 | int found = 0; |
159 | size_t len = strlen(name) + 1; | 428 | size_t len = strlen(name) + 1; |
160 | void *private = NULL; | ||
161 | u32 hash = jhash(name, len-1, 0); | 429 | u32 hash = jhash(name, len-1, 0); |
162 | 430 | ||
163 | head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)]; | 431 | head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)]; |
@@ -167,12 +435,16 @@ static void *remove_marker(const char *name) | |||
167 | break; | 435 | break; |
168 | } | 436 | } |
169 | } | 437 | } |
170 | if (found) { | 438 | if (!found) |
171 | private = e->private; | 439 | return -ENOENT; |
172 | hlist_del(&e->hlist); | 440 | if (e->single.func != __mark_empty_function) |
173 | kfree(e); | 441 | return -EBUSY; |
174 | } | 442 | hlist_del(&e->hlist); |
175 | return private; | 443 | /* Make sure the call_rcu has been executed */ |
444 | if (e->rcu_pending) | ||
445 | rcu_barrier(); | ||
446 | kfree(e); | ||
447 | return 0; | ||
176 | } | 448 | } |
177 | 449 | ||
178 | /* | 450 | /* |
@@ -184,6 +456,7 @@ static int marker_set_format(struct marker_entry **entry, const char *format) | |||
184 | size_t name_len = strlen((*entry)->name) + 1; | 456 | size_t name_len = strlen((*entry)->name) + 1; |
185 | size_t format_len = strlen(format) + 1; | 457 | size_t format_len = strlen(format) + 1; |
186 | 458 | ||
459 | |||
187 | e = kmalloc(sizeof(struct marker_entry) + name_len + format_len, | 460 | e = kmalloc(sizeof(struct marker_entry) + name_len + format_len, |
188 | GFP_KERNEL); | 461 | GFP_KERNEL); |
189 | if (!e) | 462 | if (!e) |
@@ -191,11 +464,20 @@ static int marker_set_format(struct marker_entry **entry, const char *format) | |||
191 | memcpy(&e->name[0], (*entry)->name, name_len); | 464 | memcpy(&e->name[0], (*entry)->name, name_len); |
192 | e->format = &e->name[name_len]; | 465 | e->format = &e->name[name_len]; |
193 | memcpy(e->format, format, format_len); | 466 | memcpy(e->format, format, format_len); |
194 | e->probe = (*entry)->probe; | 467 | if (strcmp(e->format, MARK_NOARGS) == 0) |
195 | e->private = (*entry)->private; | 468 | e->call = marker_probe_cb_noarg; |
469 | else | ||
470 | e->call = marker_probe_cb; | ||
471 | e->single = (*entry)->single; | ||
472 | e->multi = (*entry)->multi; | ||
473 | e->ptype = (*entry)->ptype; | ||
196 | e->refcount = (*entry)->refcount; | 474 | e->refcount = (*entry)->refcount; |
475 | e->rcu_pending = 0; | ||
197 | hlist_add_before(&e->hlist, &(*entry)->hlist); | 476 | hlist_add_before(&e->hlist, &(*entry)->hlist); |
198 | hlist_del(&(*entry)->hlist); | 477 | hlist_del(&(*entry)->hlist); |
478 | /* Make sure the call_rcu has been executed */ | ||
479 | if ((*entry)->rcu_pending) | ||
480 | rcu_barrier(); | ||
199 | kfree(*entry); | 481 | kfree(*entry); |
200 | *entry = e; | 482 | *entry = e; |
201 | trace_mark(core_marker_format, "name %s format %s", | 483 | trace_mark(core_marker_format, "name %s format %s", |
@@ -206,7 +488,8 @@ static int marker_set_format(struct marker_entry **entry, const char *format) | |||
206 | /* | 488 | /* |
207 | * Sets the probe callback corresponding to one marker. | 489 | * Sets the probe callback corresponding to one marker. |
208 | */ | 490 | */ |
209 | static int set_marker(struct marker_entry **entry, struct marker *elem) | 491 | static int set_marker(struct marker_entry **entry, struct marker *elem, |
492 | int active) | ||
210 | { | 493 | { |
211 | int ret; | 494 | int ret; |
212 | WARN_ON(strcmp((*entry)->name, elem->name) != 0); | 495 | WARN_ON(strcmp((*entry)->name, elem->name) != 0); |
@@ -226,9 +509,43 @@ static int set_marker(struct marker_entry **entry, struct marker *elem) | |||
226 | if (ret) | 509 | if (ret) |
227 | return ret; | 510 | return ret; |
228 | } | 511 | } |
229 | elem->call = (*entry)->probe; | 512 | |
230 | elem->private = (*entry)->private; | 513 | /* |
231 | elem->state = 1; | 514 | * probe_cb setup (statically known) is done here. It is |
515 | * asynchronous with the rest of execution, therefore we only | ||
516 | * pass from a "safe" callback (with argument) to an "unsafe" | ||
517 | * callback (does not set arguments). | ||
518 | */ | ||
519 | elem->call = (*entry)->call; | ||
520 | /* | ||
521 | * Sanity check : | ||
522 | * We only update the single probe private data when the ptr is | ||
523 | * set to a _non_ single probe! (0 -> 1 and N -> 1, N != 1) | ||
524 | */ | ||
525 | WARN_ON(elem->single.func != __mark_empty_function | ||
526 | && elem->single.probe_private | ||
527 | != (*entry)->single.probe_private && | ||
528 | !elem->ptype); | ||
529 | elem->single.probe_private = (*entry)->single.probe_private; | ||
530 | /* | ||
531 | * Make sure the private data is valid when we update the | ||
532 | * single probe ptr. | ||
533 | */ | ||
534 | smp_wmb(); | ||
535 | elem->single.func = (*entry)->single.func; | ||
536 | /* | ||
537 | * We also make sure that the new probe callbacks array is consistent | ||
538 | * before setting a pointer to it. | ||
539 | */ | ||
540 | rcu_assign_pointer(elem->multi, (*entry)->multi); | ||
541 | /* | ||
542 | * Update the function or multi probe array pointer before setting the | ||
543 | * ptype. | ||
544 | */ | ||
545 | smp_wmb(); | ||
546 | elem->ptype = (*entry)->ptype; | ||
547 | elem->state = active; | ||
548 | |||
232 | return 0; | 549 | return 0; |
233 | } | 550 | } |
234 | 551 | ||
@@ -240,8 +557,12 @@ static int set_marker(struct marker_entry **entry, struct marker *elem) | |||
240 | */ | 557 | */ |
241 | static void disable_marker(struct marker *elem) | 558 | static void disable_marker(struct marker *elem) |
242 | { | 559 | { |
560 | /* leave "call" as is. It is known statically. */ | ||
243 | elem->state = 0; | 561 | elem->state = 0; |
244 | elem->call = __mark_empty_function; | 562 | elem->single.func = __mark_empty_function; |
563 | /* Update the function before setting the ptype */ | ||
564 | smp_wmb(); | ||
565 | elem->ptype = 0; /* single probe */ | ||
245 | /* | 566 | /* |
246 | * Leave the private data and id there, because removal is racy and | 567 | * Leave the private data and id there, because removal is racy and |
247 | * should be done only after a synchronize_sched(). These are never used | 568 | * should be done only after a synchronize_sched(). These are never used |
@@ -253,14 +574,11 @@ static void disable_marker(struct marker *elem) | |||
253 | * marker_update_probe_range - Update a probe range | 574 | * marker_update_probe_range - Update a probe range |
254 | * @begin: beginning of the range | 575 | * @begin: beginning of the range |
255 | * @end: end of the range | 576 | * @end: end of the range |
256 | * @probe_module: module address of the probe being updated | ||
257 | * @refcount: number of references left to the given probe_module (out) | ||
258 | * | 577 | * |
259 | * Updates the probe callback corresponding to a range of markers. | 578 | * Updates the probe callback corresponding to a range of markers. |
260 | */ | 579 | */ |
261 | void marker_update_probe_range(struct marker *begin, | 580 | void marker_update_probe_range(struct marker *begin, |
262 | struct marker *end, struct module *probe_module, | 581 | struct marker *end) |
263 | int *refcount) | ||
264 | { | 582 | { |
265 | struct marker *iter; | 583 | struct marker *iter; |
266 | struct marker_entry *mark_entry; | 584 | struct marker_entry *mark_entry; |
@@ -268,15 +586,12 @@ void marker_update_probe_range(struct marker *begin, | |||
268 | mutex_lock(&markers_mutex); | 586 | mutex_lock(&markers_mutex); |
269 | for (iter = begin; iter < end; iter++) { | 587 | for (iter = begin; iter < end; iter++) { |
270 | mark_entry = get_marker(iter->name); | 588 | mark_entry = get_marker(iter->name); |
271 | if (mark_entry && mark_entry->refcount) { | 589 | if (mark_entry) { |
272 | set_marker(&mark_entry, iter); | 590 | set_marker(&mark_entry, iter, |
591 | !!mark_entry->refcount); | ||
273 | /* | 592 | /* |
274 | * ignore error, continue | 593 | * ignore error, continue |
275 | */ | 594 | */ |
276 | if (probe_module) | ||
277 | if (probe_module == | ||
278 | __module_text_address((unsigned long)mark_entry->probe)) | ||
279 | (*refcount)++; | ||
280 | } else { | 595 | } else { |
281 | disable_marker(iter); | 596 | disable_marker(iter); |
282 | } | 597 | } |
@@ -289,20 +604,27 @@ void marker_update_probe_range(struct marker *begin, | |||
289 | * Issues a synchronize_sched() when no reference to the module passed | 604 | * Issues a synchronize_sched() when no reference to the module passed |
290 | * as parameter is found in the probes so the probe module can be | 605 | * as parameter is found in the probes so the probe module can be |
291 | * safely unloaded from now on. | 606 | * safely unloaded from now on. |
607 | * | ||
608 | * Internal callback only changed before the first probe is connected to it. | ||
609 | * Single probe private data can only be changed on 0 -> 1 and 2 -> 1 | ||
610 | * transitions. All other transitions will leave the old private data valid. | ||
611 | * This makes the non-atomicity of the callback/private data updates valid. | ||
612 | * | ||
613 | * "special case" updates : | ||
614 | * 0 -> 1 callback | ||
615 | * 1 -> 0 callback | ||
616 | * 1 -> 2 callbacks | ||
617 | * 2 -> 1 callbacks | ||
618 | * Other updates all behave the same, just like the 2 -> 3 or 3 -> 2 updates. | ||
619 | * Site effect : marker_set_format may delete the marker entry (creating a | ||
620 | * replacement). | ||
292 | */ | 621 | */ |
293 | static void marker_update_probes(struct module *probe_module) | 622 | static void marker_update_probes(void) |
294 | { | 623 | { |
295 | int refcount = 0; | ||
296 | |||
297 | /* Core kernel markers */ | 624 | /* Core kernel markers */ |
298 | marker_update_probe_range(__start___markers, | 625 | marker_update_probe_range(__start___markers, __stop___markers); |
299 | __stop___markers, probe_module, &refcount); | ||
300 | /* Markers in modules. */ | 626 | /* Markers in modules. */ |
301 | module_update_markers(probe_module, &refcount); | 627 | module_update_markers(); |
302 | if (probe_module && refcount == 0) { | ||
303 | synchronize_sched(); | ||
304 | deferred_sync = 0; | ||
305 | } | ||
306 | } | 628 | } |
307 | 629 | ||
308 | /** | 630 | /** |
@@ -310,33 +632,49 @@ static void marker_update_probes(struct module *probe_module) | |||
310 | * @name: marker name | 632 | * @name: marker name |
311 | * @format: format string | 633 | * @format: format string |
312 | * @probe: probe handler | 634 | * @probe: probe handler |
313 | * @private: probe private data | 635 | * @probe_private: probe private data |
314 | * | 636 | * |
315 | * private data must be a valid allocated memory address, or NULL. | 637 | * private data must be a valid allocated memory address, or NULL. |
316 | * Returns 0 if ok, error value on error. | 638 | * Returns 0 if ok, error value on error. |
639 | * The probe address must at least be aligned on the architecture pointer size. | ||
317 | */ | 640 | */ |
318 | int marker_probe_register(const char *name, const char *format, | 641 | int marker_probe_register(const char *name, const char *format, |
319 | marker_probe_func *probe, void *private) | 642 | marker_probe_func *probe, void *probe_private) |
320 | { | 643 | { |
321 | struct marker_entry *entry; | 644 | struct marker_entry *entry; |
322 | int ret = 0; | 645 | int ret = 0; |
646 | struct marker_probe_closure *old; | ||
323 | 647 | ||
324 | mutex_lock(&markers_mutex); | 648 | mutex_lock(&markers_mutex); |
325 | entry = get_marker(name); | 649 | entry = get_marker(name); |
326 | if (entry && entry->refcount) { | 650 | if (!entry) { |
327 | ret = -EBUSY; | 651 | entry = add_marker(name, format); |
328 | goto end; | 652 | if (IS_ERR(entry)) { |
329 | } | 653 | ret = PTR_ERR(entry); |
330 | if (deferred_sync) { | 654 | goto end; |
331 | synchronize_sched(); | 655 | } |
332 | deferred_sync = 0; | ||
333 | } | 656 | } |
334 | ret = add_marker(name, format, probe, private); | 657 | /* |
335 | if (ret) | 658 | * If we detect that a call_rcu is pending for this marker, |
659 | * make sure it's executed now. | ||
660 | */ | ||
661 | if (entry->rcu_pending) | ||
662 | rcu_barrier(); | ||
663 | old = marker_entry_add_probe(entry, probe, probe_private); | ||
664 | if (IS_ERR(old)) { | ||
665 | ret = PTR_ERR(old); | ||
336 | goto end; | 666 | goto end; |
667 | } | ||
337 | mutex_unlock(&markers_mutex); | 668 | mutex_unlock(&markers_mutex); |
338 | marker_update_probes(NULL); | 669 | marker_update_probes(); /* may update entry */ |
339 | return ret; | 670 | mutex_lock(&markers_mutex); |
671 | entry = get_marker(name); | ||
672 | WARN_ON(!entry); | ||
673 | entry->oldptr = old; | ||
674 | entry->rcu_pending = 1; | ||
675 | /* write rcu_pending before calling the RCU callback */ | ||
676 | smp_wmb(); | ||
677 | call_rcu(&entry->rcu, free_old_closure); | ||
340 | end: | 678 | end: |
341 | mutex_unlock(&markers_mutex); | 679 | mutex_unlock(&markers_mutex); |
342 | return ret; | 680 | return ret; |
@@ -346,171 +684,166 @@ EXPORT_SYMBOL_GPL(marker_probe_register); | |||
346 | /** | 684 | /** |
347 | * marker_probe_unregister - Disconnect a probe from a marker | 685 | * marker_probe_unregister - Disconnect a probe from a marker |
348 | * @name: marker name | 686 | * @name: marker name |
687 | * @probe: probe function pointer | ||
688 | * @probe_private: probe private data | ||
349 | * | 689 | * |
350 | * Returns the private data given to marker_probe_register, or an ERR_PTR(). | 690 | * Returns the private data given to marker_probe_register, or an ERR_PTR(). |
691 | * We do not need to call a synchronize_sched to make sure the probes have | ||
692 | * finished running before doing a module unload, because the module unload | ||
693 | * itself uses stop_machine(), which insures that every preempt disabled section | ||
694 | * have finished. | ||
351 | */ | 695 | */ |
352 | void *marker_probe_unregister(const char *name) | 696 | int marker_probe_unregister(const char *name, |
697 | marker_probe_func *probe, void *probe_private) | ||
353 | { | 698 | { |
354 | struct module *probe_module; | ||
355 | struct marker_entry *entry; | 699 | struct marker_entry *entry; |
356 | void *private; | 700 | struct marker_probe_closure *old; |
701 | int ret = 0; | ||
357 | 702 | ||
358 | mutex_lock(&markers_mutex); | 703 | mutex_lock(&markers_mutex); |
359 | entry = get_marker(name); | 704 | entry = get_marker(name); |
360 | if (!entry) { | 705 | if (!entry) { |
361 | private = ERR_PTR(-ENOENT); | 706 | ret = -ENOENT; |
362 | goto end; | 707 | goto end; |
363 | } | 708 | } |
364 | entry->refcount = 0; | 709 | if (entry->rcu_pending) |
365 | /* In what module is the probe handler ? */ | 710 | rcu_barrier(); |
366 | probe_module = __module_text_address((unsigned long)entry->probe); | 711 | old = marker_entry_remove_probe(entry, probe, probe_private); |
367 | private = remove_marker(name); | ||
368 | deferred_sync = 1; | ||
369 | mutex_unlock(&markers_mutex); | 712 | mutex_unlock(&markers_mutex); |
370 | marker_update_probes(probe_module); | 713 | marker_update_probes(); /* may update entry */ |
371 | return private; | 714 | mutex_lock(&markers_mutex); |
715 | entry = get_marker(name); | ||
716 | entry->oldptr = old; | ||
717 | entry->rcu_pending = 1; | ||
718 | /* write rcu_pending before calling the RCU callback */ | ||
719 | smp_wmb(); | ||
720 | call_rcu(&entry->rcu, free_old_closure); | ||
721 | remove_marker(name); /* Ignore busy error message */ | ||
372 | end: | 722 | end: |
373 | mutex_unlock(&markers_mutex); | 723 | mutex_unlock(&markers_mutex); |
374 | return private; | 724 | return ret; |
375 | } | 725 | } |
376 | EXPORT_SYMBOL_GPL(marker_probe_unregister); | 726 | EXPORT_SYMBOL_GPL(marker_probe_unregister); |
377 | 727 | ||
378 | /** | 728 | static struct marker_entry * |
379 | * marker_probe_unregister_private_data - Disconnect a probe from a marker | 729 | get_marker_from_private_data(marker_probe_func *probe, void *probe_private) |
380 | * @private: probe private data | ||
381 | * | ||
382 | * Unregister a marker by providing the registered private data. | ||
383 | * Returns the private data given to marker_probe_register, or an ERR_PTR(). | ||
384 | */ | ||
385 | void *marker_probe_unregister_private_data(void *private) | ||
386 | { | 730 | { |
387 | struct module *probe_module; | ||
388 | struct hlist_head *head; | ||
389 | struct hlist_node *node; | ||
390 | struct marker_entry *entry; | 731 | struct marker_entry *entry; |
391 | int found = 0; | ||
392 | unsigned int i; | 732 | unsigned int i; |
733 | struct hlist_head *head; | ||
734 | struct hlist_node *node; | ||
393 | 735 | ||
394 | mutex_lock(&markers_mutex); | ||
395 | for (i = 0; i < MARKER_TABLE_SIZE; i++) { | 736 | for (i = 0; i < MARKER_TABLE_SIZE; i++) { |
396 | head = &marker_table[i]; | 737 | head = &marker_table[i]; |
397 | hlist_for_each_entry(entry, node, head, hlist) { | 738 | hlist_for_each_entry(entry, node, head, hlist) { |
398 | if (entry->private == private) { | 739 | if (!entry->ptype) { |
399 | found = 1; | 740 | if (entry->single.func == probe |
400 | goto iter_end; | 741 | && entry->single.probe_private |
742 | == probe_private) | ||
743 | return entry; | ||
744 | } else { | ||
745 | struct marker_probe_closure *closure; | ||
746 | closure = entry->multi; | ||
747 | for (i = 0; closure[i].func; i++) { | ||
748 | if (closure[i].func == probe && | ||
749 | closure[i].probe_private | ||
750 | == probe_private) | ||
751 | return entry; | ||
752 | } | ||
401 | } | 753 | } |
402 | } | 754 | } |
403 | } | 755 | } |
404 | iter_end: | 756 | return NULL; |
405 | if (!found) { | ||
406 | private = ERR_PTR(-ENOENT); | ||
407 | goto end; | ||
408 | } | ||
409 | entry->refcount = 0; | ||
410 | /* In what module is the probe handler ? */ | ||
411 | probe_module = __module_text_address((unsigned long)entry->probe); | ||
412 | private = remove_marker(entry->name); | ||
413 | deferred_sync = 1; | ||
414 | mutex_unlock(&markers_mutex); | ||
415 | marker_update_probes(probe_module); | ||
416 | return private; | ||
417 | end: | ||
418 | mutex_unlock(&markers_mutex); | ||
419 | return private; | ||
420 | } | 757 | } |
421 | EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data); | ||
422 | 758 | ||
423 | /** | 759 | /** |
424 | * marker_arm - Arm a marker | 760 | * marker_probe_unregister_private_data - Disconnect a probe from a marker |
425 | * @name: marker name | 761 | * @probe: probe function |
762 | * @probe_private: probe private data | ||
426 | * | 763 | * |
427 | * Activate a marker. It keeps a reference count of the number of | 764 | * Unregister a probe by providing the registered private data. |
428 | * arming/disarming done. | 765 | * Only removes the first marker found in hash table. |
429 | * Returns 0 if ok, error value on error. | 766 | * Return 0 on success or error value. |
767 | * We do not need to call a synchronize_sched to make sure the probes have | ||
768 | * finished running before doing a module unload, because the module unload | ||
769 | * itself uses stop_machine(), which insures that every preempt disabled section | ||
770 | * have finished. | ||
430 | */ | 771 | */ |
431 | int marker_arm(const char *name) | 772 | int marker_probe_unregister_private_data(marker_probe_func *probe, |
773 | void *probe_private) | ||
432 | { | 774 | { |
433 | struct marker_entry *entry; | 775 | struct marker_entry *entry; |
434 | int ret = 0; | 776 | int ret = 0; |
777 | struct marker_probe_closure *old; | ||
435 | 778 | ||
436 | mutex_lock(&markers_mutex); | 779 | mutex_lock(&markers_mutex); |
437 | entry = get_marker(name); | 780 | entry = get_marker_from_private_data(probe, probe_private); |
438 | if (!entry) { | 781 | if (!entry) { |
439 | ret = -ENOENT; | 782 | ret = -ENOENT; |
440 | goto end; | 783 | goto end; |
441 | } | 784 | } |
442 | /* | 785 | if (entry->rcu_pending) |
443 | * Only need to update probes when refcount passes from 0 to 1. | 786 | rcu_barrier(); |
444 | */ | 787 | old = marker_entry_remove_probe(entry, NULL, probe_private); |
445 | if (entry->refcount++) | ||
446 | goto end; | ||
447 | end: | ||
448 | mutex_unlock(&markers_mutex); | 788 | mutex_unlock(&markers_mutex); |
449 | marker_update_probes(NULL); | 789 | marker_update_probes(); /* may update entry */ |
450 | return ret; | ||
451 | } | ||
452 | EXPORT_SYMBOL_GPL(marker_arm); | ||
453 | |||
454 | /** | ||
455 | * marker_disarm - Disarm a marker | ||
456 | * @name: marker name | ||
457 | * | ||
458 | * Disarm a marker. It keeps a reference count of the number of arming/disarming | ||
459 | * done. | ||
460 | * Returns 0 if ok, error value on error. | ||
461 | */ | ||
462 | int marker_disarm(const char *name) | ||
463 | { | ||
464 | struct marker_entry *entry; | ||
465 | int ret = 0; | ||
466 | |||
467 | mutex_lock(&markers_mutex); | 790 | mutex_lock(&markers_mutex); |
468 | entry = get_marker(name); | 791 | entry = get_marker_from_private_data(probe, probe_private); |
469 | if (!entry) { | 792 | WARN_ON(!entry); |
470 | ret = -ENOENT; | 793 | entry->oldptr = old; |
471 | goto end; | 794 | entry->rcu_pending = 1; |
472 | } | 795 | /* write rcu_pending before calling the RCU callback */ |
473 | /* | 796 | smp_wmb(); |
474 | * Only permit decrement refcount if higher than 0. | 797 | call_rcu(&entry->rcu, free_old_closure); |
475 | * Do probe update only on 1 -> 0 transition. | 798 | remove_marker(entry->name); /* Ignore busy error message */ |
476 | */ | ||
477 | if (entry->refcount) { | ||
478 | if (--entry->refcount) | ||
479 | goto end; | ||
480 | } else { | ||
481 | ret = -EPERM; | ||
482 | goto end; | ||
483 | } | ||
484 | end: | 799 | end: |
485 | mutex_unlock(&markers_mutex); | 800 | mutex_unlock(&markers_mutex); |
486 | marker_update_probes(NULL); | ||
487 | return ret; | 801 | return ret; |
488 | } | 802 | } |
489 | EXPORT_SYMBOL_GPL(marker_disarm); | 803 | EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data); |
490 | 804 | ||
491 | /** | 805 | /** |
492 | * marker_get_private_data - Get a marker's probe private data | 806 | * marker_get_private_data - Get a marker's probe private data |
493 | * @name: marker name | 807 | * @name: marker name |
808 | * @probe: probe to match | ||
809 | * @num: get the nth matching probe's private data | ||
494 | * | 810 | * |
811 | * Returns the nth private data pointer (starting from 0) matching, or an | ||
812 | * ERR_PTR. | ||
495 | * Returns the private data pointer, or an ERR_PTR. | 813 | * Returns the private data pointer, or an ERR_PTR. |
496 | * The private data pointer should _only_ be dereferenced if the caller is the | 814 | * The private data pointer should _only_ be dereferenced if the caller is the |
497 | * owner of the data, or its content could vanish. This is mostly used to | 815 | * owner of the data, or its content could vanish. This is mostly used to |
498 | * confirm that a caller is the owner of a registered probe. | 816 | * confirm that a caller is the owner of a registered probe. |
499 | */ | 817 | */ |
500 | void *marker_get_private_data(const char *name) | 818 | void *marker_get_private_data(const char *name, marker_probe_func *probe, |
819 | int num) | ||
501 | { | 820 | { |
502 | struct hlist_head *head; | 821 | struct hlist_head *head; |
503 | struct hlist_node *node; | 822 | struct hlist_node *node; |
504 | struct marker_entry *e; | 823 | struct marker_entry *e; |
505 | size_t name_len = strlen(name) + 1; | 824 | size_t name_len = strlen(name) + 1; |
506 | u32 hash = jhash(name, name_len-1, 0); | 825 | u32 hash = jhash(name, name_len-1, 0); |
507 | int found = 0; | 826 | int i; |
508 | 827 | ||
509 | head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)]; | 828 | head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)]; |
510 | hlist_for_each_entry(e, node, head, hlist) { | 829 | hlist_for_each_entry(e, node, head, hlist) { |
511 | if (!strcmp(name, e->name)) { | 830 | if (!strcmp(name, e->name)) { |
512 | found = 1; | 831 | if (!e->ptype) { |
513 | return e->private; | 832 | if (num == 0 && e->single.func == probe) |
833 | return e->single.probe_private; | ||
834 | else | ||
835 | break; | ||
836 | } else { | ||
837 | struct marker_probe_closure *closure; | ||
838 | int match = 0; | ||
839 | closure = e->multi; | ||
840 | for (i = 0; closure[i].func; i++) { | ||
841 | if (closure[i].func != probe) | ||
842 | continue; | ||
843 | if (match++ == num) | ||
844 | return closure[i].probe_private; | ||
845 | } | ||
846 | } | ||
514 | } | 847 | } |
515 | } | 848 | } |
516 | return ERR_PTR(-ENOENT); | 849 | return ERR_PTR(-ENOENT); |
diff --git a/kernel/module.c b/kernel/module.c index 4202da97a1da..92595bad3812 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -2038,7 +2038,7 @@ static struct module *load_module(void __user *umod, | |||
2038 | #ifdef CONFIG_MARKERS | 2038 | #ifdef CONFIG_MARKERS |
2039 | if (!mod->taints) | 2039 | if (!mod->taints) |
2040 | marker_update_probe_range(mod->markers, | 2040 | marker_update_probe_range(mod->markers, |
2041 | mod->markers + mod->num_markers, NULL, NULL); | 2041 | mod->markers + mod->num_markers); |
2042 | #endif | 2042 | #endif |
2043 | err = module_finalize(hdr, sechdrs, mod); | 2043 | err = module_finalize(hdr, sechdrs, mod); |
2044 | if (err < 0) | 2044 | if (err < 0) |
@@ -2564,7 +2564,7 @@ EXPORT_SYMBOL(struct_module); | |||
2564 | #endif | 2564 | #endif |
2565 | 2565 | ||
2566 | #ifdef CONFIG_MARKERS | 2566 | #ifdef CONFIG_MARKERS |
2567 | void module_update_markers(struct module *probe_module, int *refcount) | 2567 | void module_update_markers(void) |
2568 | { | 2568 | { |
2569 | struct module *mod; | 2569 | struct module *mod; |
2570 | 2570 | ||
@@ -2572,8 +2572,7 @@ void module_update_markers(struct module *probe_module, int *refcount) | |||
2572 | list_for_each_entry(mod, &modules, list) | 2572 | list_for_each_entry(mod, &modules, list) |
2573 | if (!mod->taints) | 2573 | if (!mod->taints) |
2574 | marker_update_probe_range(mod->markers, | 2574 | marker_update_probe_range(mod->markers, |
2575 | mod->markers + mod->num_markers, | 2575 | mod->markers + mod->num_markers); |
2576 | probe_module, refcount); | ||
2577 | mutex_unlock(&module_mutex); | 2576 | mutex_unlock(&module_mutex); |
2578 | } | 2577 | } |
2579 | #endif | 2578 | #endif |
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 760dfc233a00..c09605f8d16c 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
@@ -56,7 +56,10 @@ static atomic_t rcu_barrier_cpu_count; | |||
56 | static DEFINE_MUTEX(rcu_barrier_mutex); | 56 | static DEFINE_MUTEX(rcu_barrier_mutex); |
57 | static struct completion rcu_barrier_completion; | 57 | static struct completion rcu_barrier_completion; |
58 | 58 | ||
59 | /* Because of FASTCALL declaration of complete, we use this wrapper */ | 59 | /* |
60 | * Awaken the corresponding synchronize_rcu() instance now that a | ||
61 | * grace period has elapsed. | ||
62 | */ | ||
60 | static void wakeme_after_rcu(struct rcu_head *head) | 63 | static void wakeme_after_rcu(struct rcu_head *head) |
61 | { | 64 | { |
62 | struct rcu_synchronize *rcu; | 65 | struct rcu_synchronize *rcu; |
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c index 0deef71ff8d2..6522ae5b14a2 100644 --- a/kernel/rtmutex.c +++ b/kernel/rtmutex.c | |||
@@ -630,9 +630,12 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, | |||
630 | set_current_state(state); | 630 | set_current_state(state); |
631 | 631 | ||
632 | /* Setup the timer, when timeout != NULL */ | 632 | /* Setup the timer, when timeout != NULL */ |
633 | if (unlikely(timeout)) | 633 | if (unlikely(timeout)) { |
634 | hrtimer_start(&timeout->timer, timeout->timer.expires, | 634 | hrtimer_start(&timeout->timer, timeout->timer.expires, |
635 | HRTIMER_MODE_ABS); | 635 | HRTIMER_MODE_ABS); |
636 | if (!hrtimer_active(&timeout->timer)) | ||
637 | timeout->task = NULL; | ||
638 | } | ||
636 | 639 | ||
637 | for (;;) { | 640 | for (;;) { |
638 | /* Try to acquire the lock: */ | 641 | /* Try to acquire the lock: */ |
diff --git a/kernel/sched.c b/kernel/sched.c index 3eedd5260907..f28f19e65b59 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -155,7 +155,7 @@ struct rt_prio_array { | |||
155 | struct list_head queue[MAX_RT_PRIO]; | 155 | struct list_head queue[MAX_RT_PRIO]; |
156 | }; | 156 | }; |
157 | 157 | ||
158 | #ifdef CONFIG_FAIR_GROUP_SCHED | 158 | #ifdef CONFIG_GROUP_SCHED |
159 | 159 | ||
160 | #include <linux/cgroup.h> | 160 | #include <linux/cgroup.h> |
161 | 161 | ||
@@ -165,19 +165,16 @@ static LIST_HEAD(task_groups); | |||
165 | 165 | ||
166 | /* task group related information */ | 166 | /* task group related information */ |
167 | struct task_group { | 167 | struct task_group { |
168 | #ifdef CONFIG_FAIR_CGROUP_SCHED | 168 | #ifdef CONFIG_CGROUP_SCHED |
169 | struct cgroup_subsys_state css; | 169 | struct cgroup_subsys_state css; |
170 | #endif | 170 | #endif |
171 | |||
172 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
171 | /* schedulable entities of this group on each cpu */ | 173 | /* schedulable entities of this group on each cpu */ |
172 | struct sched_entity **se; | 174 | struct sched_entity **se; |
173 | /* runqueue "owned" by this group on each cpu */ | 175 | /* runqueue "owned" by this group on each cpu */ |
174 | struct cfs_rq **cfs_rq; | 176 | struct cfs_rq **cfs_rq; |
175 | 177 | ||
176 | struct sched_rt_entity **rt_se; | ||
177 | struct rt_rq **rt_rq; | ||
178 | |||
179 | unsigned int rt_ratio; | ||
180 | |||
181 | /* | 178 | /* |
182 | * shares assigned to a task group governs how much of cpu bandwidth | 179 | * shares assigned to a task group governs how much of cpu bandwidth |
183 | * is allocated to the group. The more shares a group has, the more is | 180 | * is allocated to the group. The more shares a group has, the more is |
@@ -213,33 +210,46 @@ struct task_group { | |||
213 | * | 210 | * |
214 | */ | 211 | */ |
215 | unsigned long shares; | 212 | unsigned long shares; |
213 | #endif | ||
214 | |||
215 | #ifdef CONFIG_RT_GROUP_SCHED | ||
216 | struct sched_rt_entity **rt_se; | ||
217 | struct rt_rq **rt_rq; | ||
218 | |||
219 | u64 rt_runtime; | ||
220 | #endif | ||
216 | 221 | ||
217 | struct rcu_head rcu; | 222 | struct rcu_head rcu; |
218 | struct list_head list; | 223 | struct list_head list; |
219 | }; | 224 | }; |
220 | 225 | ||
226 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
221 | /* Default task group's sched entity on each cpu */ | 227 | /* Default task group's sched entity on each cpu */ |
222 | static DEFINE_PER_CPU(struct sched_entity, init_sched_entity); | 228 | static DEFINE_PER_CPU(struct sched_entity, init_sched_entity); |
223 | /* Default task group's cfs_rq on each cpu */ | 229 | /* Default task group's cfs_rq on each cpu */ |
224 | static DEFINE_PER_CPU(struct cfs_rq, init_cfs_rq) ____cacheline_aligned_in_smp; | 230 | static DEFINE_PER_CPU(struct cfs_rq, init_cfs_rq) ____cacheline_aligned_in_smp; |
225 | 231 | ||
226 | static DEFINE_PER_CPU(struct sched_rt_entity, init_sched_rt_entity); | ||
227 | static DEFINE_PER_CPU(struct rt_rq, init_rt_rq) ____cacheline_aligned_in_smp; | ||
228 | |||
229 | static struct sched_entity *init_sched_entity_p[NR_CPUS]; | 232 | static struct sched_entity *init_sched_entity_p[NR_CPUS]; |
230 | static struct cfs_rq *init_cfs_rq_p[NR_CPUS]; | 233 | static struct cfs_rq *init_cfs_rq_p[NR_CPUS]; |
234 | #endif | ||
235 | |||
236 | #ifdef CONFIG_RT_GROUP_SCHED | ||
237 | static DEFINE_PER_CPU(struct sched_rt_entity, init_sched_rt_entity); | ||
238 | static DEFINE_PER_CPU(struct rt_rq, init_rt_rq) ____cacheline_aligned_in_smp; | ||
231 | 239 | ||
232 | static struct sched_rt_entity *init_sched_rt_entity_p[NR_CPUS]; | 240 | static struct sched_rt_entity *init_sched_rt_entity_p[NR_CPUS]; |
233 | static struct rt_rq *init_rt_rq_p[NR_CPUS]; | 241 | static struct rt_rq *init_rt_rq_p[NR_CPUS]; |
242 | #endif | ||
234 | 243 | ||
235 | /* task_group_mutex serializes add/remove of task groups and also changes to | 244 | /* task_group_lock serializes add/remove of task groups and also changes to |
236 | * a task group's cpu shares. | 245 | * a task group's cpu shares. |
237 | */ | 246 | */ |
238 | static DEFINE_MUTEX(task_group_mutex); | 247 | static DEFINE_SPINLOCK(task_group_lock); |
239 | 248 | ||
240 | /* doms_cur_mutex serializes access to doms_cur[] array */ | 249 | /* doms_cur_mutex serializes access to doms_cur[] array */ |
241 | static DEFINE_MUTEX(doms_cur_mutex); | 250 | static DEFINE_MUTEX(doms_cur_mutex); |
242 | 251 | ||
252 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
243 | #ifdef CONFIG_SMP | 253 | #ifdef CONFIG_SMP |
244 | /* kernel thread that runs rebalance_shares() periodically */ | 254 | /* kernel thread that runs rebalance_shares() periodically */ |
245 | static struct task_struct *lb_monitor_task; | 255 | static struct task_struct *lb_monitor_task; |
@@ -248,35 +258,40 @@ static int load_balance_monitor(void *unused); | |||
248 | 258 | ||
249 | static void set_se_shares(struct sched_entity *se, unsigned long shares); | 259 | static void set_se_shares(struct sched_entity *se, unsigned long shares); |
250 | 260 | ||
261 | #ifdef CONFIG_USER_SCHED | ||
262 | # define INIT_TASK_GROUP_LOAD (2*NICE_0_LOAD) | ||
263 | #else | ||
264 | # define INIT_TASK_GROUP_LOAD NICE_0_LOAD | ||
265 | #endif | ||
266 | |||
267 | #define MIN_GROUP_SHARES 2 | ||
268 | |||
269 | static int init_task_group_load = INIT_TASK_GROUP_LOAD; | ||
270 | #endif | ||
271 | |||
251 | /* Default task group. | 272 | /* Default task group. |
252 | * Every task in system belong to this group at bootup. | 273 | * Every task in system belong to this group at bootup. |
253 | */ | 274 | */ |
254 | struct task_group init_task_group = { | 275 | struct task_group init_task_group = { |
276 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
255 | .se = init_sched_entity_p, | 277 | .se = init_sched_entity_p, |
256 | .cfs_rq = init_cfs_rq_p, | 278 | .cfs_rq = init_cfs_rq_p, |
279 | #endif | ||
257 | 280 | ||
281 | #ifdef CONFIG_RT_GROUP_SCHED | ||
258 | .rt_se = init_sched_rt_entity_p, | 282 | .rt_se = init_sched_rt_entity_p, |
259 | .rt_rq = init_rt_rq_p, | 283 | .rt_rq = init_rt_rq_p, |
260 | }; | ||
261 | |||
262 | #ifdef CONFIG_FAIR_USER_SCHED | ||
263 | # define INIT_TASK_GROUP_LOAD (2*NICE_0_LOAD) | ||
264 | #else | ||
265 | # define INIT_TASK_GROUP_LOAD NICE_0_LOAD | ||
266 | #endif | 284 | #endif |
267 | 285 | }; | |
268 | #define MIN_GROUP_SHARES 2 | ||
269 | |||
270 | static int init_task_group_load = INIT_TASK_GROUP_LOAD; | ||
271 | 286 | ||
272 | /* return group to which a task belongs */ | 287 | /* return group to which a task belongs */ |
273 | static inline struct task_group *task_group(struct task_struct *p) | 288 | static inline struct task_group *task_group(struct task_struct *p) |
274 | { | 289 | { |
275 | struct task_group *tg; | 290 | struct task_group *tg; |
276 | 291 | ||
277 | #ifdef CONFIG_FAIR_USER_SCHED | 292 | #ifdef CONFIG_USER_SCHED |
278 | tg = p->user->tg; | 293 | tg = p->user->tg; |
279 | #elif defined(CONFIG_FAIR_CGROUP_SCHED) | 294 | #elif defined(CONFIG_CGROUP_SCHED) |
280 | tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id), | 295 | tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id), |
281 | struct task_group, css); | 296 | struct task_group, css); |
282 | #else | 297 | #else |
@@ -288,21 +303,15 @@ static inline struct task_group *task_group(struct task_struct *p) | |||
288 | /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */ | 303 | /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */ |
289 | static inline void set_task_rq(struct task_struct *p, unsigned int cpu) | 304 | static inline void set_task_rq(struct task_struct *p, unsigned int cpu) |
290 | { | 305 | { |
306 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
291 | p->se.cfs_rq = task_group(p)->cfs_rq[cpu]; | 307 | p->se.cfs_rq = task_group(p)->cfs_rq[cpu]; |
292 | p->se.parent = task_group(p)->se[cpu]; | 308 | p->se.parent = task_group(p)->se[cpu]; |
309 | #endif | ||
293 | 310 | ||
311 | #ifdef CONFIG_RT_GROUP_SCHED | ||
294 | p->rt.rt_rq = task_group(p)->rt_rq[cpu]; | 312 | p->rt.rt_rq = task_group(p)->rt_rq[cpu]; |
295 | p->rt.parent = task_group(p)->rt_se[cpu]; | 313 | p->rt.parent = task_group(p)->rt_se[cpu]; |
296 | } | 314 | #endif |
297 | |||
298 | static inline void lock_task_group_list(void) | ||
299 | { | ||
300 | mutex_lock(&task_group_mutex); | ||
301 | } | ||
302 | |||
303 | static inline void unlock_task_group_list(void) | ||
304 | { | ||
305 | mutex_unlock(&task_group_mutex); | ||
306 | } | 315 | } |
307 | 316 | ||
308 | static inline void lock_doms_cur(void) | 317 | static inline void lock_doms_cur(void) |
@@ -318,12 +327,10 @@ static inline void unlock_doms_cur(void) | |||
318 | #else | 327 | #else |
319 | 328 | ||
320 | static inline void set_task_rq(struct task_struct *p, unsigned int cpu) { } | 329 | static inline void set_task_rq(struct task_struct *p, unsigned int cpu) { } |
321 | static inline void lock_task_group_list(void) { } | ||
322 | static inline void unlock_task_group_list(void) { } | ||
323 | static inline void lock_doms_cur(void) { } | 330 | static inline void lock_doms_cur(void) { } |
324 | static inline void unlock_doms_cur(void) { } | 331 | static inline void unlock_doms_cur(void) { } |
325 | 332 | ||
326 | #endif /* CONFIG_FAIR_GROUP_SCHED */ | 333 | #endif /* CONFIG_GROUP_SCHED */ |
327 | 334 | ||
328 | /* CFS-related fields in a runqueue */ | 335 | /* CFS-related fields in a runqueue */ |
329 | struct cfs_rq { | 336 | struct cfs_rq { |
@@ -363,7 +370,7 @@ struct cfs_rq { | |||
363 | struct rt_rq { | 370 | struct rt_rq { |
364 | struct rt_prio_array active; | 371 | struct rt_prio_array active; |
365 | unsigned long rt_nr_running; | 372 | unsigned long rt_nr_running; |
366 | #if defined CONFIG_SMP || defined CONFIG_FAIR_GROUP_SCHED | 373 | #if defined CONFIG_SMP || defined CONFIG_RT_GROUP_SCHED |
367 | int highest_prio; /* highest queued rt task prio */ | 374 | int highest_prio; /* highest queued rt task prio */ |
368 | #endif | 375 | #endif |
369 | #ifdef CONFIG_SMP | 376 | #ifdef CONFIG_SMP |
@@ -373,7 +380,9 @@ struct rt_rq { | |||
373 | int rt_throttled; | 380 | int rt_throttled; |
374 | u64 rt_time; | 381 | u64 rt_time; |
375 | 382 | ||
376 | #ifdef CONFIG_FAIR_GROUP_SCHED | 383 | #ifdef CONFIG_RT_GROUP_SCHED |
384 | unsigned long rt_nr_boosted; | ||
385 | |||
377 | struct rq *rq; | 386 | struct rq *rq; |
378 | struct list_head leaf_rt_rq_list; | 387 | struct list_head leaf_rt_rq_list; |
379 | struct task_group *tg; | 388 | struct task_group *tg; |
@@ -447,6 +456,8 @@ struct rq { | |||
447 | #ifdef CONFIG_FAIR_GROUP_SCHED | 456 | #ifdef CONFIG_FAIR_GROUP_SCHED |
448 | /* list of leaf cfs_rq on this cpu: */ | 457 | /* list of leaf cfs_rq on this cpu: */ |
449 | struct list_head leaf_cfs_rq_list; | 458 | struct list_head leaf_cfs_rq_list; |
459 | #endif | ||
460 | #ifdef CONFIG_RT_GROUP_SCHED | ||
450 | struct list_head leaf_rt_rq_list; | 461 | struct list_head leaf_rt_rq_list; |
451 | #endif | 462 | #endif |
452 | 463 | ||
@@ -652,19 +663,21 @@ const_debug unsigned int sysctl_sched_features = | |||
652 | const_debug unsigned int sysctl_sched_nr_migrate = 32; | 663 | const_debug unsigned int sysctl_sched_nr_migrate = 32; |
653 | 664 | ||
654 | /* | 665 | /* |
655 | * period over which we measure -rt task cpu usage in ms. | 666 | * period over which we measure -rt task cpu usage in us. |
656 | * default: 1s | 667 | * default: 1s |
657 | */ | 668 | */ |
658 | const_debug unsigned int sysctl_sched_rt_period = 1000; | 669 | unsigned int sysctl_sched_rt_period = 1000000; |
659 | 670 | ||
660 | #define SCHED_RT_FRAC_SHIFT 16 | 671 | /* |
661 | #define SCHED_RT_FRAC (1UL << SCHED_RT_FRAC_SHIFT) | 672 | * part of the period that we allow rt tasks to run in us. |
673 | * default: 0.95s | ||
674 | */ | ||
675 | int sysctl_sched_rt_runtime = 950000; | ||
662 | 676 | ||
663 | /* | 677 | /* |
664 | * ratio of time -rt tasks may consume. | 678 | * single value that denotes runtime == period, ie unlimited time. |
665 | * default: 95% | ||
666 | */ | 679 | */ |
667 | const_debug unsigned int sysctl_sched_rt_ratio = 62259; | 680 | #define RUNTIME_INF ((u64)~0ULL) |
668 | 681 | ||
669 | /* | 682 | /* |
670 | * For kernel-internal use: high-speed (but slightly incorrect) per-cpu | 683 | * For kernel-internal use: high-speed (but slightly incorrect) per-cpu |
@@ -4571,6 +4584,15 @@ recheck: | |||
4571 | return -EPERM; | 4584 | return -EPERM; |
4572 | } | 4585 | } |
4573 | 4586 | ||
4587 | #ifdef CONFIG_RT_GROUP_SCHED | ||
4588 | /* | ||
4589 | * Do not allow realtime tasks into groups that have no runtime | ||
4590 | * assigned. | ||
4591 | */ | ||
4592 | if (rt_policy(policy) && task_group(p)->rt_runtime == 0) | ||
4593 | return -EPERM; | ||
4594 | #endif | ||
4595 | |||
4574 | retval = security_task_setscheduler(p, policy, param); | 4596 | retval = security_task_setscheduler(p, policy, param); |
4575 | if (retval) | 4597 | if (retval) |
4576 | return retval; | 4598 | return retval; |
@@ -7112,7 +7134,7 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq) | |||
7112 | /* delimiter for bitsearch: */ | 7134 | /* delimiter for bitsearch: */ |
7113 | __set_bit(MAX_RT_PRIO, array->bitmap); | 7135 | __set_bit(MAX_RT_PRIO, array->bitmap); |
7114 | 7136 | ||
7115 | #if defined CONFIG_SMP || defined CONFIG_FAIR_GROUP_SCHED | 7137 | #if defined CONFIG_SMP || defined CONFIG_RT_GROUP_SCHED |
7116 | rt_rq->highest_prio = MAX_RT_PRIO; | 7138 | rt_rq->highest_prio = MAX_RT_PRIO; |
7117 | #endif | 7139 | #endif |
7118 | #ifdef CONFIG_SMP | 7140 | #ifdef CONFIG_SMP |
@@ -7123,7 +7145,8 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq) | |||
7123 | rt_rq->rt_time = 0; | 7145 | rt_rq->rt_time = 0; |
7124 | rt_rq->rt_throttled = 0; | 7146 | rt_rq->rt_throttled = 0; |
7125 | 7147 | ||
7126 | #ifdef CONFIG_FAIR_GROUP_SCHED | 7148 | #ifdef CONFIG_RT_GROUP_SCHED |
7149 | rt_rq->rt_nr_boosted = 0; | ||
7127 | rt_rq->rq = rq; | 7150 | rt_rq->rq = rq; |
7128 | #endif | 7151 | #endif |
7129 | } | 7152 | } |
@@ -7146,7 +7169,9 @@ static void init_tg_cfs_entry(struct rq *rq, struct task_group *tg, | |||
7146 | se->load.inv_weight = div64_64(1ULL<<32, se->load.weight); | 7169 | se->load.inv_weight = div64_64(1ULL<<32, se->load.weight); |
7147 | se->parent = NULL; | 7170 | se->parent = NULL; |
7148 | } | 7171 | } |
7172 | #endif | ||
7149 | 7173 | ||
7174 | #ifdef CONFIG_RT_GROUP_SCHED | ||
7150 | static void init_tg_rt_entry(struct rq *rq, struct task_group *tg, | 7175 | static void init_tg_rt_entry(struct rq *rq, struct task_group *tg, |
7151 | struct rt_rq *rt_rq, struct sched_rt_entity *rt_se, | 7176 | struct rt_rq *rt_rq, struct sched_rt_entity *rt_se, |
7152 | int cpu, int add) | 7177 | int cpu, int add) |
@@ -7175,7 +7200,7 @@ void __init sched_init(void) | |||
7175 | init_defrootdomain(); | 7200 | init_defrootdomain(); |
7176 | #endif | 7201 | #endif |
7177 | 7202 | ||
7178 | #ifdef CONFIG_FAIR_GROUP_SCHED | 7203 | #ifdef CONFIG_GROUP_SCHED |
7179 | list_add(&init_task_group.list, &task_groups); | 7204 | list_add(&init_task_group.list, &task_groups); |
7180 | #endif | 7205 | #endif |
7181 | 7206 | ||
@@ -7196,7 +7221,10 @@ void __init sched_init(void) | |||
7196 | &per_cpu(init_cfs_rq, i), | 7221 | &per_cpu(init_cfs_rq, i), |
7197 | &per_cpu(init_sched_entity, i), i, 1); | 7222 | &per_cpu(init_sched_entity, i), i, 1); |
7198 | 7223 | ||
7199 | init_task_group.rt_ratio = sysctl_sched_rt_ratio; /* XXX */ | 7224 | #endif |
7225 | #ifdef CONFIG_RT_GROUP_SCHED | ||
7226 | init_task_group.rt_runtime = | ||
7227 | sysctl_sched_rt_runtime * NSEC_PER_USEC; | ||
7200 | INIT_LIST_HEAD(&rq->leaf_rt_rq_list); | 7228 | INIT_LIST_HEAD(&rq->leaf_rt_rq_list); |
7201 | init_tg_rt_entry(rq, &init_task_group, | 7229 | init_tg_rt_entry(rq, &init_task_group, |
7202 | &per_cpu(init_rt_rq, i), | 7230 | &per_cpu(init_rt_rq, i), |
@@ -7303,7 +7331,7 @@ void normalize_rt_tasks(void) | |||
7303 | unsigned long flags; | 7331 | unsigned long flags; |
7304 | struct rq *rq; | 7332 | struct rq *rq; |
7305 | 7333 | ||
7306 | read_lock_irq(&tasklist_lock); | 7334 | read_lock_irqsave(&tasklist_lock, flags); |
7307 | do_each_thread(g, p) { | 7335 | do_each_thread(g, p) { |
7308 | /* | 7336 | /* |
7309 | * Only normalize user tasks: | 7337 | * Only normalize user tasks: |
@@ -7329,16 +7357,16 @@ void normalize_rt_tasks(void) | |||
7329 | continue; | 7357 | continue; |
7330 | } | 7358 | } |
7331 | 7359 | ||
7332 | spin_lock_irqsave(&p->pi_lock, flags); | 7360 | spin_lock(&p->pi_lock); |
7333 | rq = __task_rq_lock(p); | 7361 | rq = __task_rq_lock(p); |
7334 | 7362 | ||
7335 | normalize_task(rq, p); | 7363 | normalize_task(rq, p); |
7336 | 7364 | ||
7337 | __task_rq_unlock(rq); | 7365 | __task_rq_unlock(rq); |
7338 | spin_unlock_irqrestore(&p->pi_lock, flags); | 7366 | spin_unlock(&p->pi_lock); |
7339 | } while_each_thread(g, p); | 7367 | } while_each_thread(g, p); |
7340 | 7368 | ||
7341 | read_unlock_irq(&tasklist_lock); | 7369 | read_unlock_irqrestore(&tasklist_lock, flags); |
7342 | } | 7370 | } |
7343 | 7371 | ||
7344 | #endif /* CONFIG_MAGIC_SYSRQ */ | 7372 | #endif /* CONFIG_MAGIC_SYSRQ */ |
@@ -7387,9 +7415,9 @@ void set_curr_task(int cpu, struct task_struct *p) | |||
7387 | 7415 | ||
7388 | #endif | 7416 | #endif |
7389 | 7417 | ||
7390 | #ifdef CONFIG_FAIR_GROUP_SCHED | 7418 | #ifdef CONFIG_GROUP_SCHED |
7391 | 7419 | ||
7392 | #ifdef CONFIG_SMP | 7420 | #if defined CONFIG_FAIR_GROUP_SCHED && defined CONFIG_SMP |
7393 | /* | 7421 | /* |
7394 | * distribute shares of all task groups among their schedulable entities, | 7422 | * distribute shares of all task groups among their schedulable entities, |
7395 | * to reflect load distribution across cpus. | 7423 | * to reflect load distribution across cpus. |
@@ -7540,7 +7568,8 @@ static int load_balance_monitor(void *unused) | |||
7540 | } | 7568 | } |
7541 | #endif /* CONFIG_SMP */ | 7569 | #endif /* CONFIG_SMP */ |
7542 | 7570 | ||
7543 | static void free_sched_group(struct task_group *tg) | 7571 | #ifdef CONFIG_FAIR_GROUP_SCHED |
7572 | static void free_fair_sched_group(struct task_group *tg) | ||
7544 | { | 7573 | { |
7545 | int i; | 7574 | int i; |
7546 | 7575 | ||
@@ -7549,49 +7578,27 @@ static void free_sched_group(struct task_group *tg) | |||
7549 | kfree(tg->cfs_rq[i]); | 7578 | kfree(tg->cfs_rq[i]); |
7550 | if (tg->se) | 7579 | if (tg->se) |
7551 | kfree(tg->se[i]); | 7580 | kfree(tg->se[i]); |
7552 | if (tg->rt_rq) | ||
7553 | kfree(tg->rt_rq[i]); | ||
7554 | if (tg->rt_se) | ||
7555 | kfree(tg->rt_se[i]); | ||
7556 | } | 7581 | } |
7557 | 7582 | ||
7558 | kfree(tg->cfs_rq); | 7583 | kfree(tg->cfs_rq); |
7559 | kfree(tg->se); | 7584 | kfree(tg->se); |
7560 | kfree(tg->rt_rq); | ||
7561 | kfree(tg->rt_se); | ||
7562 | kfree(tg); | ||
7563 | } | 7585 | } |
7564 | 7586 | ||
7565 | /* allocate runqueue etc for a new task group */ | 7587 | static int alloc_fair_sched_group(struct task_group *tg) |
7566 | struct task_group *sched_create_group(void) | ||
7567 | { | 7588 | { |
7568 | struct task_group *tg; | ||
7569 | struct cfs_rq *cfs_rq; | 7589 | struct cfs_rq *cfs_rq; |
7570 | struct sched_entity *se; | 7590 | struct sched_entity *se; |
7571 | struct rt_rq *rt_rq; | ||
7572 | struct sched_rt_entity *rt_se; | ||
7573 | struct rq *rq; | 7591 | struct rq *rq; |
7574 | int i; | 7592 | int i; |
7575 | 7593 | ||
7576 | tg = kzalloc(sizeof(*tg), GFP_KERNEL); | ||
7577 | if (!tg) | ||
7578 | return ERR_PTR(-ENOMEM); | ||
7579 | |||
7580 | tg->cfs_rq = kzalloc(sizeof(cfs_rq) * NR_CPUS, GFP_KERNEL); | 7594 | tg->cfs_rq = kzalloc(sizeof(cfs_rq) * NR_CPUS, GFP_KERNEL); |
7581 | if (!tg->cfs_rq) | 7595 | if (!tg->cfs_rq) |
7582 | goto err; | 7596 | goto err; |
7583 | tg->se = kzalloc(sizeof(se) * NR_CPUS, GFP_KERNEL); | 7597 | tg->se = kzalloc(sizeof(se) * NR_CPUS, GFP_KERNEL); |
7584 | if (!tg->se) | 7598 | if (!tg->se) |
7585 | goto err; | 7599 | goto err; |
7586 | tg->rt_rq = kzalloc(sizeof(rt_rq) * NR_CPUS, GFP_KERNEL); | ||
7587 | if (!tg->rt_rq) | ||
7588 | goto err; | ||
7589 | tg->rt_se = kzalloc(sizeof(rt_se) * NR_CPUS, GFP_KERNEL); | ||
7590 | if (!tg->rt_se) | ||
7591 | goto err; | ||
7592 | 7600 | ||
7593 | tg->shares = NICE_0_LOAD; | 7601 | tg->shares = NICE_0_LOAD; |
7594 | tg->rt_ratio = 0; /* XXX */ | ||
7595 | 7602 | ||
7596 | for_each_possible_cpu(i) { | 7603 | for_each_possible_cpu(i) { |
7597 | rq = cpu_rq(i); | 7604 | rq = cpu_rq(i); |
@@ -7606,6 +7613,79 @@ struct task_group *sched_create_group(void) | |||
7606 | if (!se) | 7613 | if (!se) |
7607 | goto err; | 7614 | goto err; |
7608 | 7615 | ||
7616 | init_tg_cfs_entry(rq, tg, cfs_rq, se, i, 0); | ||
7617 | } | ||
7618 | |||
7619 | return 1; | ||
7620 | |||
7621 | err: | ||
7622 | return 0; | ||
7623 | } | ||
7624 | |||
7625 | static inline void register_fair_sched_group(struct task_group *tg, int cpu) | ||
7626 | { | ||
7627 | list_add_rcu(&tg->cfs_rq[cpu]->leaf_cfs_rq_list, | ||
7628 | &cpu_rq(cpu)->leaf_cfs_rq_list); | ||
7629 | } | ||
7630 | |||
7631 | static inline void unregister_fair_sched_group(struct task_group *tg, int cpu) | ||
7632 | { | ||
7633 | list_del_rcu(&tg->cfs_rq[cpu]->leaf_cfs_rq_list); | ||
7634 | } | ||
7635 | #else | ||
7636 | static inline void free_fair_sched_group(struct task_group *tg) | ||
7637 | { | ||
7638 | } | ||
7639 | |||
7640 | static inline int alloc_fair_sched_group(struct task_group *tg) | ||
7641 | { | ||
7642 | return 1; | ||
7643 | } | ||
7644 | |||
7645 | static inline void register_fair_sched_group(struct task_group *tg, int cpu) | ||
7646 | { | ||
7647 | } | ||
7648 | |||
7649 | static inline void unregister_fair_sched_group(struct task_group *tg, int cpu) | ||
7650 | { | ||
7651 | } | ||
7652 | #endif | ||
7653 | |||
7654 | #ifdef CONFIG_RT_GROUP_SCHED | ||
7655 | static void free_rt_sched_group(struct task_group *tg) | ||
7656 | { | ||
7657 | int i; | ||
7658 | |||
7659 | for_each_possible_cpu(i) { | ||
7660 | if (tg->rt_rq) | ||
7661 | kfree(tg->rt_rq[i]); | ||
7662 | if (tg->rt_se) | ||
7663 | kfree(tg->rt_se[i]); | ||
7664 | } | ||
7665 | |||
7666 | kfree(tg->rt_rq); | ||
7667 | kfree(tg->rt_se); | ||
7668 | } | ||
7669 | |||
7670 | static int alloc_rt_sched_group(struct task_group *tg) | ||
7671 | { | ||
7672 | struct rt_rq *rt_rq; | ||
7673 | struct sched_rt_entity *rt_se; | ||
7674 | struct rq *rq; | ||
7675 | int i; | ||
7676 | |||
7677 | tg->rt_rq = kzalloc(sizeof(rt_rq) * NR_CPUS, GFP_KERNEL); | ||
7678 | if (!tg->rt_rq) | ||
7679 | goto err; | ||
7680 | tg->rt_se = kzalloc(sizeof(rt_se) * NR_CPUS, GFP_KERNEL); | ||
7681 | if (!tg->rt_se) | ||
7682 | goto err; | ||
7683 | |||
7684 | tg->rt_runtime = 0; | ||
7685 | |||
7686 | for_each_possible_cpu(i) { | ||
7687 | rq = cpu_rq(i); | ||
7688 | |||
7609 | rt_rq = kmalloc_node(sizeof(struct rt_rq), | 7689 | rt_rq = kmalloc_node(sizeof(struct rt_rq), |
7610 | GFP_KERNEL|__GFP_ZERO, cpu_to_node(i)); | 7690 | GFP_KERNEL|__GFP_ZERO, cpu_to_node(i)); |
7611 | if (!rt_rq) | 7691 | if (!rt_rq) |
@@ -7616,20 +7696,75 @@ struct task_group *sched_create_group(void) | |||
7616 | if (!rt_se) | 7696 | if (!rt_se) |
7617 | goto err; | 7697 | goto err; |
7618 | 7698 | ||
7619 | init_tg_cfs_entry(rq, tg, cfs_rq, se, i, 0); | ||
7620 | init_tg_rt_entry(rq, tg, rt_rq, rt_se, i, 0); | 7699 | init_tg_rt_entry(rq, tg, rt_rq, rt_se, i, 0); |
7621 | } | 7700 | } |
7622 | 7701 | ||
7623 | lock_task_group_list(); | 7702 | return 1; |
7703 | |||
7704 | err: | ||
7705 | return 0; | ||
7706 | } | ||
7707 | |||
7708 | static inline void register_rt_sched_group(struct task_group *tg, int cpu) | ||
7709 | { | ||
7710 | list_add_rcu(&tg->rt_rq[cpu]->leaf_rt_rq_list, | ||
7711 | &cpu_rq(cpu)->leaf_rt_rq_list); | ||
7712 | } | ||
7713 | |||
7714 | static inline void unregister_rt_sched_group(struct task_group *tg, int cpu) | ||
7715 | { | ||
7716 | list_del_rcu(&tg->rt_rq[cpu]->leaf_rt_rq_list); | ||
7717 | } | ||
7718 | #else | ||
7719 | static inline void free_rt_sched_group(struct task_group *tg) | ||
7720 | { | ||
7721 | } | ||
7722 | |||
7723 | static inline int alloc_rt_sched_group(struct task_group *tg) | ||
7724 | { | ||
7725 | return 1; | ||
7726 | } | ||
7727 | |||
7728 | static inline void register_rt_sched_group(struct task_group *tg, int cpu) | ||
7729 | { | ||
7730 | } | ||
7731 | |||
7732 | static inline void unregister_rt_sched_group(struct task_group *tg, int cpu) | ||
7733 | { | ||
7734 | } | ||
7735 | #endif | ||
7736 | |||
7737 | static void free_sched_group(struct task_group *tg) | ||
7738 | { | ||
7739 | free_fair_sched_group(tg); | ||
7740 | free_rt_sched_group(tg); | ||
7741 | kfree(tg); | ||
7742 | } | ||
7743 | |||
7744 | /* allocate runqueue etc for a new task group */ | ||
7745 | struct task_group *sched_create_group(void) | ||
7746 | { | ||
7747 | struct task_group *tg; | ||
7748 | unsigned long flags; | ||
7749 | int i; | ||
7750 | |||
7751 | tg = kzalloc(sizeof(*tg), GFP_KERNEL); | ||
7752 | if (!tg) | ||
7753 | return ERR_PTR(-ENOMEM); | ||
7754 | |||
7755 | if (!alloc_fair_sched_group(tg)) | ||
7756 | goto err; | ||
7757 | |||
7758 | if (!alloc_rt_sched_group(tg)) | ||
7759 | goto err; | ||
7760 | |||
7761 | spin_lock_irqsave(&task_group_lock, flags); | ||
7624 | for_each_possible_cpu(i) { | 7762 | for_each_possible_cpu(i) { |
7625 | rq = cpu_rq(i); | 7763 | register_fair_sched_group(tg, i); |
7626 | cfs_rq = tg->cfs_rq[i]; | 7764 | register_rt_sched_group(tg, i); |
7627 | list_add_rcu(&cfs_rq->leaf_cfs_rq_list, &rq->leaf_cfs_rq_list); | ||
7628 | rt_rq = tg->rt_rq[i]; | ||
7629 | list_add_rcu(&rt_rq->leaf_rt_rq_list, &rq->leaf_rt_rq_list); | ||
7630 | } | 7765 | } |
7631 | list_add_rcu(&tg->list, &task_groups); | 7766 | list_add_rcu(&tg->list, &task_groups); |
7632 | unlock_task_group_list(); | 7767 | spin_unlock_irqrestore(&task_group_lock, flags); |
7633 | 7768 | ||
7634 | return tg; | 7769 | return tg; |
7635 | 7770 | ||
@@ -7648,21 +7783,16 @@ static void free_sched_group_rcu(struct rcu_head *rhp) | |||
7648 | /* Destroy runqueue etc associated with a task group */ | 7783 | /* Destroy runqueue etc associated with a task group */ |
7649 | void sched_destroy_group(struct task_group *tg) | 7784 | void sched_destroy_group(struct task_group *tg) |
7650 | { | 7785 | { |
7651 | struct cfs_rq *cfs_rq = NULL; | 7786 | unsigned long flags; |
7652 | struct rt_rq *rt_rq = NULL; | ||
7653 | int i; | 7787 | int i; |
7654 | 7788 | ||
7655 | lock_task_group_list(); | 7789 | spin_lock_irqsave(&task_group_lock, flags); |
7656 | for_each_possible_cpu(i) { | 7790 | for_each_possible_cpu(i) { |
7657 | cfs_rq = tg->cfs_rq[i]; | 7791 | unregister_fair_sched_group(tg, i); |
7658 | list_del_rcu(&cfs_rq->leaf_cfs_rq_list); | 7792 | unregister_rt_sched_group(tg, i); |
7659 | rt_rq = tg->rt_rq[i]; | ||
7660 | list_del_rcu(&rt_rq->leaf_rt_rq_list); | ||
7661 | } | 7793 | } |
7662 | list_del_rcu(&tg->list); | 7794 | list_del_rcu(&tg->list); |
7663 | unlock_task_group_list(); | 7795 | spin_unlock_irqrestore(&task_group_lock, flags); |
7664 | |||
7665 | BUG_ON(!cfs_rq); | ||
7666 | 7796 | ||
7667 | /* wait for possible concurrent references to cfs_rqs complete */ | 7797 | /* wait for possible concurrent references to cfs_rqs complete */ |
7668 | call_rcu(&tg->rcu, free_sched_group_rcu); | 7798 | call_rcu(&tg->rcu, free_sched_group_rcu); |
@@ -7703,6 +7833,7 @@ void sched_move_task(struct task_struct *tsk) | |||
7703 | task_rq_unlock(rq, &flags); | 7833 | task_rq_unlock(rq, &flags); |
7704 | } | 7834 | } |
7705 | 7835 | ||
7836 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
7706 | /* rq->lock to be locked by caller */ | 7837 | /* rq->lock to be locked by caller */ |
7707 | static void set_se_shares(struct sched_entity *se, unsigned long shares) | 7838 | static void set_se_shares(struct sched_entity *se, unsigned long shares) |
7708 | { | 7839 | { |
@@ -7728,13 +7859,14 @@ static void set_se_shares(struct sched_entity *se, unsigned long shares) | |||
7728 | } | 7859 | } |
7729 | } | 7860 | } |
7730 | 7861 | ||
7862 | static DEFINE_MUTEX(shares_mutex); | ||
7863 | |||
7731 | int sched_group_set_shares(struct task_group *tg, unsigned long shares) | 7864 | int sched_group_set_shares(struct task_group *tg, unsigned long shares) |
7732 | { | 7865 | { |
7733 | int i; | 7866 | int i; |
7734 | struct cfs_rq *cfs_rq; | 7867 | unsigned long flags; |
7735 | struct rq *rq; | ||
7736 | 7868 | ||
7737 | lock_task_group_list(); | 7869 | mutex_lock(&shares_mutex); |
7738 | if (tg->shares == shares) | 7870 | if (tg->shares == shares) |
7739 | goto done; | 7871 | goto done; |
7740 | 7872 | ||
@@ -7746,10 +7878,10 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares) | |||
7746 | * load_balance_fair) from referring to this group first, | 7878 | * load_balance_fair) from referring to this group first, |
7747 | * by taking it off the rq->leaf_cfs_rq_list on each cpu. | 7879 | * by taking it off the rq->leaf_cfs_rq_list on each cpu. |
7748 | */ | 7880 | */ |
7749 | for_each_possible_cpu(i) { | 7881 | spin_lock_irqsave(&task_group_lock, flags); |
7750 | cfs_rq = tg->cfs_rq[i]; | 7882 | for_each_possible_cpu(i) |
7751 | list_del_rcu(&cfs_rq->leaf_cfs_rq_list); | 7883 | unregister_fair_sched_group(tg, i); |
7752 | } | 7884 | spin_unlock_irqrestore(&task_group_lock, flags); |
7753 | 7885 | ||
7754 | /* wait for any ongoing reference to this group to finish */ | 7886 | /* wait for any ongoing reference to this group to finish */ |
7755 | synchronize_sched(); | 7887 | synchronize_sched(); |
@@ -7769,13 +7901,12 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares) | |||
7769 | * Enable load balance activity on this group, by inserting it back on | 7901 | * Enable load balance activity on this group, by inserting it back on |
7770 | * each cpu's rq->leaf_cfs_rq_list. | 7902 | * each cpu's rq->leaf_cfs_rq_list. |
7771 | */ | 7903 | */ |
7772 | for_each_possible_cpu(i) { | 7904 | spin_lock_irqsave(&task_group_lock, flags); |
7773 | rq = cpu_rq(i); | 7905 | for_each_possible_cpu(i) |
7774 | cfs_rq = tg->cfs_rq[i]; | 7906 | register_fair_sched_group(tg, i); |
7775 | list_add_rcu(&cfs_rq->leaf_cfs_rq_list, &rq->leaf_cfs_rq_list); | 7907 | spin_unlock_irqrestore(&task_group_lock, flags); |
7776 | } | ||
7777 | done: | 7908 | done: |
7778 | unlock_task_group_list(); | 7909 | mutex_unlock(&shares_mutex); |
7779 | return 0; | 7910 | return 0; |
7780 | } | 7911 | } |
7781 | 7912 | ||
@@ -7783,35 +7914,84 @@ unsigned long sched_group_shares(struct task_group *tg) | |||
7783 | { | 7914 | { |
7784 | return tg->shares; | 7915 | return tg->shares; |
7785 | } | 7916 | } |
7917 | #endif | ||
7786 | 7918 | ||
7919 | #ifdef CONFIG_RT_GROUP_SCHED | ||
7787 | /* | 7920 | /* |
7788 | * Ensure the total rt_ratio <= sysctl_sched_rt_ratio | 7921 | * Ensure that the real time constraints are schedulable. |
7789 | */ | 7922 | */ |
7790 | int sched_group_set_rt_ratio(struct task_group *tg, unsigned long rt_ratio) | 7923 | static DEFINE_MUTEX(rt_constraints_mutex); |
7924 | |||
7925 | static unsigned long to_ratio(u64 period, u64 runtime) | ||
7926 | { | ||
7927 | if (runtime == RUNTIME_INF) | ||
7928 | return 1ULL << 16; | ||
7929 | |||
7930 | runtime *= (1ULL << 16); | ||
7931 | div64_64(runtime, period); | ||
7932 | return runtime; | ||
7933 | } | ||
7934 | |||
7935 | static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime) | ||
7791 | { | 7936 | { |
7792 | struct task_group *tgi; | 7937 | struct task_group *tgi; |
7793 | unsigned long total = 0; | 7938 | unsigned long total = 0; |
7939 | unsigned long global_ratio = | ||
7940 | to_ratio(sysctl_sched_rt_period, | ||
7941 | sysctl_sched_rt_runtime < 0 ? | ||
7942 | RUNTIME_INF : sysctl_sched_rt_runtime); | ||
7794 | 7943 | ||
7795 | rcu_read_lock(); | 7944 | rcu_read_lock(); |
7796 | list_for_each_entry_rcu(tgi, &task_groups, list) | 7945 | list_for_each_entry_rcu(tgi, &task_groups, list) { |
7797 | total += tgi->rt_ratio; | 7946 | if (tgi == tg) |
7798 | rcu_read_unlock(); | 7947 | continue; |
7799 | 7948 | ||
7800 | if (total + rt_ratio - tg->rt_ratio > sysctl_sched_rt_ratio) | 7949 | total += to_ratio(period, tgi->rt_runtime); |
7801 | return -EINVAL; | 7950 | } |
7951 | rcu_read_unlock(); | ||
7802 | 7952 | ||
7803 | tg->rt_ratio = rt_ratio; | 7953 | return total + to_ratio(period, runtime) < global_ratio; |
7804 | return 0; | ||
7805 | } | 7954 | } |
7806 | 7955 | ||
7807 | unsigned long sched_group_rt_ratio(struct task_group *tg) | 7956 | int sched_group_set_rt_runtime(struct task_group *tg, long rt_runtime_us) |
7808 | { | 7957 | { |
7809 | return tg->rt_ratio; | 7958 | u64 rt_runtime, rt_period; |
7959 | int err = 0; | ||
7960 | |||
7961 | rt_period = sysctl_sched_rt_period * NSEC_PER_USEC; | ||
7962 | rt_runtime = (u64)rt_runtime_us * NSEC_PER_USEC; | ||
7963 | if (rt_runtime_us == -1) | ||
7964 | rt_runtime = rt_period; | ||
7965 | |||
7966 | mutex_lock(&rt_constraints_mutex); | ||
7967 | if (!__rt_schedulable(tg, rt_period, rt_runtime)) { | ||
7968 | err = -EINVAL; | ||
7969 | goto unlock; | ||
7970 | } | ||
7971 | if (rt_runtime_us == -1) | ||
7972 | rt_runtime = RUNTIME_INF; | ||
7973 | tg->rt_runtime = rt_runtime; | ||
7974 | unlock: | ||
7975 | mutex_unlock(&rt_constraints_mutex); | ||
7976 | |||
7977 | return err; | ||
7810 | } | 7978 | } |
7811 | 7979 | ||
7812 | #endif /* CONFIG_FAIR_GROUP_SCHED */ | 7980 | long sched_group_rt_runtime(struct task_group *tg) |
7981 | { | ||
7982 | u64 rt_runtime_us; | ||
7983 | |||
7984 | if (tg->rt_runtime == RUNTIME_INF) | ||
7985 | return -1; | ||
7986 | |||
7987 | rt_runtime_us = tg->rt_runtime; | ||
7988 | do_div(rt_runtime_us, NSEC_PER_USEC); | ||
7989 | return rt_runtime_us; | ||
7990 | } | ||
7991 | #endif | ||
7992 | #endif /* CONFIG_GROUP_SCHED */ | ||
7813 | 7993 | ||
7814 | #ifdef CONFIG_FAIR_CGROUP_SCHED | 7994 | #ifdef CONFIG_CGROUP_SCHED |
7815 | 7995 | ||
7816 | /* return corresponding task_group object of a cgroup */ | 7996 | /* return corresponding task_group object of a cgroup */ |
7817 | static inline struct task_group *cgroup_tg(struct cgroup *cgrp) | 7997 | static inline struct task_group *cgroup_tg(struct cgroup *cgrp) |
@@ -7857,9 +8037,15 @@ static int | |||
7857 | cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, | 8037 | cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, |
7858 | struct task_struct *tsk) | 8038 | struct task_struct *tsk) |
7859 | { | 8039 | { |
8040 | #ifdef CONFIG_RT_GROUP_SCHED | ||
8041 | /* Don't accept realtime tasks when there is no way for them to run */ | ||
8042 | if (rt_task(tsk) && cgroup_tg(cgrp)->rt_runtime == 0) | ||
8043 | return -EINVAL; | ||
8044 | #else | ||
7860 | /* We don't support RT-tasks being in separate groups */ | 8045 | /* We don't support RT-tasks being in separate groups */ |
7861 | if (tsk->sched_class != &fair_sched_class) | 8046 | if (tsk->sched_class != &fair_sched_class) |
7862 | return -EINVAL; | 8047 | return -EINVAL; |
8048 | #endif | ||
7863 | 8049 | ||
7864 | return 0; | 8050 | return 0; |
7865 | } | 8051 | } |
@@ -7871,6 +8057,7 @@ cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, | |||
7871 | sched_move_task(tsk); | 8057 | sched_move_task(tsk); |
7872 | } | 8058 | } |
7873 | 8059 | ||
8060 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
7874 | static int cpu_shares_write_uint(struct cgroup *cgrp, struct cftype *cftype, | 8061 | static int cpu_shares_write_uint(struct cgroup *cgrp, struct cftype *cftype, |
7875 | u64 shareval) | 8062 | u64 shareval) |
7876 | { | 8063 | { |
@@ -7883,31 +8070,70 @@ static u64 cpu_shares_read_uint(struct cgroup *cgrp, struct cftype *cft) | |||
7883 | 8070 | ||
7884 | return (u64) tg->shares; | 8071 | return (u64) tg->shares; |
7885 | } | 8072 | } |
8073 | #endif | ||
7886 | 8074 | ||
7887 | static int cpu_rt_ratio_write_uint(struct cgroup *cgrp, struct cftype *cftype, | 8075 | #ifdef CONFIG_RT_GROUP_SCHED |
7888 | u64 rt_ratio_val) | 8076 | static int cpu_rt_runtime_write(struct cgroup *cgrp, struct cftype *cft, |
8077 | struct file *file, | ||
8078 | const char __user *userbuf, | ||
8079 | size_t nbytes, loff_t *unused_ppos) | ||
7889 | { | 8080 | { |
7890 | return sched_group_set_rt_ratio(cgroup_tg(cgrp), rt_ratio_val); | 8081 | char buffer[64]; |
8082 | int retval = 0; | ||
8083 | s64 val; | ||
8084 | char *end; | ||
8085 | |||
8086 | if (!nbytes) | ||
8087 | return -EINVAL; | ||
8088 | if (nbytes >= sizeof(buffer)) | ||
8089 | return -E2BIG; | ||
8090 | if (copy_from_user(buffer, userbuf, nbytes)) | ||
8091 | return -EFAULT; | ||
8092 | |||
8093 | buffer[nbytes] = 0; /* nul-terminate */ | ||
8094 | |||
8095 | /* strip newline if necessary */ | ||
8096 | if (nbytes && (buffer[nbytes-1] == '\n')) | ||
8097 | buffer[nbytes-1] = 0; | ||
8098 | val = simple_strtoll(buffer, &end, 0); | ||
8099 | if (*end) | ||
8100 | return -EINVAL; | ||
8101 | |||
8102 | /* Pass to subsystem */ | ||
8103 | retval = sched_group_set_rt_runtime(cgroup_tg(cgrp), val); | ||
8104 | if (!retval) | ||
8105 | retval = nbytes; | ||
8106 | return retval; | ||
7891 | } | 8107 | } |
7892 | 8108 | ||
7893 | static u64 cpu_rt_ratio_read_uint(struct cgroup *cgrp, struct cftype *cft) | 8109 | static ssize_t cpu_rt_runtime_read(struct cgroup *cgrp, struct cftype *cft, |
8110 | struct file *file, | ||
8111 | char __user *buf, size_t nbytes, | ||
8112 | loff_t *ppos) | ||
7894 | { | 8113 | { |
7895 | struct task_group *tg = cgroup_tg(cgrp); | 8114 | char tmp[64]; |
8115 | long val = sched_group_rt_runtime(cgroup_tg(cgrp)); | ||
8116 | int len = sprintf(tmp, "%ld\n", val); | ||
7896 | 8117 | ||
7897 | return (u64) tg->rt_ratio; | 8118 | return simple_read_from_buffer(buf, nbytes, ppos, tmp, len); |
7898 | } | 8119 | } |
8120 | #endif | ||
7899 | 8121 | ||
7900 | static struct cftype cpu_files[] = { | 8122 | static struct cftype cpu_files[] = { |
8123 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
7901 | { | 8124 | { |
7902 | .name = "shares", | 8125 | .name = "shares", |
7903 | .read_uint = cpu_shares_read_uint, | 8126 | .read_uint = cpu_shares_read_uint, |
7904 | .write_uint = cpu_shares_write_uint, | 8127 | .write_uint = cpu_shares_write_uint, |
7905 | }, | 8128 | }, |
8129 | #endif | ||
8130 | #ifdef CONFIG_RT_GROUP_SCHED | ||
7906 | { | 8131 | { |
7907 | .name = "rt_ratio", | 8132 | .name = "rt_runtime_us", |
7908 | .read_uint = cpu_rt_ratio_read_uint, | 8133 | .read = cpu_rt_runtime_read, |
7909 | .write_uint = cpu_rt_ratio_write_uint, | 8134 | .write = cpu_rt_runtime_write, |
7910 | }, | 8135 | }, |
8136 | #endif | ||
7911 | }; | 8137 | }; |
7912 | 8138 | ||
7913 | static int cpu_cgroup_populate(struct cgroup_subsys *ss, struct cgroup *cont) | 8139 | static int cpu_cgroup_populate(struct cgroup_subsys *ss, struct cgroup *cont) |
@@ -7926,7 +8152,7 @@ struct cgroup_subsys cpu_cgroup_subsys = { | |||
7926 | .early_init = 1, | 8152 | .early_init = 1, |
7927 | }; | 8153 | }; |
7928 | 8154 | ||
7929 | #endif /* CONFIG_FAIR_CGROUP_SCHED */ | 8155 | #endif /* CONFIG_CGROUP_SCHED */ |
7930 | 8156 | ||
7931 | #ifdef CONFIG_CGROUP_CPUACCT | 8157 | #ifdef CONFIG_CGROUP_CPUACCT |
7932 | 8158 | ||
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 274b40d7bef2..f54792b175b2 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c | |||
@@ -55,14 +55,14 @@ static inline int on_rt_rq(struct sched_rt_entity *rt_se) | |||
55 | return !list_empty(&rt_se->run_list); | 55 | return !list_empty(&rt_se->run_list); |
56 | } | 56 | } |
57 | 57 | ||
58 | #ifdef CONFIG_FAIR_GROUP_SCHED | 58 | #ifdef CONFIG_RT_GROUP_SCHED |
59 | 59 | ||
60 | static inline unsigned int sched_rt_ratio(struct rt_rq *rt_rq) | 60 | static inline u64 sched_rt_runtime(struct rt_rq *rt_rq) |
61 | { | 61 | { |
62 | if (!rt_rq->tg) | 62 | if (!rt_rq->tg) |
63 | return SCHED_RT_FRAC; | 63 | return RUNTIME_INF; |
64 | 64 | ||
65 | return rt_rq->tg->rt_ratio; | 65 | return rt_rq->tg->rt_runtime; |
66 | } | 66 | } |
67 | 67 | ||
68 | #define for_each_leaf_rt_rq(rt_rq, rq) \ | 68 | #define for_each_leaf_rt_rq(rt_rq, rq) \ |
@@ -89,7 +89,7 @@ static inline struct rt_rq *group_rt_rq(struct sched_rt_entity *rt_se) | |||
89 | static void enqueue_rt_entity(struct sched_rt_entity *rt_se); | 89 | static void enqueue_rt_entity(struct sched_rt_entity *rt_se); |
90 | static void dequeue_rt_entity(struct sched_rt_entity *rt_se); | 90 | static void dequeue_rt_entity(struct sched_rt_entity *rt_se); |
91 | 91 | ||
92 | static void sched_rt_ratio_enqueue(struct rt_rq *rt_rq) | 92 | static void sched_rt_rq_enqueue(struct rt_rq *rt_rq) |
93 | { | 93 | { |
94 | struct sched_rt_entity *rt_se = rt_rq->rt_se; | 94 | struct sched_rt_entity *rt_se = rt_rq->rt_se; |
95 | 95 | ||
@@ -102,7 +102,7 @@ static void sched_rt_ratio_enqueue(struct rt_rq *rt_rq) | |||
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | static void sched_rt_ratio_dequeue(struct rt_rq *rt_rq) | 105 | static void sched_rt_rq_dequeue(struct rt_rq *rt_rq) |
106 | { | 106 | { |
107 | struct sched_rt_entity *rt_se = rt_rq->rt_se; | 107 | struct sched_rt_entity *rt_se = rt_rq->rt_se; |
108 | 108 | ||
@@ -110,11 +110,31 @@ static void sched_rt_ratio_dequeue(struct rt_rq *rt_rq) | |||
110 | dequeue_rt_entity(rt_se); | 110 | dequeue_rt_entity(rt_se); |
111 | } | 111 | } |
112 | 112 | ||
113 | static inline int rt_rq_throttled(struct rt_rq *rt_rq) | ||
114 | { | ||
115 | return rt_rq->rt_throttled && !rt_rq->rt_nr_boosted; | ||
116 | } | ||
117 | |||
118 | static int rt_se_boosted(struct sched_rt_entity *rt_se) | ||
119 | { | ||
120 | struct rt_rq *rt_rq = group_rt_rq(rt_se); | ||
121 | struct task_struct *p; | ||
122 | |||
123 | if (rt_rq) | ||
124 | return !!rt_rq->rt_nr_boosted; | ||
125 | |||
126 | p = rt_task_of(rt_se); | ||
127 | return p->prio != p->normal_prio; | ||
128 | } | ||
129 | |||
113 | #else | 130 | #else |
114 | 131 | ||
115 | static inline unsigned int sched_rt_ratio(struct rt_rq *rt_rq) | 132 | static inline u64 sched_rt_runtime(struct rt_rq *rt_rq) |
116 | { | 133 | { |
117 | return sysctl_sched_rt_ratio; | 134 | if (sysctl_sched_rt_runtime == -1) |
135 | return RUNTIME_INF; | ||
136 | |||
137 | return (u64)sysctl_sched_rt_runtime * NSEC_PER_USEC; | ||
118 | } | 138 | } |
119 | 139 | ||
120 | #define for_each_leaf_rt_rq(rt_rq, rq) \ | 140 | #define for_each_leaf_rt_rq(rt_rq, rq) \ |
@@ -141,19 +161,23 @@ static inline struct rt_rq *group_rt_rq(struct sched_rt_entity *rt_se) | |||
141 | return NULL; | 161 | return NULL; |
142 | } | 162 | } |
143 | 163 | ||
144 | static inline void sched_rt_ratio_enqueue(struct rt_rq *rt_rq) | 164 | static inline void sched_rt_rq_enqueue(struct rt_rq *rt_rq) |
145 | { | 165 | { |
146 | } | 166 | } |
147 | 167 | ||
148 | static inline void sched_rt_ratio_dequeue(struct rt_rq *rt_rq) | 168 | static inline void sched_rt_rq_dequeue(struct rt_rq *rt_rq) |
149 | { | 169 | { |
150 | } | 170 | } |
151 | 171 | ||
172 | static inline int rt_rq_throttled(struct rt_rq *rt_rq) | ||
173 | { | ||
174 | return rt_rq->rt_throttled; | ||
175 | } | ||
152 | #endif | 176 | #endif |
153 | 177 | ||
154 | static inline int rt_se_prio(struct sched_rt_entity *rt_se) | 178 | static inline int rt_se_prio(struct sched_rt_entity *rt_se) |
155 | { | 179 | { |
156 | #ifdef CONFIG_FAIR_GROUP_SCHED | 180 | #ifdef CONFIG_RT_GROUP_SCHED |
157 | struct rt_rq *rt_rq = group_rt_rq(rt_se); | 181 | struct rt_rq *rt_rq = group_rt_rq(rt_se); |
158 | 182 | ||
159 | if (rt_rq) | 183 | if (rt_rq) |
@@ -163,28 +187,26 @@ static inline int rt_se_prio(struct sched_rt_entity *rt_se) | |||
163 | return rt_task_of(rt_se)->prio; | 187 | return rt_task_of(rt_se)->prio; |
164 | } | 188 | } |
165 | 189 | ||
166 | static int sched_rt_ratio_exceeded(struct rt_rq *rt_rq) | 190 | static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq) |
167 | { | 191 | { |
168 | unsigned int rt_ratio = sched_rt_ratio(rt_rq); | 192 | u64 runtime = sched_rt_runtime(rt_rq); |
169 | u64 period, ratio; | ||
170 | 193 | ||
171 | if (rt_ratio == SCHED_RT_FRAC) | 194 | if (runtime == RUNTIME_INF) |
172 | return 0; | 195 | return 0; |
173 | 196 | ||
174 | if (rt_rq->rt_throttled) | 197 | if (rt_rq->rt_throttled) |
175 | return 1; | 198 | return rt_rq_throttled(rt_rq); |
176 | |||
177 | period = (u64)sysctl_sched_rt_period * NSEC_PER_MSEC; | ||
178 | ratio = (period * rt_ratio) >> SCHED_RT_FRAC_SHIFT; | ||
179 | 199 | ||
180 | if (rt_rq->rt_time > ratio) { | 200 | if (rt_rq->rt_time > runtime) { |
181 | struct rq *rq = rq_of_rt_rq(rt_rq); | 201 | struct rq *rq = rq_of_rt_rq(rt_rq); |
182 | 202 | ||
183 | rq->rt_throttled = 1; | 203 | rq->rt_throttled = 1; |
184 | rt_rq->rt_throttled = 1; | 204 | rt_rq->rt_throttled = 1; |
185 | 205 | ||
186 | sched_rt_ratio_dequeue(rt_rq); | 206 | if (rt_rq_throttled(rt_rq)) { |
187 | return 1; | 207 | sched_rt_rq_dequeue(rt_rq); |
208 | return 1; | ||
209 | } | ||
188 | } | 210 | } |
189 | 211 | ||
190 | return 0; | 212 | return 0; |
@@ -196,17 +218,16 @@ static void update_sched_rt_period(struct rq *rq) | |||
196 | u64 period; | 218 | u64 period; |
197 | 219 | ||
198 | while (rq->clock > rq->rt_period_expire) { | 220 | while (rq->clock > rq->rt_period_expire) { |
199 | period = (u64)sysctl_sched_rt_period * NSEC_PER_MSEC; | 221 | period = (u64)sysctl_sched_rt_period * NSEC_PER_USEC; |
200 | rq->rt_period_expire += period; | 222 | rq->rt_period_expire += period; |
201 | 223 | ||
202 | for_each_leaf_rt_rq(rt_rq, rq) { | 224 | for_each_leaf_rt_rq(rt_rq, rq) { |
203 | unsigned long rt_ratio = sched_rt_ratio(rt_rq); | 225 | u64 runtime = sched_rt_runtime(rt_rq); |
204 | u64 ratio = (period * rt_ratio) >> SCHED_RT_FRAC_SHIFT; | ||
205 | 226 | ||
206 | rt_rq->rt_time -= min(rt_rq->rt_time, ratio); | 227 | rt_rq->rt_time -= min(rt_rq->rt_time, runtime); |
207 | if (rt_rq->rt_throttled) { | 228 | if (rt_rq->rt_throttled && rt_rq->rt_time < runtime) { |
208 | rt_rq->rt_throttled = 0; | 229 | rt_rq->rt_throttled = 0; |
209 | sched_rt_ratio_enqueue(rt_rq); | 230 | sched_rt_rq_enqueue(rt_rq); |
210 | } | 231 | } |
211 | } | 232 | } |
212 | 233 | ||
@@ -239,12 +260,7 @@ static void update_curr_rt(struct rq *rq) | |||
239 | cpuacct_charge(curr, delta_exec); | 260 | cpuacct_charge(curr, delta_exec); |
240 | 261 | ||
241 | rt_rq->rt_time += delta_exec; | 262 | rt_rq->rt_time += delta_exec; |
242 | /* | 263 | if (sched_rt_runtime_exceeded(rt_rq)) |
243 | * might make it a tad more accurate: | ||
244 | * | ||
245 | * update_sched_rt_period(rq); | ||
246 | */ | ||
247 | if (sched_rt_ratio_exceeded(rt_rq)) | ||
248 | resched_task(curr); | 264 | resched_task(curr); |
249 | } | 265 | } |
250 | 266 | ||
@@ -253,7 +269,7 @@ void inc_rt_tasks(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq) | |||
253 | { | 269 | { |
254 | WARN_ON(!rt_prio(rt_se_prio(rt_se))); | 270 | WARN_ON(!rt_prio(rt_se_prio(rt_se))); |
255 | rt_rq->rt_nr_running++; | 271 | rt_rq->rt_nr_running++; |
256 | #if defined CONFIG_SMP || defined CONFIG_FAIR_GROUP_SCHED | 272 | #if defined CONFIG_SMP || defined CONFIG_RT_GROUP_SCHED |
257 | if (rt_se_prio(rt_se) < rt_rq->highest_prio) | 273 | if (rt_se_prio(rt_se) < rt_rq->highest_prio) |
258 | rt_rq->highest_prio = rt_se_prio(rt_se); | 274 | rt_rq->highest_prio = rt_se_prio(rt_se); |
259 | #endif | 275 | #endif |
@@ -265,6 +281,10 @@ void inc_rt_tasks(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq) | |||
265 | 281 | ||
266 | update_rt_migration(rq_of_rt_rq(rt_rq)); | 282 | update_rt_migration(rq_of_rt_rq(rt_rq)); |
267 | #endif | 283 | #endif |
284 | #ifdef CONFIG_RT_GROUP_SCHED | ||
285 | if (rt_se_boosted(rt_se)) | ||
286 | rt_rq->rt_nr_boosted++; | ||
287 | #endif | ||
268 | } | 288 | } |
269 | 289 | ||
270 | static inline | 290 | static inline |
@@ -273,7 +293,7 @@ void dec_rt_tasks(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq) | |||
273 | WARN_ON(!rt_prio(rt_se_prio(rt_se))); | 293 | WARN_ON(!rt_prio(rt_se_prio(rt_se))); |
274 | WARN_ON(!rt_rq->rt_nr_running); | 294 | WARN_ON(!rt_rq->rt_nr_running); |
275 | rt_rq->rt_nr_running--; | 295 | rt_rq->rt_nr_running--; |
276 | #if defined CONFIG_SMP || defined CONFIG_FAIR_GROUP_SCHED | 296 | #if defined CONFIG_SMP || defined CONFIG_RT_GROUP_SCHED |
277 | if (rt_rq->rt_nr_running) { | 297 | if (rt_rq->rt_nr_running) { |
278 | struct rt_prio_array *array; | 298 | struct rt_prio_array *array; |
279 | 299 | ||
@@ -295,6 +315,12 @@ void dec_rt_tasks(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq) | |||
295 | 315 | ||
296 | update_rt_migration(rq_of_rt_rq(rt_rq)); | 316 | update_rt_migration(rq_of_rt_rq(rt_rq)); |
297 | #endif /* CONFIG_SMP */ | 317 | #endif /* CONFIG_SMP */ |
318 | #ifdef CONFIG_RT_GROUP_SCHED | ||
319 | if (rt_se_boosted(rt_se)) | ||
320 | rt_rq->rt_nr_boosted--; | ||
321 | |||
322 | WARN_ON(!rt_rq->rt_nr_running && rt_rq->rt_nr_boosted); | ||
323 | #endif | ||
298 | } | 324 | } |
299 | 325 | ||
300 | static void enqueue_rt_entity(struct sched_rt_entity *rt_se) | 326 | static void enqueue_rt_entity(struct sched_rt_entity *rt_se) |
@@ -303,7 +329,7 @@ static void enqueue_rt_entity(struct sched_rt_entity *rt_se) | |||
303 | struct rt_prio_array *array = &rt_rq->active; | 329 | struct rt_prio_array *array = &rt_rq->active; |
304 | struct rt_rq *group_rq = group_rt_rq(rt_se); | 330 | struct rt_rq *group_rq = group_rt_rq(rt_se); |
305 | 331 | ||
306 | if (group_rq && group_rq->rt_throttled) | 332 | if (group_rq && rt_rq_throttled(group_rq)) |
307 | return; | 333 | return; |
308 | 334 | ||
309 | list_add_tail(&rt_se->run_list, array->queue + rt_se_prio(rt_se)); | 335 | list_add_tail(&rt_se->run_list, array->queue + rt_se_prio(rt_se)); |
@@ -496,7 +522,7 @@ static struct task_struct *pick_next_task_rt(struct rq *rq) | |||
496 | if (unlikely(!rt_rq->rt_nr_running)) | 522 | if (unlikely(!rt_rq->rt_nr_running)) |
497 | return NULL; | 523 | return NULL; |
498 | 524 | ||
499 | if (sched_rt_ratio_exceeded(rt_rq)) | 525 | if (rt_rq_throttled(rt_rq)) |
500 | return NULL; | 526 | return NULL; |
501 | 527 | ||
502 | do { | 528 | do { |
diff --git a/kernel/signal.c b/kernel/signal.c index 2c1f08defac2..84917fe507f7 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -972,7 +972,7 @@ void zap_other_threads(struct task_struct *p) | |||
972 | } | 972 | } |
973 | } | 973 | } |
974 | 974 | ||
975 | int fastcall __fatal_signal_pending(struct task_struct *tsk) | 975 | int __fatal_signal_pending(struct task_struct *tsk) |
976 | { | 976 | { |
977 | return sigismember(&tsk->pending.signal, SIGKILL); | 977 | return sigismember(&tsk->pending.signal, SIGKILL); |
978 | } | 978 | } |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index d41ef6b4cf72..8b7e95411795 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -311,22 +311,6 @@ static struct ctl_table kern_table[] = { | |||
311 | .mode = 0644, | 311 | .mode = 0644, |
312 | .proc_handler = &proc_dointvec, | 312 | .proc_handler = &proc_dointvec, |
313 | }, | 313 | }, |
314 | { | ||
315 | .ctl_name = CTL_UNNUMBERED, | ||
316 | .procname = "sched_rt_period_ms", | ||
317 | .data = &sysctl_sched_rt_period, | ||
318 | .maxlen = sizeof(unsigned int), | ||
319 | .mode = 0644, | ||
320 | .proc_handler = &proc_dointvec, | ||
321 | }, | ||
322 | { | ||
323 | .ctl_name = CTL_UNNUMBERED, | ||
324 | .procname = "sched_rt_ratio", | ||
325 | .data = &sysctl_sched_rt_ratio, | ||
326 | .maxlen = sizeof(unsigned int), | ||
327 | .mode = 0644, | ||
328 | .proc_handler = &proc_dointvec, | ||
329 | }, | ||
330 | #if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) | 314 | #if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) |
331 | { | 315 | { |
332 | .ctl_name = CTL_UNNUMBERED, | 316 | .ctl_name = CTL_UNNUMBERED, |
@@ -348,6 +332,22 @@ static struct ctl_table kern_table[] = { | |||
348 | #endif | 332 | #endif |
349 | { | 333 | { |
350 | .ctl_name = CTL_UNNUMBERED, | 334 | .ctl_name = CTL_UNNUMBERED, |
335 | .procname = "sched_rt_period_us", | ||
336 | .data = &sysctl_sched_rt_period, | ||
337 | .maxlen = sizeof(unsigned int), | ||
338 | .mode = 0644, | ||
339 | .proc_handler = &proc_dointvec, | ||
340 | }, | ||
341 | { | ||
342 | .ctl_name = CTL_UNNUMBERED, | ||
343 | .procname = "sched_rt_runtime_us", | ||
344 | .data = &sysctl_sched_rt_runtime, | ||
345 | .maxlen = sizeof(int), | ||
346 | .mode = 0644, | ||
347 | .proc_handler = &proc_dointvec, | ||
348 | }, | ||
349 | { | ||
350 | .ctl_name = CTL_UNNUMBERED, | ||
351 | .procname = "sched_compat_yield", | 351 | .procname = "sched_compat_yield", |
352 | .data = &sysctl_sched_compat_yield, | 352 | .data = &sysctl_sched_compat_yield, |
353 | .maxlen = sizeof(unsigned int), | 353 | .maxlen = sizeof(unsigned int), |
@@ -978,8 +978,8 @@ static struct ctl_table vm_table[] = { | |||
978 | { | 978 | { |
979 | .ctl_name = CTL_UNNUMBERED, | 979 | .ctl_name = CTL_UNNUMBERED, |
980 | .procname = "nr_overcommit_hugepages", | 980 | .procname = "nr_overcommit_hugepages", |
981 | .data = &nr_overcommit_huge_pages, | 981 | .data = &sysctl_overcommit_huge_pages, |
982 | .maxlen = sizeof(nr_overcommit_huge_pages), | 982 | .maxlen = sizeof(sysctl_overcommit_huge_pages), |
983 | .mode = 0644, | 983 | .mode = 0644, |
984 | .proc_handler = &hugetlb_overcommit_handler, | 984 | .proc_handler = &hugetlb_overcommit_handler, |
985 | }, | 985 | }, |
diff --git a/kernel/timeconst.pl b/kernel/timeconst.pl index 62b1287932ed..41468035473c 100644 --- a/kernel/timeconst.pl +++ b/kernel/timeconst.pl | |||
@@ -339,7 +339,7 @@ sub output($@) | |||
339 | print "\n"; | 339 | print "\n"; |
340 | 340 | ||
341 | foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ', | 341 | foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ', |
342 | 'USEC_TO_HZ','HZ_TO_USEC') { | 342 | 'HZ_TO_USEC','USEC_TO_HZ') { |
343 | foreach $bit (32, 64) { | 343 | foreach $bit (32, 64) { |
344 | foreach $suf ('MUL', 'ADJ', 'SHR') { | 344 | foreach $suf ('MUL', 'ADJ', 'SHR') { |
345 | printf "#define %-23s %s\n", | 345 | printf "#define %-23s %s\n", |
diff --git a/kernel/user.c b/kernel/user.c index 7d7900c5a1fd..7132022a040c 100644 --- a/kernel/user.c +++ b/kernel/user.c | |||
@@ -57,7 +57,7 @@ struct user_struct root_user = { | |||
57 | .uid_keyring = &root_user_keyring, | 57 | .uid_keyring = &root_user_keyring, |
58 | .session_keyring = &root_session_keyring, | 58 | .session_keyring = &root_session_keyring, |
59 | #endif | 59 | #endif |
60 | #ifdef CONFIG_FAIR_USER_SCHED | 60 | #ifdef CONFIG_USER_SCHED |
61 | .tg = &init_task_group, | 61 | .tg = &init_task_group, |
62 | #endif | 62 | #endif |
63 | }; | 63 | }; |
@@ -90,7 +90,7 @@ static struct user_struct *uid_hash_find(uid_t uid, struct hlist_head *hashent) | |||
90 | return NULL; | 90 | return NULL; |
91 | } | 91 | } |
92 | 92 | ||
93 | #ifdef CONFIG_FAIR_USER_SCHED | 93 | #ifdef CONFIG_USER_SCHED |
94 | 94 | ||
95 | static void sched_destroy_user(struct user_struct *up) | 95 | static void sched_destroy_user(struct user_struct *up) |
96 | { | 96 | { |
@@ -113,15 +113,15 @@ static void sched_switch_user(struct task_struct *p) | |||
113 | sched_move_task(p); | 113 | sched_move_task(p); |
114 | } | 114 | } |
115 | 115 | ||
116 | #else /* CONFIG_FAIR_USER_SCHED */ | 116 | #else /* CONFIG_USER_SCHED */ |
117 | 117 | ||
118 | static void sched_destroy_user(struct user_struct *up) { } | 118 | static void sched_destroy_user(struct user_struct *up) { } |
119 | static int sched_create_user(struct user_struct *up) { return 0; } | 119 | static int sched_create_user(struct user_struct *up) { return 0; } |
120 | static void sched_switch_user(struct task_struct *p) { } | 120 | static void sched_switch_user(struct task_struct *p) { } |
121 | 121 | ||
122 | #endif /* CONFIG_FAIR_USER_SCHED */ | 122 | #endif /* CONFIG_USER_SCHED */ |
123 | 123 | ||
124 | #if defined(CONFIG_FAIR_USER_SCHED) && defined(CONFIG_SYSFS) | 124 | #if defined(CONFIG_USER_SCHED) && defined(CONFIG_SYSFS) |
125 | 125 | ||
126 | static struct kset *uids_kset; /* represents the /sys/kernel/uids/ directory */ | 126 | static struct kset *uids_kset; /* represents the /sys/kernel/uids/ directory */ |
127 | static DEFINE_MUTEX(uids_mutex); | 127 | static DEFINE_MUTEX(uids_mutex); |
@@ -137,6 +137,7 @@ static inline void uids_mutex_unlock(void) | |||
137 | } | 137 | } |
138 | 138 | ||
139 | /* uid directory attributes */ | 139 | /* uid directory attributes */ |
140 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
140 | static ssize_t cpu_shares_show(struct kobject *kobj, | 141 | static ssize_t cpu_shares_show(struct kobject *kobj, |
141 | struct kobj_attribute *attr, | 142 | struct kobj_attribute *attr, |
142 | char *buf) | 143 | char *buf) |
@@ -163,10 +164,45 @@ static ssize_t cpu_shares_store(struct kobject *kobj, | |||
163 | 164 | ||
164 | static struct kobj_attribute cpu_share_attr = | 165 | static struct kobj_attribute cpu_share_attr = |
165 | __ATTR(cpu_share, 0644, cpu_shares_show, cpu_shares_store); | 166 | __ATTR(cpu_share, 0644, cpu_shares_show, cpu_shares_store); |
167 | #endif | ||
168 | |||
169 | #ifdef CONFIG_RT_GROUP_SCHED | ||
170 | static ssize_t cpu_rt_runtime_show(struct kobject *kobj, | ||
171 | struct kobj_attribute *attr, | ||
172 | char *buf) | ||
173 | { | ||
174 | struct user_struct *up = container_of(kobj, struct user_struct, kobj); | ||
175 | |||
176 | return sprintf(buf, "%lu\n", sched_group_rt_runtime(up->tg)); | ||
177 | } | ||
178 | |||
179 | static ssize_t cpu_rt_runtime_store(struct kobject *kobj, | ||
180 | struct kobj_attribute *attr, | ||
181 | const char *buf, size_t size) | ||
182 | { | ||
183 | struct user_struct *up = container_of(kobj, struct user_struct, kobj); | ||
184 | unsigned long rt_runtime; | ||
185 | int rc; | ||
186 | |||
187 | sscanf(buf, "%lu", &rt_runtime); | ||
188 | |||
189 | rc = sched_group_set_rt_runtime(up->tg, rt_runtime); | ||
190 | |||
191 | return (rc ? rc : size); | ||
192 | } | ||
193 | |||
194 | static struct kobj_attribute cpu_rt_runtime_attr = | ||
195 | __ATTR(cpu_rt_runtime, 0644, cpu_rt_runtime_show, cpu_rt_runtime_store); | ||
196 | #endif | ||
166 | 197 | ||
167 | /* default attributes per uid directory */ | 198 | /* default attributes per uid directory */ |
168 | static struct attribute *uids_attributes[] = { | 199 | static struct attribute *uids_attributes[] = { |
200 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
169 | &cpu_share_attr.attr, | 201 | &cpu_share_attr.attr, |
202 | #endif | ||
203 | #ifdef CONFIG_RT_GROUP_SCHED | ||
204 | &cpu_rt_runtime_attr.attr, | ||
205 | #endif | ||
170 | NULL | 206 | NULL |
171 | }; | 207 | }; |
172 | 208 | ||
@@ -269,7 +305,7 @@ static inline void free_user(struct user_struct *up, unsigned long flags) | |||
269 | schedule_work(&up->work); | 305 | schedule_work(&up->work); |
270 | } | 306 | } |
271 | 307 | ||
272 | #else /* CONFIG_FAIR_USER_SCHED && CONFIG_SYSFS */ | 308 | #else /* CONFIG_USER_SCHED && CONFIG_SYSFS */ |
273 | 309 | ||
274 | int uids_sysfs_init(void) { return 0; } | 310 | int uids_sysfs_init(void) { return 0; } |
275 | static inline int uids_user_create(struct user_struct *up) { return 0; } | 311 | static inline int uids_user_create(struct user_struct *up) { return 0; } |
@@ -373,7 +409,7 @@ struct user_struct * alloc_uid(struct user_namespace *ns, uid_t uid) | |||
373 | spin_lock_irq(&uidhash_lock); | 409 | spin_lock_irq(&uidhash_lock); |
374 | up = uid_hash_find(uid, hashent); | 410 | up = uid_hash_find(uid, hashent); |
375 | if (up) { | 411 | if (up) { |
376 | /* This case is not possible when CONFIG_FAIR_USER_SCHED | 412 | /* This case is not possible when CONFIG_USER_SCHED |
377 | * is defined, since we serialize alloc_uid() using | 413 | * is defined, since we serialize alloc_uid() using |
378 | * uids_mutex. Hence no need to call | 414 | * uids_mutex. Hence no need to call |
379 | * sched_destroy_user() or remove_user_sysfs_dir(). | 415 | * sched_destroy_user() or remove_user_sysfs_dir(). |
diff --git a/mm/filemap.c b/mm/filemap.c index b7b1be6dbd83..5c74b68935ac 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -604,7 +604,7 @@ void __lock_page(struct page *page) | |||
604 | } | 604 | } |
605 | EXPORT_SYMBOL(__lock_page); | 605 | EXPORT_SYMBOL(__lock_page); |
606 | 606 | ||
607 | int fastcall __lock_page_killable(struct page *page) | 607 | int __lock_page_killable(struct page *page) |
608 | { | 608 | { |
609 | DEFINE_WAIT_BIT(wait, &page->flags, PG_locked); | 609 | DEFINE_WAIT_BIT(wait, &page->flags, PG_locked); |
610 | 610 | ||
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index d9a380312467..cb1b3a7ecdfc 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -24,14 +24,15 @@ | |||
24 | const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; | 24 | const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; |
25 | static unsigned long nr_huge_pages, free_huge_pages, resv_huge_pages; | 25 | static unsigned long nr_huge_pages, free_huge_pages, resv_huge_pages; |
26 | static unsigned long surplus_huge_pages; | 26 | static unsigned long surplus_huge_pages; |
27 | static unsigned long nr_overcommit_huge_pages; | ||
27 | unsigned long max_huge_pages; | 28 | unsigned long max_huge_pages; |
29 | unsigned long sysctl_overcommit_huge_pages; | ||
28 | static struct list_head hugepage_freelists[MAX_NUMNODES]; | 30 | static struct list_head hugepage_freelists[MAX_NUMNODES]; |
29 | static unsigned int nr_huge_pages_node[MAX_NUMNODES]; | 31 | static unsigned int nr_huge_pages_node[MAX_NUMNODES]; |
30 | static unsigned int free_huge_pages_node[MAX_NUMNODES]; | 32 | static unsigned int free_huge_pages_node[MAX_NUMNODES]; |
31 | static unsigned int surplus_huge_pages_node[MAX_NUMNODES]; | 33 | static unsigned int surplus_huge_pages_node[MAX_NUMNODES]; |
32 | static gfp_t htlb_alloc_mask = GFP_HIGHUSER; | 34 | static gfp_t htlb_alloc_mask = GFP_HIGHUSER; |
33 | unsigned long hugepages_treat_as_movable; | 35 | unsigned long hugepages_treat_as_movable; |
34 | unsigned long nr_overcommit_huge_pages; | ||
35 | static int hugetlb_next_nid; | 36 | static int hugetlb_next_nid; |
36 | 37 | ||
37 | /* | 38 | /* |
@@ -609,8 +610,9 @@ int hugetlb_overcommit_handler(struct ctl_table *table, int write, | |||
609 | struct file *file, void __user *buffer, | 610 | struct file *file, void __user *buffer, |
610 | size_t *length, loff_t *ppos) | 611 | size_t *length, loff_t *ppos) |
611 | { | 612 | { |
612 | spin_lock(&hugetlb_lock); | ||
613 | proc_doulongvec_minmax(table, write, file, buffer, length, ppos); | 613 | proc_doulongvec_minmax(table, write, file, buffer, length, ppos); |
614 | spin_lock(&hugetlb_lock); | ||
615 | nr_overcommit_huge_pages = sysctl_overcommit_huge_pages; | ||
614 | spin_unlock(&hugetlb_lock); | 616 | spin_unlock(&hugetlb_lock); |
615 | return 0; | 617 | return 0; |
616 | } | 618 | } |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index d3e4e1877e6a..0c2c93735e93 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -465,7 +465,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) | |||
465 | return len; | 465 | return len; |
466 | } | 466 | } |
467 | 467 | ||
468 | void fastcall __rfcomm_dlc_throttle(struct rfcomm_dlc *d) | 468 | void __rfcomm_dlc_throttle(struct rfcomm_dlc *d) |
469 | { | 469 | { |
470 | BT_DBG("dlc %p state %ld", d, d->state); | 470 | BT_DBG("dlc %p state %ld", d, d->state); |
471 | 471 | ||
@@ -476,7 +476,7 @@ void fastcall __rfcomm_dlc_throttle(struct rfcomm_dlc *d) | |||
476 | rfcomm_schedule(RFCOMM_SCHED_TX); | 476 | rfcomm_schedule(RFCOMM_SCHED_TX); |
477 | } | 477 | } |
478 | 478 | ||
479 | void fastcall __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) | 479 | void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) |
480 | { | 480 | { |
481 | BT_DBG("dlc %p state %ld", d, d->state); | 481 | BT_DBG("dlc %p state %ld", d, d->state); |
482 | 482 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 9549417250bb..b3e19ae57f95 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2143,7 +2143,7 @@ static int process_backlog(struct napi_struct *napi, int quota) | |||
2143 | * | 2143 | * |
2144 | * The entry's receive function will be scheduled to run | 2144 | * The entry's receive function will be scheduled to run |
2145 | */ | 2145 | */ |
2146 | void fastcall __napi_schedule(struct napi_struct *n) | 2146 | void __napi_schedule(struct napi_struct *n) |
2147 | { | 2147 | { |
2148 | unsigned long flags; | 2148 | unsigned long flags; |
2149 | 2149 | ||
@@ -3038,8 +3038,7 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from) | |||
3038 | EXPORT_SYMBOL(dev_unicast_sync); | 3038 | EXPORT_SYMBOL(dev_unicast_sync); |
3039 | 3039 | ||
3040 | /** | 3040 | /** |
3041 | * dev_unicast_unsync - Remove synchronized addresses from the destination | 3041 | * dev_unicast_unsync - Remove synchronized addresses from the destination device |
3042 | * device | ||
3043 | * @to: destination device | 3042 | * @to: destination device |
3044 | * @from: source device | 3043 | * @from: source device |
3045 | * | 3044 | * |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 4e354221ec23..cfc07dac636c 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -1907,11 +1907,11 @@ void skb_prepare_seq_read(struct sk_buff *skb, unsigned int from, | |||
1907 | * of bytes already consumed and the next call to | 1907 | * of bytes already consumed and the next call to |
1908 | * skb_seq_read() will return the remaining part of the block. | 1908 | * skb_seq_read() will return the remaining part of the block. |
1909 | * | 1909 | * |
1910 | * Note: The size of each block of data returned can be arbitary, | 1910 | * Note 1: The size of each block of data returned can be arbitary, |
1911 | * this limitation is the cost for zerocopy seqeuental | 1911 | * this limitation is the cost for zerocopy seqeuental |
1912 | * reads of potentially non linear data. | 1912 | * reads of potentially non linear data. |
1913 | * | 1913 | * |
1914 | * Note: Fragment lists within fragments are not implemented | 1914 | * Note 2: Fragment lists within fragments are not implemented |
1915 | * at the moment, state->root_skb could be replaced with | 1915 | * at the moment, state->root_skb could be replaced with |
1916 | * a stack for this purpose. | 1916 | * a stack for this purpose. |
1917 | */ | 1917 | */ |
diff --git a/net/core/sock.c b/net/core/sock.c index 433715fb141a..09cb3a74de7f 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1731,7 +1731,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
1731 | atomic_set(&sk->sk_drops, 0); | 1731 | atomic_set(&sk->sk_drops, 0); |
1732 | } | 1732 | } |
1733 | 1733 | ||
1734 | void fastcall lock_sock_nested(struct sock *sk, int subclass) | 1734 | void lock_sock_nested(struct sock *sk, int subclass) |
1735 | { | 1735 | { |
1736 | might_sleep(); | 1736 | might_sleep(); |
1737 | spin_lock_bh(&sk->sk_lock.slock); | 1737 | spin_lock_bh(&sk->sk_lock.slock); |
@@ -1748,7 +1748,7 @@ void fastcall lock_sock_nested(struct sock *sk, int subclass) | |||
1748 | 1748 | ||
1749 | EXPORT_SYMBOL(lock_sock_nested); | 1749 | EXPORT_SYMBOL(lock_sock_nested); |
1750 | 1750 | ||
1751 | void fastcall release_sock(struct sock *sk) | 1751 | void release_sock(struct sock *sk) |
1752 | { | 1752 | { |
1753 | /* | 1753 | /* |
1754 | * The sk_lock has mutex_unlock() semantics: | 1754 | * The sk_lock has mutex_unlock() semantics: |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 0998e6d09664..8c6a7f1a25e9 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -464,9 +464,9 @@ rpc_release_client(struct rpc_clnt *clnt) | |||
464 | 464 | ||
465 | /** | 465 | /** |
466 | * rpc_bind_new_program - bind a new RPC program to an existing client | 466 | * rpc_bind_new_program - bind a new RPC program to an existing client |
467 | * @old - old rpc_client | 467 | * @old: old rpc_client |
468 | * @program - rpc program to set | 468 | * @program: rpc program to set |
469 | * @vers - rpc program version | 469 | * @vers: rpc program version |
470 | * | 470 | * |
471 | * Clones the rpc client and sets up a new RPC program. This is mainly | 471 | * Clones the rpc client and sets up a new RPC program. This is mainly |
472 | * of use for enabling different RPC programs to share the same transport. | 472 | * of use for enabling different RPC programs to share the same transport. |
@@ -575,7 +575,7 @@ EXPORT_SYMBOL_GPL(rpc_call_sync); | |||
575 | * @clnt: pointer to RPC client | 575 | * @clnt: pointer to RPC client |
576 | * @msg: RPC call parameters | 576 | * @msg: RPC call parameters |
577 | * @flags: RPC call flags | 577 | * @flags: RPC call flags |
578 | * @ops: RPC call ops | 578 | * @tk_ops: RPC call ops |
579 | * @data: user call data | 579 | * @data: user call data |
580 | */ | 580 | */ |
581 | int | 581 | int |
@@ -610,7 +610,7 @@ EXPORT_SYMBOL_GPL(rpc_call_start); | |||
610 | * rpc_peeraddr - extract remote peer address from clnt's xprt | 610 | * rpc_peeraddr - extract remote peer address from clnt's xprt |
611 | * @clnt: RPC client structure | 611 | * @clnt: RPC client structure |
612 | * @buf: target buffer | 612 | * @buf: target buffer |
613 | * @size: length of target buffer | 613 | * @bufsize: length of target buffer |
614 | * | 614 | * |
615 | * Returns the number of bytes that are actually in the stored address. | 615 | * Returns the number of bytes that are actually in the stored address. |
616 | */ | 616 | */ |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 7e197168a245..0e3ead7e11b9 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -677,7 +677,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd) | |||
677 | /** | 677 | /** |
678 | * rpc_mkdir - Create a new directory in rpc_pipefs | 678 | * rpc_mkdir - Create a new directory in rpc_pipefs |
679 | * @path: path from the rpc_pipefs root to the new directory | 679 | * @path: path from the rpc_pipefs root to the new directory |
680 | * @rpc_clnt: rpc client to associate with this directory | 680 | * @rpc_client: rpc client to associate with this directory |
681 | * | 681 | * |
682 | * This creates a directory at the given @path associated with | 682 | * This creates a directory at the given @path associated with |
683 | * @rpc_clnt, which will contain a file named "info" with some basic | 683 | * @rpc_clnt, which will contain a file named "info" with some basic |
@@ -748,6 +748,7 @@ rpc_rmdir(struct dentry *dentry) | |||
748 | * @private: private data to associate with the pipe, for the caller's use | 748 | * @private: private data to associate with the pipe, for the caller's use |
749 | * @ops: operations defining the behavior of the pipe: upcall, downcall, | 749 | * @ops: operations defining the behavior of the pipe: upcall, downcall, |
750 | * release_pipe, and destroy_msg. | 750 | * release_pipe, and destroy_msg. |
751 | * @flags: rpc_inode flags | ||
751 | * | 752 | * |
752 | * Data is made available for userspace to read by calls to | 753 | * Data is made available for userspace to read by calls to |
753 | * rpc_queue_upcall(). The actual reads will result in calls to | 754 | * rpc_queue_upcall(). The actual reads will result in calls to |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index cfcade906a56..d5553b8179f9 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -124,7 +124,7 @@ EXPORT_SYMBOL_GPL(xprt_register_transport); | |||
124 | 124 | ||
125 | /** | 125 | /** |
126 | * xprt_unregister_transport - unregister a transport implementation | 126 | * xprt_unregister_transport - unregister a transport implementation |
127 | * transport: transport to unregister | 127 | * @transport: transport to unregister |
128 | * | 128 | * |
129 | * Returns: | 129 | * Returns: |
130 | * 0: transport successfully unregistered | 130 | * 0: transport successfully unregistered |
diff --git a/samples/markers/probe-example.c b/samples/markers/probe-example.c index a36797535615..c8e099d4d1fd 100644 --- a/samples/markers/probe-example.c +++ b/samples/markers/probe-example.c | |||
@@ -20,31 +20,27 @@ struct probe_data { | |||
20 | marker_probe_func *probe_func; | 20 | marker_probe_func *probe_func; |
21 | }; | 21 | }; |
22 | 22 | ||
23 | void probe_subsystem_event(const struct marker *mdata, void *private, | 23 | void probe_subsystem_event(void *probe_data, void *call_data, |
24 | const char *format, ...) | 24 | const char *format, va_list *args) |
25 | { | 25 | { |
26 | va_list ap; | ||
27 | /* Declare args */ | 26 | /* Declare args */ |
28 | unsigned int value; | 27 | unsigned int value; |
29 | const char *mystr; | 28 | const char *mystr; |
30 | 29 | ||
31 | /* Assign args */ | 30 | /* Assign args */ |
32 | va_start(ap, format); | 31 | value = va_arg(*args, typeof(value)); |
33 | value = va_arg(ap, typeof(value)); | 32 | mystr = va_arg(*args, typeof(mystr)); |
34 | mystr = va_arg(ap, typeof(mystr)); | ||
35 | 33 | ||
36 | /* Call printk */ | 34 | /* Call printk */ |
37 | printk(KERN_DEBUG "Value %u, string %s\n", value, mystr); | 35 | printk(KERN_INFO "Value %u, string %s\n", value, mystr); |
38 | 36 | ||
39 | /* or count, check rights, serialize data in a buffer */ | 37 | /* or count, check rights, serialize data in a buffer */ |
40 | |||
41 | va_end(ap); | ||
42 | } | 38 | } |
43 | 39 | ||
44 | atomic_t eventb_count = ATOMIC_INIT(0); | 40 | atomic_t eventb_count = ATOMIC_INIT(0); |
45 | 41 | ||
46 | void probe_subsystem_eventb(const struct marker *mdata, void *private, | 42 | void probe_subsystem_eventb(void *probe_data, void *call_data, |
47 | const char *format, ...) | 43 | const char *format, va_list *args) |
48 | { | 44 | { |
49 | /* Increment counter */ | 45 | /* Increment counter */ |
50 | atomic_inc(&eventb_count); | 46 | atomic_inc(&eventb_count); |
@@ -72,10 +68,6 @@ static int __init probe_init(void) | |||
72 | if (result) | 68 | if (result) |
73 | printk(KERN_INFO "Unable to register probe %s\n", | 69 | printk(KERN_INFO "Unable to register probe %s\n", |
74 | probe_array[i].name); | 70 | probe_array[i].name); |
75 | result = marker_arm(probe_array[i].name); | ||
76 | if (result) | ||
77 | printk(KERN_INFO "Unable to arm probe %s\n", | ||
78 | probe_array[i].name); | ||
79 | } | 71 | } |
80 | return 0; | 72 | return 0; |
81 | } | 73 | } |
@@ -85,7 +77,8 @@ static void __exit probe_fini(void) | |||
85 | int i; | 77 | int i; |
86 | 78 | ||
87 | for (i = 0; i < ARRAY_SIZE(probe_array); i++) | 79 | for (i = 0; i < ARRAY_SIZE(probe_array); i++) |
88 | marker_probe_unregister(probe_array[i].name); | 80 | marker_probe_unregister(probe_array[i].name, |
81 | probe_array[i].probe_func, &probe_array[i]); | ||
89 | printk(KERN_INFO "Number of event b : %u\n", | 82 | printk(KERN_INFO "Number of event b : %u\n", |
90 | atomic_read(&eventb_count)); | 83 | atomic_read(&eventb_count)); |
91 | } | 84 | } |
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 65e707e1ffc3..cfc004e04417 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost | |||
@@ -13,6 +13,7 @@ | |||
13 | # 2) modpost is then used to | 13 | # 2) modpost is then used to |
14 | # 3) create one <module>.mod.c file pr. module | 14 | # 3) create one <module>.mod.c file pr. module |
15 | # 4) create one Module.symvers file with CRC for all exported symbols | 15 | # 4) create one Module.symvers file with CRC for all exported symbols |
16 | # 4a) [CONFIG_MARKERS] create one Module.markers file listing defined markers | ||
16 | # 5) compile all <module>.mod.c files | 17 | # 5) compile all <module>.mod.c files |
17 | # 6) final link of the module to a <module.ko> file | 18 | # 6) final link of the module to a <module.ko> file |
18 | 19 | ||
@@ -45,6 +46,10 @@ include scripts/Makefile.lib | |||
45 | 46 | ||
46 | kernelsymfile := $(objtree)/Module.symvers | 47 | kernelsymfile := $(objtree)/Module.symvers |
47 | modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers | 48 | modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers |
49 | kernelmarkersfile := $(objtree)/Module.markers | ||
50 | modulemarkersfile := $(firstword $(KBUILD_EXTMOD))/Module.markers | ||
51 | |||
52 | markersfile = $(if $(KBUILD_EXTMOD),$(modulemarkersfile),$(kernelmarkersfile)) | ||
48 | 53 | ||
49 | # Step 1), find all modules listed in $(MODVERDIR)/ | 54 | # Step 1), find all modules listed in $(MODVERDIR)/ |
50 | __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) | 55 | __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) |
@@ -63,6 +68,8 @@ modpost = scripts/mod/modpost \ | |||
63 | $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ | 68 | $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ |
64 | $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ | 69 | $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ |
65 | $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \ | 70 | $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \ |
71 | $(if $(CONFIG_MARKERS),-K $(kernelmarkersfile)) \ | ||
72 | $(if $(CONFIG_MARKERS),-M $(markersfile)) \ | ||
66 | $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) | 73 | $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) |
67 | 74 | ||
68 | quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules | 75 | quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules |
@@ -82,6 +89,10 @@ vmlinux.o: FORCE | |||
82 | $(symverfile): __modpost ; | 89 | $(symverfile): __modpost ; |
83 | $(modules:.ko=.mod.c): __modpost ; | 90 | $(modules:.ko=.mod.c): __modpost ; |
84 | 91 | ||
92 | ifdef CONFIG_MARKERS | ||
93 | $(markersfile): __modpost ; | ||
94 | endif | ||
95 | |||
85 | 96 | ||
86 | # Step 5), compile all *.mod.c files | 97 | # Step 5), compile all *.mod.c files |
87 | 98 | ||
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index dbe1fb5e8cc0..61742771c65d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * Usage: modpost vmlinux module1.o module2.o ... | 11 | * Usage: modpost vmlinux module1.o module2.o ... |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define _GNU_SOURCE | ||
15 | #include <stdio.h> | ||
14 | #include <ctype.h> | 16 | #include <ctype.h> |
15 | #include "modpost.h" | 17 | #include "modpost.h" |
16 | #include "../../include/linux/license.h" | 18 | #include "../../include/linux/license.h" |
@@ -435,6 +437,8 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
435 | info->export_unused_gpl_sec = i; | 437 | info->export_unused_gpl_sec = i; |
436 | else if (strcmp(secname, "__ksymtab_gpl_future") == 0) | 438 | else if (strcmp(secname, "__ksymtab_gpl_future") == 0) |
437 | info->export_gpl_future_sec = i; | 439 | info->export_gpl_future_sec = i; |
440 | else if (strcmp(secname, "__markers_strings") == 0) | ||
441 | info->markers_strings_sec = i; | ||
438 | 442 | ||
439 | if (sechdrs[i].sh_type != SHT_SYMTAB) | 443 | if (sechdrs[i].sh_type != SHT_SYMTAB) |
440 | continue; | 444 | continue; |
@@ -1470,6 +1474,62 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
1470 | } | 1474 | } |
1471 | } | 1475 | } |
1472 | 1476 | ||
1477 | static void get_markers(struct elf_info *info, struct module *mod) | ||
1478 | { | ||
1479 | const Elf_Shdr *sh = &info->sechdrs[info->markers_strings_sec]; | ||
1480 | const char *strings = (const char *) info->hdr + sh->sh_offset; | ||
1481 | const Elf_Sym *sym, *first_sym, *last_sym; | ||
1482 | size_t n; | ||
1483 | |||
1484 | if (!info->markers_strings_sec) | ||
1485 | return; | ||
1486 | |||
1487 | /* | ||
1488 | * First count the strings. We look for all the symbols defined | ||
1489 | * in the __markers_strings section named __mstrtab_*. For | ||
1490 | * these local names, the compiler puts a random .NNN suffix on, | ||
1491 | * so the names don't correspond exactly. | ||
1492 | */ | ||
1493 | first_sym = last_sym = NULL; | ||
1494 | n = 0; | ||
1495 | for (sym = info->symtab_start; sym < info->symtab_stop; sym++) | ||
1496 | if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT && | ||
1497 | sym->st_shndx == info->markers_strings_sec && | ||
1498 | !strncmp(info->strtab + sym->st_name, | ||
1499 | "__mstrtab_", sizeof "__mstrtab_" - 1)) { | ||
1500 | if (first_sym == NULL) | ||
1501 | first_sym = sym; | ||
1502 | last_sym = sym; | ||
1503 | ++n; | ||
1504 | } | ||
1505 | |||
1506 | if (n == 0) | ||
1507 | return; | ||
1508 | |||
1509 | /* | ||
1510 | * Now collect each name and format into a line for the output. | ||
1511 | * Lines look like: | ||
1512 | * marker_name vmlinux marker %s format %d | ||
1513 | * The format string after the second \t can use whitespace. | ||
1514 | */ | ||
1515 | mod->markers = NOFAIL(malloc(sizeof mod->markers[0] * n)); | ||
1516 | mod->nmarkers = n; | ||
1517 | |||
1518 | n = 0; | ||
1519 | for (sym = first_sym; sym <= last_sym; sym++) | ||
1520 | if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT && | ||
1521 | sym->st_shndx == info->markers_strings_sec && | ||
1522 | !strncmp(info->strtab + sym->st_name, | ||
1523 | "__mstrtab_", sizeof "__mstrtab_" - 1)) { | ||
1524 | const char *name = strings + sym->st_value; | ||
1525 | const char *fmt = strchr(name, '\0') + 1; | ||
1526 | char *line = NULL; | ||
1527 | asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt); | ||
1528 | NOFAIL(line); | ||
1529 | mod->markers[n++] = line; | ||
1530 | } | ||
1531 | } | ||
1532 | |||
1473 | static void read_symbols(char *modname) | 1533 | static void read_symbols(char *modname) |
1474 | { | 1534 | { |
1475 | const char *symname; | 1535 | const char *symname; |
@@ -1521,6 +1581,8 @@ static void read_symbols(char *modname) | |||
1521 | get_src_version(modname, mod->srcversion, | 1581 | get_src_version(modname, mod->srcversion, |
1522 | sizeof(mod->srcversion)-1); | 1582 | sizeof(mod->srcversion)-1); |
1523 | 1583 | ||
1584 | get_markers(&info, mod); | ||
1585 | |||
1524 | parse_elf_finish(&info); | 1586 | parse_elf_finish(&info); |
1525 | 1587 | ||
1526 | /* Our trick to get versioning for struct_module - it's | 1588 | /* Our trick to get versioning for struct_module - it's |
@@ -1867,16 +1929,104 @@ static void write_dump(const char *fname) | |||
1867 | write_if_changed(&buf, fname); | 1929 | write_if_changed(&buf, fname); |
1868 | } | 1930 | } |
1869 | 1931 | ||
1932 | static void add_marker(struct module *mod, const char *name, const char *fmt) | ||
1933 | { | ||
1934 | char *line = NULL; | ||
1935 | asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt); | ||
1936 | NOFAIL(line); | ||
1937 | |||
1938 | mod->markers = NOFAIL(realloc(mod->markers, ((mod->nmarkers + 1) * | ||
1939 | sizeof mod->markers[0]))); | ||
1940 | mod->markers[mod->nmarkers++] = line; | ||
1941 | } | ||
1942 | |||
1943 | static void read_markers(const char *fname) | ||
1944 | { | ||
1945 | unsigned long size, pos = 0; | ||
1946 | void *file = grab_file(fname, &size); | ||
1947 | char *line; | ||
1948 | |||
1949 | if (!file) /* No old markers, silently ignore */ | ||
1950 | return; | ||
1951 | |||
1952 | while ((line = get_next_line(&pos, file, size))) { | ||
1953 | char *marker, *modname, *fmt; | ||
1954 | struct module *mod; | ||
1955 | |||
1956 | marker = line; | ||
1957 | modname = strchr(marker, '\t'); | ||
1958 | if (!modname) | ||
1959 | goto fail; | ||
1960 | *modname++ = '\0'; | ||
1961 | fmt = strchr(modname, '\t'); | ||
1962 | if (!fmt) | ||
1963 | goto fail; | ||
1964 | *fmt++ = '\0'; | ||
1965 | if (*marker == '\0' || *modname == '\0') | ||
1966 | goto fail; | ||
1967 | |||
1968 | mod = find_module(modname); | ||
1969 | if (!mod) { | ||
1970 | if (is_vmlinux(modname)) | ||
1971 | have_vmlinux = 1; | ||
1972 | mod = new_module(NOFAIL(strdup(modname))); | ||
1973 | mod->skip = 1; | ||
1974 | } | ||
1975 | |||
1976 | add_marker(mod, marker, fmt); | ||
1977 | } | ||
1978 | return; | ||
1979 | fail: | ||
1980 | fatal("parse error in markers list file\n"); | ||
1981 | } | ||
1982 | |||
1983 | static int compare_strings(const void *a, const void *b) | ||
1984 | { | ||
1985 | return strcmp(*(const char **) a, *(const char **) b); | ||
1986 | } | ||
1987 | |||
1988 | static void write_markers(const char *fname) | ||
1989 | { | ||
1990 | struct buffer buf = { }; | ||
1991 | struct module *mod; | ||
1992 | size_t i; | ||
1993 | |||
1994 | for (mod = modules; mod; mod = mod->next) | ||
1995 | if ((!external_module || !mod->skip) && mod->markers != NULL) { | ||
1996 | /* | ||
1997 | * Sort the strings so we can skip duplicates when | ||
1998 | * we write them out. | ||
1999 | */ | ||
2000 | qsort(mod->markers, mod->nmarkers, | ||
2001 | sizeof mod->markers[0], &compare_strings); | ||
2002 | for (i = 0; i < mod->nmarkers; ++i) { | ||
2003 | char *line = mod->markers[i]; | ||
2004 | buf_write(&buf, line, strlen(line)); | ||
2005 | while (i + 1 < mod->nmarkers && | ||
2006 | !strcmp(mod->markers[i], | ||
2007 | mod->markers[i + 1])) | ||
2008 | free(mod->markers[i++]); | ||
2009 | free(mod->markers[i]); | ||
2010 | } | ||
2011 | free(mod->markers); | ||
2012 | mod->markers = NULL; | ||
2013 | } | ||
2014 | |||
2015 | write_if_changed(&buf, fname); | ||
2016 | } | ||
2017 | |||
1870 | int main(int argc, char **argv) | 2018 | int main(int argc, char **argv) |
1871 | { | 2019 | { |
1872 | struct module *mod; | 2020 | struct module *mod; |
1873 | struct buffer buf = { }; | 2021 | struct buffer buf = { }; |
1874 | char *kernel_read = NULL, *module_read = NULL; | 2022 | char *kernel_read = NULL, *module_read = NULL; |
1875 | char *dump_write = NULL; | 2023 | char *dump_write = NULL; |
2024 | char *markers_read = NULL; | ||
2025 | char *markers_write = NULL; | ||
1876 | int opt; | 2026 | int opt; |
1877 | int err; | 2027 | int err; |
1878 | 2028 | ||
1879 | while ((opt = getopt(argc, argv, "i:I:msSo:aw")) != -1) { | 2029 | while ((opt = getopt(argc, argv, "i:I:msSo:awM:K:")) != -1) { |
1880 | switch (opt) { | 2030 | switch (opt) { |
1881 | case 'i': | 2031 | case 'i': |
1882 | kernel_read = optarg; | 2032 | kernel_read = optarg; |
@@ -1903,6 +2053,12 @@ int main(int argc, char **argv) | |||
1903 | case 'w': | 2053 | case 'w': |
1904 | warn_unresolved = 1; | 2054 | warn_unresolved = 1; |
1905 | break; | 2055 | break; |
2056 | case 'M': | ||
2057 | markers_write = optarg; | ||
2058 | break; | ||
2059 | case 'K': | ||
2060 | markers_read = optarg; | ||
2061 | break; | ||
1906 | default: | 2062 | default: |
1907 | exit(1); | 2063 | exit(1); |
1908 | } | 2064 | } |
@@ -1950,5 +2106,11 @@ int main(int argc, char **argv) | |||
1950 | "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n", | 2106 | "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n", |
1951 | sec_mismatch_count); | 2107 | sec_mismatch_count); |
1952 | 2108 | ||
2109 | if (markers_read) | ||
2110 | read_markers(markers_read); | ||
2111 | |||
2112 | if (markers_write) | ||
2113 | write_markers(markers_write); | ||
2114 | |||
1953 | return err; | 2115 | return err; |
1954 | } | 2116 | } |
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 999f15e0e008..565c5872407e 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h | |||
@@ -112,6 +112,8 @@ struct module { | |||
112 | int has_init; | 112 | int has_init; |
113 | int has_cleanup; | 113 | int has_cleanup; |
114 | struct buffer dev_table_buf; | 114 | struct buffer dev_table_buf; |
115 | char **markers; | ||
116 | size_t nmarkers; | ||
115 | char srcversion[25]; | 117 | char srcversion[25]; |
116 | }; | 118 | }; |
117 | 119 | ||
@@ -126,6 +128,7 @@ struct elf_info { | |||
126 | Elf_Section export_gpl_sec; | 128 | Elf_Section export_gpl_sec; |
127 | Elf_Section export_unused_gpl_sec; | 129 | Elf_Section export_unused_gpl_sec; |
128 | Elf_Section export_gpl_future_sec; | 130 | Elf_Section export_gpl_future_sec; |
131 | Elf_Section markers_strings_sec; | ||
129 | const char *strtab; | 132 | const char *strtab; |
130 | char *modinfo; | 133 | char *modinfo; |
131 | unsigned int modinfo_len; | 134 | unsigned int modinfo_len; |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 1c11e4245859..5b690482f8cb 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -701,7 +701,7 @@ static int smack_inode_getsecurity(const struct inode *inode, | |||
701 | return -EOPNOTSUPP; | 701 | return -EOPNOTSUPP; |
702 | 702 | ||
703 | sock = SOCKET_I(ip); | 703 | sock = SOCKET_I(ip); |
704 | if (sock == NULL) | 704 | if (sock == NULL || sock->sk == NULL) |
705 | return -EOPNOTSUPP; | 705 | return -EOPNOTSUPP; |
706 | 706 | ||
707 | ssp = sock->sk->sk_security; | 707 | ssp = sock->sk->sk_security; |
@@ -1280,10 +1280,11 @@ static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp) | |||
1280 | */ | 1280 | */ |
1281 | static int smack_netlabel(struct sock *sk) | 1281 | static int smack_netlabel(struct sock *sk) |
1282 | { | 1282 | { |
1283 | struct socket_smack *ssp = sk->sk_security; | 1283 | struct socket_smack *ssp; |
1284 | struct netlbl_lsm_secattr secattr; | 1284 | struct netlbl_lsm_secattr secattr; |
1285 | int rc = 0; | 1285 | int rc = 0; |
1286 | 1286 | ||
1287 | ssp = sk->sk_security; | ||
1287 | netlbl_secattr_init(&secattr); | 1288 | netlbl_secattr_init(&secattr); |
1288 | smack_to_secattr(ssp->smk_out, &secattr); | 1289 | smack_to_secattr(ssp->smk_out, &secattr); |
1289 | if (secattr.flags != NETLBL_SECATTR_NONE) | 1290 | if (secattr.flags != NETLBL_SECATTR_NONE) |
@@ -1331,7 +1332,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, | |||
1331 | return -EOPNOTSUPP; | 1332 | return -EOPNOTSUPP; |
1332 | 1333 | ||
1333 | sock = SOCKET_I(inode); | 1334 | sock = SOCKET_I(inode); |
1334 | if (sock == NULL) | 1335 | if (sock == NULL || sock->sk == NULL) |
1335 | return -EOPNOTSUPP; | 1336 | return -EOPNOTSUPP; |
1336 | 1337 | ||
1337 | ssp = sock->sk->sk_security; | 1338 | ssp = sock->sk->sk_security; |
@@ -1362,7 +1363,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, | |||
1362 | static int smack_socket_post_create(struct socket *sock, int family, | 1363 | static int smack_socket_post_create(struct socket *sock, int family, |
1363 | int type, int protocol, int kern) | 1364 | int type, int protocol, int kern) |
1364 | { | 1365 | { |
1365 | if (family != PF_INET) | 1366 | if (family != PF_INET || sock->sk == NULL) |
1366 | return 0; | 1367 | return 0; |
1367 | /* | 1368 | /* |
1368 | * Set the outbound netlbl. | 1369 | * Set the outbound netlbl. |