diff options
396 files changed, 9316 insertions, 4797 deletions
diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt index 5c8d74968090..fc103d7a0474 100644 --- a/Documentation/RCU/checklist.txt +++ b/Documentation/RCU/checklist.txt | |||
@@ -162,9 +162,9 @@ over a rather long period of time, but improvements are always welcome! | |||
162 | when publicizing a pointer to a structure that can | 162 | when publicizing a pointer to a structure that can |
163 | be traversed by an RCU read-side critical section. | 163 | be traversed by an RCU read-side critical section. |
164 | 164 | ||
165 | 5. If call_rcu(), or a related primitive such as call_rcu_bh() or | 165 | 5. If call_rcu(), or a related primitive such as call_rcu_bh(), |
166 | call_rcu_sched(), is used, the callback function must be | 166 | call_rcu_sched(), or call_srcu() is used, the callback function |
167 | written to be called from softirq context. In particular, | 167 | must be written to be called from softirq context. In particular, |
168 | it cannot block. | 168 | it cannot block. |
169 | 169 | ||
170 | 6. Since synchronize_rcu() can block, it cannot be called from | 170 | 6. Since synchronize_rcu() can block, it cannot be called from |
@@ -202,11 +202,12 @@ over a rather long period of time, but improvements are always welcome! | |||
202 | updater uses call_rcu_sched() or synchronize_sched(), then | 202 | updater uses call_rcu_sched() or synchronize_sched(), then |
203 | the corresponding readers must disable preemption, possibly | 203 | the corresponding readers must disable preemption, possibly |
204 | by calling rcu_read_lock_sched() and rcu_read_unlock_sched(). | 204 | by calling rcu_read_lock_sched() and rcu_read_unlock_sched(). |
205 | If the updater uses synchronize_srcu(), the the corresponding | 205 | If the updater uses synchronize_srcu() or call_srcu(), |
206 | readers must use srcu_read_lock() and srcu_read_unlock(), | 206 | the the corresponding readers must use srcu_read_lock() and |
207 | and with the same srcu_struct. The rules for the expedited | 207 | srcu_read_unlock(), and with the same srcu_struct. The rules for |
208 | primitives are the same as for their non-expedited counterparts. | 208 | the expedited primitives are the same as for their non-expedited |
209 | Mixing things up will result in confusion and broken kernels. | 209 | counterparts. Mixing things up will result in confusion and |
210 | broken kernels. | ||
210 | 211 | ||
211 | One exception to this rule: rcu_read_lock() and rcu_read_unlock() | 212 | One exception to this rule: rcu_read_lock() and rcu_read_unlock() |
212 | may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh() | 213 | may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh() |
@@ -333,14 +334,14 @@ over a rather long period of time, but improvements are always welcome! | |||
333 | victim CPU from ever going offline.) | 334 | victim CPU from ever going offline.) |
334 | 335 | ||
335 | 14. SRCU (srcu_read_lock(), srcu_read_unlock(), srcu_dereference(), | 336 | 14. SRCU (srcu_read_lock(), srcu_read_unlock(), srcu_dereference(), |
336 | synchronize_srcu(), and synchronize_srcu_expedited()) may only | 337 | synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu()) |
337 | be invoked from process context. Unlike other forms of RCU, it | 338 | may only be invoked from process context. Unlike other forms of |
338 | -is- permissible to block in an SRCU read-side critical section | 339 | RCU, it -is- permissible to block in an SRCU read-side critical |
339 | (demarked by srcu_read_lock() and srcu_read_unlock()), hence the | 340 | section (demarked by srcu_read_lock() and srcu_read_unlock()), |
340 | "SRCU": "sleepable RCU". Please note that if you don't need | 341 | hence the "SRCU": "sleepable RCU". Please note that if you |
341 | to sleep in read-side critical sections, you should be using | 342 | don't need to sleep in read-side critical sections, you should be |
342 | RCU rather than SRCU, because RCU is almost always faster and | 343 | using RCU rather than SRCU, because RCU is almost always faster |
343 | easier to use than is SRCU. | 344 | and easier to use than is SRCU. |
344 | 345 | ||
345 | If you need to enter your read-side critical section in a | 346 | If you need to enter your read-side critical section in a |
346 | hardirq or exception handler, and then exit that same read-side | 347 | hardirq or exception handler, and then exit that same read-side |
@@ -353,8 +354,8 @@ over a rather long period of time, but improvements are always welcome! | |||
353 | cleanup_srcu_struct(). These are passed a "struct srcu_struct" | 354 | cleanup_srcu_struct(). These are passed a "struct srcu_struct" |
354 | that defines the scope of a given SRCU domain. Once initialized, | 355 | that defines the scope of a given SRCU domain. Once initialized, |
355 | the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock() | 356 | the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock() |
356 | synchronize_srcu(), and synchronize_srcu_expedited(). A given | 357 | synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu(). |
357 | synchronize_srcu() waits only for SRCU read-side critical | 358 | A given synchronize_srcu() waits only for SRCU read-side critical |
358 | sections governed by srcu_read_lock() and srcu_read_unlock() | 359 | sections governed by srcu_read_lock() and srcu_read_unlock() |
359 | calls that have been passed the same srcu_struct. This property | 360 | calls that have been passed the same srcu_struct. This property |
360 | is what makes sleeping read-side critical sections tolerable -- | 361 | is what makes sleeping read-side critical sections tolerable -- |
@@ -374,7 +375,7 @@ over a rather long period of time, but improvements are always welcome! | |||
374 | requiring SRCU's read-side deadlock immunity or low read-side | 375 | requiring SRCU's read-side deadlock immunity or low read-side |
375 | realtime latency. | 376 | realtime latency. |
376 | 377 | ||
377 | Note that, rcu_assign_pointer() relates to SRCU just as they do | 378 | Note that, rcu_assign_pointer() relates to SRCU just as it does |
378 | to other forms of RCU. | 379 | to other forms of RCU. |
379 | 380 | ||
380 | 15. The whole point of call_rcu(), synchronize_rcu(), and friends | 381 | 15. The whole point of call_rcu(), synchronize_rcu(), and friends |
diff --git a/Documentation/RCU/rcubarrier.txt b/Documentation/RCU/rcubarrier.txt index e439a0edee22..38428c125135 100644 --- a/Documentation/RCU/rcubarrier.txt +++ b/Documentation/RCU/rcubarrier.txt | |||
@@ -79,8 +79,6 @@ complete. Pseudo-code using rcu_barrier() is as follows: | |||
79 | 2. Execute rcu_barrier(). | 79 | 2. Execute rcu_barrier(). |
80 | 3. Allow the module to be unloaded. | 80 | 3. Allow the module to be unloaded. |
81 | 81 | ||
82 | Quick Quiz #1: Why is there no srcu_barrier()? | ||
83 | |||
84 | The rcutorture module makes use of rcu_barrier in its exit function | 82 | The rcutorture module makes use of rcu_barrier in its exit function |
85 | as follows: | 83 | as follows: |
86 | 84 | ||
@@ -162,7 +160,7 @@ for any pre-existing callbacks to complete. | |||
162 | Then lines 55-62 print status and do operation-specific cleanup, and | 160 | Then lines 55-62 print status and do operation-specific cleanup, and |
163 | then return, permitting the module-unload operation to be completed. | 161 | then return, permitting the module-unload operation to be completed. |
164 | 162 | ||
165 | Quick Quiz #2: Is there any other situation where rcu_barrier() might | 163 | Quick Quiz #1: Is there any other situation where rcu_barrier() might |
166 | be required? | 164 | be required? |
167 | 165 | ||
168 | Your module might have additional complications. For example, if your | 166 | Your module might have additional complications. For example, if your |
@@ -242,7 +240,7 @@ reaches zero, as follows: | |||
242 | 4 complete(&rcu_barrier_completion); | 240 | 4 complete(&rcu_barrier_completion); |
243 | 5 } | 241 | 5 } |
244 | 242 | ||
245 | Quick Quiz #3: What happens if CPU 0's rcu_barrier_func() executes | 243 | Quick Quiz #2: What happens if CPU 0's rcu_barrier_func() executes |
246 | immediately (thus incrementing rcu_barrier_cpu_count to the | 244 | immediately (thus incrementing rcu_barrier_cpu_count to the |
247 | value one), but the other CPU's rcu_barrier_func() invocations | 245 | value one), but the other CPU's rcu_barrier_func() invocations |
248 | are delayed for a full grace period? Couldn't this result in | 246 | are delayed for a full grace period? Couldn't this result in |
@@ -259,12 +257,7 @@ so that your module may be safely unloaded. | |||
259 | 257 | ||
260 | Answers to Quick Quizzes | 258 | Answers to Quick Quizzes |
261 | 259 | ||
262 | Quick Quiz #1: Why is there no srcu_barrier()? | 260 | Quick Quiz #1: Is there any other situation where rcu_barrier() might |
263 | |||
264 | Answer: Since there is no call_srcu(), there can be no outstanding SRCU | ||
265 | callbacks. Therefore, there is no need to wait for them. | ||
266 | |||
267 | Quick Quiz #2: Is there any other situation where rcu_barrier() might | ||
268 | be required? | 261 | be required? |
269 | 262 | ||
270 | Answer: Interestingly enough, rcu_barrier() was not originally | 263 | Answer: Interestingly enough, rcu_barrier() was not originally |
@@ -278,7 +271,7 @@ Answer: Interestingly enough, rcu_barrier() was not originally | |||
278 | implementing rcutorture, and found that rcu_barrier() solves | 271 | implementing rcutorture, and found that rcu_barrier() solves |
279 | this problem as well. | 272 | this problem as well. |
280 | 273 | ||
281 | Quick Quiz #3: What happens if CPU 0's rcu_barrier_func() executes | 274 | Quick Quiz #2: What happens if CPU 0's rcu_barrier_func() executes |
282 | immediately (thus incrementing rcu_barrier_cpu_count to the | 275 | immediately (thus incrementing rcu_barrier_cpu_count to the |
283 | value one), but the other CPU's rcu_barrier_func() invocations | 276 | value one), but the other CPU's rcu_barrier_func() invocations |
284 | are delayed for a full grace period? Couldn't this result in | 277 | are delayed for a full grace period? Couldn't this result in |
diff --git a/Documentation/RCU/torture.txt b/Documentation/RCU/torture.txt index 4ddf3913fd8c..7dce8a17eac2 100644 --- a/Documentation/RCU/torture.txt +++ b/Documentation/RCU/torture.txt | |||
@@ -174,11 +174,20 @@ torture_type The type of RCU to test, with string values as follows: | |||
174 | and synchronize_rcu_bh_expedited(). | 174 | and synchronize_rcu_bh_expedited(). |
175 | 175 | ||
176 | "srcu": srcu_read_lock(), srcu_read_unlock() and | 176 | "srcu": srcu_read_lock(), srcu_read_unlock() and |
177 | call_srcu(). | ||
178 | |||
179 | "srcu_sync": srcu_read_lock(), srcu_read_unlock() and | ||
177 | synchronize_srcu(). | 180 | synchronize_srcu(). |
178 | 181 | ||
179 | "srcu_expedited": srcu_read_lock(), srcu_read_unlock() and | 182 | "srcu_expedited": srcu_read_lock(), srcu_read_unlock() and |
180 | synchronize_srcu_expedited(). | 183 | synchronize_srcu_expedited(). |
181 | 184 | ||
185 | "srcu_raw": srcu_read_lock_raw(), srcu_read_unlock_raw(), | ||
186 | and call_srcu(). | ||
187 | |||
188 | "srcu_raw_sync": srcu_read_lock_raw(), srcu_read_unlock_raw(), | ||
189 | and synchronize_srcu(). | ||
190 | |||
182 | "sched": preempt_disable(), preempt_enable(), and | 191 | "sched": preempt_disable(), preempt_enable(), and |
183 | call_rcu_sched(). | 192 | call_rcu_sched(). |
184 | 193 | ||
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index 6bbe8dcdc3da..69ee188515e7 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt | |||
@@ -833,9 +833,9 @@ sched: Critical sections Grace period Barrier | |||
833 | 833 | ||
834 | SRCU: Critical sections Grace period Barrier | 834 | SRCU: Critical sections Grace period Barrier |
835 | 835 | ||
836 | srcu_read_lock synchronize_srcu N/A | 836 | srcu_read_lock synchronize_srcu srcu_barrier |
837 | srcu_read_unlock synchronize_srcu_expedited | 837 | srcu_read_unlock call_srcu |
838 | srcu_read_lock_raw | 838 | srcu_read_lock_raw synchronize_srcu_expedited |
839 | srcu_read_unlock_raw | 839 | srcu_read_unlock_raw |
840 | srcu_dereference | 840 | srcu_dereference |
841 | 841 | ||
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt index 82b43f915857..a4119f6422d9 100644 --- a/Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx6q-pinctrl.txt | |||
@@ -1626,3 +1626,5 @@ MX6Q_PAD_SD2_DAT3__PCIE_CTRL_MUX_11 1587 | |||
1626 | MX6Q_PAD_SD2_DAT3__GPIO_1_12 1588 | 1626 | MX6Q_PAD_SD2_DAT3__GPIO_1_12 1588 |
1627 | MX6Q_PAD_SD2_DAT3__SJC_DONE 1589 | 1627 | MX6Q_PAD_SD2_DAT3__SJC_DONE 1589 |
1628 | MX6Q_PAD_SD2_DAT3__ANATOP_TESTO_3 1590 | 1628 | MX6Q_PAD_SD2_DAT3__ANATOP_TESTO_3 1590 |
1629 | MX6Q_PAD_ENET_RX_ER__ANATOP_USBOTG_ID 1591 | ||
1630 | MX6Q_PAD_GPIO_1__ANATOP_USBOTG_ID 1592 | ||
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt index 506c7390c2b9..13f1aa09b938 100644 --- a/Documentation/kdump/kdump.txt +++ b/Documentation/kdump/kdump.txt | |||
@@ -86,7 +86,7 @@ There is also a gitweb interface available at | |||
86 | http://www.kernel.org/git/?p=utils/kernel/kexec/kexec-tools.git | 86 | http://www.kernel.org/git/?p=utils/kernel/kexec/kexec-tools.git |
87 | 87 | ||
88 | More information about kexec-tools can be found at | 88 | More information about kexec-tools can be found at |
89 | http://www.kernel.org/pub/linux/utils/kernel/kexec/README.html | 89 | http://horms.net/projects/kexec/ |
90 | 90 | ||
91 | 3) Unpack the tarball with the tar command, as follows: | 91 | 3) Unpack the tarball with the tar command, as follows: |
92 | 92 | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index a92c5ebf373e..12783fa833c3 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2367,6 +2367,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2367 | Set maximum number of finished RCU callbacks to process | 2367 | Set maximum number of finished RCU callbacks to process |
2368 | in one batch. | 2368 | in one batch. |
2369 | 2369 | ||
2370 | rcutree.fanout_leaf= [KNL,BOOT] | ||
2371 | Increase the number of CPUs assigned to each | ||
2372 | leaf rcu_node structure. Useful for very large | ||
2373 | systems. | ||
2374 | |||
2370 | rcutree.qhimark= [KNL,BOOT] | 2375 | rcutree.qhimark= [KNL,BOOT] |
2371 | Set threshold of queued | 2376 | Set threshold of queued |
2372 | RCU callbacks over which batch limiting is disabled. | 2377 | RCU callbacks over which batch limiting is disabled. |
diff --git a/MAINTAINERS b/MAINTAINERS index 1b71f6ceae0a..fe643e7b9df6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3433,13 +3433,14 @@ S: Supported | |||
3433 | F: drivers/idle/i7300_idle.c | 3433 | F: drivers/idle/i7300_idle.c |
3434 | 3434 | ||
3435 | IEEE 802.15.4 SUBSYSTEM | 3435 | IEEE 802.15.4 SUBSYSTEM |
3436 | M: Alexander Smirnov <alex.bluesman.smirnov@gmail.com> | ||
3436 | M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3437 | M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
3437 | M: Sergey Lapin <slapin@ossfans.org> | ||
3438 | L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers) | 3438 | L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers) |
3439 | W: http://apps.sourceforge.net/trac/linux-zigbee | 3439 | W: http://apps.sourceforge.net/trac/linux-zigbee |
3440 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git | 3440 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git |
3441 | S: Maintained | 3441 | S: Maintained |
3442 | F: net/ieee802154/ | 3442 | F: net/ieee802154/ |
3443 | F: net/mac802154/ | ||
3443 | F: drivers/ieee802154/ | 3444 | F: drivers/ieee802154/ |
3444 | 3445 | ||
3445 | IIO SUBSYSTEM AND DRIVERS | 3446 | IIO SUBSYSTEM AND DRIVERS |
@@ -5564,7 +5565,7 @@ F: Documentation/networking/LICENSE.qla3xxx | |||
5564 | F: drivers/net/ethernet/qlogic/qla3xxx.* | 5565 | F: drivers/net/ethernet/qlogic/qla3xxx.* |
5565 | 5566 | ||
5566 | QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER | 5567 | QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER |
5567 | M: Anirban Chakraborty <anirban.chakraborty@qlogic.com> | 5568 | M: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> |
5568 | M: Sony Chacko <sony.chacko@qlogic.com> | 5569 | M: Sony Chacko <sony.chacko@qlogic.com> |
5569 | M: linux-driver@qlogic.com | 5570 | M: linux-driver@qlogic.com |
5570 | L: netdev@vger.kernel.org | 5571 | L: netdev@vger.kernel.org |
@@ -5572,7 +5573,6 @@ S: Supported | |||
5572 | F: drivers/net/ethernet/qlogic/qlcnic/ | 5573 | F: drivers/net/ethernet/qlogic/qlcnic/ |
5573 | 5574 | ||
5574 | QLOGIC QLGE 10Gb ETHERNET DRIVER | 5575 | QLOGIC QLGE 10Gb ETHERNET DRIVER |
5575 | M: Anirban Chakraborty <anirban.chakraborty@qlogic.com> | ||
5576 | M: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> | 5576 | M: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> |
5577 | M: Ron Mercer <ron.mercer@qlogic.com> | 5577 | M: Ron Mercer <ron.mercer@qlogic.com> |
5578 | M: linux-driver@qlogic.com | 5578 | M: linux-driver@qlogic.com |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 3 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 5 | 2 | PATCHLEVEL = 5 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc7 | 4 | EXTRAVERSION = |
5 | NAME = Saber-toothed Squirrel | 5 | NAME = Saber-toothed Squirrel |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi index 10dcec7e7321..f7b84aced654 100644 --- a/arch/arm/boot/dts/spear13xx.dtsi +++ b/arch/arm/boot/dts/spear13xx.dtsi | |||
@@ -43,8 +43,8 @@ | |||
43 | 43 | ||
44 | pmu { | 44 | pmu { |
45 | compatible = "arm,cortex-a9-pmu"; | 45 | compatible = "arm,cortex-a9-pmu"; |
46 | interrupts = <0 8 0x04 | 46 | interrupts = <0 6 0x04 |
47 | 0 9 0x04>; | 47 | 0 7 0x04>; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | L2: l2-cache { | 50 | L2: l2-cache { |
@@ -119,8 +119,8 @@ | |||
119 | gmac0: eth@e2000000 { | 119 | gmac0: eth@e2000000 { |
120 | compatible = "st,spear600-gmac"; | 120 | compatible = "st,spear600-gmac"; |
121 | reg = <0xe2000000 0x8000>; | 121 | reg = <0xe2000000 0x8000>; |
122 | interrupts = <0 23 0x4 | 122 | interrupts = <0 33 0x4 |
123 | 0 24 0x4>; | 123 | 0 34 0x4>; |
124 | interrupt-names = "macirq", "eth_wake_irq"; | 124 | interrupt-names = "macirq", "eth_wake_irq"; |
125 | status = "disabled"; | 125 | status = "disabled"; |
126 | }; | 126 | }; |
@@ -202,6 +202,7 @@ | |||
202 | kbd@e0300000 { | 202 | kbd@e0300000 { |
203 | compatible = "st,spear300-kbd"; | 203 | compatible = "st,spear300-kbd"; |
204 | reg = <0xe0300000 0x1000>; | 204 | reg = <0xe0300000 0x1000>; |
205 | interrupts = <0 52 0x4>; | ||
205 | status = "disabled"; | 206 | status = "disabled"; |
206 | }; | 207 | }; |
207 | 208 | ||
@@ -224,7 +225,7 @@ | |||
224 | serial@e0000000 { | 225 | serial@e0000000 { |
225 | compatible = "arm,pl011", "arm,primecell"; | 226 | compatible = "arm,pl011", "arm,primecell"; |
226 | reg = <0xe0000000 0x1000>; | 227 | reg = <0xe0000000 0x1000>; |
227 | interrupts = <0 36 0x4>; | 228 | interrupts = <0 35 0x4>; |
228 | status = "disabled"; | 229 | status = "disabled"; |
229 | }; | 230 | }; |
230 | 231 | ||
diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts index c13fd1f3b09f..e4e912f95024 100644 --- a/arch/arm/boot/dts/spear320-evb.dts +++ b/arch/arm/boot/dts/spear320-evb.dts | |||
@@ -15,8 +15,8 @@ | |||
15 | /include/ "spear320.dtsi" | 15 | /include/ "spear320.dtsi" |
16 | 16 | ||
17 | / { | 17 | / { |
18 | model = "ST SPEAr300 Evaluation Board"; | 18 | model = "ST SPEAr320 Evaluation Board"; |
19 | compatible = "st,spear300-evb", "st,spear300"; | 19 | compatible = "st,spear320-evb", "st,spear320"; |
20 | #address-cells = <1>; | 20 | #address-cells = <1>; |
21 | #size-cells = <1>; | 21 | #size-cells = <1>; |
22 | 22 | ||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | ahb { | 27 | ahb { |
28 | pinmux@b3000000 { | 28 | pinmux@b3000000 { |
29 | st,pinmux-mode = <3>; | 29 | st,pinmux-mode = <4>; |
30 | pinctrl-names = "default"; | 30 | pinctrl-names = "default"; |
31 | pinctrl-0 = <&state_default>; | 31 | pinctrl-0 = <&state_default>; |
32 | 32 | ||
diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi index 089f0a42c50e..a3c36e47d7ef 100644 --- a/arch/arm/boot/dts/spear600.dtsi +++ b/arch/arm/boot/dts/spear600.dtsi | |||
@@ -181,6 +181,7 @@ | |||
181 | timer@f0000000 { | 181 | timer@f0000000 { |
182 | compatible = "st,spear-timer"; | 182 | compatible = "st,spear-timer"; |
183 | reg = <0xf0000000 0x400>; | 183 | reg = <0xf0000000 0x400>; |
184 | interrupt-parent = <&vic0>; | ||
184 | interrupts = <16>; | 185 | interrupts = <16>; |
185 | }; | 186 | }; |
186 | }; | 187 | }; |
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c index 0f41bd1c47c3..66db5f13af84 100644 --- a/arch/arm/mach-spear3xx/spear3xx.c +++ b/arch/arm/mach-spear3xx/spear3xx.c | |||
@@ -87,7 +87,7 @@ void __init spear3xx_map_io(void) | |||
87 | 87 | ||
88 | static void __init spear3xx_timer_init(void) | 88 | static void __init spear3xx_timer_init(void) |
89 | { | 89 | { |
90 | char pclk_name[] = "pll3_48m_clk"; | 90 | char pclk_name[] = "pll3_clk"; |
91 | struct clk *gpt_clk, *pclk; | 91 | struct clk *gpt_clk, *pclk; |
92 | 92 | ||
93 | spear3xx_clk_init(); | 93 | spear3xx_clk_init(); |
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c index 2e2e3596583e..9af67d003c62 100644 --- a/arch/arm/mach-spear6xx/spear6xx.c +++ b/arch/arm/mach-spear6xx/spear6xx.c | |||
@@ -423,7 +423,7 @@ void __init spear6xx_map_io(void) | |||
423 | 423 | ||
424 | static void __init spear6xx_timer_init(void) | 424 | static void __init spear6xx_timer_init(void) |
425 | { | 425 | { |
426 | char pclk_name[] = "pll3_48m_clk"; | 426 | char pclk_name[] = "pll3_clk"; |
427 | struct clk *gpt_clk, *pclk; | 427 | struct clk *gpt_clk, *pclk; |
428 | 428 | ||
429 | spear6xx_clk_init(); | 429 | spear6xx_clk_init(); |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 4044abcf6f9d..655878bcc96d 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -1091,7 +1091,7 @@ error: | |||
1091 | while (--i) | 1091 | while (--i) |
1092 | if (pages[i]) | 1092 | if (pages[i]) |
1093 | __free_pages(pages[i], 0); | 1093 | __free_pages(pages[i], 0); |
1094 | if (array_size < PAGE_SIZE) | 1094 | if (array_size <= PAGE_SIZE) |
1095 | kfree(pages); | 1095 | kfree(pages); |
1096 | else | 1096 | else |
1097 | vfree(pages); | 1097 | vfree(pages); |
@@ -1106,7 +1106,7 @@ static int __iommu_free_buffer(struct device *dev, struct page **pages, size_t s | |||
1106 | for (i = 0; i < count; i++) | 1106 | for (i = 0; i < count; i++) |
1107 | if (pages[i]) | 1107 | if (pages[i]) |
1108 | __free_pages(pages[i], 0); | 1108 | __free_pages(pages[i], 0); |
1109 | if (array_size < PAGE_SIZE) | 1109 | if (array_size <= PAGE_SIZE) |
1110 | kfree(pages); | 1110 | kfree(pages); |
1111 | else | 1111 | else |
1112 | vfree(pages); | 1112 | vfree(pages); |
diff --git a/arch/hexagon/kernel/smp.c b/arch/hexagon/kernel/smp.c index f7264621e58d..149fbefc1a4d 100644 --- a/arch/hexagon/kernel/smp.c +++ b/arch/hexagon/kernel/smp.c | |||
@@ -180,9 +180,7 @@ void __cpuinit start_secondary(void) | |||
180 | 180 | ||
181 | notify_cpu_starting(cpu); | 181 | notify_cpu_starting(cpu); |
182 | 182 | ||
183 | ipi_call_lock(); | ||
184 | set_cpu_online(cpu, true); | 183 | set_cpu_online(cpu, true); |
185 | ipi_call_unlock(); | ||
186 | 184 | ||
187 | local_irq_enable(); | 185 | local_irq_enable(); |
188 | 186 | ||
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 1113b8aba07f..963d2db53bfa 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -382,7 +382,6 @@ smp_callin (void) | |||
382 | set_numa_node(cpu_to_node_map[cpuid]); | 382 | set_numa_node(cpu_to_node_map[cpuid]); |
383 | set_numa_mem(local_memory_node(cpu_to_node_map[cpuid])); | 383 | set_numa_mem(local_memory_node(cpu_to_node_map[cpuid])); |
384 | 384 | ||
385 | ipi_call_lock_irq(); | ||
386 | spin_lock(&vector_lock); | 385 | spin_lock(&vector_lock); |
387 | /* Setup the per cpu irq handling data structures */ | 386 | /* Setup the per cpu irq handling data structures */ |
388 | __setup_vector_irq(cpuid); | 387 | __setup_vector_irq(cpuid); |
@@ -390,7 +389,6 @@ smp_callin (void) | |||
390 | set_cpu_online(cpuid, true); | 389 | set_cpu_online(cpuid, true); |
391 | per_cpu(cpu_state, cpuid) = CPU_ONLINE; | 390 | per_cpu(cpu_state, cpuid) = CPU_ONLINE; |
392 | spin_unlock(&vector_lock); | 391 | spin_unlock(&vector_lock); |
393 | ipi_call_unlock_irq(); | ||
394 | 392 | ||
395 | smp_setup_percpu_timer(); | 393 | smp_setup_percpu_timer(); |
396 | 394 | ||
diff --git a/arch/m32r/boot/compressed/Makefile b/arch/m32r/boot/compressed/Makefile index 177716b1d613..01729c2979ba 100644 --- a/arch/m32r/boot/compressed/Makefile +++ b/arch/m32r/boot/compressed/Makefile | |||
@@ -43,9 +43,9 @@ endif | |||
43 | 43 | ||
44 | OBJCOPYFLAGS += -R .empty_zero_page | 44 | OBJCOPYFLAGS += -R .empty_zero_page |
45 | 45 | ||
46 | suffix_$(CONFIG_KERNEL_GZIP) = gz | 46 | suffix-$(CONFIG_KERNEL_GZIP) = gz |
47 | suffix_$(CONFIG_KERNEL_BZIP2) = bz2 | 47 | suffix-$(CONFIG_KERNEL_BZIP2) = bz2 |
48 | suffix_$(CONFIG_KERNEL_LZMA) = lzma | 48 | suffix-$(CONFIG_KERNEL_LZMA) = lzma |
49 | 49 | ||
50 | $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE | 50 | $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE |
51 | $(call if_changed,ld) | 51 | $(call if_changed,ld) |
diff --git a/arch/m32r/boot/compressed/misc.c b/arch/m32r/boot/compressed/misc.c index 370d60881977..28a09529f206 100644 --- a/arch/m32r/boot/compressed/misc.c +++ b/arch/m32r/boot/compressed/misc.c | |||
@@ -28,7 +28,7 @@ static unsigned long free_mem_ptr; | |||
28 | static unsigned long free_mem_end_ptr; | 28 | static unsigned long free_mem_end_ptr; |
29 | 29 | ||
30 | #ifdef CONFIG_KERNEL_BZIP2 | 30 | #ifdef CONFIG_KERNEL_BZIP2 |
31 | static void *memset(void *s, int c, size_t n) | 31 | void *memset(void *s, int c, size_t n) |
32 | { | 32 | { |
33 | char *ss = s; | 33 | char *ss = s; |
34 | 34 | ||
@@ -39,6 +39,16 @@ static void *memset(void *s, int c, size_t n) | |||
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #ifdef CONFIG_KERNEL_GZIP | 41 | #ifdef CONFIG_KERNEL_GZIP |
42 | void *memcpy(void *dest, const void *src, size_t n) | ||
43 | { | ||
44 | char *d = dest; | ||
45 | const char *s = src; | ||
46 | while (n--) | ||
47 | *d++ = *s++; | ||
48 | |||
49 | return dest; | ||
50 | } | ||
51 | |||
42 | #define BOOT_HEAP_SIZE 0x10000 | 52 | #define BOOT_HEAP_SIZE 0x10000 |
43 | #include "../../../../lib/decompress_inflate.c" | 53 | #include "../../../../lib/decompress_inflate.c" |
44 | #endif | 54 | #endif |
diff --git a/arch/m32r/include/asm/ptrace.h b/arch/m32r/include/asm/ptrace.h index 527527584dd0..4313aa62b51b 100644 --- a/arch/m32r/include/asm/ptrace.h +++ b/arch/m32r/include/asm/ptrace.h | |||
@@ -113,9 +113,6 @@ struct pt_regs { | |||
113 | 113 | ||
114 | #define PTRACE_OLDSETOPTIONS 21 | 114 | #define PTRACE_OLDSETOPTIONS 21 |
115 | 115 | ||
116 | /* options set using PTRACE_SETOPTIONS */ | ||
117 | #define PTRACE_O_TRACESYSGOOD 0x00000001 | ||
118 | |||
119 | #ifdef __KERNEL__ | 116 | #ifdef __KERNEL__ |
120 | 117 | ||
121 | #include <asm/m32r.h> /* M32R_PSW_BSM, M32R_PSW_BPM */ | 118 | #include <asm/m32r.h> /* M32R_PSW_BSM, M32R_PSW_BPM */ |
diff --git a/arch/m32r/include/asm/smp.h b/arch/m32r/include/asm/smp.h index cf7829a61551..c689b828dfe2 100644 --- a/arch/m32r/include/asm/smp.h +++ b/arch/m32r/include/asm/smp.h | |||
@@ -79,11 +79,6 @@ static __inline__ int cpu_number_map(int cpu) | |||
79 | return cpu; | 79 | return cpu; |
80 | } | 80 | } |
81 | 81 | ||
82 | static __inline__ unsigned int num_booting_cpus(void) | ||
83 | { | ||
84 | return cpumask_weight(&cpu_callout_map); | ||
85 | } | ||
86 | |||
87 | extern void smp_send_timer(void); | 82 | extern void smp_send_timer(void); |
88 | extern unsigned long send_IPI_mask_phys(const cpumask_t*, int, int); | 83 | extern unsigned long send_IPI_mask_phys(const cpumask_t*, int, int); |
89 | 84 | ||
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c index 4c03361537aa..51f5e9aa4901 100644 --- a/arch/m32r/kernel/ptrace.c +++ b/arch/m32r/kernel/ptrace.c | |||
@@ -591,17 +591,16 @@ void user_enable_single_step(struct task_struct *child) | |||
591 | 591 | ||
592 | if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) | 592 | if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) |
593 | != sizeof(insn)) | 593 | != sizeof(insn)) |
594 | return -EIO; | 594 | return; |
595 | 595 | ||
596 | compute_next_pc(insn, pc, &next_pc, child); | 596 | compute_next_pc(insn, pc, &next_pc, child); |
597 | if (next_pc & 0x80000000) | 597 | if (next_pc & 0x80000000) |
598 | return -EIO; | 598 | return; |
599 | 599 | ||
600 | if (embed_debug_trap(child, next_pc)) | 600 | if (embed_debug_trap(child, next_pc)) |
601 | return -EIO; | 601 | return; |
602 | 602 | ||
603 | invalidate_cache(); | 603 | invalidate_cache(); |
604 | return 0; | ||
605 | } | 604 | } |
606 | 605 | ||
607 | void user_disable_single_step(struct task_struct *child) | 606 | void user_disable_single_step(struct task_struct *child) |
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index f3fb2c029cfc..d0f60b97bbc5 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c | |||
@@ -286,7 +286,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
286 | case -ERESTARTNOINTR: | 286 | case -ERESTARTNOINTR: |
287 | regs->r0 = regs->orig_r0; | 287 | regs->r0 = regs->orig_r0; |
288 | if (prev_insn(regs) < 0) | 288 | if (prev_insn(regs) < 0) |
289 | return -EFAULT; | 289 | return; |
290 | } | 290 | } |
291 | } | 291 | } |
292 | 292 | ||
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 09ab87ee6fef..b3e10fdd3898 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -288,6 +288,7 @@ config MIPS_MALTA | |||
288 | select SYS_HAS_CPU_MIPS32_R1 | 288 | select SYS_HAS_CPU_MIPS32_R1 |
289 | select SYS_HAS_CPU_MIPS32_R2 | 289 | select SYS_HAS_CPU_MIPS32_R2 |
290 | select SYS_HAS_CPU_MIPS64_R1 | 290 | select SYS_HAS_CPU_MIPS64_R1 |
291 | select SYS_HAS_CPU_MIPS64_R2 | ||
291 | select SYS_HAS_CPU_NEVADA | 292 | select SYS_HAS_CPU_NEVADA |
292 | select SYS_HAS_CPU_RM7000 | 293 | select SYS_HAS_CPU_RM7000 |
293 | select SYS_HAS_EARLY_PRINTK | 294 | select SYS_HAS_EARLY_PRINTK |
@@ -1423,6 +1424,7 @@ config CPU_SB1 | |||
1423 | config CPU_CAVIUM_OCTEON | 1424 | config CPU_CAVIUM_OCTEON |
1424 | bool "Cavium Octeon processor" | 1425 | bool "Cavium Octeon processor" |
1425 | depends on SYS_HAS_CPU_CAVIUM_OCTEON | 1426 | depends on SYS_HAS_CPU_CAVIUM_OCTEON |
1427 | select ARCH_SPARSEMEM_ENABLE | ||
1426 | select CPU_HAS_PREFETCH | 1428 | select CPU_HAS_PREFETCH |
1427 | select CPU_SUPPORTS_64BIT_KERNEL | 1429 | select CPU_SUPPORTS_64BIT_KERNEL |
1428 | select SYS_SUPPORTS_SMP | 1430 | select SYS_SUPPORTS_SMP |
diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig index 6210b8d84109..b311be45a720 100644 --- a/arch/mips/bcm47xx/Kconfig +++ b/arch/mips/bcm47xx/Kconfig | |||
@@ -21,6 +21,7 @@ config BCM47XX_BCMA | |||
21 | select BCMA | 21 | select BCMA |
22 | select BCMA_HOST_SOC | 22 | select BCMA_HOST_SOC |
23 | select BCMA_DRIVER_MIPS | 23 | select BCMA_DRIVER_MIPS |
24 | select BCMA_HOST_PCI if PCI | ||
24 | select BCMA_DRIVER_PCI_HOSTMODE if PCI | 25 | select BCMA_DRIVER_PCI_HOSTMODE if PCI |
25 | default y | 26 | default y |
26 | help | 27 | help |
diff --git a/arch/mips/bcm63xx/dev-pcmcia.c b/arch/mips/bcm63xx/dev-pcmcia.c index de4d917fd54d..a551bab5ecb9 100644 --- a/arch/mips/bcm63xx/dev-pcmcia.c +++ b/arch/mips/bcm63xx/dev-pcmcia.c | |||
@@ -79,11 +79,11 @@ static int __init config_pcmcia_cs(unsigned int cs, | |||
79 | return ret; | 79 | return ret; |
80 | } | 80 | } |
81 | 81 | ||
82 | static const __initdata struct { | 82 | static const struct { |
83 | unsigned int cs; | 83 | unsigned int cs; |
84 | unsigned int base; | 84 | unsigned int base; |
85 | unsigned int size; | 85 | unsigned int size; |
86 | } pcmcia_cs[3] = { | 86 | } pcmcia_cs[3] __initconst = { |
87 | { | 87 | { |
88 | .cs = MPI_CS_PCMCIA_COMMON, | 88 | .cs = MPI_CS_PCMCIA_COMMON, |
89 | .base = BCM_PCMCIA_COMMON_BASE_PA, | 89 | .base = BCM_PCMCIA_COMMON_BASE_PA, |
diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig index f9e275a50d98..2f4f6d5e05b6 100644 --- a/arch/mips/cavium-octeon/Kconfig +++ b/arch/mips/cavium-octeon/Kconfig | |||
@@ -82,10 +82,6 @@ config CAVIUM_OCTEON_LOCK_L2_MEMCPY | |||
82 | help | 82 | help |
83 | Lock the kernel's implementation of memcpy() into L2. | 83 | Lock the kernel's implementation of memcpy() into L2. |
84 | 84 | ||
85 | config ARCH_SPARSEMEM_ENABLE | ||
86 | def_bool y | ||
87 | select SPARSEMEM_STATIC | ||
88 | |||
89 | config IOMMU_HELPER | 85 | config IOMMU_HELPER |
90 | bool | 86 | bool |
91 | 87 | ||
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 4b93048044eb..ee1fb9f7f517 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c | |||
@@ -185,7 +185,6 @@ static void __cpuinit octeon_init_secondary(void) | |||
185 | octeon_init_cvmcount(); | 185 | octeon_init_cvmcount(); |
186 | 186 | ||
187 | octeon_irq_setup_secondary(); | 187 | octeon_irq_setup_secondary(); |
188 | raw_local_irq_enable(); | ||
189 | } | 188 | } |
190 | 189 | ||
191 | /** | 190 | /** |
@@ -233,6 +232,7 @@ static void octeon_smp_finish(void) | |||
233 | 232 | ||
234 | /* to generate the first CPU timer interrupt */ | 233 | /* to generate the first CPU timer interrupt */ |
235 | write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); | 234 | write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); |
235 | local_irq_enable(); | ||
236 | } | 236 | } |
237 | 237 | ||
238 | /** | 238 | /** |
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 2e1ad4c652b7..82ad35ce2b45 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/irqflags.h> | 17 | #include <linux/irqflags.h> |
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <asm/barrier.h> | 19 | #include <asm/barrier.h> |
20 | #include <asm/bug.h> | ||
21 | #include <asm/byteorder.h> /* sigh ... */ | 20 | #include <asm/byteorder.h> /* sigh ... */ |
22 | #include <asm/cpu-features.h> | 21 | #include <asm/cpu-features.h> |
23 | #include <asm/sgidefs.h> | 22 | #include <asm/sgidefs.h> |
diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h index 285a41fa0b18..eee10dc07ac1 100644 --- a/arch/mips/include/asm/cmpxchg.h +++ b/arch/mips/include/asm/cmpxchg.h | |||
@@ -8,6 +8,7 @@ | |||
8 | #ifndef __ASM_CMPXCHG_H | 8 | #ifndef __ASM_CMPXCHG_H |
9 | #define __ASM_CMPXCHG_H | 9 | #define __ASM_CMPXCHG_H |
10 | 10 | ||
11 | #include <linux/bug.h> | ||
11 | #include <linux/irqflags.h> | 12 | #include <linux/irqflags.h> |
12 | #include <asm/war.h> | 13 | #include <asm/war.h> |
13 | 14 | ||
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index f9fa2a479dd0..95e40c1e8ed1 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
@@ -94,6 +94,7 @@ | |||
94 | #define PRID_IMP_24KE 0x9600 | 94 | #define PRID_IMP_24KE 0x9600 |
95 | #define PRID_IMP_74K 0x9700 | 95 | #define PRID_IMP_74K 0x9700 |
96 | #define PRID_IMP_1004K 0x9900 | 96 | #define PRID_IMP_1004K 0x9900 |
97 | #define PRID_IMP_M14KC 0x9c00 | ||
97 | 98 | ||
98 | /* | 99 | /* |
99 | * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE | 100 | * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE |
@@ -260,12 +261,12 @@ enum cpu_type_enum { | |||
260 | */ | 261 | */ |
261 | CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, | 262 | CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, |
262 | CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, | 263 | CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, |
263 | CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, | 264 | CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_M14KC, |
264 | 265 | ||
265 | /* | 266 | /* |
266 | * MIPS64 class processors | 267 | * MIPS64 class processors |
267 | */ | 268 | */ |
268 | CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2, | 269 | CPU_5KC, CPU_5KE, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2, |
269 | CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2, | 270 | CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2, |
270 | CPU_XLR, CPU_XLP, | 271 | CPU_XLR, CPU_XLP, |
271 | 272 | ||
@@ -288,7 +289,7 @@ enum cpu_type_enum { | |||
288 | #define MIPS_CPU_ISA_M64R2 0x00000100 | 289 | #define MIPS_CPU_ISA_M64R2 0x00000100 |
289 | 290 | ||
290 | #define MIPS_CPU_ISA_32BIT (MIPS_CPU_ISA_I | MIPS_CPU_ISA_II | \ | 291 | #define MIPS_CPU_ISA_32BIT (MIPS_CPU_ISA_I | MIPS_CPU_ISA_II | \ |
291 | MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 ) | 292 | MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2) |
292 | #define MIPS_CPU_ISA_64BIT (MIPS_CPU_ISA_III | MIPS_CPU_ISA_IV | \ | 293 | #define MIPS_CPU_ISA_64BIT (MIPS_CPU_ISA_III | MIPS_CPU_ISA_IV | \ |
293 | MIPS_CPU_ISA_V | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2) | 294 | MIPS_CPU_ISA_V | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2) |
294 | 295 | ||
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 86548da650e7..991b659e2548 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h | |||
@@ -206,7 +206,7 @@ | |||
206 | 206 | ||
207 | #define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 | 207 | #define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 |
208 | #define GIC_VPE_EIC_SS(intr) \ | 208 | #define GIC_VPE_EIC_SS(intr) \ |
209 | (GIC_EIC_SHADOW_SET_BASE + (4 * intr)) | 209 | (GIC_VPE_EIC_SHADOW_SET_BASE + (4 * intr)) |
210 | 210 | ||
211 | #define GIC_VPE_EIC_VEC_BASE 0x0800 | 211 | #define GIC_VPE_EIC_VEC_BASE 0x0800 |
212 | #define GIC_VPE_EIC_VEC(intr) \ | 212 | #define GIC_VPE_EIC_VEC(intr) \ |
@@ -330,6 +330,17 @@ struct gic_intr_map { | |||
330 | #define GIC_FLAG_TRANSPARENT 0x02 | 330 | #define GIC_FLAG_TRANSPARENT 0x02 |
331 | }; | 331 | }; |
332 | 332 | ||
333 | /* | ||
334 | * This is only used in EIC mode. This helps to figure out which | ||
335 | * shared interrupts we need to process when we get a vector interrupt. | ||
336 | */ | ||
337 | #define GIC_MAX_SHARED_INTR 0x5 | ||
338 | struct gic_shared_intr_map { | ||
339 | unsigned int num_shared_intr; | ||
340 | unsigned int intr_list[GIC_MAX_SHARED_INTR]; | ||
341 | unsigned int local_intr_mask; | ||
342 | }; | ||
343 | |||
333 | extern void gic_init(unsigned long gic_base_addr, | 344 | extern void gic_init(unsigned long gic_base_addr, |
334 | unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, | 345 | unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, |
335 | unsigned int intrmap_size, unsigned int irqbase); | 346 | unsigned int intrmap_size, unsigned int irqbase); |
@@ -338,5 +349,7 @@ extern unsigned int gic_get_int(void); | |||
338 | extern void gic_send_ipi(unsigned int intr); | 349 | extern void gic_send_ipi(unsigned int intr); |
339 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); | 350 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); |
340 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); | 351 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); |
352 | extern void gic_bind_eic_interrupt(int irq, int set); | ||
353 | extern unsigned int gic_get_timer_pending(void); | ||
341 | 354 | ||
342 | #endif /* _ASM_GICREGS_H */ | 355 | #endif /* _ASM_GICREGS_H */ |
diff --git a/arch/mips/include/asm/inst.h b/arch/mips/include/asm/inst.h index 7ebfc392e58d..ab84064283db 100644 --- a/arch/mips/include/asm/inst.h +++ b/arch/mips/include/asm/inst.h | |||
@@ -251,7 +251,7 @@ struct f_format { /* FPU register format */ | |||
251 | unsigned int func : 6; | 251 | unsigned int func : 6; |
252 | }; | 252 | }; |
253 | 253 | ||
254 | struct ma_format { /* FPU multipy and add format (MIPS IV) */ | 254 | struct ma_format { /* FPU multiply and add format (MIPS IV) */ |
255 | unsigned int opcode : 6; | 255 | unsigned int opcode : 6; |
256 | unsigned int fr : 5; | 256 | unsigned int fr : 5; |
257 | unsigned int ft : 5; | 257 | unsigned int ft : 5; |
@@ -324,7 +324,7 @@ struct f_format { /* FPU register format */ | |||
324 | unsigned int opcode : 6; | 324 | unsigned int opcode : 6; |
325 | }; | 325 | }; |
326 | 326 | ||
327 | struct ma_format { /* FPU multipy and add format (MIPS IV) */ | 327 | struct ma_format { /* FPU multiply and add format (MIPS IV) */ |
328 | unsigned int fmt : 2; | 328 | unsigned int fmt : 2; |
329 | unsigned int func : 4; | 329 | unsigned int func : 4; |
330 | unsigned int fd : 5; | 330 | unsigned int fd : 5; |
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index a58f22998a86..29d9c23c20c7 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | 18 | ||
19 | #include <asm/addrspace.h> | 19 | #include <asm/addrspace.h> |
20 | #include <asm/bug.h> | ||
20 | #include <asm/byteorder.h> | 21 | #include <asm/byteorder.h> |
21 | #include <asm/cpu.h> | 22 | #include <asm/cpu.h> |
22 | #include <asm/cpu-features.h> | 23 | #include <asm/cpu-features.h> |
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index fb698dc09bc9..78dbb8a86da2 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h | |||
@@ -136,6 +136,7 @@ extern void free_irqno(unsigned int irq); | |||
136 | * IE7. Since R2 their number has to be read from the c0_intctl register. | 136 | * IE7. Since R2 their number has to be read from the c0_intctl register. |
137 | */ | 137 | */ |
138 | #define CP0_LEGACY_COMPARE_IRQ 7 | 138 | #define CP0_LEGACY_COMPARE_IRQ 7 |
139 | #define CP0_LEGACY_PERFCNT_IRQ 7 | ||
139 | 140 | ||
140 | extern int cp0_compare_irq; | 141 | extern int cp0_compare_irq; |
141 | extern int cp0_compare_irq_shift; | 142 | extern int cp0_compare_irq_shift; |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index 94d4faad29a1..fdcd78ca1b03 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | |||
@@ -99,7 +99,7 @@ | |||
99 | #define CKCTL_6368_USBH_CLK_EN (1 << 15) | 99 | #define CKCTL_6368_USBH_CLK_EN (1 << 15) |
100 | #define CKCTL_6368_DISABLE_GLESS_EN (1 << 16) | 100 | #define CKCTL_6368_DISABLE_GLESS_EN (1 << 16) |
101 | #define CKCTL_6368_NAND_CLK_EN (1 << 17) | 101 | #define CKCTL_6368_NAND_CLK_EN (1 << 17) |
102 | #define CKCTL_6368_IPSEC_CLK_EN (1 << 17) | 102 | #define CKCTL_6368_IPSEC_CLK_EN (1 << 18) |
103 | 103 | ||
104 | #define CKCTL_6368_ALL_SAFE_EN (CKCTL_6368_SWPKT_USB_EN | \ | 104 | #define CKCTL_6368_ALL_SAFE_EN (CKCTL_6368_SWPKT_USB_EN | \ |
105 | CKCTL_6368_SWPKT_SAR_EN | \ | 105 | CKCTL_6368_SWPKT_SAR_EN | \ |
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index d11aa02a956a..5447d9fc4219 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h | |||
@@ -86,6 +86,16 @@ | |||
86 | #define GIC_CPU_INT4 4 /* . */ | 86 | #define GIC_CPU_INT4 4 /* . */ |
87 | #define GIC_CPU_INT5 5 /* Core Interrupt 5 */ | 87 | #define GIC_CPU_INT5 5 /* Core Interrupt 5 */ |
88 | 88 | ||
89 | /* MALTA GIC local interrupts */ | ||
90 | #define GIC_INT_TMR (GIC_CPU_INT5) | ||
91 | #define GIC_INT_PERFCTR (GIC_CPU_INT5) | ||
92 | |||
93 | /* GIC constants */ | ||
94 | /* Add 2 to convert non-eic hw int # to eic vector # */ | ||
95 | #define GIC_CPU_TO_VEC_OFFSET (2) | ||
96 | /* If we map an intr to pin X, GIC will actually generate vector X+1 */ | ||
97 | #define GIC_PIN_TO_VEC_OFFSET (1) | ||
98 | |||
89 | #define GIC_EXT_INTR(x) x | 99 | #define GIC_EXT_INTR(x) x |
90 | 100 | ||
91 | /* External Interrupts used for IPI */ | 101 | /* External Interrupts used for IPI */ |
diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h index c9420aa97e32..e71ff4c317f2 100644 --- a/arch/mips/include/asm/mipsmtregs.h +++ b/arch/mips/include/asm/mipsmtregs.h | |||
@@ -48,7 +48,7 @@ | |||
48 | #define CP0_VPECONF0 $1, 2 | 48 | #define CP0_VPECONF0 $1, 2 |
49 | #define CP0_VPECONF1 $1, 3 | 49 | #define CP0_VPECONF1 $1, 3 |
50 | #define CP0_YQMASK $1, 4 | 50 | #define CP0_YQMASK $1, 4 |
51 | #define CP0_VPESCHEDULE $1, 5 | 51 | #define CP0_VPESCHEDULE $1, 5 |
52 | #define CP0_VPESCHEFBK $1, 6 | 52 | #define CP0_VPESCHEFBK $1, 6 |
53 | #define CP0_TCSTATUS $2, 1 | 53 | #define CP0_TCSTATUS $2, 1 |
54 | #define CP0_TCBIND $2, 2 | 54 | #define CP0_TCBIND $2, 2 |
diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h index 5d33621b5658..4f8ddba8c360 100644 --- a/arch/mips/include/asm/switch_to.h +++ b/arch/mips/include/asm/switch_to.h | |||
@@ -22,7 +22,7 @@ struct task_struct; | |||
22 | * switch_to(n) should switch tasks to task nr n, first | 22 | * switch_to(n) should switch tasks to task nr n, first |
23 | * checking that n isn't the current task, in which case it does nothing. | 23 | * checking that n isn't the current task, in which case it does nothing. |
24 | */ | 24 | */ |
25 | extern asmlinkage void *resume(void *last, void *next, void *next_ti); | 25 | extern asmlinkage void *resume(void *last, void *next, void *next_ti, u32 __usedfpu); |
26 | 26 | ||
27 | extern unsigned int ll_bit; | 27 | extern unsigned int ll_bit; |
28 | extern struct task_struct *ll_task; | 28 | extern struct task_struct *ll_task; |
@@ -66,11 +66,13 @@ do { \ | |||
66 | 66 | ||
67 | #define switch_to(prev, next, last) \ | 67 | #define switch_to(prev, next, last) \ |
68 | do { \ | 68 | do { \ |
69 | u32 __usedfpu; \ | ||
69 | __mips_mt_fpaff_switch_to(prev); \ | 70 | __mips_mt_fpaff_switch_to(prev); \ |
70 | if (cpu_has_dsp) \ | 71 | if (cpu_has_dsp) \ |
71 | __save_dsp(prev); \ | 72 | __save_dsp(prev); \ |
72 | __clear_software_ll_bit(); \ | 73 | __clear_software_ll_bit(); \ |
73 | (last) = resume(prev, next, task_thread_info(next)); \ | 74 | __usedfpu = test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU); \ |
75 | (last) = resume(prev, next, task_thread_info(next), __usedfpu); \ | ||
74 | } while (0) | 76 | } while (0) |
75 | 77 | ||
76 | #define finish_arch_switch(prev) \ | 78 | #define finish_arch_switch(prev) \ |
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index e2eca7d10598..ca97e0ecb64b 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h | |||
@@ -60,6 +60,8 @@ struct thread_info { | |||
60 | register struct thread_info *__current_thread_info __asm__("$28"); | 60 | register struct thread_info *__current_thread_info __asm__("$28"); |
61 | #define current_thread_info() __current_thread_info | 61 | #define current_thread_info() __current_thread_info |
62 | 62 | ||
63 | #endif /* !__ASSEMBLY__ */ | ||
64 | |||
63 | /* thread information allocation */ | 65 | /* thread information allocation */ |
64 | #if defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_32BIT) | 66 | #if defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_32BIT) |
65 | #define THREAD_SIZE_ORDER (1) | 67 | #define THREAD_SIZE_ORDER (1) |
@@ -85,8 +87,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); | |||
85 | 87 | ||
86 | #define STACK_WARN (THREAD_SIZE / 8) | 88 | #define STACK_WARN (THREAD_SIZE / 8) |
87 | 89 | ||
88 | #endif /* !__ASSEMBLY__ */ | ||
89 | |||
90 | #define PREEMPT_ACTIVE 0x10000000 | 90 | #define PREEMPT_ACTIVE 0x10000000 |
91 | 91 | ||
92 | /* | 92 | /* |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 6ae7ce4ac63e..f4630e1082ab 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) xxxx the Anonymous | 4 | * Copyright (C) xxxx the Anonymous |
5 | * Copyright (C) 1994 - 2006 Ralf Baechle | 5 | * Copyright (C) 1994 - 2006 Ralf Baechle |
6 | * Copyright (C) 2003, 2004 Maciej W. Rozycki | 6 | * Copyright (C) 2003, 2004 Maciej W. Rozycki |
7 | * Copyright (C) 2001, 2004 MIPS Inc. | 7 | * Copyright (C) 2001, 2004, 2011, 2012 MIPS Technologies, Inc. |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License | 10 | * modify it under the terms of the GNU General Public License |
@@ -199,6 +199,7 @@ void __init check_wait(void) | |||
199 | cpu_wait = rm7k_wait_irqoff; | 199 | cpu_wait = rm7k_wait_irqoff; |
200 | break; | 200 | break; |
201 | 201 | ||
202 | case CPU_M14KC: | ||
202 | case CPU_24K: | 203 | case CPU_24K: |
203 | case CPU_34K: | 204 | case CPU_34K: |
204 | case CPU_1004K: | 205 | case CPU_1004K: |
@@ -810,6 +811,10 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | |||
810 | c->cputype = CPU_5KC; | 811 | c->cputype = CPU_5KC; |
811 | __cpu_name[cpu] = "MIPS 5Kc"; | 812 | __cpu_name[cpu] = "MIPS 5Kc"; |
812 | break; | 813 | break; |
814 | case PRID_IMP_5KE: | ||
815 | c->cputype = CPU_5KE; | ||
816 | __cpu_name[cpu] = "MIPS 5KE"; | ||
817 | break; | ||
813 | case PRID_IMP_20KC: | 818 | case PRID_IMP_20KC: |
814 | c->cputype = CPU_20KC; | 819 | c->cputype = CPU_20KC; |
815 | __cpu_name[cpu] = "MIPS 20Kc"; | 820 | __cpu_name[cpu] = "MIPS 20Kc"; |
@@ -831,6 +836,10 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | |||
831 | c->cputype = CPU_74K; | 836 | c->cputype = CPU_74K; |
832 | __cpu_name[cpu] = "MIPS 74Kc"; | 837 | __cpu_name[cpu] = "MIPS 74Kc"; |
833 | break; | 838 | break; |
839 | case PRID_IMP_M14KC: | ||
840 | c->cputype = CPU_M14KC; | ||
841 | __cpu_name[cpu] = "MIPS M14Kc"; | ||
842 | break; | ||
834 | case PRID_IMP_1004K: | 843 | case PRID_IMP_1004K: |
835 | c->cputype = CPU_1004K; | 844 | c->cputype = CPU_1004K; |
836 | __cpu_name[cpu] = "MIPS 1004Kc"; | 845 | __cpu_name[cpu] = "MIPS 1004Kc"; |
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 57ba13edb03a..3fc1691110dc 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03, 04, 05 by Ralf Baechle | 8 | * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03, 04, 05, 12 by Ralf Baechle |
9 | * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc. | 9 | * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc. |
10 | */ | 10 | */ |
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
@@ -35,6 +35,12 @@ EXPORT_SYMBOL(memmove); | |||
35 | EXPORT_SYMBOL(kernel_thread); | 35 | EXPORT_SYMBOL(kernel_thread); |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * Functions that operate on entire pages. Mostly used by memory management. | ||
39 | */ | ||
40 | EXPORT_SYMBOL(clear_page); | ||
41 | EXPORT_SYMBOL(copy_page); | ||
42 | |||
43 | /* | ||
38 | * Userspace access stuff. | 44 | * Userspace access stuff. |
39 | */ | 45 | */ |
40 | EXPORT_SYMBOL(__copy_user); | 46 | EXPORT_SYMBOL(__copy_user); |
diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S index ce89c8061708..0441f54b2a6a 100644 --- a/arch/mips/kernel/octeon_switch.S +++ b/arch/mips/kernel/octeon_switch.S | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | /* | 32 | /* |
33 | * task_struct *resume(task_struct *prev, task_struct *next, | 33 | * task_struct *resume(task_struct *prev, task_struct *next, |
34 | * struct thread_info *next_ti) | 34 | * struct thread_info *next_ti, int usedfpu) |
35 | */ | 35 | */ |
36 | .align 7 | 36 | .align 7 |
37 | LEAF(resume) | 37 | LEAF(resume) |
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index f29099b104c4..eb5e394a4650 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
@@ -162,11 +162,6 @@ static unsigned int counters_total_to_per_cpu(unsigned int counters) | |||
162 | return counters >> vpe_shift(); | 162 | return counters >> vpe_shift(); |
163 | } | 163 | } |
164 | 164 | ||
165 | static unsigned int counters_per_cpu_to_total(unsigned int counters) | ||
166 | { | ||
167 | return counters << vpe_shift(); | ||
168 | } | ||
169 | |||
170 | #else /* !CONFIG_MIPS_MT_SMP */ | 165 | #else /* !CONFIG_MIPS_MT_SMP */ |
171 | #define vpe_id() 0 | 166 | #define vpe_id() 0 |
172 | 167 | ||
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 293898391e67..9c51be5a163a 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S | |||
@@ -43,7 +43,7 @@ | |||
43 | 43 | ||
44 | /* | 44 | /* |
45 | * task_struct *resume(task_struct *prev, task_struct *next, | 45 | * task_struct *resume(task_struct *prev, task_struct *next, |
46 | * struct thread_info *next_ti) ) | 46 | * struct thread_info *next_ti, int usedfpu) |
47 | */ | 47 | */ |
48 | LEAF(resume) | 48 | LEAF(resume) |
49 | mfc0 t1, CP0_STATUS | 49 | mfc0 t1, CP0_STATUS |
@@ -51,18 +51,9 @@ LEAF(resume) | |||
51 | cpu_save_nonscratch a0 | 51 | cpu_save_nonscratch a0 |
52 | sw ra, THREAD_REG31(a0) | 52 | sw ra, THREAD_REG31(a0) |
53 | 53 | ||
54 | /* | 54 | beqz a3, 1f |
55 | * check if we need to save FPU registers | ||
56 | */ | ||
57 | lw t3, TASK_THREAD_INFO(a0) | ||
58 | lw t0, TI_FLAGS(t3) | ||
59 | li t1, _TIF_USEDFPU | ||
60 | and t2, t0, t1 | ||
61 | beqz t2, 1f | ||
62 | nor t1, zero, t1 | ||
63 | 55 | ||
64 | and t0, t0, t1 | 56 | PTR_L t3, TASK_THREAD_INFO(a0) |
65 | sw t0, TI_FLAGS(t3) | ||
66 | 57 | ||
67 | /* | 58 | /* |
68 | * clear saved user stack CU1 bit | 59 | * clear saved user stack CU1 bit |
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 9414f9354469..42d2a3938420 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | /* | 42 | /* |
43 | * task_struct *resume(task_struct *prev, task_struct *next, | 43 | * task_struct *resume(task_struct *prev, task_struct *next, |
44 | * struct thread_info *next_ti) | 44 | * struct thread_info *next_ti, int usedfpu) |
45 | */ | 45 | */ |
46 | .align 5 | 46 | .align 5 |
47 | LEAF(resume) | 47 | LEAF(resume) |
@@ -53,16 +53,10 @@ | |||
53 | /* | 53 | /* |
54 | * check if we need to save FPU registers | 54 | * check if we need to save FPU registers |
55 | */ | 55 | */ |
56 | PTR_L t3, TASK_THREAD_INFO(a0) | ||
57 | LONG_L t0, TI_FLAGS(t3) | ||
58 | li t1, _TIF_USEDFPU | ||
59 | and t2, t0, t1 | ||
60 | beqz t2, 1f | ||
61 | nor t1, zero, t1 | ||
62 | 56 | ||
63 | and t0, t0, t1 | 57 | beqz a3, 1f |
64 | LONG_S t0, TI_FLAGS(t3) | ||
65 | 58 | ||
59 | PTR_L t3, TASK_THREAD_INFO(a0) | ||
66 | /* | 60 | /* |
67 | * clear saved user stack CU1 bit | 61 | * clear saved user stack CU1 bit |
68 | */ | 62 | */ |
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 3046e2986006..8e393b8443f7 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
18 | #include <linux/init.h> | ||
19 | #include <linux/cpu.h> | 18 | #include <linux/cpu.h> |
20 | #include <linux/cpumask.h> | 19 | #include <linux/cpumask.h> |
21 | #include <linux/reboot.h> | 20 | #include <linux/reboot.h> |
@@ -197,13 +196,6 @@ static void bmips_init_secondary(void) | |||
197 | 196 | ||
198 | write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); | 197 | write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); |
199 | #endif | 198 | #endif |
200 | |||
201 | /* make sure there won't be a timer interrupt for a little while */ | ||
202 | write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); | ||
203 | |||
204 | irq_enable_hazard(); | ||
205 | set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE); | ||
206 | irq_enable_hazard(); | ||
207 | } | 199 | } |
208 | 200 | ||
209 | /* | 201 | /* |
@@ -212,6 +204,13 @@ static void bmips_init_secondary(void) | |||
212 | static void bmips_smp_finish(void) | 204 | static void bmips_smp_finish(void) |
213 | { | 205 | { |
214 | pr_info("SMP: CPU%d is running\n", smp_processor_id()); | 206 | pr_info("SMP: CPU%d is running\n", smp_processor_id()); |
207 | |||
208 | /* make sure there won't be a timer interrupt for a little while */ | ||
209 | write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); | ||
210 | |||
211 | irq_enable_hazard(); | ||
212 | set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE); | ||
213 | irq_enable_hazard(); | ||
215 | } | 214 | } |
216 | 215 | ||
217 | /* | 216 | /* |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 48650c818040..1268392f1d27 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -122,13 +122,21 @@ asmlinkage __cpuinit void start_secondary(void) | |||
122 | 122 | ||
123 | notify_cpu_starting(cpu); | 123 | notify_cpu_starting(cpu); |
124 | 124 | ||
125 | mp_ops->smp_finish(); | 125 | set_cpu_online(cpu, true); |
126 | |||
126 | set_cpu_sibling_map(cpu); | 127 | set_cpu_sibling_map(cpu); |
127 | 128 | ||
128 | cpu_set(cpu, cpu_callin_map); | 129 | cpu_set(cpu, cpu_callin_map); |
129 | 130 | ||
130 | synchronise_count_slave(); | 131 | synchronise_count_slave(); |
131 | 132 | ||
133 | /* | ||
134 | * irq will be enabled in ->smp_finish(), enabling it too early | ||
135 | * is dangerous. | ||
136 | */ | ||
137 | WARN_ON_ONCE(!irqs_disabled()); | ||
138 | mp_ops->smp_finish(); | ||
139 | |||
132 | cpu_idle(); | 140 | cpu_idle(); |
133 | } | 141 | } |
134 | 142 | ||
@@ -196,8 +204,6 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) | |||
196 | while (!cpu_isset(cpu, cpu_callin_map)) | 204 | while (!cpu_isset(cpu, cpu_callin_map)) |
197 | udelay(100); | 205 | udelay(100); |
198 | 206 | ||
199 | set_cpu_online(cpu, true); | ||
200 | |||
201 | return 0; | 207 | return 0; |
202 | } | 208 | } |
203 | 209 | ||
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index f5dd38f1d015..15b5f3cfd20c 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -322,7 +322,7 @@ int __init smtc_build_cpu_map(int start_cpu_slot) | |||
322 | 322 | ||
323 | /* | 323 | /* |
324 | * Common setup before any secondaries are started | 324 | * Common setup before any secondaries are started |
325 | * Make sure all CPU's are in a sensible state before we boot any of the | 325 | * Make sure all CPUs are in a sensible state before we boot any of the |
326 | * secondaries. | 326 | * secondaries. |
327 | * | 327 | * |
328 | * For MIPS MT "SMTC" operation, we set up all TCs, spread as evenly | 328 | * For MIPS MT "SMTC" operation, we set up all TCs, spread as evenly |
@@ -340,12 +340,12 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) | |||
340 | /* | 340 | /* |
341 | * TCContext gets an offset from the base of the IPIQ array | 341 | * TCContext gets an offset from the base of the IPIQ array |
342 | * to be used in low-level code to detect the presence of | 342 | * to be used in low-level code to detect the presence of |
343 | * an active IPI queue | 343 | * an active IPI queue. |
344 | */ | 344 | */ |
345 | write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); | 345 | write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); |
346 | /* Bind tc to vpe */ | 346 | /* Bind tc to vpe */ |
347 | write_tc_c0_tcbind(vpe); | 347 | write_tc_c0_tcbind(vpe); |
348 | /* In general, all TCs should have the same cpu_data indications */ | 348 | /* In general, all TCs should have the same cpu_data indications. */ |
349 | memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); | 349 | memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); |
350 | /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */ | 350 | /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */ |
351 | if (cpu_data[0].cputype == CPU_34K || | 351 | if (cpu_data[0].cputype == CPU_34K || |
@@ -358,8 +358,8 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) | |||
358 | } | 358 | } |
359 | 359 | ||
360 | /* | 360 | /* |
361 | * Tweak to get Count registes in as close a sync as possible. | 361 | * Tweak to get Count registes in as close a sync as possible. The |
362 | * Value seems good for 34K-class cores. | 362 | * value seems good for 34K-class cores. |
363 | */ | 363 | */ |
364 | 364 | ||
365 | #define CP0_SKEW 8 | 365 | #define CP0_SKEW 8 |
@@ -615,7 +615,6 @@ void __cpuinit smtc_boot_secondary(int cpu, struct task_struct *idle) | |||
615 | 615 | ||
616 | void smtc_init_secondary(void) | 616 | void smtc_init_secondary(void) |
617 | { | 617 | { |
618 | local_irq_enable(); | ||
619 | } | 618 | } |
620 | 619 | ||
621 | void smtc_smp_finish(void) | 620 | void smtc_smp_finish(void) |
@@ -631,6 +630,8 @@ void smtc_smp_finish(void) | |||
631 | if (cpu > 0 && (cpu_data[cpu].vpe_id != cpu_data[cpu - 1].vpe_id)) | 630 | if (cpu > 0 && (cpu_data[cpu].vpe_id != cpu_data[cpu - 1].vpe_id)) |
632 | write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); | 631 | write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); |
633 | 632 | ||
633 | local_irq_enable(); | ||
634 | |||
634 | printk("TC %d going on-line as CPU %d\n", | 635 | printk("TC %d going on-line as CPU %d\n", |
635 | cpu_data[smp_processor_id()].tc_id, smp_processor_id()); | 636 | cpu_data[smp_processor_id()].tc_id, smp_processor_id()); |
636 | } | 637 | } |
diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c index 99f913c8d7a6..842d55e411fd 100644 --- a/arch/mips/kernel/sync-r4k.c +++ b/arch/mips/kernel/sync-r4k.c | |||
@@ -111,7 +111,6 @@ void __cpuinit synchronise_count_master(void) | |||
111 | void __cpuinit synchronise_count_slave(void) | 111 | void __cpuinit synchronise_count_slave(void) |
112 | { | 112 | { |
113 | int i; | 113 | int i; |
114 | unsigned long flags; | ||
115 | unsigned int initcount; | 114 | unsigned int initcount; |
116 | int ncpus; | 115 | int ncpus; |
117 | 116 | ||
@@ -123,8 +122,6 @@ void __cpuinit synchronise_count_slave(void) | |||
123 | return; | 122 | return; |
124 | #endif | 123 | #endif |
125 | 124 | ||
126 | local_irq_save(flags); | ||
127 | |||
128 | /* | 125 | /* |
129 | * Not every cpu is online at the time this gets called, | 126 | * Not every cpu is online at the time this gets called, |
130 | * so we first wait for the master to say everyone is ready | 127 | * so we first wait for the master to say everyone is ready |
@@ -154,7 +151,5 @@ void __cpuinit synchronise_count_slave(void) | |||
154 | } | 151 | } |
155 | /* Arrange for an interrupt in a short while */ | 152 | /* Arrange for an interrupt in a short while */ |
156 | write_c0_compare(read_c0_count() + COUNTON); | 153 | write_c0_compare(read_c0_count() + COUNTON); |
157 | |||
158 | local_irq_restore(flags); | ||
159 | } | 154 | } |
160 | #undef NR_LOOPS | 155 | #undef NR_LOOPS |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 2d0c2a277f52..c3c293543703 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -132,6 +132,9 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs) | |||
132 | unsigned long ra = regs->regs[31]; | 132 | unsigned long ra = regs->regs[31]; |
133 | unsigned long pc = regs->cp0_epc; | 133 | unsigned long pc = regs->cp0_epc; |
134 | 134 | ||
135 | if (!task) | ||
136 | task = current; | ||
137 | |||
135 | if (raw_show_trace || !__kernel_text_address(pc)) { | 138 | if (raw_show_trace || !__kernel_text_address(pc)) { |
136 | show_raw_backtrace(sp); | 139 | show_raw_backtrace(sp); |
137 | return; | 140 | return; |
@@ -1249,6 +1252,7 @@ static inline void parity_protection_init(void) | |||
1249 | break; | 1252 | break; |
1250 | 1253 | ||
1251 | case CPU_5KC: | 1254 | case CPU_5KC: |
1255 | case CPU_5KE: | ||
1252 | write_c0_ecc(0x80000000); | 1256 | write_c0_ecc(0x80000000); |
1253 | back_to_back_c0_hazard(); | 1257 | back_to_back_c0_hazard(); |
1254 | /* Set the PE bit (bit 31) in the c0_errctl register. */ | 1258 | /* Set the PE bit (bit 31) in the c0_errctl register. */ |
@@ -1498,6 +1502,7 @@ extern void flush_tlb_handlers(void); | |||
1498 | * Timer interrupt | 1502 | * Timer interrupt |
1499 | */ | 1503 | */ |
1500 | int cp0_compare_irq; | 1504 | int cp0_compare_irq; |
1505 | EXPORT_SYMBOL_GPL(cp0_compare_irq); | ||
1501 | int cp0_compare_irq_shift; | 1506 | int cp0_compare_irq_shift; |
1502 | 1507 | ||
1503 | /* | 1508 | /* |
@@ -1597,7 +1602,7 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) | |||
1597 | cp0_perfcount_irq = -1; | 1602 | cp0_perfcount_irq = -1; |
1598 | } else { | 1603 | } else { |
1599 | cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ; | 1604 | cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ; |
1600 | cp0_compare_irq_shift = cp0_compare_irq; | 1605 | cp0_compare_irq_shift = CP0_LEGACY_PERFCNT_IRQ; |
1601 | cp0_perfcount_irq = -1; | 1606 | cp0_perfcount_irq = -1; |
1602 | } | 1607 | } |
1603 | 1608 | ||
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 924da5eb7031..df243a64f430 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <asm/asm-offsets.h> | 1 | #include <asm/asm-offsets.h> |
2 | #include <asm/page.h> | 2 | #include <asm/page.h> |
3 | #include <asm/thread_info.h> | ||
3 | #include <asm-generic/vmlinux.lds.h> | 4 | #include <asm-generic/vmlinux.lds.h> |
4 | 5 | ||
5 | #undef mips | 6 | #undef mips |
@@ -72,7 +73,7 @@ SECTIONS | |||
72 | .data : { /* Data */ | 73 | .data : { /* Data */ |
73 | . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ | 74 | . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ |
74 | 75 | ||
75 | INIT_TASK_DATA(PAGE_SIZE) | 76 | INIT_TASK_DATA(THREAD_SIZE) |
76 | NOSAVE_DATA | 77 | NOSAVE_DATA |
77 | CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) | 78 | CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) |
78 | READ_MOSTLY_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) | 79 | READ_MOSTLY_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) |
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 4aa20280613e..fd6203f14f1f 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile | |||
@@ -3,8 +3,8 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += cache.o dma-default.o extable.o fault.o \ | 5 | obj-y += cache.o dma-default.o extable.o fault.o \ |
6 | gup.o init.o mmap.o page.o tlbex.o \ | 6 | gup.o init.o mmap.o page.o page-funcs.o \ |
7 | tlbex-fault.o uasm.o | 7 | tlbex.o tlbex-fault.o uasm.o |
8 | 8 | ||
9 | obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o | 9 | obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o |
10 | obj-$(CONFIG_64BIT) += pgtable-64.o | 10 | obj-$(CONFIG_64BIT) += pgtable-64.o |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 5109be96d98d..f092c265dc63 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -977,7 +977,7 @@ static void __cpuinit probe_pcache(void) | |||
977 | c->icache.linesz = 2 << lsize; | 977 | c->icache.linesz = 2 << lsize; |
978 | else | 978 | else |
979 | c->icache.linesz = lsize; | 979 | c->icache.linesz = lsize; |
980 | c->icache.sets = 64 << ((config1 >> 22) & 7); | 980 | c->icache.sets = 32 << (((config1 >> 22) + 1) & 7); |
981 | c->icache.ways = 1 + ((config1 >> 16) & 7); | 981 | c->icache.ways = 1 + ((config1 >> 16) & 7); |
982 | 982 | ||
983 | icache_size = c->icache.sets * | 983 | icache_size = c->icache.sets * |
@@ -997,7 +997,7 @@ static void __cpuinit probe_pcache(void) | |||
997 | c->dcache.linesz = 2 << lsize; | 997 | c->dcache.linesz = 2 << lsize; |
998 | else | 998 | else |
999 | c->dcache.linesz= lsize; | 999 | c->dcache.linesz= lsize; |
1000 | c->dcache.sets = 64 << ((config1 >> 13) & 7); | 1000 | c->dcache.sets = 32 << (((config1 >> 13) + 1) & 7); |
1001 | c->dcache.ways = 1 + ((config1 >> 7) & 7); | 1001 | c->dcache.ways = 1 + ((config1 >> 7) & 7); |
1002 | 1002 | ||
1003 | dcache_size = c->dcache.sets * | 1003 | dcache_size = c->dcache.sets * |
@@ -1051,6 +1051,7 @@ static void __cpuinit probe_pcache(void) | |||
1051 | case CPU_R14000: | 1051 | case CPU_R14000: |
1052 | break; | 1052 | break; |
1053 | 1053 | ||
1054 | case CPU_M14KC: | ||
1054 | case CPU_24K: | 1055 | case CPU_24K: |
1055 | case CPU_34K: | 1056 | case CPU_34K: |
1056 | case CPU_74K: | 1057 | case CPU_74K: |
diff --git a/arch/mips/mm/page-funcs.S b/arch/mips/mm/page-funcs.S new file mode 100644 index 000000000000..48a6b38ff13e --- /dev/null +++ b/arch/mips/mm/page-funcs.S | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Micro-assembler generated clear_page/copy_page functions. | ||
7 | * | ||
8 | * Copyright (C) 2012 MIPS Technologies, Inc. | ||
9 | * Copyright (C) 2012 Ralf Baechle <ralf@linux-mips.org> | ||
10 | */ | ||
11 | #include <asm/asm.h> | ||
12 | #include <asm/regdef.h> | ||
13 | |||
14 | #ifdef CONFIG_SIBYTE_DMA_PAGEOPS | ||
15 | #define cpu_clear_page_function_name clear_page_cpu | ||
16 | #define cpu_copy_page_function_name copy_page_cpu | ||
17 | #else | ||
18 | #define cpu_clear_page_function_name clear_page | ||
19 | #define cpu_copy_page_function_name copy_page | ||
20 | #endif | ||
21 | |||
22 | /* | ||
23 | * Maximum sizes: | ||
24 | * | ||
25 | * R4000 128 bytes S-cache: 0x058 bytes | ||
26 | * R4600 v1.7: 0x05c bytes | ||
27 | * R4600 v2.0: 0x060 bytes | ||
28 | * With prefetching, 16 word strides 0x120 bytes | ||
29 | */ | ||
30 | EXPORT(__clear_page_start) | ||
31 | LEAF(cpu_clear_page_function_name) | ||
32 | 1: j 1b /* Dummy, will be replaced. */ | ||
33 | .space 288 | ||
34 | END(cpu_clear_page_function_name) | ||
35 | EXPORT(__clear_page_end) | ||
36 | |||
37 | /* | ||
38 | * Maximum sizes: | ||
39 | * | ||
40 | * R4000 128 bytes S-cache: 0x11c bytes | ||
41 | * R4600 v1.7: 0x080 bytes | ||
42 | * R4600 v2.0: 0x07c bytes | ||
43 | * With prefetching, 16 word strides 0x540 bytes | ||
44 | */ | ||
45 | EXPORT(__copy_page_start) | ||
46 | LEAF(cpu_copy_page_function_name) | ||
47 | 1: j 1b /* Dummy, will be replaced. */ | ||
48 | .space 1344 | ||
49 | END(cpu_copy_page_function_name) | ||
50 | EXPORT(__copy_page_end) | ||
diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c index cc0b626858b3..98f530e18216 100644 --- a/arch/mips/mm/page.c +++ b/arch/mips/mm/page.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org) | 6 | * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org) |
7 | * Copyright (C) 2007 Maciej W. Rozycki | 7 | * Copyright (C) 2007 Maciej W. Rozycki |
8 | * Copyright (C) 2008 Thiemo Seufer | 8 | * Copyright (C) 2008 Thiemo Seufer |
9 | * Copyright (C) 2012 MIPS Technologies, Inc. | ||
9 | */ | 10 | */ |
10 | #include <linux/init.h> | 11 | #include <linux/init.h> |
11 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
@@ -71,45 +72,6 @@ static struct uasm_reloc __cpuinitdata relocs[5]; | |||
71 | #define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010) | 72 | #define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010) |
72 | #define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020) | 73 | #define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020) |
73 | 74 | ||
74 | /* | ||
75 | * Maximum sizes: | ||
76 | * | ||
77 | * R4000 128 bytes S-cache: 0x058 bytes | ||
78 | * R4600 v1.7: 0x05c bytes | ||
79 | * R4600 v2.0: 0x060 bytes | ||
80 | * With prefetching, 16 word strides 0x120 bytes | ||
81 | */ | ||
82 | |||
83 | static u32 clear_page_array[0x120 / 4]; | ||
84 | |||
85 | #ifdef CONFIG_SIBYTE_DMA_PAGEOPS | ||
86 | void clear_page_cpu(void *page) __attribute__((alias("clear_page_array"))); | ||
87 | #else | ||
88 | void clear_page(void *page) __attribute__((alias("clear_page_array"))); | ||
89 | #endif | ||
90 | |||
91 | EXPORT_SYMBOL(clear_page); | ||
92 | |||
93 | /* | ||
94 | * Maximum sizes: | ||
95 | * | ||
96 | * R4000 128 bytes S-cache: 0x11c bytes | ||
97 | * R4600 v1.7: 0x080 bytes | ||
98 | * R4600 v2.0: 0x07c bytes | ||
99 | * With prefetching, 16 word strides 0x540 bytes | ||
100 | */ | ||
101 | static u32 copy_page_array[0x540 / 4]; | ||
102 | |||
103 | #ifdef CONFIG_SIBYTE_DMA_PAGEOPS | ||
104 | void | ||
105 | copy_page_cpu(void *to, void *from) __attribute__((alias("copy_page_array"))); | ||
106 | #else | ||
107 | void copy_page(void *to, void *from) __attribute__((alias("copy_page_array"))); | ||
108 | #endif | ||
109 | |||
110 | EXPORT_SYMBOL(copy_page); | ||
111 | |||
112 | |||
113 | static int pref_bias_clear_store __cpuinitdata; | 75 | static int pref_bias_clear_store __cpuinitdata; |
114 | static int pref_bias_copy_load __cpuinitdata; | 76 | static int pref_bias_copy_load __cpuinitdata; |
115 | static int pref_bias_copy_store __cpuinitdata; | 77 | static int pref_bias_copy_store __cpuinitdata; |
@@ -282,10 +244,15 @@ static inline void __cpuinit build_clear_pref(u32 **buf, int off) | |||
282 | } | 244 | } |
283 | } | 245 | } |
284 | 246 | ||
247 | extern u32 __clear_page_start; | ||
248 | extern u32 __clear_page_end; | ||
249 | extern u32 __copy_page_start; | ||
250 | extern u32 __copy_page_end; | ||
251 | |||
285 | void __cpuinit build_clear_page(void) | 252 | void __cpuinit build_clear_page(void) |
286 | { | 253 | { |
287 | int off; | 254 | int off; |
288 | u32 *buf = (u32 *)&clear_page_array; | 255 | u32 *buf = &__clear_page_start; |
289 | struct uasm_label *l = labels; | 256 | struct uasm_label *l = labels; |
290 | struct uasm_reloc *r = relocs; | 257 | struct uasm_reloc *r = relocs; |
291 | int i; | 258 | int i; |
@@ -356,17 +323,17 @@ void __cpuinit build_clear_page(void) | |||
356 | uasm_i_jr(&buf, RA); | 323 | uasm_i_jr(&buf, RA); |
357 | uasm_i_nop(&buf); | 324 | uasm_i_nop(&buf); |
358 | 325 | ||
359 | BUG_ON(buf > clear_page_array + ARRAY_SIZE(clear_page_array)); | 326 | BUG_ON(buf > &__clear_page_end); |
360 | 327 | ||
361 | uasm_resolve_relocs(relocs, labels); | 328 | uasm_resolve_relocs(relocs, labels); |
362 | 329 | ||
363 | pr_debug("Synthesized clear page handler (%u instructions).\n", | 330 | pr_debug("Synthesized clear page handler (%u instructions).\n", |
364 | (u32)(buf - clear_page_array)); | 331 | (u32)(buf - &__clear_page_start)); |
365 | 332 | ||
366 | pr_debug("\t.set push\n"); | 333 | pr_debug("\t.set push\n"); |
367 | pr_debug("\t.set noreorder\n"); | 334 | pr_debug("\t.set noreorder\n"); |
368 | for (i = 0; i < (buf - clear_page_array); i++) | 335 | for (i = 0; i < (buf - &__clear_page_start); i++) |
369 | pr_debug("\t.word 0x%08x\n", clear_page_array[i]); | 336 | pr_debug("\t.word 0x%08x\n", (&__clear_page_start)[i]); |
370 | pr_debug("\t.set pop\n"); | 337 | pr_debug("\t.set pop\n"); |
371 | } | 338 | } |
372 | 339 | ||
@@ -427,7 +394,7 @@ static inline void build_copy_store_pref(u32 **buf, int off) | |||
427 | void __cpuinit build_copy_page(void) | 394 | void __cpuinit build_copy_page(void) |
428 | { | 395 | { |
429 | int off; | 396 | int off; |
430 | u32 *buf = (u32 *)©_page_array; | 397 | u32 *buf = &__copy_page_start; |
431 | struct uasm_label *l = labels; | 398 | struct uasm_label *l = labels; |
432 | struct uasm_reloc *r = relocs; | 399 | struct uasm_reloc *r = relocs; |
433 | int i; | 400 | int i; |
@@ -595,21 +562,23 @@ void __cpuinit build_copy_page(void) | |||
595 | uasm_i_jr(&buf, RA); | 562 | uasm_i_jr(&buf, RA); |
596 | uasm_i_nop(&buf); | 563 | uasm_i_nop(&buf); |
597 | 564 | ||
598 | BUG_ON(buf > copy_page_array + ARRAY_SIZE(copy_page_array)); | 565 | BUG_ON(buf > &__copy_page_end); |
599 | 566 | ||
600 | uasm_resolve_relocs(relocs, labels); | 567 | uasm_resolve_relocs(relocs, labels); |
601 | 568 | ||
602 | pr_debug("Synthesized copy page handler (%u instructions).\n", | 569 | pr_debug("Synthesized copy page handler (%u instructions).\n", |
603 | (u32)(buf - copy_page_array)); | 570 | (u32)(buf - &__copy_page_start)); |
604 | 571 | ||
605 | pr_debug("\t.set push\n"); | 572 | pr_debug("\t.set push\n"); |
606 | pr_debug("\t.set noreorder\n"); | 573 | pr_debug("\t.set noreorder\n"); |
607 | for (i = 0; i < (buf - copy_page_array); i++) | 574 | for (i = 0; i < (buf - &__copy_page_start); i++) |
608 | pr_debug("\t.word 0x%08x\n", copy_page_array[i]); | 575 | pr_debug("\t.word 0x%08x\n", (&__copy_page_start)[i]); |
609 | pr_debug("\t.set pop\n"); | 576 | pr_debug("\t.set pop\n"); |
610 | } | 577 | } |
611 | 578 | ||
612 | #ifdef CONFIG_SIBYTE_DMA_PAGEOPS | 579 | #ifdef CONFIG_SIBYTE_DMA_PAGEOPS |
580 | extern void clear_page_cpu(void *page); | ||
581 | extern void copy_page_cpu(void *to, void *from); | ||
613 | 582 | ||
614 | /* | 583 | /* |
615 | * Pad descriptors to cacheline, since each is exclusively owned by a | 584 | * Pad descriptors to cacheline, since each is exclusively owned by a |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 0bc485b3cd60..03eb0ef91580 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * Copyright (C) 2005, 2007, 2008, 2009 Maciej W. Rozycki | 9 | * Copyright (C) 2005, 2007, 2008, 2009 Maciej W. Rozycki |
10 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | 10 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) |
11 | * Copyright (C) 2008, 2009 Cavium Networks, Inc. | 11 | * Copyright (C) 2008, 2009 Cavium Networks, Inc. |
12 | * Copyright (C) 2011 MIPS Technologies, Inc. | ||
12 | * | 13 | * |
13 | * ... and the days got worse and worse and now you see | 14 | * ... and the days got worse and worse and now you see |
14 | * I've gone completly out of my mind. | 15 | * I've gone completly out of my mind. |
@@ -494,6 +495,7 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l, | |||
494 | case CPU_R14000: | 495 | case CPU_R14000: |
495 | case CPU_4KC: | 496 | case CPU_4KC: |
496 | case CPU_4KEC: | 497 | case CPU_4KEC: |
498 | case CPU_M14KC: | ||
497 | case CPU_SB1: | 499 | case CPU_SB1: |
498 | case CPU_SB1A: | 500 | case CPU_SB1A: |
499 | case CPU_4KSC: | 501 | case CPU_4KSC: |
diff --git a/arch/mips/mti-malta/malta-pci.c b/arch/mips/mti-malta/malta-pci.c index bf80921f2f56..284dea54faf5 100644 --- a/arch/mips/mti-malta/malta-pci.c +++ b/arch/mips/mti-malta/malta-pci.c | |||
@@ -241,8 +241,9 @@ void __init mips_pcibios_init(void) | |||
241 | return; | 241 | return; |
242 | } | 242 | } |
243 | 243 | ||
244 | if (controller->io_resource->start < 0x00001000UL) /* FIXME */ | 244 | /* Change start address to avoid conflicts with ACPI and SMB devices */ |
245 | controller->io_resource->start = 0x00001000UL; | 245 | if (controller->io_resource->start < 0x00002000UL) |
246 | controller->io_resource->start = 0x00002000UL; | ||
246 | 247 | ||
247 | iomem_resource.end &= 0xfffffffffULL; /* 64 GB */ | 248 | iomem_resource.end &= 0xfffffffffULL; /* 64 GB */ |
248 | ioport_resource.end = controller->io_resource->end; | 249 | ioport_resource.end = controller->io_resource->end; |
@@ -253,7 +254,7 @@ void __init mips_pcibios_init(void) | |||
253 | } | 254 | } |
254 | 255 | ||
255 | /* Enable PCI 2.1 compatibility in PIIX4 */ | 256 | /* Enable PCI 2.1 compatibility in PIIX4 */ |
256 | static void __init quirk_dlcsetup(struct pci_dev *dev) | 257 | static void __devinit quirk_dlcsetup(struct pci_dev *dev) |
257 | { | 258 | { |
258 | u8 odlc, ndlc; | 259 | u8 odlc, ndlc; |
259 | (void) pci_read_config_byte(dev, 0x82, &odlc); | 260 | (void) pci_read_config_byte(dev, 0x82, &odlc); |
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index b7f37d4982fa..2e28f653f66d 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c | |||
@@ -111,7 +111,7 @@ static void __init pci_clock_check(void) | |||
111 | unsigned int __iomem *jmpr_p = | 111 | unsigned int __iomem *jmpr_p = |
112 | (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int)); | 112 | (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int)); |
113 | int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07; | 113 | int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07; |
114 | static const int pciclocks[] __initdata = { | 114 | static const int pciclocks[] __initconst = { |
115 | 33, 20, 25, 30, 12, 16, 37, 10 | 115 | 33, 20, 25, 30, 12, 16, 37, 10 |
116 | }; | 116 | }; |
117 | int pciclock = pciclocks[jmpr]; | 117 | int pciclock = pciclocks[jmpr]; |
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c index acb677a1227c..b3df7c2aad1e 100644 --- a/arch/mips/netlogic/xlp/setup.c +++ b/arch/mips/netlogic/xlp/setup.c | |||
@@ -82,8 +82,10 @@ void __init prom_free_prom_memory(void) | |||
82 | 82 | ||
83 | void xlp_mmu_init(void) | 83 | void xlp_mmu_init(void) |
84 | { | 84 | { |
85 | /* enable extended TLB and Large Fixed TLB */ | ||
85 | write_c0_config6(read_c0_config6() | 0x24); | 86 | write_c0_config6(read_c0_config6() | 0x24); |
86 | current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1; | 87 | |
88 | /* set page mask of Fixed TLB in config7 */ | ||
87 | write_c0_config7(PM_DEFAULT_MASK >> | 89 | write_c0_config7(PM_DEFAULT_MASK >> |
88 | (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2))); | 90 | (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2))); |
89 | } | 91 | } |
@@ -100,6 +102,10 @@ void __init prom_init(void) | |||
100 | nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1)); | 102 | nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1)); |
101 | #ifdef CONFIG_SMP | 103 | #ifdef CONFIG_SMP |
102 | nlm_wakeup_secondary_cpus(0xffffffff); | 104 | nlm_wakeup_secondary_cpus(0xffffffff); |
105 | |||
106 | /* update TLB size after waking up threads */ | ||
107 | current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1; | ||
108 | |||
103 | register_smp_ops(&nlm_smp_ops); | 109 | register_smp_ops(&nlm_smp_ops); |
104 | #endif | 110 | #endif |
105 | } | 111 | } |
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index d1f2d4c52d42..b6e378211a2c 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c | |||
@@ -78,6 +78,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
78 | 78 | ||
79 | switch (current_cpu_type()) { | 79 | switch (current_cpu_type()) { |
80 | case CPU_5KC: | 80 | case CPU_5KC: |
81 | case CPU_M14KC: | ||
81 | case CPU_20KC: | 82 | case CPU_20KC: |
82 | case CPU_24K: | 83 | case CPU_24K: |
83 | case CPU_25KF: | 84 | case CPU_25KF: |
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index baba3bcaa3c2..4d80a856048d 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c | |||
@@ -322,6 +322,10 @@ static int __init mipsxx_init(void) | |||
322 | 322 | ||
323 | op_model_mipsxx_ops.num_counters = counters; | 323 | op_model_mipsxx_ops.num_counters = counters; |
324 | switch (current_cpu_type()) { | 324 | switch (current_cpu_type()) { |
325 | case CPU_M14KC: | ||
326 | op_model_mipsxx_ops.cpu_type = "mips/M14Kc"; | ||
327 | break; | ||
328 | |||
325 | case CPU_20KC: | 329 | case CPU_20KC: |
326 | op_model_mipsxx_ops.cpu_type = "mips/20K"; | 330 | op_model_mipsxx_ops.cpu_type = "mips/20K"; |
327 | break; | 331 | break; |
diff --git a/arch/mips/pci/fixup-fuloong2e.c b/arch/mips/pci/fixup-fuloong2e.c index d5d4c018fb04..0857ab8c3919 100644 --- a/arch/mips/pci/fixup-fuloong2e.c +++ b/arch/mips/pci/fixup-fuloong2e.c | |||
@@ -48,7 +48,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) | |||
48 | return 0; | 48 | return 0; |
49 | } | 49 | } |
50 | 50 | ||
51 | static void __init loongson2e_nec_fixup(struct pci_dev *pdev) | 51 | static void __devinit loongson2e_nec_fixup(struct pci_dev *pdev) |
52 | { | 52 | { |
53 | unsigned int val; | 53 | unsigned int val; |
54 | 54 | ||
@@ -60,7 +60,7 @@ static void __init loongson2e_nec_fixup(struct pci_dev *pdev) | |||
60 | pci_write_config_dword(pdev, 0xe4, 1 << 5); | 60 | pci_write_config_dword(pdev, 0xe4, 1 << 5); |
61 | } | 61 | } |
62 | 62 | ||
63 | static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev) | 63 | static void __devinit loongson2e_686b_func0_fixup(struct pci_dev *pdev) |
64 | { | 64 | { |
65 | unsigned char c; | 65 | unsigned char c; |
66 | 66 | ||
@@ -135,7 +135,7 @@ static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev) | |||
135 | printk(KERN_INFO"via686b fix: ISA bridge done\n"); | 135 | printk(KERN_INFO"via686b fix: ISA bridge done\n"); |
136 | } | 136 | } |
137 | 137 | ||
138 | static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev) | 138 | static void __devinit loongson2e_686b_func1_fixup(struct pci_dev *pdev) |
139 | { | 139 | { |
140 | printk(KERN_INFO"via686b fix: IDE\n"); | 140 | printk(KERN_INFO"via686b fix: IDE\n"); |
141 | 141 | ||
@@ -168,19 +168,19 @@ static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev) | |||
168 | printk(KERN_INFO"via686b fix: IDE done\n"); | 168 | printk(KERN_INFO"via686b fix: IDE done\n"); |
169 | } | 169 | } |
170 | 170 | ||
171 | static void __init loongson2e_686b_func2_fixup(struct pci_dev *pdev) | 171 | static void __devinit loongson2e_686b_func2_fixup(struct pci_dev *pdev) |
172 | { | 172 | { |
173 | /* irq routing */ | 173 | /* irq routing */ |
174 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10); | 174 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10); |
175 | } | 175 | } |
176 | 176 | ||
177 | static void __init loongson2e_686b_func3_fixup(struct pci_dev *pdev) | 177 | static void __devinit loongson2e_686b_func3_fixup(struct pci_dev *pdev) |
178 | { | 178 | { |
179 | /* irq routing */ | 179 | /* irq routing */ |
180 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11); | 180 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11); |
181 | } | 181 | } |
182 | 182 | ||
183 | static void __init loongson2e_686b_func5_fixup(struct pci_dev *pdev) | 183 | static void __devinit loongson2e_686b_func5_fixup(struct pci_dev *pdev) |
184 | { | 184 | { |
185 | unsigned int val; | 185 | unsigned int val; |
186 | unsigned char c; | 186 | unsigned char c; |
diff --git a/arch/mips/pci/fixup-lemote2f.c b/arch/mips/pci/fixup-lemote2f.c index 4b9768d5d729..a7b917dcf604 100644 --- a/arch/mips/pci/fixup-lemote2f.c +++ b/arch/mips/pci/fixup-lemote2f.c | |||
@@ -96,21 +96,21 @@ int pcibios_plat_dev_init(struct pci_dev *dev) | |||
96 | } | 96 | } |
97 | 97 | ||
98 | /* CS5536 SPEC. fixup */ | 98 | /* CS5536 SPEC. fixup */ |
99 | static void __init loongson_cs5536_isa_fixup(struct pci_dev *pdev) | 99 | static void __devinit loongson_cs5536_isa_fixup(struct pci_dev *pdev) |
100 | { | 100 | { |
101 | /* the uart1 and uart2 interrupt in PIC is enabled as default */ | 101 | /* the uart1 and uart2 interrupt in PIC is enabled as default */ |
102 | pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1); | 102 | pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1); |
103 | pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1); | 103 | pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1); |
104 | } | 104 | } |
105 | 105 | ||
106 | static void __init loongson_cs5536_ide_fixup(struct pci_dev *pdev) | 106 | static void __devinit loongson_cs5536_ide_fixup(struct pci_dev *pdev) |
107 | { | 107 | { |
108 | /* setting the mutex pin as IDE function */ | 108 | /* setting the mutex pin as IDE function */ |
109 | pci_write_config_dword(pdev, PCI_IDE_CFG_REG, | 109 | pci_write_config_dword(pdev, PCI_IDE_CFG_REG, |
110 | CS5536_IDE_FLASH_SIGNATURE); | 110 | CS5536_IDE_FLASH_SIGNATURE); |
111 | } | 111 | } |
112 | 112 | ||
113 | static void __init loongson_cs5536_acc_fixup(struct pci_dev *pdev) | 113 | static void __devinit loongson_cs5536_acc_fixup(struct pci_dev *pdev) |
114 | { | 114 | { |
115 | /* enable the AUDIO interrupt in PIC */ | 115 | /* enable the AUDIO interrupt in PIC */ |
116 | pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1); | 116 | pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1); |
@@ -118,14 +118,14 @@ static void __init loongson_cs5536_acc_fixup(struct pci_dev *pdev) | |||
118 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0); | 118 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0); |
119 | } | 119 | } |
120 | 120 | ||
121 | static void __init loongson_cs5536_ohci_fixup(struct pci_dev *pdev) | 121 | static void __devinit loongson_cs5536_ohci_fixup(struct pci_dev *pdev) |
122 | { | 122 | { |
123 | /* enable the OHCI interrupt in PIC */ | 123 | /* enable the OHCI interrupt in PIC */ |
124 | /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */ | 124 | /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */ |
125 | pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1); | 125 | pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1); |
126 | } | 126 | } |
127 | 127 | ||
128 | static void __init loongson_cs5536_ehci_fixup(struct pci_dev *pdev) | 128 | static void __devinit loongson_cs5536_ehci_fixup(struct pci_dev *pdev) |
129 | { | 129 | { |
130 | u32 hi, lo; | 130 | u32 hi, lo; |
131 | 131 | ||
@@ -137,7 +137,7 @@ static void __init loongson_cs5536_ehci_fixup(struct pci_dev *pdev) | |||
137 | pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000); | 137 | pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000); |
138 | } | 138 | } |
139 | 139 | ||
140 | static void __init loongson_nec_fixup(struct pci_dev *pdev) | 140 | static void __devinit loongson_nec_fixup(struct pci_dev *pdev) |
141 | { | 141 | { |
142 | unsigned int val; | 142 | unsigned int val; |
143 | 143 | ||
diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c index 0f48498bc231..70073c98ed32 100644 --- a/arch/mips/pci/fixup-malta.c +++ b/arch/mips/pci/fixup-malta.c | |||
@@ -49,10 +49,10 @@ int pcibios_plat_dev_init(struct pci_dev *dev) | |||
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | 51 | ||
52 | static void __init malta_piix_func0_fixup(struct pci_dev *pdev) | 52 | static void __devinit malta_piix_func0_fixup(struct pci_dev *pdev) |
53 | { | 53 | { |
54 | unsigned char reg_val; | 54 | unsigned char reg_val; |
55 | static int piixirqmap[16] __initdata = { /* PIIX PIRQC[A:D] irq mappings */ | 55 | static int piixirqmap[16] __devinitdata = { /* PIIX PIRQC[A:D] irq mappings */ |
56 | 0, 0, 0, 3, | 56 | 0, 0, 0, 3, |
57 | 4, 5, 6, 7, | 57 | 4, 5, 6, 7, |
58 | 0, 9, 10, 11, | 58 | 0, 9, 10, 11, |
@@ -83,7 +83,7 @@ static void __init malta_piix_func0_fixup(struct pci_dev *pdev) | |||
83 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, | 83 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, |
84 | malta_piix_func0_fixup); | 84 | malta_piix_func0_fixup); |
85 | 85 | ||
86 | static void __init malta_piix_func1_fixup(struct pci_dev *pdev) | 86 | static void __devinit malta_piix_func1_fixup(struct pci_dev *pdev) |
87 | { | 87 | { |
88 | unsigned char reg_val; | 88 | unsigned char reg_val; |
89 | 89 | ||
diff --git a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c index e08f49cb6875..8e4f8288eca2 100644 --- a/arch/mips/pci/fixup-mpc30x.c +++ b/arch/mips/pci/fixup-mpc30x.c | |||
@@ -22,13 +22,13 @@ | |||
22 | 22 | ||
23 | #include <asm/vr41xx/mpc30x.h> | 23 | #include <asm/vr41xx/mpc30x.h> |
24 | 24 | ||
25 | static const int internal_func_irqs[] __initdata = { | 25 | static const int internal_func_irqs[] __initconst = { |
26 | VRC4173_CASCADE_IRQ, | 26 | VRC4173_CASCADE_IRQ, |
27 | VRC4173_AC97_IRQ, | 27 | VRC4173_AC97_IRQ, |
28 | VRC4173_USB_IRQ, | 28 | VRC4173_USB_IRQ, |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static const int irq_tab_mpc30x[] __initdata = { | 31 | static const int irq_tab_mpc30x[] __initconst = { |
32 | [12] = VRC4173_PCMCIA1_IRQ, | 32 | [12] = VRC4173_PCMCIA1_IRQ, |
33 | [13] = VRC4173_PCMCIA2_IRQ, | 33 | [13] = VRC4173_PCMCIA2_IRQ, |
34 | [29] = MQ200_IRQ, | 34 | [29] = MQ200_IRQ, |
diff --git a/arch/mips/pci/fixup-sb1250.c b/arch/mips/pci/fixup-sb1250.c index f0bb9146e6c0..d02900a72916 100644 --- a/arch/mips/pci/fixup-sb1250.c +++ b/arch/mips/pci/fixup-sb1250.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * Set the BCM1250, etc. PCI host bridge's TRDY timeout | 15 | * Set the BCM1250, etc. PCI host bridge's TRDY timeout |
16 | * to the finite max. | 16 | * to the finite max. |
17 | */ | 17 | */ |
18 | static void __init quirk_sb1250_pci(struct pci_dev *dev) | 18 | static void __devinit quirk_sb1250_pci(struct pci_dev *dev) |
19 | { | 19 | { |
20 | pci_write_config_byte(dev, 0x40, 0xff); | 20 | pci_write_config_byte(dev, 0x40, 0xff); |
21 | } | 21 | } |
@@ -25,7 +25,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_PCI, | |||
25 | /* | 25 | /* |
26 | * The BCM1250, etc. PCI/HT bridge reports as a host bridge. | 26 | * The BCM1250, etc. PCI/HT bridge reports as a host bridge. |
27 | */ | 27 | */ |
28 | static void __init quirk_sb1250_ht(struct pci_dev *dev) | 28 | static void __devinit quirk_sb1250_ht(struct pci_dev *dev) |
29 | { | 29 | { |
30 | dev->class = PCI_CLASS_BRIDGE_PCI << 8; | 30 | dev->class = PCI_CLASS_BRIDGE_PCI << 8; |
31 | } | 31 | } |
@@ -35,7 +35,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_HT, | |||
35 | /* | 35 | /* |
36 | * Set the SP1011 HT/PCI bridge's TRDY timeout to the finite max. | 36 | * Set the SP1011 HT/PCI bridge's TRDY timeout to the finite max. |
37 | */ | 37 | */ |
38 | static void __init quirk_sp1011(struct pci_dev *dev) | 38 | static void __devinit quirk_sp1011(struct pci_dev *dev) |
39 | { | 39 | { |
40 | pci_write_config_byte(dev, 0x64, 0xff); | 40 | pci_write_config_byte(dev, 0x64, 0xff); |
41 | } | 41 | } |
diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c index a1e7e6d80c8c..bc13e29d2bb3 100644 --- a/arch/mips/pci/ops-tx4927.c +++ b/arch/mips/pci/ops-tx4927.c | |||
@@ -495,7 +495,7 @@ irqreturn_t tx4927_pcierr_interrupt(int irq, void *dev_id) | |||
495 | } | 495 | } |
496 | 496 | ||
497 | #ifdef CONFIG_TOSHIBA_FPCIB0 | 497 | #ifdef CONFIG_TOSHIBA_FPCIB0 |
498 | static void __init tx4927_quirk_slc90e66_bridge(struct pci_dev *dev) | 498 | static void __devinit tx4927_quirk_slc90e66_bridge(struct pci_dev *dev) |
499 | { | 499 | { |
500 | struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(dev->bus); | 500 | struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(dev->bus); |
501 | 501 | ||
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index 0fbe4c0c170a..fdc24440294c 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c | |||
@@ -212,7 +212,7 @@ static inline void pci_enable_swapping(struct pci_dev *dev) | |||
212 | bridge->b_widget.w_tflush; /* Flush */ | 212 | bridge->b_widget.w_tflush; /* Flush */ |
213 | } | 213 | } |
214 | 214 | ||
215 | static void __init pci_fixup_ioc3(struct pci_dev *d) | 215 | static void __devinit pci_fixup_ioc3(struct pci_dev *d) |
216 | { | 216 | { |
217 | pci_disable_swapping(d); | 217 | pci_disable_swapping(d); |
218 | } | 218 | } |
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c index 1644805a6730..172af1cd5867 100644 --- a/arch/mips/pci/pci-xlr.c +++ b/arch/mips/pci/pci-xlr.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/irq.h> | 41 | #include <linux/irq.h> |
42 | #include <linux/irqdesc.h> | 42 | #include <linux/irqdesc.h> |
43 | #include <linux/console.h> | 43 | #include <linux/console.h> |
44 | #include <linux/pci_regs.h> | ||
44 | 45 | ||
45 | #include <asm/io.h> | 46 | #include <asm/io.h> |
46 | 47 | ||
@@ -156,35 +157,55 @@ struct pci_controller nlm_pci_controller = { | |||
156 | .io_offset = 0x00000000UL, | 157 | .io_offset = 0x00000000UL, |
157 | }; | 158 | }; |
158 | 159 | ||
160 | /* | ||
161 | * The top level PCIe links on the XLS PCIe controller appear as | ||
162 | * bridges. Given a device, this function finds which link it is | ||
163 | * on. | ||
164 | */ | ||
165 | static struct pci_dev *xls_get_pcie_link(const struct pci_dev *dev) | ||
166 | { | ||
167 | struct pci_bus *bus, *p; | ||
168 | |||
169 | /* Find the bridge on bus 0 */ | ||
170 | bus = dev->bus; | ||
171 | for (p = bus->parent; p && p->number != 0; p = p->parent) | ||
172 | bus = p; | ||
173 | |||
174 | return p ? bus->self : NULL; | ||
175 | } | ||
176 | |||
159 | static int get_irq_vector(const struct pci_dev *dev) | 177 | static int get_irq_vector(const struct pci_dev *dev) |
160 | { | 178 | { |
179 | struct pci_dev *lnk; | ||
180 | |||
161 | if (!nlm_chip_is_xls()) | 181 | if (!nlm_chip_is_xls()) |
162 | return PIC_PCIX_IRQ; /* for XLR just one IRQ*/ | 182 | return PIC_PCIX_IRQ; /* for XLR just one IRQ */ |
163 | 183 | ||
164 | /* | 184 | /* |
165 | * For XLS PCIe, there is an IRQ per Link, find out which | 185 | * For XLS PCIe, there is an IRQ per Link, find out which |
166 | * link the device is on to assign interrupts | 186 | * link the device is on to assign interrupts |
167 | */ | 187 | */ |
168 | if (dev->bus->self == NULL) | 188 | lnk = xls_get_pcie_link(dev); |
189 | if (lnk == NULL) | ||
169 | return 0; | 190 | return 0; |
170 | 191 | ||
171 | switch (dev->bus->self->devfn) { | 192 | switch (PCI_SLOT(lnk->devfn)) { |
172 | case 0x0: | 193 | case 0: |
173 | return PIC_PCIE_LINK0_IRQ; | 194 | return PIC_PCIE_LINK0_IRQ; |
174 | case 0x8: | 195 | case 1: |
175 | return PIC_PCIE_LINK1_IRQ; | 196 | return PIC_PCIE_LINK1_IRQ; |
176 | case 0x10: | 197 | case 2: |
177 | if (nlm_chip_is_xls_b()) | 198 | if (nlm_chip_is_xls_b()) |
178 | return PIC_PCIE_XLSB0_LINK2_IRQ; | 199 | return PIC_PCIE_XLSB0_LINK2_IRQ; |
179 | else | 200 | else |
180 | return PIC_PCIE_LINK2_IRQ; | 201 | return PIC_PCIE_LINK2_IRQ; |
181 | case 0x18: | 202 | case 3: |
182 | if (nlm_chip_is_xls_b()) | 203 | if (nlm_chip_is_xls_b()) |
183 | return PIC_PCIE_XLSB0_LINK3_IRQ; | 204 | return PIC_PCIE_XLSB0_LINK3_IRQ; |
184 | else | 205 | else |
185 | return PIC_PCIE_LINK3_IRQ; | 206 | return PIC_PCIE_LINK3_IRQ; |
186 | } | 207 | } |
187 | WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn); | 208 | WARN(1, "Unexpected devfn %d\n", lnk->devfn); |
188 | return 0; | 209 | return 0; |
189 | } | 210 | } |
190 | 211 | ||
@@ -202,7 +223,27 @@ void arch_teardown_msi_irq(unsigned int irq) | |||
202 | int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) | 223 | int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) |
203 | { | 224 | { |
204 | struct msi_msg msg; | 225 | struct msi_msg msg; |
226 | struct pci_dev *lnk; | ||
205 | int irq, ret; | 227 | int irq, ret; |
228 | u16 val; | ||
229 | |||
230 | /* MSI not supported on XLR */ | ||
231 | if (!nlm_chip_is_xls()) | ||
232 | return 1; | ||
233 | |||
234 | /* | ||
235 | * Enable MSI on the XLS PCIe controller bridge which was disabled | ||
236 | * at enumeration, the bridge MSI capability is at 0x50 | ||
237 | */ | ||
238 | lnk = xls_get_pcie_link(dev); | ||
239 | if (lnk == NULL) | ||
240 | return 1; | ||
241 | |||
242 | pci_read_config_word(lnk, 0x50 + PCI_MSI_FLAGS, &val); | ||
243 | if ((val & PCI_MSI_FLAGS_ENABLE) == 0) { | ||
244 | val |= PCI_MSI_FLAGS_ENABLE; | ||
245 | pci_write_config_word(lnk, 0x50 + PCI_MSI_FLAGS, val); | ||
246 | } | ||
206 | 247 | ||
207 | irq = get_irq_vector(dev); | 248 | irq = get_irq_vector(dev); |
208 | if (irq <= 0) | 249 | if (irq <= 0) |
@@ -327,7 +368,7 @@ static int __init pcibios_init(void) | |||
327 | } | 368 | } |
328 | } else { | 369 | } else { |
329 | /* XLR PCI controller ACK */ | 370 | /* XLR PCI controller ACK */ |
330 | irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, xlr_pci_ack); | 371 | irq_set_handler_data(PIC_PCIX_IRQ, xlr_pci_ack); |
331 | } | 372 | } |
332 | 373 | ||
333 | return 0; | 374 | return 0; |
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c index b71fae231049..5edab2bc6fc0 100644 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ b/arch/mips/pmc-sierra/yosemite/smp.c | |||
@@ -115,11 +115,11 @@ static void yos_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |||
115 | */ | 115 | */ |
116 | static void __cpuinit yos_init_secondary(void) | 116 | static void __cpuinit yos_init_secondary(void) |
117 | { | 117 | { |
118 | set_c0_status(ST0_CO | ST0_IE | ST0_IM); | ||
119 | } | 118 | } |
120 | 119 | ||
121 | static void __cpuinit yos_smp_finish(void) | 120 | static void __cpuinit yos_smp_finish(void) |
122 | { | 121 | { |
122 | set_c0_status(ST0_CO | ST0_IM | ST0_IE); | ||
123 | } | 123 | } |
124 | 124 | ||
125 | /* Hook for after all CPUs are online */ | 125 | /* Hook for after all CPUs are online */ |
diff --git a/arch/mips/powertv/asic/asic-calliope.c b/arch/mips/powertv/asic/asic-calliope.c index 0a170e0ffeaa..7773f3d956b0 100644 --- a/arch/mips/powertv/asic/asic-calliope.c +++ b/arch/mips/powertv/asic/asic-calliope.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | #define CALLIOPE_ADDR(x) (CALLIOPE_IO_BASE + (x)) | 29 | #define CALLIOPE_ADDR(x) (CALLIOPE_IO_BASE + (x)) |
30 | 30 | ||
31 | const struct register_map calliope_register_map __initdata = { | 31 | const struct register_map calliope_register_map __initconst = { |
32 | .eic_slow0_strt_add = {.phys = CALLIOPE_ADDR(0x800000)}, | 32 | .eic_slow0_strt_add = {.phys = CALLIOPE_ADDR(0x800000)}, |
33 | .eic_cfg_bits = {.phys = CALLIOPE_ADDR(0x800038)}, | 33 | .eic_cfg_bits = {.phys = CALLIOPE_ADDR(0x800038)}, |
34 | .eic_ready_status = {.phys = CALLIOPE_ADDR(0x80004c)}, | 34 | .eic_ready_status = {.phys = CALLIOPE_ADDR(0x80004c)}, |
diff --git a/arch/mips/powertv/asic/asic-cronus.c b/arch/mips/powertv/asic/asic-cronus.c index bbc0c122be5e..da076db7b7ed 100644 --- a/arch/mips/powertv/asic/asic-cronus.c +++ b/arch/mips/powertv/asic/asic-cronus.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | #define CRONUS_ADDR(x) (CRONUS_IO_BASE + (x)) | 29 | #define CRONUS_ADDR(x) (CRONUS_IO_BASE + (x)) |
30 | 30 | ||
31 | const struct register_map cronus_register_map __initdata = { | 31 | const struct register_map cronus_register_map __initconst = { |
32 | .eic_slow0_strt_add = {.phys = CRONUS_ADDR(0x000000)}, | 32 | .eic_slow0_strt_add = {.phys = CRONUS_ADDR(0x000000)}, |
33 | .eic_cfg_bits = {.phys = CRONUS_ADDR(0x000038)}, | 33 | .eic_cfg_bits = {.phys = CRONUS_ADDR(0x000038)}, |
34 | .eic_ready_status = {.phys = CRONUS_ADDR(0x00004C)}, | 34 | .eic_ready_status = {.phys = CRONUS_ADDR(0x00004C)}, |
diff --git a/arch/mips/powertv/asic/asic-gaia.c b/arch/mips/powertv/asic/asic-gaia.c index 91dda682752c..47683b370e74 100644 --- a/arch/mips/powertv/asic/asic-gaia.c +++ b/arch/mips/powertv/asic/asic-gaia.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <asm/mach-powertv/asic.h> | 24 | #include <asm/mach-powertv/asic.h> |
25 | 25 | ||
26 | const struct register_map gaia_register_map __initdata = { | 26 | const struct register_map gaia_register_map __initconst = { |
27 | .eic_slow0_strt_add = {.phys = GAIA_IO_BASE + 0x000000}, | 27 | .eic_slow0_strt_add = {.phys = GAIA_IO_BASE + 0x000000}, |
28 | .eic_cfg_bits = {.phys = GAIA_IO_BASE + 0x000038}, | 28 | .eic_cfg_bits = {.phys = GAIA_IO_BASE + 0x000038}, |
29 | .eic_ready_status = {.phys = GAIA_IO_BASE + 0x00004C}, | 29 | .eic_ready_status = {.phys = GAIA_IO_BASE + 0x00004C}, |
diff --git a/arch/mips/powertv/asic/asic-zeus.c b/arch/mips/powertv/asic/asic-zeus.c index 4a05bb096476..6ff4b10f09da 100644 --- a/arch/mips/powertv/asic/asic-zeus.c +++ b/arch/mips/powertv/asic/asic-zeus.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | #define ZEUS_ADDR(x) (ZEUS_IO_BASE + (x)) | 29 | #define ZEUS_ADDR(x) (ZEUS_IO_BASE + (x)) |
30 | 30 | ||
31 | const struct register_map zeus_register_map __initdata = { | 31 | const struct register_map zeus_register_map __initconst = { |
32 | .eic_slow0_strt_add = {.phys = ZEUS_ADDR(0x000000)}, | 32 | .eic_slow0_strt_add = {.phys = ZEUS_ADDR(0x000000)}, |
33 | .eic_cfg_bits = {.phys = ZEUS_ADDR(0x000038)}, | 33 | .eic_cfg_bits = {.phys = ZEUS_ADDR(0x000038)}, |
34 | .eic_ready_status = {.phys = ZEUS_ADDR(0x00004c)}, | 34 | .eic_ready_status = {.phys = ZEUS_ADDR(0x00004c)}, |
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 682efb0c108d..64eb71b15280 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c | |||
@@ -269,7 +269,7 @@ txx9_i8259_irq_setup(int irq) | |||
269 | return err; | 269 | return err; |
270 | } | 270 | } |
271 | 271 | ||
272 | static void __init quirk_slc90e66_bridge(struct pci_dev *dev) | 272 | static void __devinit quirk_slc90e66_bridge(struct pci_dev *dev) |
273 | { | 273 | { |
274 | int irq; /* PCI/ISA Bridge interrupt */ | 274 | int irq; /* PCI/ISA Bridge interrupt */ |
275 | u8 reg_64; | 275 | u8 reg_64; |
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c index 6ab0bee2a54f..4d584ae29ae1 100644 --- a/arch/mn10300/kernel/signal.c +++ b/arch/mn10300/kernel/signal.c | |||
@@ -459,10 +459,11 @@ static int handle_signal(int sig, | |||
459 | else | 459 | else |
460 | ret = setup_frame(sig, ka, oldset, regs); | 460 | ret = setup_frame(sig, ka, oldset, regs); |
461 | if (ret) | 461 | if (ret) |
462 | return; | 462 | return ret; |
463 | 463 | ||
464 | signal_delivered(sig, info, ka, regs, | 464 | signal_delivered(sig, info, ka, regs, |
465 | test_thread_flag(TIF_SINGLESTEP)); | 465 | test_thread_flag(TIF_SINGLESTEP)); |
466 | return 0; | ||
466 | } | 467 | } |
467 | 468 | ||
468 | /* | 469 | /* |
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c index 090d35d36973..e62c223e4c45 100644 --- a/arch/mn10300/kernel/smp.c +++ b/arch/mn10300/kernel/smp.c | |||
@@ -876,9 +876,7 @@ static void __init smp_online(void) | |||
876 | 876 | ||
877 | notify_cpu_starting(cpu); | 877 | notify_cpu_starting(cpu); |
878 | 878 | ||
879 | ipi_call_lock(); | ||
880 | set_cpu_online(cpu, true); | 879 | set_cpu_online(cpu, true); |
881 | ipi_call_unlock(); | ||
882 | 880 | ||
883 | local_irq_enable(); | 881 | local_irq_enable(); |
884 | } | 882 | } |
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index a47828d31fe6..6266730efd61 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c | |||
@@ -300,9 +300,7 @@ smp_cpu_init(int cpunum) | |||
300 | 300 | ||
301 | notify_cpu_starting(cpunum); | 301 | notify_cpu_starting(cpunum); |
302 | 302 | ||
303 | ipi_call_lock(); | ||
304 | set_cpu_online(cpunum, true); | 303 | set_cpu_online(cpunum, true); |
305 | ipi_call_unlock(); | ||
306 | 304 | ||
307 | /* Initialise the idle task for this CPU */ | 305 | /* Initialise the idle task for this CPU */ |
308 | atomic_inc(&init_mm.mm_count); | 306 | atomic_inc(&init_mm.mm_count); |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index e4cb34322de4..e1417c42155c 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -571,7 +571,6 @@ void __devinit start_secondary(void *unused) | |||
571 | if (system_state == SYSTEM_RUNNING) | 571 | if (system_state == SYSTEM_RUNNING) |
572 | vdso_data->processorCount++; | 572 | vdso_data->processorCount++; |
573 | #endif | 573 | #endif |
574 | ipi_call_lock(); | ||
575 | notify_cpu_starting(cpu); | 574 | notify_cpu_starting(cpu); |
576 | set_cpu_online(cpu, true); | 575 | set_cpu_online(cpu, true); |
577 | /* Update sibling maps */ | 576 | /* Update sibling maps */ |
@@ -601,7 +600,6 @@ void __devinit start_secondary(void *unused) | |||
601 | of_node_put(np); | 600 | of_node_put(np); |
602 | } | 601 | } |
603 | of_node_put(l2_cache); | 602 | of_node_put(l2_cache); |
604 | ipi_call_unlock(); | ||
605 | 603 | ||
606 | local_irq_enable(); | 604 | local_irq_enable(); |
607 | 605 | ||
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 15cca26ccb6c..8dca9c248ac7 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -717,9 +717,7 @@ static void __cpuinit smp_start_secondary(void *cpuvoid) | |||
717 | init_cpu_vtimer(); | 717 | init_cpu_vtimer(); |
718 | pfault_init(); | 718 | pfault_init(); |
719 | notify_cpu_starting(smp_processor_id()); | 719 | notify_cpu_starting(smp_processor_id()); |
720 | ipi_call_lock(); | ||
721 | set_cpu_online(smp_processor_id(), true); | 720 | set_cpu_online(smp_processor_id(), true); |
722 | ipi_call_unlock(); | ||
723 | local_irq_enable(); | 721 | local_irq_enable(); |
724 | /* cpu_idle will call schedule for us */ | 722 | /* cpu_idle will call schedule for us */ |
725 | cpu_idle(); | 723 | cpu_idle(); |
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index f591598d92f6..781bcb10b8bd 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
@@ -103,8 +103,6 @@ void __cpuinit smp_callin(void) | |||
103 | if (cheetah_pcache_forced_on) | 103 | if (cheetah_pcache_forced_on) |
104 | cheetah_enable_pcache(); | 104 | cheetah_enable_pcache(); |
105 | 105 | ||
106 | local_irq_enable(); | ||
107 | |||
108 | callin_flag = 1; | 106 | callin_flag = 1; |
109 | __asm__ __volatile__("membar #Sync\n\t" | 107 | __asm__ __volatile__("membar #Sync\n\t" |
110 | "flush %%g6" : : : "memory"); | 108 | "flush %%g6" : : : "memory"); |
@@ -124,9 +122,8 @@ void __cpuinit smp_callin(void) | |||
124 | while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) | 122 | while (!cpumask_test_cpu(cpuid, &smp_commenced_mask)) |
125 | rmb(); | 123 | rmb(); |
126 | 124 | ||
127 | ipi_call_lock_irq(); | ||
128 | set_cpu_online(cpuid, true); | 125 | set_cpu_online(cpuid, true); |
129 | ipi_call_unlock_irq(); | 126 | local_irq_enable(); |
130 | 127 | ||
131 | /* idle thread is expected to have preempt disabled */ | 128 | /* idle thread is expected to have preempt disabled */ |
132 | preempt_disable(); | 129 | preempt_disable(); |
@@ -1308,9 +1305,7 @@ int __cpu_disable(void) | |||
1308 | mdelay(1); | 1305 | mdelay(1); |
1309 | local_irq_disable(); | 1306 | local_irq_disable(); |
1310 | 1307 | ||
1311 | ipi_call_lock(); | ||
1312 | set_cpu_online(cpu, false); | 1308 | set_cpu_online(cpu, false); |
1313 | ipi_call_unlock(); | ||
1314 | 1309 | ||
1315 | cpu_map_rebuild(); | 1310 | cpu_map_rebuild(); |
1316 | 1311 | ||
diff --git a/arch/tile/kernel/smpboot.c b/arch/tile/kernel/smpboot.c index 84873fbe8f27..e686c5ac90be 100644 --- a/arch/tile/kernel/smpboot.c +++ b/arch/tile/kernel/smpboot.c | |||
@@ -198,17 +198,7 @@ void __cpuinit online_secondary(void) | |||
198 | 198 | ||
199 | notify_cpu_starting(smp_processor_id()); | 199 | notify_cpu_starting(smp_processor_id()); |
200 | 200 | ||
201 | /* | ||
202 | * We need to hold call_lock, so there is no inconsistency | ||
203 | * between the time smp_call_function() determines number of | ||
204 | * IPI recipients, and the time when the determination is made | ||
205 | * for which cpus receive the IPI. Holding this | ||
206 | * lock helps us to not include this cpu in a currently in progress | ||
207 | * smp_call_function(). | ||
208 | */ | ||
209 | ipi_call_lock(); | ||
210 | set_cpu_online(smp_processor_id(), 1); | 201 | set_cpu_online(smp_processor_id(), 1); |
211 | ipi_call_unlock(); | ||
212 | __get_cpu_var(cpu_state) = CPU_ONLINE; | 202 | __get_cpu_var(cpu_state) = CPU_ONLINE; |
213 | 203 | ||
214 | /* Set up tile-specific state for this cpu. */ | 204 | /* Set up tile-specific state for this cpu. */ |
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 1f2521434554..b0c5276861ec 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
@@ -49,6 +49,9 @@ else | |||
49 | KBUILD_AFLAGS += -m64 | 49 | KBUILD_AFLAGS += -m64 |
50 | KBUILD_CFLAGS += -m64 | 50 | KBUILD_CFLAGS += -m64 |
51 | 51 | ||
52 | # Use -mpreferred-stack-boundary=3 if supported. | ||
53 | KBUILD_CFLAGS += $(call cc-option,-mno-sse -mpreferred-stack-boundary=3) | ||
54 | |||
52 | # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu) | 55 | # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu) |
53 | cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) | 56 | cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) |
54 | cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) | 57 | cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) |
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 49331bedc158..70780689599a 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h | |||
@@ -75,23 +75,54 @@ static inline int alternatives_text_reserved(void *start, void *end) | |||
75 | } | 75 | } |
76 | #endif /* CONFIG_SMP */ | 76 | #endif /* CONFIG_SMP */ |
77 | 77 | ||
78 | #define OLDINSTR(oldinstr) "661:\n\t" oldinstr "\n662:\n" | ||
79 | |||
80 | #define b_replacement(number) "663"#number | ||
81 | #define e_replacement(number) "664"#number | ||
82 | |||
83 | #define alt_slen "662b-661b" | ||
84 | #define alt_rlen(number) e_replacement(number)"f-"b_replacement(number)"f" | ||
85 | |||
86 | #define ALTINSTR_ENTRY(feature, number) \ | ||
87 | " .long 661b - .\n" /* label */ \ | ||
88 | " .long " b_replacement(number)"f - .\n" /* new instruction */ \ | ||
89 | " .word " __stringify(feature) "\n" /* feature bit */ \ | ||
90 | " .byte " alt_slen "\n" /* source len */ \ | ||
91 | " .byte " alt_rlen(number) "\n" /* replacement len */ | ||
92 | |||
93 | #define DISCARD_ENTRY(number) /* rlen <= slen */ \ | ||
94 | " .byte 0xff + (" alt_rlen(number) ") - (" alt_slen ")\n" | ||
95 | |||
96 | #define ALTINSTR_REPLACEMENT(newinstr, feature, number) /* replacement */ \ | ||
97 | b_replacement(number)":\n\t" newinstr "\n" e_replacement(number) ":\n\t" | ||
98 | |||
78 | /* alternative assembly primitive: */ | 99 | /* alternative assembly primitive: */ |
79 | #define ALTERNATIVE(oldinstr, newinstr, feature) \ | 100 | #define ALTERNATIVE(oldinstr, newinstr, feature) \ |
80 | \ | 101 | OLDINSTR(oldinstr) \ |
81 | "661:\n\t" oldinstr "\n662:\n" \ | 102 | ".section .altinstructions,\"a\"\n" \ |
82 | ".section .altinstructions,\"a\"\n" \ | 103 | ALTINSTR_ENTRY(feature, 1) \ |
83 | " .long 661b - .\n" /* label */ \ | 104 | ".previous\n" \ |
84 | " .long 663f - .\n" /* new instruction */ \ | 105 | ".section .discard,\"aw\",@progbits\n" \ |
85 | " .word " __stringify(feature) "\n" /* feature bit */ \ | 106 | DISCARD_ENTRY(1) \ |
86 | " .byte 662b-661b\n" /* sourcelen */ \ | 107 | ".previous\n" \ |
87 | " .byte 664f-663f\n" /* replacementlen */ \ | 108 | ".section .altinstr_replacement, \"ax\"\n" \ |
88 | ".previous\n" \ | 109 | ALTINSTR_REPLACEMENT(newinstr, feature, 1) \ |
89 | ".section .discard,\"aw\",@progbits\n" \ | 110 | ".previous" |
90 | " .byte 0xff + (664f-663f) - (662b-661b)\n" /* rlen <= slen */ \ | 111 | |
91 | ".previous\n" \ | 112 | #define ALTERNATIVE_2(oldinstr, newinstr1, feature1, newinstr2, feature2)\ |
92 | ".section .altinstr_replacement, \"ax\"\n" \ | 113 | OLDINSTR(oldinstr) \ |
93 | "663:\n\t" newinstr "\n664:\n" /* replacement */ \ | 114 | ".section .altinstructions,\"a\"\n" \ |
94 | ".previous" | 115 | ALTINSTR_ENTRY(feature1, 1) \ |
116 | ALTINSTR_ENTRY(feature2, 2) \ | ||
117 | ".previous\n" \ | ||
118 | ".section .discard,\"aw\",@progbits\n" \ | ||
119 | DISCARD_ENTRY(1) \ | ||
120 | DISCARD_ENTRY(2) \ | ||
121 | ".previous\n" \ | ||
122 | ".section .altinstr_replacement, \"ax\"\n" \ | ||
123 | ALTINSTR_REPLACEMENT(newinstr1, feature1, 1) \ | ||
124 | ALTINSTR_REPLACEMENT(newinstr2, feature2, 2) \ | ||
125 | ".previous" | ||
95 | 126 | ||
96 | /* | 127 | /* |
97 | * This must be included *after* the definition of ALTERNATIVE due to | 128 | * This must be included *after* the definition of ALTERNATIVE due to |
@@ -140,6 +171,19 @@ static inline int alternatives_text_reserved(void *start, void *end) | |||
140 | : output : [old] "i" (oldfunc), [new] "i" (newfunc), ## input) | 171 | : output : [old] "i" (oldfunc), [new] "i" (newfunc), ## input) |
141 | 172 | ||
142 | /* | 173 | /* |
174 | * Like alternative_call, but there are two features and respective functions. | ||
175 | * If CPU has feature2, function2 is used. | ||
176 | * Otherwise, if CPU has feature1, function1 is used. | ||
177 | * Otherwise, old function is used. | ||
178 | */ | ||
179 | #define alternative_call_2(oldfunc, newfunc1, feature1, newfunc2, feature2, \ | ||
180 | output, input...) \ | ||
181 | asm volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", feature1,\ | ||
182 | "call %P[new2]", feature2) \ | ||
183 | : output : [old] "i" (oldfunc), [new1] "i" (newfunc1), \ | ||
184 | [new2] "i" (newfunc2), ## input) | ||
185 | |||
186 | /* | ||
143 | * use this macro(s) if you need more than one output parameter | 187 | * use this macro(s) if you need more than one output parameter |
144 | * in alternative_io | 188 | * in alternative_io |
145 | */ | 189 | */ |
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index eaff4790ed96..88093c1d44fd 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
@@ -306,7 +306,8 @@ struct apic { | |||
306 | unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid); | 306 | unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid); |
307 | unsigned long (*check_apicid_present)(int apicid); | 307 | unsigned long (*check_apicid_present)(int apicid); |
308 | 308 | ||
309 | void (*vector_allocation_domain)(int cpu, struct cpumask *retmask); | 309 | void (*vector_allocation_domain)(int cpu, struct cpumask *retmask, |
310 | const struct cpumask *mask); | ||
310 | void (*init_apic_ldr)(void); | 311 | void (*init_apic_ldr)(void); |
311 | 312 | ||
312 | void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap); | 313 | void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap); |
@@ -331,9 +332,9 @@ struct apic { | |||
331 | unsigned long (*set_apic_id)(unsigned int id); | 332 | unsigned long (*set_apic_id)(unsigned int id); |
332 | unsigned long apic_id_mask; | 333 | unsigned long apic_id_mask; |
333 | 334 | ||
334 | unsigned int (*cpu_mask_to_apicid)(const struct cpumask *cpumask); | 335 | int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, |
335 | unsigned int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, | 336 | const struct cpumask *andmask, |
336 | const struct cpumask *andmask); | 337 | unsigned int *apicid); |
337 | 338 | ||
338 | /* ipi */ | 339 | /* ipi */ |
339 | void (*send_IPI_mask)(const struct cpumask *mask, int vector); | 340 | void (*send_IPI_mask)(const struct cpumask *mask, int vector); |
@@ -537,6 +538,11 @@ static inline const struct cpumask *default_target_cpus(void) | |||
537 | #endif | 538 | #endif |
538 | } | 539 | } |
539 | 540 | ||
541 | static inline const struct cpumask *online_target_cpus(void) | ||
542 | { | ||
543 | return cpu_online_mask; | ||
544 | } | ||
545 | |||
540 | DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); | 546 | DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid); |
541 | 547 | ||
542 | 548 | ||
@@ -586,21 +592,50 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb) | |||
586 | 592 | ||
587 | #endif | 593 | #endif |
588 | 594 | ||
589 | static inline unsigned int | 595 | static inline int |
590 | default_cpu_mask_to_apicid(const struct cpumask *cpumask) | 596 | flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
597 | const struct cpumask *andmask, | ||
598 | unsigned int *apicid) | ||
591 | { | 599 | { |
592 | return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS; | 600 | unsigned long cpu_mask = cpumask_bits(cpumask)[0] & |
601 | cpumask_bits(andmask)[0] & | ||
602 | cpumask_bits(cpu_online_mask)[0] & | ||
603 | APIC_ALL_CPUS; | ||
604 | |||
605 | if (likely(cpu_mask)) { | ||
606 | *apicid = (unsigned int)cpu_mask; | ||
607 | return 0; | ||
608 | } else { | ||
609 | return -EINVAL; | ||
610 | } | ||
593 | } | 611 | } |
594 | 612 | ||
595 | static inline unsigned int | 613 | extern int |
596 | default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 614 | default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
597 | const struct cpumask *andmask) | 615 | const struct cpumask *andmask, |
616 | unsigned int *apicid); | ||
617 | |||
618 | static inline void | ||
619 | flat_vector_allocation_domain(int cpu, struct cpumask *retmask, | ||
620 | const struct cpumask *mask) | ||
598 | { | 621 | { |
599 | unsigned long mask1 = cpumask_bits(cpumask)[0]; | 622 | /* Careful. Some cpus do not strictly honor the set of cpus |
600 | unsigned long mask2 = cpumask_bits(andmask)[0]; | 623 | * specified in the interrupt destination when using lowest |
601 | unsigned long mask3 = cpumask_bits(cpu_online_mask)[0]; | 624 | * priority interrupt delivery mode. |
625 | * | ||
626 | * In particular there was a hyperthreading cpu observed to | ||
627 | * deliver interrupts to the wrong hyperthread when only one | ||
628 | * hyperthread was specified in the interrupt desitination. | ||
629 | */ | ||
630 | cpumask_clear(retmask); | ||
631 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
632 | } | ||
602 | 633 | ||
603 | return (unsigned int)(mask1 & mask2 & mask3); | 634 | static inline void |
635 | default_vector_allocation_domain(int cpu, struct cpumask *retmask, | ||
636 | const struct cpumask *mask) | ||
637 | { | ||
638 | cpumask_copy(retmask, cpumask_of(cpu)); | ||
604 | } | 639 | } |
605 | 640 | ||
606 | static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid) | 641 | static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid) |
diff --git a/arch/x86/include/asm/emergency-restart.h b/arch/x86/include/asm/emergency-restart.h index cc70c1c78ca4..75ce3f47d204 100644 --- a/arch/x86/include/asm/emergency-restart.h +++ b/arch/x86/include/asm/emergency-restart.h | |||
@@ -4,9 +4,7 @@ | |||
4 | enum reboot_type { | 4 | enum reboot_type { |
5 | BOOT_TRIPLE = 't', | 5 | BOOT_TRIPLE = 't', |
6 | BOOT_KBD = 'k', | 6 | BOOT_KBD = 'k', |
7 | #ifdef CONFIG_X86_32 | ||
8 | BOOT_BIOS = 'b', | 7 | BOOT_BIOS = 'b', |
9 | #endif | ||
10 | BOOT_ACPI = 'a', | 8 | BOOT_ACPI = 'a', |
11 | BOOT_EFI = 'e', | 9 | BOOT_EFI = 'e', |
12 | BOOT_CF9 = 'p', | 10 | BOOT_CF9 = 'p', |
diff --git a/arch/x86/include/asm/floppy.h b/arch/x86/include/asm/floppy.h index dbe82a5c5eac..d3d74698dce9 100644 --- a/arch/x86/include/asm/floppy.h +++ b/arch/x86/include/asm/floppy.h | |||
@@ -99,7 +99,7 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id) | |||
99 | virtual_dma_residue += virtual_dma_count; | 99 | virtual_dma_residue += virtual_dma_count; |
100 | virtual_dma_count = 0; | 100 | virtual_dma_count = 0; |
101 | #ifdef TRACE_FLPY_INT | 101 | #ifdef TRACE_FLPY_INT |
102 | printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", | 102 | printk(KERN_DEBUG "count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", |
103 | virtual_dma_count, virtual_dma_residue, calls, bytes, | 103 | virtual_dma_count, virtual_dma_residue, calls, bytes, |
104 | dma_wait); | 104 | dma_wait); |
105 | calls = 0; | 105 | calls = 0; |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index db7c1f2709a2..2da88c0cda14 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -313,8 +313,8 @@ struct kvm_pmu { | |||
313 | u64 counter_bitmask[2]; | 313 | u64 counter_bitmask[2]; |
314 | u64 global_ctrl_mask; | 314 | u64 global_ctrl_mask; |
315 | u8 version; | 315 | u8 version; |
316 | struct kvm_pmc gp_counters[X86_PMC_MAX_GENERIC]; | 316 | struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC]; |
317 | struct kvm_pmc fixed_counters[X86_PMC_MAX_FIXED]; | 317 | struct kvm_pmc fixed_counters[INTEL_PMC_MAX_FIXED]; |
318 | struct irq_work irq_work; | 318 | struct irq_work irq_work; |
319 | u64 reprogram_pmi; | 319 | u64 reprogram_pmi; |
320 | }; | 320 | }; |
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 084ef95274cd..813ed103f45e 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h | |||
@@ -115,8 +115,8 @@ notrace static inline int native_write_msr_safe(unsigned int msr, | |||
115 | 115 | ||
116 | extern unsigned long long native_read_tsc(void); | 116 | extern unsigned long long native_read_tsc(void); |
117 | 117 | ||
118 | extern int native_rdmsr_safe_regs(u32 regs[8]); | 118 | extern int rdmsr_safe_regs(u32 regs[8]); |
119 | extern int native_wrmsr_safe_regs(u32 regs[8]); | 119 | extern int wrmsr_safe_regs(u32 regs[8]); |
120 | 120 | ||
121 | static __always_inline unsigned long long __native_read_tsc(void) | 121 | static __always_inline unsigned long long __native_read_tsc(void) |
122 | { | 122 | { |
@@ -187,43 +187,6 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) | |||
187 | return err; | 187 | return err; |
188 | } | 188 | } |
189 | 189 | ||
190 | static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) | ||
191 | { | ||
192 | u32 gprs[8] = { 0 }; | ||
193 | int err; | ||
194 | |||
195 | gprs[1] = msr; | ||
196 | gprs[7] = 0x9c5a203a; | ||
197 | |||
198 | err = native_rdmsr_safe_regs(gprs); | ||
199 | |||
200 | *p = gprs[0] | ((u64)gprs[2] << 32); | ||
201 | |||
202 | return err; | ||
203 | } | ||
204 | |||
205 | static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) | ||
206 | { | ||
207 | u32 gprs[8] = { 0 }; | ||
208 | |||
209 | gprs[0] = (u32)val; | ||
210 | gprs[1] = msr; | ||
211 | gprs[2] = val >> 32; | ||
212 | gprs[7] = 0x9c5a203a; | ||
213 | |||
214 | return native_wrmsr_safe_regs(gprs); | ||
215 | } | ||
216 | |||
217 | static inline int rdmsr_safe_regs(u32 regs[8]) | ||
218 | { | ||
219 | return native_rdmsr_safe_regs(regs); | ||
220 | } | ||
221 | |||
222 | static inline int wrmsr_safe_regs(u32 regs[8]) | ||
223 | { | ||
224 | return native_wrmsr_safe_regs(regs); | ||
225 | } | ||
226 | |||
227 | #define rdtscl(low) \ | 190 | #define rdtscl(low) \ |
228 | ((low) = (u32)__native_read_tsc()) | 191 | ((low) = (u32)__native_read_tsc()) |
229 | 192 | ||
@@ -237,6 +200,8 @@ do { \ | |||
237 | (high) = (u32)(_l >> 32); \ | 200 | (high) = (u32)(_l >> 32); \ |
238 | } while (0) | 201 | } while (0) |
239 | 202 | ||
203 | #define rdpmcl(counter, val) ((val) = native_read_pmc(counter)) | ||
204 | |||
240 | #define rdtscp(low, high, aux) \ | 205 | #define rdtscp(low, high, aux) \ |
241 | do { \ | 206 | do { \ |
242 | unsigned long long _val = native_read_tscp(&(aux)); \ | 207 | unsigned long long _val = native_read_tscp(&(aux)); \ |
@@ -248,8 +213,7 @@ do { \ | |||
248 | 213 | ||
249 | #endif /* !CONFIG_PARAVIRT */ | 214 | #endif /* !CONFIG_PARAVIRT */ |
250 | 215 | ||
251 | 216 | #define wrmsrl_safe(msr, val) wrmsr_safe((msr), (u32)(val), \ | |
252 | #define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \ | ||
253 | (u32)((val) >> 32)) | 217 | (u32)((val) >> 32)) |
254 | 218 | ||
255 | #define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2)) | 219 | #define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2)) |
diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h index dc580c42851c..c0fa356e90de 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h | |||
@@ -44,28 +44,14 @@ struct nmiaction { | |||
44 | const char *name; | 44 | const char *name; |
45 | }; | 45 | }; |
46 | 46 | ||
47 | #define register_nmi_handler(t, fn, fg, n) \ | 47 | #define register_nmi_handler(t, fn, fg, n, init...) \ |
48 | ({ \ | 48 | ({ \ |
49 | static struct nmiaction fn##_na = { \ | 49 | static struct nmiaction init fn##_na = { \ |
50 | .handler = (fn), \ | 50 | .handler = (fn), \ |
51 | .name = (n), \ | 51 | .name = (n), \ |
52 | .flags = (fg), \ | 52 | .flags = (fg), \ |
53 | }; \ | 53 | }; \ |
54 | __register_nmi_handler((t), &fn##_na); \ | 54 | __register_nmi_handler((t), &fn##_na); \ |
55 | }) | ||
56 | |||
57 | /* | ||
58 | * For special handlers that register/unregister in the | ||
59 | * init section only. This should be considered rare. | ||
60 | */ | ||
61 | #define register_nmi_handler_initonly(t, fn, fg, n) \ | ||
62 | ({ \ | ||
63 | static struct nmiaction fn##_na __initdata = { \ | ||
64 | .handler = (fn), \ | ||
65 | .name = (n), \ | ||
66 | .flags = (fg), \ | ||
67 | }; \ | ||
68 | __register_nmi_handler((t), &fn##_na); \ | ||
69 | }) | 55 | }) |
70 | 56 | ||
71 | int __register_nmi_handler(unsigned int, struct nmiaction *); | 57 | int __register_nmi_handler(unsigned int, struct nmiaction *); |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 6cbbabf52707..0b47ddb6f00b 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -128,21 +128,11 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err) | |||
128 | return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err); | 128 | return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err); |
129 | } | 129 | } |
130 | 130 | ||
131 | static inline int paravirt_rdmsr_regs(u32 *regs) | ||
132 | { | ||
133 | return PVOP_CALL1(int, pv_cpu_ops.rdmsr_regs, regs); | ||
134 | } | ||
135 | |||
136 | static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) | 131 | static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high) |
137 | { | 132 | { |
138 | return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high); | 133 | return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high); |
139 | } | 134 | } |
140 | 135 | ||
141 | static inline int paravirt_wrmsr_regs(u32 *regs) | ||
142 | { | ||
143 | return PVOP_CALL1(int, pv_cpu_ops.wrmsr_regs, regs); | ||
144 | } | ||
145 | |||
146 | /* These should all do BUG_ON(_err), but our headers are too tangled. */ | 136 | /* These should all do BUG_ON(_err), but our headers are too tangled. */ |
147 | #define rdmsr(msr, val1, val2) \ | 137 | #define rdmsr(msr, val1, val2) \ |
148 | do { \ | 138 | do { \ |
@@ -176,9 +166,6 @@ do { \ | |||
176 | _err; \ | 166 | _err; \ |
177 | }) | 167 | }) |
178 | 168 | ||
179 | #define rdmsr_safe_regs(regs) paravirt_rdmsr_regs(regs) | ||
180 | #define wrmsr_safe_regs(regs) paravirt_wrmsr_regs(regs) | ||
181 | |||
182 | static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) | 169 | static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) |
183 | { | 170 | { |
184 | int err; | 171 | int err; |
@@ -186,32 +173,6 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p) | |||
186 | *p = paravirt_read_msr(msr, &err); | 173 | *p = paravirt_read_msr(msr, &err); |
187 | return err; | 174 | return err; |
188 | } | 175 | } |
189 | static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) | ||
190 | { | ||
191 | u32 gprs[8] = { 0 }; | ||
192 | int err; | ||
193 | |||
194 | gprs[1] = msr; | ||
195 | gprs[7] = 0x9c5a203a; | ||
196 | |||
197 | err = paravirt_rdmsr_regs(gprs); | ||
198 | |||
199 | *p = gprs[0] | ((u64)gprs[2] << 32); | ||
200 | |||
201 | return err; | ||
202 | } | ||
203 | |||
204 | static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) | ||
205 | { | ||
206 | u32 gprs[8] = { 0 }; | ||
207 | |||
208 | gprs[0] = (u32)val; | ||
209 | gprs[1] = msr; | ||
210 | gprs[2] = val >> 32; | ||
211 | gprs[7] = 0x9c5a203a; | ||
212 | |||
213 | return paravirt_wrmsr_regs(gprs); | ||
214 | } | ||
215 | 176 | ||
216 | static inline u64 paravirt_read_tsc(void) | 177 | static inline u64 paravirt_read_tsc(void) |
217 | { | 178 | { |
@@ -252,6 +213,8 @@ do { \ | |||
252 | high = _l >> 32; \ | 213 | high = _l >> 32; \ |
253 | } while (0) | 214 | } while (0) |
254 | 215 | ||
216 | #define rdpmcl(counter, val) ((val) = paravirt_read_pmc(counter)) | ||
217 | |||
255 | static inline unsigned long long paravirt_rdtscp(unsigned int *aux) | 218 | static inline unsigned long long paravirt_rdtscp(unsigned int *aux) |
256 | { | 219 | { |
257 | return PVOP_CALL1(u64, pv_cpu_ops.read_tscp, aux); | 220 | return PVOP_CALL1(u64, pv_cpu_ops.read_tscp, aux); |
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 8e8b9a4987ee..8613cbb7ba41 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h | |||
@@ -153,9 +153,7 @@ struct pv_cpu_ops { | |||
153 | /* MSR, PMC and TSR operations. | 153 | /* MSR, PMC and TSR operations. |
154 | err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */ | 154 | err = 0/-EFAULT. wrmsr returns 0/-EFAULT. */ |
155 | u64 (*read_msr)(unsigned int msr, int *err); | 155 | u64 (*read_msr)(unsigned int msr, int *err); |
156 | int (*rdmsr_regs)(u32 *regs); | ||
157 | int (*write_msr)(unsigned int msr, unsigned low, unsigned high); | 156 | int (*write_msr)(unsigned int msr, unsigned low, unsigned high); |
158 | int (*wrmsr_regs)(u32 *regs); | ||
159 | 157 | ||
160 | u64 (*read_tsc)(void); | 158 | u64 (*read_tsc)(void); |
161 | u64 (*read_pmc)(int counter); | 159 | u64 (*read_pmc)(int counter); |
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index b3a531746026..5ad24a89b19b 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
@@ -7,9 +7,13 @@ | |||
7 | #undef DEBUG | 7 | #undef DEBUG |
8 | 8 | ||
9 | #ifdef DEBUG | 9 | #ifdef DEBUG |
10 | #define DBG(x...) printk(x) | 10 | #define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__) |
11 | #else | 11 | #else |
12 | #define DBG(x...) | 12 | #define DBG(fmt, ...) \ |
13 | do { \ | ||
14 | if (0) \ | ||
15 | printk(fmt, ##__VA_ARGS__); \ | ||
16 | } while (0) | ||
13 | #endif | 17 | #endif |
14 | 18 | ||
15 | #define PCI_PROBE_BIOS 0x0001 | 19 | #define PCI_PROBE_BIOS 0x0001 |
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 588f52ea810e..c78f14a0df00 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h | |||
@@ -5,11 +5,10 @@ | |||
5 | * Performance event hw details: | 5 | * Performance event hw details: |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #define X86_PMC_MAX_GENERIC 32 | 8 | #define INTEL_PMC_MAX_GENERIC 32 |
9 | #define X86_PMC_MAX_FIXED 3 | 9 | #define INTEL_PMC_MAX_FIXED 3 |
10 | #define INTEL_PMC_IDX_FIXED 32 | ||
10 | 11 | ||
11 | #define X86_PMC_IDX_GENERIC 0 | ||
12 | #define X86_PMC_IDX_FIXED 32 | ||
13 | #define X86_PMC_IDX_MAX 64 | 12 | #define X86_PMC_IDX_MAX 64 |
14 | 13 | ||
15 | #define MSR_ARCH_PERFMON_PERFCTR0 0xc1 | 14 | #define MSR_ARCH_PERFMON_PERFCTR0 0xc1 |
@@ -48,8 +47,7 @@ | |||
48 | (X86_RAW_EVENT_MASK | \ | 47 | (X86_RAW_EVENT_MASK | \ |
49 | AMD64_EVENTSEL_EVENT) | 48 | AMD64_EVENTSEL_EVENT) |
50 | #define AMD64_NUM_COUNTERS 4 | 49 | #define AMD64_NUM_COUNTERS 4 |
51 | #define AMD64_NUM_COUNTERS_F15H 6 | 50 | #define AMD64_NUM_COUNTERS_CORE 6 |
52 | #define AMD64_NUM_COUNTERS_MAX AMD64_NUM_COUNTERS_F15H | ||
53 | 51 | ||
54 | #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c | 52 | #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c |
55 | #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8) | 53 | #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8) |
@@ -121,16 +119,16 @@ struct x86_pmu_capability { | |||
121 | 119 | ||
122 | /* Instr_Retired.Any: */ | 120 | /* Instr_Retired.Any: */ |
123 | #define MSR_ARCH_PERFMON_FIXED_CTR0 0x309 | 121 | #define MSR_ARCH_PERFMON_FIXED_CTR0 0x309 |
124 | #define X86_PMC_IDX_FIXED_INSTRUCTIONS (X86_PMC_IDX_FIXED + 0) | 122 | #define INTEL_PMC_IDX_FIXED_INSTRUCTIONS (INTEL_PMC_IDX_FIXED + 0) |
125 | 123 | ||
126 | /* CPU_CLK_Unhalted.Core: */ | 124 | /* CPU_CLK_Unhalted.Core: */ |
127 | #define MSR_ARCH_PERFMON_FIXED_CTR1 0x30a | 125 | #define MSR_ARCH_PERFMON_FIXED_CTR1 0x30a |
128 | #define X86_PMC_IDX_FIXED_CPU_CYCLES (X86_PMC_IDX_FIXED + 1) | 126 | #define INTEL_PMC_IDX_FIXED_CPU_CYCLES (INTEL_PMC_IDX_FIXED + 1) |
129 | 127 | ||
130 | /* CPU_CLK_Unhalted.Ref: */ | 128 | /* CPU_CLK_Unhalted.Ref: */ |
131 | #define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b | 129 | #define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b |
132 | #define X86_PMC_IDX_FIXED_REF_CYCLES (X86_PMC_IDX_FIXED + 2) | 130 | #define INTEL_PMC_IDX_FIXED_REF_CYCLES (INTEL_PMC_IDX_FIXED + 2) |
133 | #define X86_PMC_MSK_FIXED_REF_CYCLES (1ULL << X86_PMC_IDX_FIXED_REF_CYCLES) | 131 | #define INTEL_PMC_MSK_FIXED_REF_CYCLES (1ULL << INTEL_PMC_IDX_FIXED_REF_CYCLES) |
134 | 132 | ||
135 | /* | 133 | /* |
136 | * We model BTS tracing as another fixed-mode PMC. | 134 | * We model BTS tracing as another fixed-mode PMC. |
@@ -139,7 +137,7 @@ struct x86_pmu_capability { | |||
139 | * values are used by actual fixed events and higher values are used | 137 | * values are used by actual fixed events and higher values are used |
140 | * to indicate other overflow conditions in the PERF_GLOBAL_STATUS msr. | 138 | * to indicate other overflow conditions in the PERF_GLOBAL_STATUS msr. |
141 | */ | 139 | */ |
142 | #define X86_PMC_IDX_FIXED_BTS (X86_PMC_IDX_FIXED + 16) | 140 | #define INTEL_PMC_IDX_FIXED_BTS (INTEL_PMC_IDX_FIXED + 16) |
143 | 141 | ||
144 | /* | 142 | /* |
145 | * IBS cpuid feature detection | 143 | * IBS cpuid feature detection |
@@ -234,6 +232,7 @@ struct perf_guest_switch_msr { | |||
234 | 232 | ||
235 | extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr); | 233 | extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr); |
236 | extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap); | 234 | extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap); |
235 | extern void perf_check_microcode(void); | ||
237 | #else | 236 | #else |
238 | static inline perf_guest_switch_msr *perf_guest_get_msrs(int *nr) | 237 | static inline perf_guest_switch_msr *perf_guest_get_msrs(int *nr) |
239 | { | 238 | { |
@@ -247,6 +246,7 @@ static inline void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap) | |||
247 | } | 246 | } |
248 | 247 | ||
249 | static inline void perf_events_lapic_init(void) { } | 248 | static inline void perf_events_lapic_init(void) { } |
249 | static inline void perf_check_microcode(void) { } | ||
250 | #endif | 250 | #endif |
251 | 251 | ||
252 | #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) | 252 | #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) |
diff --git a/arch/x86/include/asm/pgtable-2level.h b/arch/x86/include/asm/pgtable-2level.h index 98391db840c6..f2b489cf1602 100644 --- a/arch/x86/include/asm/pgtable-2level.h +++ b/arch/x86/include/asm/pgtable-2level.h | |||
@@ -2,9 +2,9 @@ | |||
2 | #define _ASM_X86_PGTABLE_2LEVEL_H | 2 | #define _ASM_X86_PGTABLE_2LEVEL_H |
3 | 3 | ||
4 | #define pte_ERROR(e) \ | 4 | #define pte_ERROR(e) \ |
5 | printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low) | 5 | pr_err("%s:%d: bad pte %08lx\n", __FILE__, __LINE__, (e).pte_low) |
6 | #define pgd_ERROR(e) \ | 6 | #define pgd_ERROR(e) \ |
7 | printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) | 7 | pr_err("%s:%d: bad pgd %08lx\n", __FILE__, __LINE__, pgd_val(e)) |
8 | 8 | ||
9 | /* | 9 | /* |
10 | * Certain architectures need to do special things when PTEs | 10 | * Certain architectures need to do special things when PTEs |
diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index cb00ccc7d571..4cc9f2b7cdc3 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h | |||
@@ -9,13 +9,13 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define pte_ERROR(e) \ | 11 | #define pte_ERROR(e) \ |
12 | printk("%s:%d: bad pte %p(%08lx%08lx).\n", \ | 12 | pr_err("%s:%d: bad pte %p(%08lx%08lx)\n", \ |
13 | __FILE__, __LINE__, &(e), (e).pte_high, (e).pte_low) | 13 | __FILE__, __LINE__, &(e), (e).pte_high, (e).pte_low) |
14 | #define pmd_ERROR(e) \ | 14 | #define pmd_ERROR(e) \ |
15 | printk("%s:%d: bad pmd %p(%016Lx).\n", \ | 15 | pr_err("%s:%d: bad pmd %p(%016Lx)\n", \ |
16 | __FILE__, __LINE__, &(e), pmd_val(e)) | 16 | __FILE__, __LINE__, &(e), pmd_val(e)) |
17 | #define pgd_ERROR(e) \ | 17 | #define pgd_ERROR(e) \ |
18 | printk("%s:%d: bad pgd %p(%016Lx).\n", \ | 18 | pr_err("%s:%d: bad pgd %p(%016Lx)\n", \ |
19 | __FILE__, __LINE__, &(e), pgd_val(e)) | 19 | __FILE__, __LINE__, &(e), pgd_val(e)) |
20 | 20 | ||
21 | /* Rules for using set_pte: the pte being assigned *must* be | 21 | /* Rules for using set_pte: the pte being assigned *must* be |
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index 975f709e09ae..8251be02301e 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h | |||
@@ -26,16 +26,16 @@ extern pgd_t init_level4_pgt[]; | |||
26 | extern void paging_init(void); | 26 | extern void paging_init(void); |
27 | 27 | ||
28 | #define pte_ERROR(e) \ | 28 | #define pte_ERROR(e) \ |
29 | printk("%s:%d: bad pte %p(%016lx).\n", \ | 29 | pr_err("%s:%d: bad pte %p(%016lx)\n", \ |
30 | __FILE__, __LINE__, &(e), pte_val(e)) | 30 | __FILE__, __LINE__, &(e), pte_val(e)) |
31 | #define pmd_ERROR(e) \ | 31 | #define pmd_ERROR(e) \ |
32 | printk("%s:%d: bad pmd %p(%016lx).\n", \ | 32 | pr_err("%s:%d: bad pmd %p(%016lx)\n", \ |
33 | __FILE__, __LINE__, &(e), pmd_val(e)) | 33 | __FILE__, __LINE__, &(e), pmd_val(e)) |
34 | #define pud_ERROR(e) \ | 34 | #define pud_ERROR(e) \ |
35 | printk("%s:%d: bad pud %p(%016lx).\n", \ | 35 | pr_err("%s:%d: bad pud %p(%016lx)\n", \ |
36 | __FILE__, __LINE__, &(e), pud_val(e)) | 36 | __FILE__, __LINE__, &(e), pud_val(e)) |
37 | #define pgd_ERROR(e) \ | 37 | #define pgd_ERROR(e) \ |
38 | printk("%s:%d: bad pgd %p(%016lx).\n", \ | 38 | pr_err("%s:%d: bad pgd %p(%016lx)\n", \ |
39 | __FILE__, __LINE__, &(e), pgd_val(e)) | 39 | __FILE__, __LINE__, &(e), pgd_val(e)) |
40 | 40 | ||
41 | struct mm_struct; | 41 | struct mm_struct; |
diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h index fce3f4ae5bd6..fe1ec5bcd846 100644 --- a/arch/x86/include/asm/realmode.h +++ b/arch/x86/include/asm/realmode.h | |||
@@ -21,8 +21,9 @@ struct real_mode_header { | |||
21 | u32 wakeup_header; | 21 | u32 wakeup_header; |
22 | #endif | 22 | #endif |
23 | /* APM/BIOS reboot */ | 23 | /* APM/BIOS reboot */ |
24 | #ifdef CONFIG_X86_32 | ||
25 | u32 machine_real_restart_asm; | 24 | u32 machine_real_restart_asm; |
25 | #ifdef CONFIG_X86_64 | ||
26 | u32 machine_real_restart_seg; | ||
26 | #endif | 27 | #endif |
27 | }; | 28 | }; |
28 | 29 | ||
diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h index 92f297069e87..a82c4f1b4d83 100644 --- a/arch/x86/include/asm/reboot.h +++ b/arch/x86/include/asm/reboot.h | |||
@@ -18,8 +18,8 @@ extern struct machine_ops machine_ops; | |||
18 | 18 | ||
19 | void native_machine_crash_shutdown(struct pt_regs *regs); | 19 | void native_machine_crash_shutdown(struct pt_regs *regs); |
20 | void native_machine_shutdown(void); | 20 | void native_machine_shutdown(void); |
21 | void machine_real_restart(unsigned int type); | 21 | void __noreturn machine_real_restart(unsigned int type); |
22 | /* These must match dispatch_table in reboot_32.S */ | 22 | /* These must match dispatch in arch/x86/realmore/rm/reboot.S */ |
23 | #define MRR_BIOS 0 | 23 | #define MRR_BIOS 0 |
24 | #define MRR_APM 1 | 24 | #define MRR_APM 1 |
25 | 25 | ||
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index f48394513c37..2ffa95dc2333 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h | |||
@@ -169,11 +169,6 @@ void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle); | |||
169 | void smp_store_cpu_info(int id); | 169 | void smp_store_cpu_info(int id); |
170 | #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) | 170 | #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) |
171 | 171 | ||
172 | /* We don't mark CPUs online until __cpu_up(), so we need another measure */ | ||
173 | static inline int num_booting_cpus(void) | ||
174 | { | ||
175 | return cpumask_weight(cpu_callout_mask); | ||
176 | } | ||
177 | #else /* !CONFIG_SMP */ | 172 | #else /* !CONFIG_SMP */ |
178 | #define wbinvd_on_cpu(cpu) wbinvd() | 173 | #define wbinvd_on_cpu(cpu) wbinvd() |
179 | static inline int wbinvd_on_all_cpus(void) | 174 | static inline int wbinvd_on_all_cpus(void) |
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 8e796fbbf9c6..d8def8b3dba0 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h | |||
@@ -17,6 +17,8 @@ | |||
17 | 17 | ||
18 | /* Handles exceptions in both to and from, but doesn't do access_ok */ | 18 | /* Handles exceptions in both to and from, but doesn't do access_ok */ |
19 | __must_check unsigned long | 19 | __must_check unsigned long |
20 | copy_user_enhanced_fast_string(void *to, const void *from, unsigned len); | ||
21 | __must_check unsigned long | ||
20 | copy_user_generic_string(void *to, const void *from, unsigned len); | 22 | copy_user_generic_string(void *to, const void *from, unsigned len); |
21 | __must_check unsigned long | 23 | __must_check unsigned long |
22 | copy_user_generic_unrolled(void *to, const void *from, unsigned len); | 24 | copy_user_generic_unrolled(void *to, const void *from, unsigned len); |
@@ -26,9 +28,16 @@ copy_user_generic(void *to, const void *from, unsigned len) | |||
26 | { | 28 | { |
27 | unsigned ret; | 29 | unsigned ret; |
28 | 30 | ||
29 | alternative_call(copy_user_generic_unrolled, | 31 | /* |
32 | * If CPU has ERMS feature, use copy_user_enhanced_fast_string. | ||
33 | * Otherwise, if CPU has rep_good feature, use copy_user_generic_string. | ||
34 | * Otherwise, use copy_user_generic_unrolled. | ||
35 | */ | ||
36 | alternative_call_2(copy_user_generic_unrolled, | ||
30 | copy_user_generic_string, | 37 | copy_user_generic_string, |
31 | X86_FEATURE_REP_GOOD, | 38 | X86_FEATURE_REP_GOOD, |
39 | copy_user_enhanced_fast_string, | ||
40 | X86_FEATURE_ERMS, | ||
32 | ASM_OUTPUT2("=a" (ret), "=D" (to), "=S" (from), | 41 | ASM_OUTPUT2("=a" (ret), "=D" (to), "=S" (from), |
33 | "=d" (len)), | 42 | "=d" (len)), |
34 | "1" (to), "2" (from), "3" (len) | 43 | "1" (to), "2" (from), "3" (len) |
diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h index 1e9bed14f7ae..f3971bbcd1de 100644 --- a/arch/x86/include/asm/uprobes.h +++ b/arch/x86/include/asm/uprobes.h | |||
@@ -48,7 +48,7 @@ struct arch_uprobe_task { | |||
48 | #endif | 48 | #endif |
49 | }; | 49 | }; |
50 | 50 | ||
51 | extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm); | 51 | extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr); |
52 | extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); | 52 | extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); |
53 | extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); | 53 | extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); |
54 | extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); | 54 | extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); |
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index 6149b476d9df..a06983cdc125 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
@@ -140,6 +140,9 @@ | |||
140 | #define IPI_RESET_LIMIT 1 | 140 | #define IPI_RESET_LIMIT 1 |
141 | /* after this # consecutive successes, bump up the throttle if it was lowered */ | 141 | /* after this # consecutive successes, bump up the throttle if it was lowered */ |
142 | #define COMPLETE_THRESHOLD 5 | 142 | #define COMPLETE_THRESHOLD 5 |
143 | /* after this # of giveups (fall back to kernel IPI's) disable the use of | ||
144 | the BAU for a period of time */ | ||
145 | #define GIVEUP_LIMIT 100 | ||
143 | 146 | ||
144 | #define UV_LB_SUBNODEID 0x10 | 147 | #define UV_LB_SUBNODEID 0x10 |
145 | 148 | ||
@@ -166,7 +169,6 @@ | |||
166 | #define FLUSH_RETRY_TIMEOUT 2 | 169 | #define FLUSH_RETRY_TIMEOUT 2 |
167 | #define FLUSH_GIVEUP 3 | 170 | #define FLUSH_GIVEUP 3 |
168 | #define FLUSH_COMPLETE 4 | 171 | #define FLUSH_COMPLETE 4 |
169 | #define FLUSH_RETRY_BUSYBUG 5 | ||
170 | 172 | ||
171 | /* | 173 | /* |
172 | * tuning the action when the numalink network is extremely delayed | 174 | * tuning the action when the numalink network is extremely delayed |
@@ -175,7 +177,7 @@ | |||
175 | microseconds */ | 177 | microseconds */ |
176 | #define CONGESTED_REPS 10 /* long delays averaged over | 178 | #define CONGESTED_REPS 10 /* long delays averaged over |
177 | this many broadcasts */ | 179 | this many broadcasts */ |
178 | #define CONGESTED_PERIOD 30 /* time for the bau to be | 180 | #define DISABLED_PERIOD 10 /* time for the bau to be |
179 | disabled, in seconds */ | 181 | disabled, in seconds */ |
180 | /* see msg_type: */ | 182 | /* see msg_type: */ |
181 | #define MSG_NOOP 0 | 183 | #define MSG_NOOP 0 |
@@ -520,6 +522,12 @@ struct ptc_stats { | |||
520 | unsigned long s_uv2_wars; /* uv2 workaround, perm. busy */ | 522 | unsigned long s_uv2_wars; /* uv2 workaround, perm. busy */ |
521 | unsigned long s_uv2_wars_hw; /* uv2 workaround, hiwater */ | 523 | unsigned long s_uv2_wars_hw; /* uv2 workaround, hiwater */ |
522 | unsigned long s_uv2_war_waits; /* uv2 workaround, long waits */ | 524 | unsigned long s_uv2_war_waits; /* uv2 workaround, long waits */ |
525 | unsigned long s_overipilimit; /* over the ipi reset limit */ | ||
526 | unsigned long s_giveuplimit; /* disables, over giveup limit*/ | ||
527 | unsigned long s_enters; /* entries to the driver */ | ||
528 | unsigned long s_ipifordisabled; /* fall back to IPI; disabled */ | ||
529 | unsigned long s_plugged; /* plugged by h/w bug*/ | ||
530 | unsigned long s_congested; /* giveup on long wait */ | ||
523 | /* destination statistics */ | 531 | /* destination statistics */ |
524 | unsigned long d_alltlb; /* times all tlb's on this | 532 | unsigned long d_alltlb; /* times all tlb's on this |
525 | cpu were flushed */ | 533 | cpu were flushed */ |
@@ -586,8 +594,8 @@ struct bau_control { | |||
586 | int timeout_tries; | 594 | int timeout_tries; |
587 | int ipi_attempts; | 595 | int ipi_attempts; |
588 | int conseccompletes; | 596 | int conseccompletes; |
589 | int baudisabled; | 597 | short nobau; |
590 | int set_bau_off; | 598 | short baudisabled; |
591 | short cpu; | 599 | short cpu; |
592 | short osnode; | 600 | short osnode; |
593 | short uvhub_cpu; | 601 | short uvhub_cpu; |
@@ -596,14 +604,16 @@ struct bau_control { | |||
596 | short cpus_in_socket; | 604 | short cpus_in_socket; |
597 | short cpus_in_uvhub; | 605 | short cpus_in_uvhub; |
598 | short partition_base_pnode; | 606 | short partition_base_pnode; |
599 | short using_desc; /* an index, like uvhub_cpu */ | 607 | short busy; /* all were busy (war) */ |
600 | unsigned int inuse_map; | ||
601 | unsigned short message_number; | 608 | unsigned short message_number; |
602 | unsigned short uvhub_quiesce; | 609 | unsigned short uvhub_quiesce; |
603 | short socket_acknowledge_count[DEST_Q_SIZE]; | 610 | short socket_acknowledge_count[DEST_Q_SIZE]; |
604 | cycles_t send_message; | 611 | cycles_t send_message; |
612 | cycles_t period_end; | ||
613 | cycles_t period_time; | ||
605 | spinlock_t uvhub_lock; | 614 | spinlock_t uvhub_lock; |
606 | spinlock_t queue_lock; | 615 | spinlock_t queue_lock; |
616 | spinlock_t disable_lock; | ||
607 | /* tunables */ | 617 | /* tunables */ |
608 | int max_concurr; | 618 | int max_concurr; |
609 | int max_concurr_const; | 619 | int max_concurr_const; |
@@ -614,9 +624,9 @@ struct bau_control { | |||
614 | int complete_threshold; | 624 | int complete_threshold; |
615 | int cong_response_us; | 625 | int cong_response_us; |
616 | int cong_reps; | 626 | int cong_reps; |
617 | int cong_period; | 627 | cycles_t disabled_period; |
618 | unsigned long clocks_per_100_usec; | 628 | int period_giveups; |
619 | cycles_t period_time; | 629 | int giveup_limit; |
620 | long period_requests; | 630 | long period_requests; |
621 | struct hub_and_pnode *thp; | 631 | struct hub_and_pnode *thp; |
622 | }; | 632 | }; |
diff --git a/arch/x86/include/asm/x2apic.h b/arch/x86/include/asm/x2apic.h index 92e54abf89e0..f90f0a587c66 100644 --- a/arch/x86/include/asm/x2apic.h +++ b/arch/x86/include/asm/x2apic.h | |||
@@ -9,15 +9,6 @@ | |||
9 | #include <asm/ipi.h> | 9 | #include <asm/ipi.h> |
10 | #include <linux/cpumask.h> | 10 | #include <linux/cpumask.h> |
11 | 11 | ||
12 | /* | ||
13 | * Need to use more than cpu 0, because we need more vectors | ||
14 | * when MSI-X are used. | ||
15 | */ | ||
16 | static const struct cpumask *x2apic_target_cpus(void) | ||
17 | { | ||
18 | return cpu_online_mask; | ||
19 | } | ||
20 | |||
21 | static int x2apic_apic_id_valid(int apicid) | 12 | static int x2apic_apic_id_valid(int apicid) |
22 | { | 13 | { |
23 | return 1; | 14 | return 1; |
@@ -28,15 +19,6 @@ static int x2apic_apic_id_registered(void) | |||
28 | return 1; | 19 | return 1; |
29 | } | 20 | } |
30 | 21 | ||
31 | /* | ||
32 | * For now each logical cpu is in its own vector allocation domain. | ||
33 | */ | ||
34 | static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
35 | { | ||
36 | cpumask_clear(retmask); | ||
37 | cpumask_set_cpu(cpu, retmask); | ||
38 | } | ||
39 | |||
40 | static void | 22 | static void |
41 | __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest) | 23 | __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest) |
42 | { | 24 | { |
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index c090af10ac7d..38155f667144 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h | |||
@@ -156,7 +156,6 @@ struct x86_cpuinit_ops { | |||
156 | /** | 156 | /** |
157 | * struct x86_platform_ops - platform specific runtime functions | 157 | * struct x86_platform_ops - platform specific runtime functions |
158 | * @calibrate_tsc: calibrate TSC | 158 | * @calibrate_tsc: calibrate TSC |
159 | * @wallclock_init: init the wallclock device | ||
160 | * @get_wallclock: get time from HW clock like RTC etc. | 159 | * @get_wallclock: get time from HW clock like RTC etc. |
161 | * @set_wallclock: set time back to HW clock | 160 | * @set_wallclock: set time back to HW clock |
162 | * @is_untracked_pat_range exclude from PAT logic | 161 | * @is_untracked_pat_range exclude from PAT logic |
@@ -164,10 +163,10 @@ struct x86_cpuinit_ops { | |||
164 | * @i8042_detect pre-detect if i8042 controller exists | 163 | * @i8042_detect pre-detect if i8042 controller exists |
165 | * @save_sched_clock_state: save state for sched_clock() on suspend | 164 | * @save_sched_clock_state: save state for sched_clock() on suspend |
166 | * @restore_sched_clock_state: restore state for sched_clock() on resume | 165 | * @restore_sched_clock_state: restore state for sched_clock() on resume |
166 | * @apic_post_init: adjust apic if neeeded | ||
167 | */ | 167 | */ |
168 | struct x86_platform_ops { | 168 | struct x86_platform_ops { |
169 | unsigned long (*calibrate_tsc)(void); | 169 | unsigned long (*calibrate_tsc)(void); |
170 | void (*wallclock_init)(void); | ||
171 | unsigned long (*get_wallclock)(void); | 170 | unsigned long (*get_wallclock)(void); |
172 | int (*set_wallclock)(unsigned long nowtime); | 171 | int (*set_wallclock)(unsigned long nowtime); |
173 | void (*iommu_shutdown)(void); | 172 | void (*iommu_shutdown)(void); |
@@ -177,6 +176,7 @@ struct x86_platform_ops { | |||
177 | int (*i8042_detect)(void); | 176 | int (*i8042_detect)(void); |
178 | void (*save_sched_clock_state)(void); | 177 | void (*save_sched_clock_state)(void); |
179 | void (*restore_sched_clock_state)(void); | 178 | void (*restore_sched_clock_state)(void); |
179 | void (*apic_post_init)(void); | ||
180 | }; | 180 | }; |
181 | 181 | ||
182 | struct pci_dev; | 182 | struct pci_dev; |
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 1f84794f0759..931280ff8299 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -1,3 +1,5 @@ | |||
1 | #define pr_fmt(fmt) "SMP alternatives: " fmt | ||
2 | |||
1 | #include <linux/module.h> | 3 | #include <linux/module.h> |
2 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
3 | #include <linux/mutex.h> | 5 | #include <linux/mutex.h> |
@@ -63,8 +65,11 @@ static int __init setup_noreplace_paravirt(char *str) | |||
63 | __setup("noreplace-paravirt", setup_noreplace_paravirt); | 65 | __setup("noreplace-paravirt", setup_noreplace_paravirt); |
64 | #endif | 66 | #endif |
65 | 67 | ||
66 | #define DPRINTK(fmt, args...) if (debug_alternative) \ | 68 | #define DPRINTK(fmt, ...) \ |
67 | printk(KERN_DEBUG fmt, args) | 69 | do { \ |
70 | if (debug_alternative) \ | ||
71 | printk(KERN_DEBUG fmt, ##__VA_ARGS__); \ | ||
72 | } while (0) | ||
68 | 73 | ||
69 | /* | 74 | /* |
70 | * Each GENERIC_NOPX is of X bytes, and defined as an array of bytes | 75 | * Each GENERIC_NOPX is of X bytes, and defined as an array of bytes |
@@ -428,7 +433,7 @@ void alternatives_smp_switch(int smp) | |||
428 | * If this still occurs then you should see a hang | 433 | * If this still occurs then you should see a hang |
429 | * or crash shortly after this line: | 434 | * or crash shortly after this line: |
430 | */ | 435 | */ |
431 | printk("lockdep: fixing up alternatives.\n"); | 436 | pr_info("lockdep: fixing up alternatives\n"); |
432 | #endif | 437 | #endif |
433 | 438 | ||
434 | if (noreplace_smp || smp_alt_once || skip_smp_alternatives) | 439 | if (noreplace_smp || smp_alt_once || skip_smp_alternatives) |
@@ -444,14 +449,14 @@ void alternatives_smp_switch(int smp) | |||
444 | if (smp == smp_mode) { | 449 | if (smp == smp_mode) { |
445 | /* nothing */ | 450 | /* nothing */ |
446 | } else if (smp) { | 451 | } else if (smp) { |
447 | printk(KERN_INFO "SMP alternatives: switching to SMP code\n"); | 452 | pr_info("switching to SMP code\n"); |
448 | clear_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); | 453 | clear_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); |
449 | clear_cpu_cap(&cpu_data(0), X86_FEATURE_UP); | 454 | clear_cpu_cap(&cpu_data(0), X86_FEATURE_UP); |
450 | list_for_each_entry(mod, &smp_alt_modules, next) | 455 | list_for_each_entry(mod, &smp_alt_modules, next) |
451 | alternatives_smp_lock(mod->locks, mod->locks_end, | 456 | alternatives_smp_lock(mod->locks, mod->locks_end, |
452 | mod->text, mod->text_end); | 457 | mod->text, mod->text_end); |
453 | } else { | 458 | } else { |
454 | printk(KERN_INFO "SMP alternatives: switching to UP code\n"); | 459 | pr_info("switching to UP code\n"); |
455 | set_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); | 460 | set_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); |
456 | set_cpu_cap(&cpu_data(0), X86_FEATURE_UP); | 461 | set_cpu_cap(&cpu_data(0), X86_FEATURE_UP); |
457 | list_for_each_entry(mod, &smp_alt_modules, next) | 462 | list_for_each_entry(mod, &smp_alt_modules, next) |
@@ -546,7 +551,7 @@ void __init alternative_instructions(void) | |||
546 | #ifdef CONFIG_SMP | 551 | #ifdef CONFIG_SMP |
547 | if (smp_alt_once) { | 552 | if (smp_alt_once) { |
548 | if (1 == num_possible_cpus()) { | 553 | if (1 == num_possible_cpus()) { |
549 | printk(KERN_INFO "SMP alternatives: switching to UP code\n"); | 554 | pr_info("switching to UP code\n"); |
550 | set_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); | 555 | set_cpu_cap(&boot_cpu_data, X86_FEATURE_UP); |
551 | set_cpu_cap(&cpu_data(0), X86_FEATURE_UP); | 556 | set_cpu_cap(&cpu_data(0), X86_FEATURE_UP); |
552 | 557 | ||
@@ -664,7 +669,7 @@ static int __kprobes stop_machine_text_poke(void *data) | |||
664 | struct text_poke_param *p; | 669 | struct text_poke_param *p; |
665 | int i; | 670 | int i; |
666 | 671 | ||
667 | if (atomic_dec_and_test(&stop_machine_first)) { | 672 | if (atomic_xchg(&stop_machine_first, 0)) { |
668 | for (i = 0; i < tpp->nparams; i++) { | 673 | for (i = 0; i < tpp->nparams; i++) { |
669 | p = &tpp->params[i]; | 674 | p = &tpp->params[i]; |
670 | text_poke(p->addr, p->opcode, p->len); | 675 | text_poke(p->addr, p->opcode, p->len); |
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index be16854591cc..f29f6dd6bc08 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c | |||
@@ -2,6 +2,9 @@ | |||
2 | * Shared support code for AMD K8 northbridges and derivates. | 2 | * Shared support code for AMD K8 northbridges and derivates. |
3 | * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2. | 3 | * Copyright 2006 Andi Kleen, SUSE Labs. Subject to GPLv2. |
4 | */ | 4 | */ |
5 | |||
6 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
7 | |||
5 | #include <linux/types.h> | 8 | #include <linux/types.h> |
6 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
7 | #include <linux/init.h> | 10 | #include <linux/init.h> |
@@ -258,7 +261,7 @@ void amd_flush_garts(void) | |||
258 | } | 261 | } |
259 | spin_unlock_irqrestore(&gart_lock, flags); | 262 | spin_unlock_irqrestore(&gart_lock, flags); |
260 | if (!flushed) | 263 | if (!flushed) |
261 | printk("nothing to flush?\n"); | 264 | pr_notice("nothing to flush?\n"); |
262 | } | 265 | } |
263 | EXPORT_SYMBOL_GPL(amd_flush_garts); | 266 | EXPORT_SYMBOL_GPL(amd_flush_garts); |
264 | 267 | ||
@@ -269,11 +272,10 @@ static __init int init_amd_nbs(void) | |||
269 | err = amd_cache_northbridges(); | 272 | err = amd_cache_northbridges(); |
270 | 273 | ||
271 | if (err < 0) | 274 | if (err < 0) |
272 | printk(KERN_NOTICE "AMD NB: Cannot enumerate AMD northbridges.\n"); | 275 | pr_notice("Cannot enumerate AMD northbridges\n"); |
273 | 276 | ||
274 | if (amd_cache_gart() < 0) | 277 | if (amd_cache_gart() < 0) |
275 | printk(KERN_NOTICE "AMD NB: Cannot initialize GART flush words, " | 278 | pr_notice("Cannot initialize GART flush words, GART support disabled\n"); |
276 | "GART support disabled.\n"); | ||
277 | 279 | ||
278 | return err; | 280 | return err; |
279 | } | 281 | } |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 39a222e094af..c421512ca5eb 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -2123,6 +2123,25 @@ void default_init_apic_ldr(void) | |||
2123 | apic_write(APIC_LDR, val); | 2123 | apic_write(APIC_LDR, val); |
2124 | } | 2124 | } |
2125 | 2125 | ||
2126 | int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | ||
2127 | const struct cpumask *andmask, | ||
2128 | unsigned int *apicid) | ||
2129 | { | ||
2130 | unsigned int cpu; | ||
2131 | |||
2132 | for_each_cpu_and(cpu, cpumask, andmask) { | ||
2133 | if (cpumask_test_cpu(cpu, cpu_online_mask)) | ||
2134 | break; | ||
2135 | } | ||
2136 | |||
2137 | if (likely(cpu < nr_cpu_ids)) { | ||
2138 | *apicid = per_cpu(x86_cpu_to_apicid, cpu); | ||
2139 | return 0; | ||
2140 | } | ||
2141 | |||
2142 | return -EINVAL; | ||
2143 | } | ||
2144 | |||
2126 | /* | 2145 | /* |
2127 | * Power management | 2146 | * Power management |
2128 | */ | 2147 | */ |
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 0e881c46e8c8..00c77cf78e9e 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c | |||
@@ -36,25 +36,6 @@ static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
36 | return 1; | 36 | return 1; |
37 | } | 37 | } |
38 | 38 | ||
39 | static const struct cpumask *flat_target_cpus(void) | ||
40 | { | ||
41 | return cpu_online_mask; | ||
42 | } | ||
43 | |||
44 | static void flat_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
45 | { | ||
46 | /* Careful. Some cpus do not strictly honor the set of cpus | ||
47 | * specified in the interrupt destination when using lowest | ||
48 | * priority interrupt delivery mode. | ||
49 | * | ||
50 | * In particular there was a hyperthreading cpu observed to | ||
51 | * deliver interrupts to the wrong hyperthread when only one | ||
52 | * hyperthread was specified in the interrupt desitination. | ||
53 | */ | ||
54 | cpumask_clear(retmask); | ||
55 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
56 | } | ||
57 | |||
58 | /* | 39 | /* |
59 | * Set up the logical destination ID. | 40 | * Set up the logical destination ID. |
60 | * | 41 | * |
@@ -92,7 +73,7 @@ static void flat_send_IPI_mask(const struct cpumask *cpumask, int vector) | |||
92 | } | 73 | } |
93 | 74 | ||
94 | static void | 75 | static void |
95 | flat_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) | 76 | flat_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector) |
96 | { | 77 | { |
97 | unsigned long mask = cpumask_bits(cpumask)[0]; | 78 | unsigned long mask = cpumask_bits(cpumask)[0]; |
98 | int cpu = smp_processor_id(); | 79 | int cpu = smp_processor_id(); |
@@ -186,7 +167,7 @@ static struct apic apic_flat = { | |||
186 | .irq_delivery_mode = dest_LowestPrio, | 167 | .irq_delivery_mode = dest_LowestPrio, |
187 | .irq_dest_mode = 1, /* logical */ | 168 | .irq_dest_mode = 1, /* logical */ |
188 | 169 | ||
189 | .target_cpus = flat_target_cpus, | 170 | .target_cpus = online_target_cpus, |
190 | .disable_esr = 0, | 171 | .disable_esr = 0, |
191 | .dest_logical = APIC_DEST_LOGICAL, | 172 | .dest_logical = APIC_DEST_LOGICAL, |
192 | .check_apicid_used = NULL, | 173 | .check_apicid_used = NULL, |
@@ -210,8 +191,7 @@ static struct apic apic_flat = { | |||
210 | .set_apic_id = set_apic_id, | 191 | .set_apic_id = set_apic_id, |
211 | .apic_id_mask = 0xFFu << 24, | 192 | .apic_id_mask = 0xFFu << 24, |
212 | 193 | ||
213 | .cpu_mask_to_apicid = default_cpu_mask_to_apicid, | 194 | .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, |
214 | .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, | ||
215 | 195 | ||
216 | .send_IPI_mask = flat_send_IPI_mask, | 196 | .send_IPI_mask = flat_send_IPI_mask, |
217 | .send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself, | 197 | .send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself, |
@@ -262,17 +242,6 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
262 | return 0; | 242 | return 0; |
263 | } | 243 | } |
264 | 244 | ||
265 | static const struct cpumask *physflat_target_cpus(void) | ||
266 | { | ||
267 | return cpu_online_mask; | ||
268 | } | ||
269 | |||
270 | static void physflat_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
271 | { | ||
272 | cpumask_clear(retmask); | ||
273 | cpumask_set_cpu(cpu, retmask); | ||
274 | } | ||
275 | |||
276 | static void physflat_send_IPI_mask(const struct cpumask *cpumask, int vector) | 245 | static void physflat_send_IPI_mask(const struct cpumask *cpumask, int vector) |
277 | { | 246 | { |
278 | default_send_IPI_mask_sequence_phys(cpumask, vector); | 247 | default_send_IPI_mask_sequence_phys(cpumask, vector); |
@@ -294,38 +263,6 @@ static void physflat_send_IPI_all(int vector) | |||
294 | physflat_send_IPI_mask(cpu_online_mask, vector); | 263 | physflat_send_IPI_mask(cpu_online_mask, vector); |
295 | } | 264 | } |
296 | 265 | ||
297 | static unsigned int physflat_cpu_mask_to_apicid(const struct cpumask *cpumask) | ||
298 | { | ||
299 | int cpu; | ||
300 | |||
301 | /* | ||
302 | * We're using fixed IRQ delivery, can only return one phys APIC ID. | ||
303 | * May as well be the first. | ||
304 | */ | ||
305 | cpu = cpumask_first(cpumask); | ||
306 | if ((unsigned)cpu < nr_cpu_ids) | ||
307 | return per_cpu(x86_cpu_to_apicid, cpu); | ||
308 | else | ||
309 | return BAD_APICID; | ||
310 | } | ||
311 | |||
312 | static unsigned int | ||
313 | physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | ||
314 | const struct cpumask *andmask) | ||
315 | { | ||
316 | int cpu; | ||
317 | |||
318 | /* | ||
319 | * We're using fixed IRQ delivery, can only return one phys APIC ID. | ||
320 | * May as well be the first. | ||
321 | */ | ||
322 | for_each_cpu_and(cpu, cpumask, andmask) { | ||
323 | if (cpumask_test_cpu(cpu, cpu_online_mask)) | ||
324 | break; | ||
325 | } | ||
326 | return per_cpu(x86_cpu_to_apicid, cpu); | ||
327 | } | ||
328 | |||
329 | static int physflat_probe(void) | 266 | static int physflat_probe(void) |
330 | { | 267 | { |
331 | if (apic == &apic_physflat || num_possible_cpus() > 8) | 268 | if (apic == &apic_physflat || num_possible_cpus() > 8) |
@@ -345,13 +282,13 @@ static struct apic apic_physflat = { | |||
345 | .irq_delivery_mode = dest_Fixed, | 282 | .irq_delivery_mode = dest_Fixed, |
346 | .irq_dest_mode = 0, /* physical */ | 283 | .irq_dest_mode = 0, /* physical */ |
347 | 284 | ||
348 | .target_cpus = physflat_target_cpus, | 285 | .target_cpus = online_target_cpus, |
349 | .disable_esr = 0, | 286 | .disable_esr = 0, |
350 | .dest_logical = 0, | 287 | .dest_logical = 0, |
351 | .check_apicid_used = NULL, | 288 | .check_apicid_used = NULL, |
352 | .check_apicid_present = NULL, | 289 | .check_apicid_present = NULL, |
353 | 290 | ||
354 | .vector_allocation_domain = physflat_vector_allocation_domain, | 291 | .vector_allocation_domain = default_vector_allocation_domain, |
355 | /* not needed, but shouldn't hurt: */ | 292 | /* not needed, but shouldn't hurt: */ |
356 | .init_apic_ldr = flat_init_apic_ldr, | 293 | .init_apic_ldr = flat_init_apic_ldr, |
357 | 294 | ||
@@ -370,8 +307,7 @@ static struct apic apic_physflat = { | |||
370 | .set_apic_id = set_apic_id, | 307 | .set_apic_id = set_apic_id, |
371 | .apic_id_mask = 0xFFu << 24, | 308 | .apic_id_mask = 0xFFu << 24, |
372 | 309 | ||
373 | .cpu_mask_to_apicid = physflat_cpu_mask_to_apicid, | 310 | .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, |
374 | .cpu_mask_to_apicid_and = physflat_cpu_mask_to_apicid_and, | ||
375 | 311 | ||
376 | .send_IPI_mask = physflat_send_IPI_mask, | 312 | .send_IPI_mask = physflat_send_IPI_mask, |
377 | .send_IPI_mask_allbutself = physflat_send_IPI_mask_allbutself, | 313 | .send_IPI_mask_allbutself = physflat_send_IPI_mask_allbutself, |
diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index a6e4c6e06c08..e145f28b4099 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c | |||
@@ -100,12 +100,12 @@ static unsigned long noop_check_apicid_present(int bit) | |||
100 | return physid_isset(bit, phys_cpu_present_map); | 100 | return physid_isset(bit, phys_cpu_present_map); |
101 | } | 101 | } |
102 | 102 | ||
103 | static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask) | 103 | static void noop_vector_allocation_domain(int cpu, struct cpumask *retmask, |
104 | const struct cpumask *mask) | ||
104 | { | 105 | { |
105 | if (cpu != 0) | 106 | if (cpu != 0) |
106 | pr_warning("APIC: Vector allocated for non-BSP cpu\n"); | 107 | pr_warning("APIC: Vector allocated for non-BSP cpu\n"); |
107 | cpumask_clear(retmask); | 108 | cpumask_copy(retmask, cpumask_of(cpu)); |
108 | cpumask_set_cpu(cpu, retmask); | ||
109 | } | 109 | } |
110 | 110 | ||
111 | static u32 noop_apic_read(u32 reg) | 111 | static u32 noop_apic_read(u32 reg) |
@@ -159,8 +159,7 @@ struct apic apic_noop = { | |||
159 | .set_apic_id = NULL, | 159 | .set_apic_id = NULL, |
160 | .apic_id_mask = 0x0F << 24, | 160 | .apic_id_mask = 0x0F << 24, |
161 | 161 | ||
162 | .cpu_mask_to_apicid = default_cpu_mask_to_apicid, | 162 | .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, |
163 | .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, | ||
164 | 163 | ||
165 | .send_IPI_mask = noop_send_IPI_mask, | 164 | .send_IPI_mask = noop_send_IPI_mask, |
166 | .send_IPI_mask_allbutself = noop_send_IPI_mask_allbutself, | 165 | .send_IPI_mask_allbutself = noop_send_IPI_mask_allbutself, |
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index 6ec6d5d297c3..bc552cff2578 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c | |||
@@ -72,17 +72,6 @@ static int numachip_phys_pkg_id(int initial_apic_id, int index_msb) | |||
72 | return initial_apic_id >> index_msb; | 72 | return initial_apic_id >> index_msb; |
73 | } | 73 | } |
74 | 74 | ||
75 | static const struct cpumask *numachip_target_cpus(void) | ||
76 | { | ||
77 | return cpu_online_mask; | ||
78 | } | ||
79 | |||
80 | static void numachip_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
81 | { | ||
82 | cpumask_clear(retmask); | ||
83 | cpumask_set_cpu(cpu, retmask); | ||
84 | } | ||
85 | |||
86 | static int __cpuinit numachip_wakeup_secondary(int phys_apicid, unsigned long start_rip) | 75 | static int __cpuinit numachip_wakeup_secondary(int phys_apicid, unsigned long start_rip) |
87 | { | 76 | { |
88 | union numachip_csr_g3_ext_irq_gen int_gen; | 77 | union numachip_csr_g3_ext_irq_gen int_gen; |
@@ -157,38 +146,6 @@ static void numachip_send_IPI_self(int vector) | |||
157 | __default_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL); | 146 | __default_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL); |
158 | } | 147 | } |
159 | 148 | ||
160 | static unsigned int numachip_cpu_mask_to_apicid(const struct cpumask *cpumask) | ||
161 | { | ||
162 | int cpu; | ||
163 | |||
164 | /* | ||
165 | * We're using fixed IRQ delivery, can only return one phys APIC ID. | ||
166 | * May as well be the first. | ||
167 | */ | ||
168 | cpu = cpumask_first(cpumask); | ||
169 | if (likely((unsigned)cpu < nr_cpu_ids)) | ||
170 | return per_cpu(x86_cpu_to_apicid, cpu); | ||
171 | |||
172 | return BAD_APICID; | ||
173 | } | ||
174 | |||
175 | static unsigned int | ||
176 | numachip_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | ||
177 | const struct cpumask *andmask) | ||
178 | { | ||
179 | int cpu; | ||
180 | |||
181 | /* | ||
182 | * We're using fixed IRQ delivery, can only return one phys APIC ID. | ||
183 | * May as well be the first. | ||
184 | */ | ||
185 | for_each_cpu_and(cpu, cpumask, andmask) { | ||
186 | if (cpumask_test_cpu(cpu, cpu_online_mask)) | ||
187 | break; | ||
188 | } | ||
189 | return per_cpu(x86_cpu_to_apicid, cpu); | ||
190 | } | ||
191 | |||
192 | static int __init numachip_probe(void) | 149 | static int __init numachip_probe(void) |
193 | { | 150 | { |
194 | return apic == &apic_numachip; | 151 | return apic == &apic_numachip; |
@@ -253,13 +210,13 @@ static struct apic apic_numachip __refconst = { | |||
253 | .irq_delivery_mode = dest_Fixed, | 210 | .irq_delivery_mode = dest_Fixed, |
254 | .irq_dest_mode = 0, /* physical */ | 211 | .irq_dest_mode = 0, /* physical */ |
255 | 212 | ||
256 | .target_cpus = numachip_target_cpus, | 213 | .target_cpus = online_target_cpus, |
257 | .disable_esr = 0, | 214 | .disable_esr = 0, |
258 | .dest_logical = 0, | 215 | .dest_logical = 0, |
259 | .check_apicid_used = NULL, | 216 | .check_apicid_used = NULL, |
260 | .check_apicid_present = NULL, | 217 | .check_apicid_present = NULL, |
261 | 218 | ||
262 | .vector_allocation_domain = numachip_vector_allocation_domain, | 219 | .vector_allocation_domain = default_vector_allocation_domain, |
263 | .init_apic_ldr = flat_init_apic_ldr, | 220 | .init_apic_ldr = flat_init_apic_ldr, |
264 | 221 | ||
265 | .ioapic_phys_id_map = NULL, | 222 | .ioapic_phys_id_map = NULL, |
@@ -277,8 +234,7 @@ static struct apic apic_numachip __refconst = { | |||
277 | .set_apic_id = set_apic_id, | 234 | .set_apic_id = set_apic_id, |
278 | .apic_id_mask = 0xffU << 24, | 235 | .apic_id_mask = 0xffU << 24, |
279 | 236 | ||
280 | .cpu_mask_to_apicid = numachip_cpu_mask_to_apicid, | 237 | .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, |
281 | .cpu_mask_to_apicid_and = numachip_cpu_mask_to_apicid_and, | ||
282 | 238 | ||
283 | .send_IPI_mask = numachip_send_IPI_mask, | 239 | .send_IPI_mask = numachip_send_IPI_mask, |
284 | .send_IPI_mask_allbutself = numachip_send_IPI_mask_allbutself, | 240 | .send_IPI_mask_allbutself = numachip_send_IPI_mask_allbutself, |
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index 31fbdbfbf960..d50e3640d5ae 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c | |||
@@ -26,15 +26,6 @@ static int bigsmp_apic_id_registered(void) | |||
26 | return 1; | 26 | return 1; |
27 | } | 27 | } |
28 | 28 | ||
29 | static const struct cpumask *bigsmp_target_cpus(void) | ||
30 | { | ||
31 | #ifdef CONFIG_SMP | ||
32 | return cpu_online_mask; | ||
33 | #else | ||
34 | return cpumask_of(0); | ||
35 | #endif | ||
36 | } | ||
37 | |||
38 | static unsigned long bigsmp_check_apicid_used(physid_mask_t *map, int apicid) | 29 | static unsigned long bigsmp_check_apicid_used(physid_mask_t *map, int apicid) |
39 | { | 30 | { |
40 | return 0; | 31 | return 0; |
@@ -105,32 +96,6 @@ static int bigsmp_check_phys_apicid_present(int phys_apicid) | |||
105 | return 1; | 96 | return 1; |
106 | } | 97 | } |
107 | 98 | ||
108 | /* As we are using single CPU as destination, pick only one CPU here */ | ||
109 | static unsigned int bigsmp_cpu_mask_to_apicid(const struct cpumask *cpumask) | ||
110 | { | ||
111 | int cpu = cpumask_first(cpumask); | ||
112 | |||
113 | if (cpu < nr_cpu_ids) | ||
114 | return cpu_physical_id(cpu); | ||
115 | return BAD_APICID; | ||
116 | } | ||
117 | |||
118 | static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | ||
119 | const struct cpumask *andmask) | ||
120 | { | ||
121 | int cpu; | ||
122 | |||
123 | /* | ||
124 | * We're using fixed IRQ delivery, can only return one phys APIC ID. | ||
125 | * May as well be the first. | ||
126 | */ | ||
127 | for_each_cpu_and(cpu, cpumask, andmask) { | ||
128 | if (cpumask_test_cpu(cpu, cpu_online_mask)) | ||
129 | return cpu_physical_id(cpu); | ||
130 | } | ||
131 | return BAD_APICID; | ||
132 | } | ||
133 | |||
134 | static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb) | 99 | static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb) |
135 | { | 100 | { |
136 | return cpuid_apic >> index_msb; | 101 | return cpuid_apic >> index_msb; |
@@ -177,12 +142,6 @@ static const struct dmi_system_id bigsmp_dmi_table[] = { | |||
177 | { } /* NULL entry stops DMI scanning */ | 142 | { } /* NULL entry stops DMI scanning */ |
178 | }; | 143 | }; |
179 | 144 | ||
180 | static void bigsmp_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
181 | { | ||
182 | cpumask_clear(retmask); | ||
183 | cpumask_set_cpu(cpu, retmask); | ||
184 | } | ||
185 | |||
186 | static int probe_bigsmp(void) | 145 | static int probe_bigsmp(void) |
187 | { | 146 | { |
188 | if (def_to_bigsmp) | 147 | if (def_to_bigsmp) |
@@ -205,13 +164,13 @@ static struct apic apic_bigsmp = { | |||
205 | /* phys delivery to target CPU: */ | 164 | /* phys delivery to target CPU: */ |
206 | .irq_dest_mode = 0, | 165 | .irq_dest_mode = 0, |
207 | 166 | ||
208 | .target_cpus = bigsmp_target_cpus, | 167 | .target_cpus = default_target_cpus, |
209 | .disable_esr = 1, | 168 | .disable_esr = 1, |
210 | .dest_logical = 0, | 169 | .dest_logical = 0, |
211 | .check_apicid_used = bigsmp_check_apicid_used, | 170 | .check_apicid_used = bigsmp_check_apicid_used, |
212 | .check_apicid_present = bigsmp_check_apicid_present, | 171 | .check_apicid_present = bigsmp_check_apicid_present, |
213 | 172 | ||
214 | .vector_allocation_domain = bigsmp_vector_allocation_domain, | 173 | .vector_allocation_domain = default_vector_allocation_domain, |
215 | .init_apic_ldr = bigsmp_init_apic_ldr, | 174 | .init_apic_ldr = bigsmp_init_apic_ldr, |
216 | 175 | ||
217 | .ioapic_phys_id_map = bigsmp_ioapic_phys_id_map, | 176 | .ioapic_phys_id_map = bigsmp_ioapic_phys_id_map, |
@@ -229,8 +188,7 @@ static struct apic apic_bigsmp = { | |||
229 | .set_apic_id = NULL, | 188 | .set_apic_id = NULL, |
230 | .apic_id_mask = 0xFF << 24, | 189 | .apic_id_mask = 0xFF << 24, |
231 | 190 | ||
232 | .cpu_mask_to_apicid = bigsmp_cpu_mask_to_apicid, | 191 | .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, |
233 | .cpu_mask_to_apicid_and = bigsmp_cpu_mask_to_apicid_and, | ||
234 | 192 | ||
235 | .send_IPI_mask = bigsmp_send_IPI_mask, | 193 | .send_IPI_mask = bigsmp_send_IPI_mask, |
236 | .send_IPI_mask_allbutself = NULL, | 194 | .send_IPI_mask_allbutself = NULL, |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index db4ab1be3c79..0874799a98c6 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
@@ -394,21 +394,6 @@ static void es7000_enable_apic_mode(void) | |||
394 | WARN(1, "Command failed, status = %x\n", mip_status); | 394 | WARN(1, "Command failed, status = %x\n", mip_status); |
395 | } | 395 | } |
396 | 396 | ||
397 | static void es7000_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
398 | { | ||
399 | /* Careful. Some cpus do not strictly honor the set of cpus | ||
400 | * specified in the interrupt destination when using lowest | ||
401 | * priority interrupt delivery mode. | ||
402 | * | ||
403 | * In particular there was a hyperthreading cpu observed to | ||
404 | * deliver interrupts to the wrong hyperthread when only one | ||
405 | * hyperthread was specified in the interrupt desitination. | ||
406 | */ | ||
407 | cpumask_clear(retmask); | ||
408 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
409 | } | ||
410 | |||
411 | |||
412 | static void es7000_wait_for_init_deassert(atomic_t *deassert) | 397 | static void es7000_wait_for_init_deassert(atomic_t *deassert) |
413 | { | 398 | { |
414 | while (!atomic_read(deassert)) | 399 | while (!atomic_read(deassert)) |
@@ -540,45 +525,49 @@ static int es7000_check_phys_apicid_present(int cpu_physical_apicid) | |||
540 | return 1; | 525 | return 1; |
541 | } | 526 | } |
542 | 527 | ||
543 | static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask) | 528 | static inline int |
529 | es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) | ||
544 | { | 530 | { |
545 | unsigned int round = 0; | 531 | unsigned int round = 0; |
546 | int cpu, uninitialized_var(apicid); | 532 | unsigned int cpu, uninitialized_var(apicid); |
547 | 533 | ||
548 | /* | 534 | /* |
549 | * The cpus in the mask must all be on the apic cluster. | 535 | * The cpus in the mask must all be on the apic cluster. |
550 | */ | 536 | */ |
551 | for_each_cpu(cpu, cpumask) { | 537 | for_each_cpu_and(cpu, cpumask, cpu_online_mask) { |
552 | int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); | 538 | int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); |
553 | 539 | ||
554 | if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { | 540 | if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { |
555 | WARN(1, "Not a valid mask!"); | 541 | WARN(1, "Not a valid mask!"); |
556 | 542 | ||
557 | return BAD_APICID; | 543 | return -EINVAL; |
558 | } | 544 | } |
559 | apicid = new_apicid; | 545 | apicid |= new_apicid; |
560 | round++; | 546 | round++; |
561 | } | 547 | } |
562 | return apicid; | 548 | if (!round) |
549 | return -EINVAL; | ||
550 | *dest_id = apicid; | ||
551 | return 0; | ||
563 | } | 552 | } |
564 | 553 | ||
565 | static unsigned int | 554 | static int |
566 | es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, | 555 | es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask, |
567 | const struct cpumask *andmask) | 556 | const struct cpumask *andmask, |
557 | unsigned int *apicid) | ||
568 | { | 558 | { |
569 | int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); | ||
570 | cpumask_var_t cpumask; | 559 | cpumask_var_t cpumask; |
560 | *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); | ||
571 | 561 | ||
572 | if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) | 562 | if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) |
573 | return apicid; | 563 | return 0; |
574 | 564 | ||
575 | cpumask_and(cpumask, inmask, andmask); | 565 | cpumask_and(cpumask, inmask, andmask); |
576 | cpumask_and(cpumask, cpumask, cpu_online_mask); | 566 | es7000_cpu_mask_to_apicid(cpumask, apicid); |
577 | apicid = es7000_cpu_mask_to_apicid(cpumask); | ||
578 | 567 | ||
579 | free_cpumask_var(cpumask); | 568 | free_cpumask_var(cpumask); |
580 | 569 | ||
581 | return apicid; | 570 | return 0; |
582 | } | 571 | } |
583 | 572 | ||
584 | static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) | 573 | static int es7000_phys_pkg_id(int cpuid_apic, int index_msb) |
@@ -638,7 +627,7 @@ static struct apic __refdata apic_es7000_cluster = { | |||
638 | .check_apicid_used = es7000_check_apicid_used, | 627 | .check_apicid_used = es7000_check_apicid_used, |
639 | .check_apicid_present = es7000_check_apicid_present, | 628 | .check_apicid_present = es7000_check_apicid_present, |
640 | 629 | ||
641 | .vector_allocation_domain = es7000_vector_allocation_domain, | 630 | .vector_allocation_domain = flat_vector_allocation_domain, |
642 | .init_apic_ldr = es7000_init_apic_ldr_cluster, | 631 | .init_apic_ldr = es7000_init_apic_ldr_cluster, |
643 | 632 | ||
644 | .ioapic_phys_id_map = es7000_ioapic_phys_id_map, | 633 | .ioapic_phys_id_map = es7000_ioapic_phys_id_map, |
@@ -656,7 +645,6 @@ static struct apic __refdata apic_es7000_cluster = { | |||
656 | .set_apic_id = NULL, | 645 | .set_apic_id = NULL, |
657 | .apic_id_mask = 0xFF << 24, | 646 | .apic_id_mask = 0xFF << 24, |
658 | 647 | ||
659 | .cpu_mask_to_apicid = es7000_cpu_mask_to_apicid, | ||
660 | .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, | 648 | .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, |
661 | 649 | ||
662 | .send_IPI_mask = es7000_send_IPI_mask, | 650 | .send_IPI_mask = es7000_send_IPI_mask, |
@@ -705,7 +693,7 @@ static struct apic __refdata apic_es7000 = { | |||
705 | .check_apicid_used = es7000_check_apicid_used, | 693 | .check_apicid_used = es7000_check_apicid_used, |
706 | .check_apicid_present = es7000_check_apicid_present, | 694 | .check_apicid_present = es7000_check_apicid_present, |
707 | 695 | ||
708 | .vector_allocation_domain = es7000_vector_allocation_domain, | 696 | .vector_allocation_domain = flat_vector_allocation_domain, |
709 | .init_apic_ldr = es7000_init_apic_ldr, | 697 | .init_apic_ldr = es7000_init_apic_ldr, |
710 | 698 | ||
711 | .ioapic_phys_id_map = es7000_ioapic_phys_id_map, | 699 | .ioapic_phys_id_map = es7000_ioapic_phys_id_map, |
@@ -723,7 +711,6 @@ static struct apic __refdata apic_es7000 = { | |||
723 | .set_apic_id = NULL, | 711 | .set_apic_id = NULL, |
724 | .apic_id_mask = 0xFF << 24, | 712 | .apic_id_mask = 0xFF << 24, |
725 | 713 | ||
726 | .cpu_mask_to_apicid = es7000_cpu_mask_to_apicid, | ||
727 | .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, | 714 | .cpu_mask_to_apicid_and = es7000_cpu_mask_to_apicid_and, |
728 | 715 | ||
729 | .send_IPI_mask = es7000_send_IPI_mask, | 716 | .send_IPI_mask = es7000_send_IPI_mask, |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 5f0ff597437c..406eee784684 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -448,8 +448,8 @@ static int __add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pi | |||
448 | 448 | ||
449 | entry = alloc_irq_pin_list(node); | 449 | entry = alloc_irq_pin_list(node); |
450 | if (!entry) { | 450 | if (!entry) { |
451 | printk(KERN_ERR "can not alloc irq_pin_list (%d,%d,%d)\n", | 451 | pr_err("can not alloc irq_pin_list (%d,%d,%d)\n", |
452 | node, apic, pin); | 452 | node, apic, pin); |
453 | return -ENOMEM; | 453 | return -ENOMEM; |
454 | } | 454 | } |
455 | entry->apic = apic; | 455 | entry->apic = apic; |
@@ -661,7 +661,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) | |||
661 | ioapic_mask_entry(apic, pin); | 661 | ioapic_mask_entry(apic, pin); |
662 | entry = ioapic_read_entry(apic, pin); | 662 | entry = ioapic_read_entry(apic, pin); |
663 | if (entry.irr) | 663 | if (entry.irr) |
664 | printk(KERN_ERR "Unable to reset IRR for apic: %d, pin :%d\n", | 664 | pr_err("Unable to reset IRR for apic: %d, pin :%d\n", |
665 | mpc_ioapic_id(apic), pin); | 665 | mpc_ioapic_id(apic), pin); |
666 | } | 666 | } |
667 | 667 | ||
@@ -895,7 +895,7 @@ static int irq_polarity(int idx) | |||
895 | } | 895 | } |
896 | case 2: /* reserved */ | 896 | case 2: /* reserved */ |
897 | { | 897 | { |
898 | printk(KERN_WARNING "broken BIOS!!\n"); | 898 | pr_warn("broken BIOS!!\n"); |
899 | polarity = 1; | 899 | polarity = 1; |
900 | break; | 900 | break; |
901 | } | 901 | } |
@@ -906,7 +906,7 @@ static int irq_polarity(int idx) | |||
906 | } | 906 | } |
907 | default: /* invalid */ | 907 | default: /* invalid */ |
908 | { | 908 | { |
909 | printk(KERN_WARNING "broken BIOS!!\n"); | 909 | pr_warn("broken BIOS!!\n"); |
910 | polarity = 1; | 910 | polarity = 1; |
911 | break; | 911 | break; |
912 | } | 912 | } |
@@ -948,7 +948,7 @@ static int irq_trigger(int idx) | |||
948 | } | 948 | } |
949 | default: | 949 | default: |
950 | { | 950 | { |
951 | printk(KERN_WARNING "broken BIOS!!\n"); | 951 | pr_warn("broken BIOS!!\n"); |
952 | trigger = 1; | 952 | trigger = 1; |
953 | break; | 953 | break; |
954 | } | 954 | } |
@@ -962,7 +962,7 @@ static int irq_trigger(int idx) | |||
962 | } | 962 | } |
963 | case 2: /* reserved */ | 963 | case 2: /* reserved */ |
964 | { | 964 | { |
965 | printk(KERN_WARNING "broken BIOS!!\n"); | 965 | pr_warn("broken BIOS!!\n"); |
966 | trigger = 1; | 966 | trigger = 1; |
967 | break; | 967 | break; |
968 | } | 968 | } |
@@ -973,7 +973,7 @@ static int irq_trigger(int idx) | |||
973 | } | 973 | } |
974 | default: /* invalid */ | 974 | default: /* invalid */ |
975 | { | 975 | { |
976 | printk(KERN_WARNING "broken BIOS!!\n"); | 976 | pr_warn("broken BIOS!!\n"); |
977 | trigger = 0; | 977 | trigger = 0; |
978 | break; | 978 | break; |
979 | } | 979 | } |
@@ -991,7 +991,7 @@ static int pin_2_irq(int idx, int apic, int pin) | |||
991 | * Debugging check, we are in big trouble if this message pops up! | 991 | * Debugging check, we are in big trouble if this message pops up! |
992 | */ | 992 | */ |
993 | if (mp_irqs[idx].dstirq != pin) | 993 | if (mp_irqs[idx].dstirq != pin) |
994 | printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); | 994 | pr_err("broken BIOS or MPTABLE parser, ayiee!!\n"); |
995 | 995 | ||
996 | if (test_bit(bus, mp_bus_not_pci)) { | 996 | if (test_bit(bus, mp_bus_not_pci)) { |
997 | irq = mp_irqs[idx].srcbusirq; | 997 | irq = mp_irqs[idx].srcbusirq; |
@@ -1112,8 +1112,7 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) | |||
1112 | * 0x80, because int 0x80 is hm, kind of importantish. ;) | 1112 | * 0x80, because int 0x80 is hm, kind of importantish. ;) |
1113 | */ | 1113 | */ |
1114 | static int current_vector = FIRST_EXTERNAL_VECTOR + VECTOR_OFFSET_START; | 1114 | static int current_vector = FIRST_EXTERNAL_VECTOR + VECTOR_OFFSET_START; |
1115 | static int current_offset = VECTOR_OFFSET_START % 8; | 1115 | static int current_offset = VECTOR_OFFSET_START % 16; |
1116 | unsigned int old_vector; | ||
1117 | int cpu, err; | 1116 | int cpu, err; |
1118 | cpumask_var_t tmp_mask; | 1117 | cpumask_var_t tmp_mask; |
1119 | 1118 | ||
@@ -1123,35 +1122,45 @@ __assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) | |||
1123 | if (!alloc_cpumask_var(&tmp_mask, GFP_ATOMIC)) | 1122 | if (!alloc_cpumask_var(&tmp_mask, GFP_ATOMIC)) |
1124 | return -ENOMEM; | 1123 | return -ENOMEM; |
1125 | 1124 | ||
1126 | old_vector = cfg->vector; | ||
1127 | if (old_vector) { | ||
1128 | cpumask_and(tmp_mask, mask, cpu_online_mask); | ||
1129 | cpumask_and(tmp_mask, cfg->domain, tmp_mask); | ||
1130 | if (!cpumask_empty(tmp_mask)) { | ||
1131 | free_cpumask_var(tmp_mask); | ||
1132 | return 0; | ||
1133 | } | ||
1134 | } | ||
1135 | |||
1136 | /* Only try and allocate irqs on cpus that are present */ | 1125 | /* Only try and allocate irqs on cpus that are present */ |
1137 | err = -ENOSPC; | 1126 | err = -ENOSPC; |
1138 | for_each_cpu_and(cpu, mask, cpu_online_mask) { | 1127 | cpumask_clear(cfg->old_domain); |
1139 | int new_cpu; | 1128 | cpu = cpumask_first_and(mask, cpu_online_mask); |
1140 | int vector, offset; | 1129 | while (cpu < nr_cpu_ids) { |
1130 | int new_cpu, vector, offset; | ||
1141 | 1131 | ||
1142 | apic->vector_allocation_domain(cpu, tmp_mask); | 1132 | apic->vector_allocation_domain(cpu, tmp_mask, mask); |
1133 | |||
1134 | if (cpumask_subset(tmp_mask, cfg->domain)) { | ||
1135 | err = 0; | ||
1136 | if (cpumask_equal(tmp_mask, cfg->domain)) | ||
1137 | break; | ||
1138 | /* | ||
1139 | * New cpumask using the vector is a proper subset of | ||
1140 | * the current in use mask. So cleanup the vector | ||
1141 | * allocation for the members that are not used anymore. | ||
1142 | */ | ||
1143 | cpumask_andnot(cfg->old_domain, cfg->domain, tmp_mask); | ||
1144 | cfg->move_in_progress = 1; | ||
1145 | cpumask_and(cfg->domain, cfg->domain, tmp_mask); | ||
1146 | break; | ||
1147 | } | ||
1143 | 1148 | ||
1144 | vector = current_vector; | 1149 | vector = current_vector; |
1145 | offset = current_offset; | 1150 | offset = current_offset; |
1146 | next: | 1151 | next: |
1147 | vector += 8; | 1152 | vector += 16; |
1148 | if (vector >= first_system_vector) { | 1153 | if (vector >= first_system_vector) { |
1149 | /* If out of vectors on large boxen, must share them. */ | 1154 | offset = (offset + 1) % 16; |
1150 | offset = (offset + 1) % 8; | ||
1151 | vector = FIRST_EXTERNAL_VECTOR + offset; | 1155 | vector = FIRST_EXTERNAL_VECTOR + offset; |
1152 | } | 1156 | } |
1153 | if (unlikely(current_vector == vector)) | 1157 | |
1158 | if (unlikely(current_vector == vector)) { | ||
1159 | cpumask_or(cfg->old_domain, cfg->old_domain, tmp_mask); | ||
1160 | cpumask_andnot(tmp_mask, mask, cfg->old_domain); | ||
1161 | cpu = cpumask_first_and(tmp_mask, cpu_online_mask); | ||
1154 | continue; | 1162 | continue; |
1163 | } | ||
1155 | 1164 | ||
1156 | if (test_bit(vector, used_vectors)) | 1165 | if (test_bit(vector, used_vectors)) |
1157 | goto next; | 1166 | goto next; |
@@ -1162,7 +1171,7 @@ next: | |||
1162 | /* Found one! */ | 1171 | /* Found one! */ |
1163 | current_vector = vector; | 1172 | current_vector = vector; |
1164 | current_offset = offset; | 1173 | current_offset = offset; |
1165 | if (old_vector) { | 1174 | if (cfg->vector) { |
1166 | cfg->move_in_progress = 1; | 1175 | cfg->move_in_progress = 1; |
1167 | cpumask_copy(cfg->old_domain, cfg->domain); | 1176 | cpumask_copy(cfg->old_domain, cfg->domain); |
1168 | } | 1177 | } |
@@ -1346,18 +1355,18 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, | |||
1346 | 1355 | ||
1347 | if (!IO_APIC_IRQ(irq)) | 1356 | if (!IO_APIC_IRQ(irq)) |
1348 | return; | 1357 | return; |
1349 | /* | ||
1350 | * For legacy irqs, cfg->domain starts with cpu 0 for legacy | ||
1351 | * controllers like 8259. Now that IO-APIC can handle this irq, update | ||
1352 | * the cfg->domain. | ||
1353 | */ | ||
1354 | if (irq < legacy_pic->nr_legacy_irqs && cpumask_test_cpu(0, cfg->domain)) | ||
1355 | apic->vector_allocation_domain(0, cfg->domain); | ||
1356 | 1358 | ||
1357 | if (assign_irq_vector(irq, cfg, apic->target_cpus())) | 1359 | if (assign_irq_vector(irq, cfg, apic->target_cpus())) |
1358 | return; | 1360 | return; |
1359 | 1361 | ||
1360 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); | 1362 | if (apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus(), |
1363 | &dest)) { | ||
1364 | pr_warn("Failed to obtain apicid for ioapic %d, pin %d\n", | ||
1365 | mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); | ||
1366 | __clear_irq_vector(irq, cfg); | ||
1367 | |||
1368 | return; | ||
1369 | } | ||
1361 | 1370 | ||
1362 | apic_printk(APIC_VERBOSE,KERN_DEBUG | 1371 | apic_printk(APIC_VERBOSE,KERN_DEBUG |
1363 | "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " | 1372 | "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " |
@@ -1366,7 +1375,7 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, | |||
1366 | cfg->vector, irq, attr->trigger, attr->polarity, dest); | 1375 | cfg->vector, irq, attr->trigger, attr->polarity, dest); |
1367 | 1376 | ||
1368 | if (setup_ioapic_entry(irq, &entry, dest, cfg->vector, attr)) { | 1377 | if (setup_ioapic_entry(irq, &entry, dest, cfg->vector, attr)) { |
1369 | pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n", | 1378 | pr_warn("Failed to setup ioapic entry for ioapic %d, pin %d\n", |
1370 | mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); | 1379 | mpc_ioapic_id(attr->ioapic), attr->ioapic_pin); |
1371 | __clear_irq_vector(irq, cfg); | 1380 | __clear_irq_vector(irq, cfg); |
1372 | 1381 | ||
@@ -1469,9 +1478,10 @@ void setup_IO_APIC_irq_extra(u32 gsi) | |||
1469 | * Set up the timer pin, possibly with the 8259A-master behind. | 1478 | * Set up the timer pin, possibly with the 8259A-master behind. |
1470 | */ | 1479 | */ |
1471 | static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, | 1480 | static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, |
1472 | unsigned int pin, int vector) | 1481 | unsigned int pin, int vector) |
1473 | { | 1482 | { |
1474 | struct IO_APIC_route_entry entry; | 1483 | struct IO_APIC_route_entry entry; |
1484 | unsigned int dest; | ||
1475 | 1485 | ||
1476 | if (irq_remapping_enabled) | 1486 | if (irq_remapping_enabled) |
1477 | return; | 1487 | return; |
@@ -1482,9 +1492,13 @@ static void __init setup_timer_IRQ0_pin(unsigned int ioapic_idx, | |||
1482 | * We use logical delivery to get the timer IRQ | 1492 | * We use logical delivery to get the timer IRQ |
1483 | * to the first CPU. | 1493 | * to the first CPU. |
1484 | */ | 1494 | */ |
1495 | if (unlikely(apic->cpu_mask_to_apicid_and(apic->target_cpus(), | ||
1496 | apic->target_cpus(), &dest))) | ||
1497 | dest = BAD_APICID; | ||
1498 | |||
1485 | entry.dest_mode = apic->irq_dest_mode; | 1499 | entry.dest_mode = apic->irq_dest_mode; |
1486 | entry.mask = 0; /* don't mask IRQ for edge */ | 1500 | entry.mask = 0; /* don't mask IRQ for edge */ |
1487 | entry.dest = apic->cpu_mask_to_apicid(apic->target_cpus()); | 1501 | entry.dest = dest; |
1488 | entry.delivery_mode = apic->irq_delivery_mode; | 1502 | entry.delivery_mode = apic->irq_delivery_mode; |
1489 | entry.polarity = 0; | 1503 | entry.polarity = 0; |
1490 | entry.trigger = 0; | 1504 | entry.trigger = 0; |
@@ -1521,7 +1535,6 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) | |||
1521 | reg_03.raw = io_apic_read(ioapic_idx, 3); | 1535 | reg_03.raw = io_apic_read(ioapic_idx, 3); |
1522 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 1536 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
1523 | 1537 | ||
1524 | printk("\n"); | ||
1525 | printk(KERN_DEBUG "IO APIC #%d......\n", mpc_ioapic_id(ioapic_idx)); | 1538 | printk(KERN_DEBUG "IO APIC #%d......\n", mpc_ioapic_id(ioapic_idx)); |
1526 | printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); | 1539 | printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); |
1527 | printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); | 1540 | printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); |
@@ -1578,7 +1591,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) | |||
1578 | i, | 1591 | i, |
1579 | ir_entry->index | 1592 | ir_entry->index |
1580 | ); | 1593 | ); |
1581 | printk("%1d %1d %1d %1d %1d " | 1594 | pr_cont("%1d %1d %1d %1d %1d " |
1582 | "%1d %1d %X %02X\n", | 1595 | "%1d %1d %X %02X\n", |
1583 | ir_entry->format, | 1596 | ir_entry->format, |
1584 | ir_entry->mask, | 1597 | ir_entry->mask, |
@@ -1598,7 +1611,7 @@ __apicdebuginit(void) print_IO_APIC(int ioapic_idx) | |||
1598 | i, | 1611 | i, |
1599 | entry.dest | 1612 | entry.dest |
1600 | ); | 1613 | ); |
1601 | printk("%1d %1d %1d %1d %1d " | 1614 | pr_cont("%1d %1d %1d %1d %1d " |
1602 | "%1d %1d %02X\n", | 1615 | "%1d %1d %02X\n", |
1603 | entry.mask, | 1616 | entry.mask, |
1604 | entry.trigger, | 1617 | entry.trigger, |
@@ -1651,8 +1664,8 @@ __apicdebuginit(void) print_IO_APICs(void) | |||
1651 | continue; | 1664 | continue; |
1652 | printk(KERN_DEBUG "IRQ%d ", irq); | 1665 | printk(KERN_DEBUG "IRQ%d ", irq); |
1653 | for_each_irq_pin(entry, cfg->irq_2_pin) | 1666 | for_each_irq_pin(entry, cfg->irq_2_pin) |
1654 | printk("-> %d:%d", entry->apic, entry->pin); | 1667 | pr_cont("-> %d:%d", entry->apic, entry->pin); |
1655 | printk("\n"); | 1668 | pr_cont("\n"); |
1656 | } | 1669 | } |
1657 | 1670 | ||
1658 | printk(KERN_INFO ".................................... done.\n"); | 1671 | printk(KERN_INFO ".................................... done.\n"); |
@@ -1665,9 +1678,9 @@ __apicdebuginit(void) print_APIC_field(int base) | |||
1665 | printk(KERN_DEBUG); | 1678 | printk(KERN_DEBUG); |
1666 | 1679 | ||
1667 | for (i = 0; i < 8; i++) | 1680 | for (i = 0; i < 8; i++) |
1668 | printk(KERN_CONT "%08x", apic_read(base + i*0x10)); | 1681 | pr_cont("%08x", apic_read(base + i*0x10)); |
1669 | 1682 | ||
1670 | printk(KERN_CONT "\n"); | 1683 | pr_cont("\n"); |
1671 | } | 1684 | } |
1672 | 1685 | ||
1673 | __apicdebuginit(void) print_local_APIC(void *dummy) | 1686 | __apicdebuginit(void) print_local_APIC(void *dummy) |
@@ -1769,7 +1782,7 @@ __apicdebuginit(void) print_local_APIC(void *dummy) | |||
1769 | printk(KERN_DEBUG "... APIC EILVT%d: %08x\n", i, v); | 1782 | printk(KERN_DEBUG "... APIC EILVT%d: %08x\n", i, v); |
1770 | } | 1783 | } |
1771 | } | 1784 | } |
1772 | printk("\n"); | 1785 | pr_cont("\n"); |
1773 | } | 1786 | } |
1774 | 1787 | ||
1775 | __apicdebuginit(void) print_local_APICs(int maxcpu) | 1788 | __apicdebuginit(void) print_local_APICs(int maxcpu) |
@@ -2065,7 +2078,7 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void) | |||
2065 | reg_00.raw = io_apic_read(ioapic_idx, 0); | 2078 | reg_00.raw = io_apic_read(ioapic_idx, 0); |
2066 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 2079 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
2067 | if (reg_00.bits.ID != mpc_ioapic_id(ioapic_idx)) | 2080 | if (reg_00.bits.ID != mpc_ioapic_id(ioapic_idx)) |
2068 | printk("could not set ID!\n"); | 2081 | pr_cont("could not set ID!\n"); |
2069 | else | 2082 | else |
2070 | apic_printk(APIC_VERBOSE, " ok.\n"); | 2083 | apic_printk(APIC_VERBOSE, " ok.\n"); |
2071 | } | 2084 | } |
@@ -2210,71 +2223,6 @@ void send_cleanup_vector(struct irq_cfg *cfg) | |||
2210 | cfg->move_in_progress = 0; | 2223 | cfg->move_in_progress = 0; |
2211 | } | 2224 | } |
2212 | 2225 | ||
2213 | static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) | ||
2214 | { | ||
2215 | int apic, pin; | ||
2216 | struct irq_pin_list *entry; | ||
2217 | u8 vector = cfg->vector; | ||
2218 | |||
2219 | for_each_irq_pin(entry, cfg->irq_2_pin) { | ||
2220 | unsigned int reg; | ||
2221 | |||
2222 | apic = entry->apic; | ||
2223 | pin = entry->pin; | ||
2224 | /* | ||
2225 | * With interrupt-remapping, destination information comes | ||
2226 | * from interrupt-remapping table entry. | ||
2227 | */ | ||
2228 | if (!irq_remapped(cfg)) | ||
2229 | io_apic_write(apic, 0x11 + pin*2, dest); | ||
2230 | reg = io_apic_read(apic, 0x10 + pin*2); | ||
2231 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; | ||
2232 | reg |= vector; | ||
2233 | io_apic_modify(apic, 0x10 + pin*2, reg); | ||
2234 | } | ||
2235 | } | ||
2236 | |||
2237 | /* | ||
2238 | * Either sets data->affinity to a valid value, and returns | ||
2239 | * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and | ||
2240 | * leaves data->affinity untouched. | ||
2241 | */ | ||
2242 | int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | ||
2243 | unsigned int *dest_id) | ||
2244 | { | ||
2245 | struct irq_cfg *cfg = data->chip_data; | ||
2246 | |||
2247 | if (!cpumask_intersects(mask, cpu_online_mask)) | ||
2248 | return -1; | ||
2249 | |||
2250 | if (assign_irq_vector(data->irq, data->chip_data, mask)) | ||
2251 | return -1; | ||
2252 | |||
2253 | cpumask_copy(data->affinity, mask); | ||
2254 | |||
2255 | *dest_id = apic->cpu_mask_to_apicid_and(mask, cfg->domain); | ||
2256 | return 0; | ||
2257 | } | ||
2258 | |||
2259 | static int | ||
2260 | ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | ||
2261 | bool force) | ||
2262 | { | ||
2263 | unsigned int dest, irq = data->irq; | ||
2264 | unsigned long flags; | ||
2265 | int ret; | ||
2266 | |||
2267 | raw_spin_lock_irqsave(&ioapic_lock, flags); | ||
2268 | ret = __ioapic_set_affinity(data, mask, &dest); | ||
2269 | if (!ret) { | ||
2270 | /* Only the high 8 bits are valid. */ | ||
2271 | dest = SET_APIC_LOGICAL_ID(dest); | ||
2272 | __target_IO_APIC_irq(irq, dest, data->chip_data); | ||
2273 | } | ||
2274 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2275 | return ret; | ||
2276 | } | ||
2277 | |||
2278 | asmlinkage void smp_irq_move_cleanup_interrupt(void) | 2226 | asmlinkage void smp_irq_move_cleanup_interrupt(void) |
2279 | { | 2227 | { |
2280 | unsigned vector, me; | 2228 | unsigned vector, me; |
@@ -2362,6 +2310,87 @@ void irq_force_complete_move(int irq) | |||
2362 | static inline void irq_complete_move(struct irq_cfg *cfg) { } | 2310 | static inline void irq_complete_move(struct irq_cfg *cfg) { } |
2363 | #endif | 2311 | #endif |
2364 | 2312 | ||
2313 | static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq_cfg *cfg) | ||
2314 | { | ||
2315 | int apic, pin; | ||
2316 | struct irq_pin_list *entry; | ||
2317 | u8 vector = cfg->vector; | ||
2318 | |||
2319 | for_each_irq_pin(entry, cfg->irq_2_pin) { | ||
2320 | unsigned int reg; | ||
2321 | |||
2322 | apic = entry->apic; | ||
2323 | pin = entry->pin; | ||
2324 | /* | ||
2325 | * With interrupt-remapping, destination information comes | ||
2326 | * from interrupt-remapping table entry. | ||
2327 | */ | ||
2328 | if (!irq_remapped(cfg)) | ||
2329 | io_apic_write(apic, 0x11 + pin*2, dest); | ||
2330 | reg = io_apic_read(apic, 0x10 + pin*2); | ||
2331 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; | ||
2332 | reg |= vector; | ||
2333 | io_apic_modify(apic, 0x10 + pin*2, reg); | ||
2334 | } | ||
2335 | } | ||
2336 | |||
2337 | /* | ||
2338 | * Either sets data->affinity to a valid value, and returns | ||
2339 | * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and | ||
2340 | * leaves data->affinity untouched. | ||
2341 | */ | ||
2342 | int __ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | ||
2343 | unsigned int *dest_id) | ||
2344 | { | ||
2345 | struct irq_cfg *cfg = data->chip_data; | ||
2346 | unsigned int irq = data->irq; | ||
2347 | int err; | ||
2348 | |||
2349 | if (!config_enabled(CONFIG_SMP)) | ||
2350 | return -1; | ||
2351 | |||
2352 | if (!cpumask_intersects(mask, cpu_online_mask)) | ||
2353 | return -EINVAL; | ||
2354 | |||
2355 | err = assign_irq_vector(irq, cfg, mask); | ||
2356 | if (err) | ||
2357 | return err; | ||
2358 | |||
2359 | err = apic->cpu_mask_to_apicid_and(mask, cfg->domain, dest_id); | ||
2360 | if (err) { | ||
2361 | if (assign_irq_vector(irq, cfg, data->affinity)) | ||
2362 | pr_err("Failed to recover vector for irq %d\n", irq); | ||
2363 | return err; | ||
2364 | } | ||
2365 | |||
2366 | cpumask_copy(data->affinity, mask); | ||
2367 | |||
2368 | return 0; | ||
2369 | } | ||
2370 | |||
2371 | static int | ||
2372 | ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | ||
2373 | bool force) | ||
2374 | { | ||
2375 | unsigned int dest, irq = data->irq; | ||
2376 | unsigned long flags; | ||
2377 | int ret; | ||
2378 | |||
2379 | if (!config_enabled(CONFIG_SMP)) | ||
2380 | return -1; | ||
2381 | |||
2382 | raw_spin_lock_irqsave(&ioapic_lock, flags); | ||
2383 | ret = __ioapic_set_affinity(data, mask, &dest); | ||
2384 | if (!ret) { | ||
2385 | /* Only the high 8 bits are valid. */ | ||
2386 | dest = SET_APIC_LOGICAL_ID(dest); | ||
2387 | __target_IO_APIC_irq(irq, dest, data->chip_data); | ||
2388 | ret = IRQ_SET_MASK_OK_NOCOPY; | ||
2389 | } | ||
2390 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2391 | return ret; | ||
2392 | } | ||
2393 | |||
2365 | static void ack_apic_edge(struct irq_data *data) | 2394 | static void ack_apic_edge(struct irq_data *data) |
2366 | { | 2395 | { |
2367 | irq_complete_move(data->chip_data); | 2396 | irq_complete_move(data->chip_data); |
@@ -2541,9 +2570,7 @@ static void irq_remap_modify_chip_defaults(struct irq_chip *chip) | |||
2541 | chip->irq_ack = ir_ack_apic_edge; | 2570 | chip->irq_ack = ir_ack_apic_edge; |
2542 | chip->irq_eoi = ir_ack_apic_level; | 2571 | chip->irq_eoi = ir_ack_apic_level; |
2543 | 2572 | ||
2544 | #ifdef CONFIG_SMP | ||
2545 | chip->irq_set_affinity = set_remapped_irq_affinity; | 2573 | chip->irq_set_affinity = set_remapped_irq_affinity; |
2546 | #endif | ||
2547 | } | 2574 | } |
2548 | #endif /* CONFIG_IRQ_REMAP */ | 2575 | #endif /* CONFIG_IRQ_REMAP */ |
2549 | 2576 | ||
@@ -2554,9 +2581,7 @@ static struct irq_chip ioapic_chip __read_mostly = { | |||
2554 | .irq_unmask = unmask_ioapic_irq, | 2581 | .irq_unmask = unmask_ioapic_irq, |
2555 | .irq_ack = ack_apic_edge, | 2582 | .irq_ack = ack_apic_edge, |
2556 | .irq_eoi = ack_apic_level, | 2583 | .irq_eoi = ack_apic_level, |
2557 | #ifdef CONFIG_SMP | ||
2558 | .irq_set_affinity = ioapic_set_affinity, | 2584 | .irq_set_affinity = ioapic_set_affinity, |
2559 | #endif | ||
2560 | .irq_retrigger = ioapic_retrigger_irq, | 2585 | .irq_retrigger = ioapic_retrigger_irq, |
2561 | }; | 2586 | }; |
2562 | 2587 | ||
@@ -3038,7 +3063,10 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, | |||
3038 | if (err) | 3063 | if (err) |
3039 | return err; | 3064 | return err; |
3040 | 3065 | ||
3041 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus()); | 3066 | err = apic->cpu_mask_to_apicid_and(cfg->domain, |
3067 | apic->target_cpus(), &dest); | ||
3068 | if (err) | ||
3069 | return err; | ||
3042 | 3070 | ||
3043 | if (irq_remapped(cfg)) { | 3071 | if (irq_remapped(cfg)) { |
3044 | compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id); | 3072 | compose_remapped_msi_msg(pdev, irq, dest, msg, hpet_id); |
@@ -3072,7 +3100,6 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, | |||
3072 | return err; | 3100 | return err; |
3073 | } | 3101 | } |
3074 | 3102 | ||
3075 | #ifdef CONFIG_SMP | ||
3076 | static int | 3103 | static int |
3077 | msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) | 3104 | msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) |
3078 | { | 3105 | { |
@@ -3092,9 +3119,8 @@ msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) | |||
3092 | 3119 | ||
3093 | __write_msi_msg(data->msi_desc, &msg); | 3120 | __write_msi_msg(data->msi_desc, &msg); |
3094 | 3121 | ||
3095 | return 0; | 3122 | return IRQ_SET_MASK_OK_NOCOPY; |
3096 | } | 3123 | } |
3097 | #endif /* CONFIG_SMP */ | ||
3098 | 3124 | ||
3099 | /* | 3125 | /* |
3100 | * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices, | 3126 | * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices, |
@@ -3105,9 +3131,7 @@ static struct irq_chip msi_chip = { | |||
3105 | .irq_unmask = unmask_msi_irq, | 3131 | .irq_unmask = unmask_msi_irq, |
3106 | .irq_mask = mask_msi_irq, | 3132 | .irq_mask = mask_msi_irq, |
3107 | .irq_ack = ack_apic_edge, | 3133 | .irq_ack = ack_apic_edge, |
3108 | #ifdef CONFIG_SMP | ||
3109 | .irq_set_affinity = msi_set_affinity, | 3134 | .irq_set_affinity = msi_set_affinity, |
3110 | #endif | ||
3111 | .irq_retrigger = ioapic_retrigger_irq, | 3135 | .irq_retrigger = ioapic_retrigger_irq, |
3112 | }; | 3136 | }; |
3113 | 3137 | ||
@@ -3192,7 +3216,6 @@ void native_teardown_msi_irq(unsigned int irq) | |||
3192 | } | 3216 | } |
3193 | 3217 | ||
3194 | #ifdef CONFIG_DMAR_TABLE | 3218 | #ifdef CONFIG_DMAR_TABLE |
3195 | #ifdef CONFIG_SMP | ||
3196 | static int | 3219 | static int |
3197 | dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, | 3220 | dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, |
3198 | bool force) | 3221 | bool force) |
@@ -3214,19 +3237,15 @@ dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, | |||
3214 | 3237 | ||
3215 | dmar_msi_write(irq, &msg); | 3238 | dmar_msi_write(irq, &msg); |
3216 | 3239 | ||
3217 | return 0; | 3240 | return IRQ_SET_MASK_OK_NOCOPY; |
3218 | } | 3241 | } |
3219 | 3242 | ||
3220 | #endif /* CONFIG_SMP */ | ||
3221 | |||
3222 | static struct irq_chip dmar_msi_type = { | 3243 | static struct irq_chip dmar_msi_type = { |
3223 | .name = "DMAR_MSI", | 3244 | .name = "DMAR_MSI", |
3224 | .irq_unmask = dmar_msi_unmask, | 3245 | .irq_unmask = dmar_msi_unmask, |
3225 | .irq_mask = dmar_msi_mask, | 3246 | .irq_mask = dmar_msi_mask, |
3226 | .irq_ack = ack_apic_edge, | 3247 | .irq_ack = ack_apic_edge, |
3227 | #ifdef CONFIG_SMP | ||
3228 | .irq_set_affinity = dmar_msi_set_affinity, | 3248 | .irq_set_affinity = dmar_msi_set_affinity, |
3229 | #endif | ||
3230 | .irq_retrigger = ioapic_retrigger_irq, | 3249 | .irq_retrigger = ioapic_retrigger_irq, |
3231 | }; | 3250 | }; |
3232 | 3251 | ||
@@ -3247,7 +3266,6 @@ int arch_setup_dmar_msi(unsigned int irq) | |||
3247 | 3266 | ||
3248 | #ifdef CONFIG_HPET_TIMER | 3267 | #ifdef CONFIG_HPET_TIMER |
3249 | 3268 | ||
3250 | #ifdef CONFIG_SMP | ||
3251 | static int hpet_msi_set_affinity(struct irq_data *data, | 3269 | static int hpet_msi_set_affinity(struct irq_data *data, |
3252 | const struct cpumask *mask, bool force) | 3270 | const struct cpumask *mask, bool force) |
3253 | { | 3271 | { |
@@ -3267,19 +3285,15 @@ static int hpet_msi_set_affinity(struct irq_data *data, | |||
3267 | 3285 | ||
3268 | hpet_msi_write(data->handler_data, &msg); | 3286 | hpet_msi_write(data->handler_data, &msg); |
3269 | 3287 | ||
3270 | return 0; | 3288 | return IRQ_SET_MASK_OK_NOCOPY; |
3271 | } | 3289 | } |
3272 | 3290 | ||
3273 | #endif /* CONFIG_SMP */ | ||
3274 | |||
3275 | static struct irq_chip hpet_msi_type = { | 3291 | static struct irq_chip hpet_msi_type = { |
3276 | .name = "HPET_MSI", | 3292 | .name = "HPET_MSI", |
3277 | .irq_unmask = hpet_msi_unmask, | 3293 | .irq_unmask = hpet_msi_unmask, |
3278 | .irq_mask = hpet_msi_mask, | 3294 | .irq_mask = hpet_msi_mask, |
3279 | .irq_ack = ack_apic_edge, | 3295 | .irq_ack = ack_apic_edge, |
3280 | #ifdef CONFIG_SMP | ||
3281 | .irq_set_affinity = hpet_msi_set_affinity, | 3296 | .irq_set_affinity = hpet_msi_set_affinity, |
3282 | #endif | ||
3283 | .irq_retrigger = ioapic_retrigger_irq, | 3297 | .irq_retrigger = ioapic_retrigger_irq, |
3284 | }; | 3298 | }; |
3285 | 3299 | ||
@@ -3314,8 +3328,6 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id) | |||
3314 | */ | 3328 | */ |
3315 | #ifdef CONFIG_HT_IRQ | 3329 | #ifdef CONFIG_HT_IRQ |
3316 | 3330 | ||
3317 | #ifdef CONFIG_SMP | ||
3318 | |||
3319 | static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector) | 3331 | static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector) |
3320 | { | 3332 | { |
3321 | struct ht_irq_msg msg; | 3333 | struct ht_irq_msg msg; |
@@ -3340,25 +3352,23 @@ ht_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) | |||
3340 | return -1; | 3352 | return -1; |
3341 | 3353 | ||
3342 | target_ht_irq(data->irq, dest, cfg->vector); | 3354 | target_ht_irq(data->irq, dest, cfg->vector); |
3343 | return 0; | 3355 | return IRQ_SET_MASK_OK_NOCOPY; |
3344 | } | 3356 | } |
3345 | 3357 | ||
3346 | #endif | ||
3347 | |||
3348 | static struct irq_chip ht_irq_chip = { | 3358 | static struct irq_chip ht_irq_chip = { |
3349 | .name = "PCI-HT", | 3359 | .name = "PCI-HT", |
3350 | .irq_mask = mask_ht_irq, | 3360 | .irq_mask = mask_ht_irq, |
3351 | .irq_unmask = unmask_ht_irq, | 3361 | .irq_unmask = unmask_ht_irq, |
3352 | .irq_ack = ack_apic_edge, | 3362 | .irq_ack = ack_apic_edge, |
3353 | #ifdef CONFIG_SMP | ||
3354 | .irq_set_affinity = ht_set_affinity, | 3363 | .irq_set_affinity = ht_set_affinity, |
3355 | #endif | ||
3356 | .irq_retrigger = ioapic_retrigger_irq, | 3364 | .irq_retrigger = ioapic_retrigger_irq, |
3357 | }; | 3365 | }; |
3358 | 3366 | ||
3359 | int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | 3367 | int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) |
3360 | { | 3368 | { |
3361 | struct irq_cfg *cfg; | 3369 | struct irq_cfg *cfg; |
3370 | struct ht_irq_msg msg; | ||
3371 | unsigned dest; | ||
3362 | int err; | 3372 | int err; |
3363 | 3373 | ||
3364 | if (disable_apic) | 3374 | if (disable_apic) |
@@ -3366,36 +3376,37 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | |||
3366 | 3376 | ||
3367 | cfg = irq_cfg(irq); | 3377 | cfg = irq_cfg(irq); |
3368 | err = assign_irq_vector(irq, cfg, apic->target_cpus()); | 3378 | err = assign_irq_vector(irq, cfg, apic->target_cpus()); |
3369 | if (!err) { | 3379 | if (err) |
3370 | struct ht_irq_msg msg; | 3380 | return err; |
3371 | unsigned dest; | 3381 | |
3382 | err = apic->cpu_mask_to_apicid_and(cfg->domain, | ||
3383 | apic->target_cpus(), &dest); | ||
3384 | if (err) | ||
3385 | return err; | ||
3372 | 3386 | ||
3373 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, | 3387 | msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); |
3374 | apic->target_cpus()); | ||
3375 | 3388 | ||
3376 | msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); | 3389 | msg.address_lo = |
3390 | HT_IRQ_LOW_BASE | | ||
3391 | HT_IRQ_LOW_DEST_ID(dest) | | ||
3392 | HT_IRQ_LOW_VECTOR(cfg->vector) | | ||
3393 | ((apic->irq_dest_mode == 0) ? | ||
3394 | HT_IRQ_LOW_DM_PHYSICAL : | ||
3395 | HT_IRQ_LOW_DM_LOGICAL) | | ||
3396 | HT_IRQ_LOW_RQEOI_EDGE | | ||
3397 | ((apic->irq_delivery_mode != dest_LowestPrio) ? | ||
3398 | HT_IRQ_LOW_MT_FIXED : | ||
3399 | HT_IRQ_LOW_MT_ARBITRATED) | | ||
3400 | HT_IRQ_LOW_IRQ_MASKED; | ||
3377 | 3401 | ||
3378 | msg.address_lo = | 3402 | write_ht_irq_msg(irq, &msg); |
3379 | HT_IRQ_LOW_BASE | | ||
3380 | HT_IRQ_LOW_DEST_ID(dest) | | ||
3381 | HT_IRQ_LOW_VECTOR(cfg->vector) | | ||
3382 | ((apic->irq_dest_mode == 0) ? | ||
3383 | HT_IRQ_LOW_DM_PHYSICAL : | ||
3384 | HT_IRQ_LOW_DM_LOGICAL) | | ||
3385 | HT_IRQ_LOW_RQEOI_EDGE | | ||
3386 | ((apic->irq_delivery_mode != dest_LowestPrio) ? | ||
3387 | HT_IRQ_LOW_MT_FIXED : | ||
3388 | HT_IRQ_LOW_MT_ARBITRATED) | | ||
3389 | HT_IRQ_LOW_IRQ_MASKED; | ||
3390 | 3403 | ||
3391 | write_ht_irq_msg(irq, &msg); | 3404 | irq_set_chip_and_handler_name(irq, &ht_irq_chip, |
3405 | handle_edge_irq, "edge"); | ||
3392 | 3406 | ||
3393 | irq_set_chip_and_handler_name(irq, &ht_irq_chip, | 3407 | dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq); |
3394 | handle_edge_irq, "edge"); | ||
3395 | 3408 | ||
3396 | dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq); | 3409 | return 0; |
3397 | } | ||
3398 | return err; | ||
3399 | } | 3410 | } |
3400 | #endif /* CONFIG_HT_IRQ */ | 3411 | #endif /* CONFIG_HT_IRQ */ |
3401 | 3412 | ||
@@ -3563,7 +3574,8 @@ static int __init io_apic_get_unique_id(int ioapic, int apic_id) | |||
3563 | 3574 | ||
3564 | /* Sanity check */ | 3575 | /* Sanity check */ |
3565 | if (reg_00.bits.ID != apic_id) { | 3576 | if (reg_00.bits.ID != apic_id) { |
3566 | printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic); | 3577 | pr_err("IOAPIC[%d]: Unable to change apic_id!\n", |
3578 | ioapic); | ||
3567 | return -1; | 3579 | return -1; |
3568 | } | 3580 | } |
3569 | } | 3581 | } |
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index f00a68cca37a..d661ee95cabf 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c | |||
@@ -406,16 +406,13 @@ static inline int numaq_check_phys_apicid_present(int phys_apicid) | |||
406 | * We use physical apicids here, not logical, so just return the default | 406 | * We use physical apicids here, not logical, so just return the default |
407 | * physical broadcast to stop people from breaking us | 407 | * physical broadcast to stop people from breaking us |
408 | */ | 408 | */ |
409 | static unsigned int numaq_cpu_mask_to_apicid(const struct cpumask *cpumask) | 409 | static int |
410 | { | ||
411 | return 0x0F; | ||
412 | } | ||
413 | |||
414 | static inline unsigned int | ||
415 | numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 410 | numaq_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
416 | const struct cpumask *andmask) | 411 | const struct cpumask *andmask, |
412 | unsigned int *apicid) | ||
417 | { | 413 | { |
418 | return 0x0F; | 414 | *apicid = 0x0F; |
415 | return 0; | ||
419 | } | 416 | } |
420 | 417 | ||
421 | /* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */ | 418 | /* No NUMA-Q box has a HT CPU, but it can't hurt to use the default code. */ |
@@ -441,20 +438,6 @@ static int probe_numaq(void) | |||
441 | return found_numaq; | 438 | return found_numaq; |
442 | } | 439 | } |
443 | 440 | ||
444 | static void numaq_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
445 | { | ||
446 | /* Careful. Some cpus do not strictly honor the set of cpus | ||
447 | * specified in the interrupt destination when using lowest | ||
448 | * priority interrupt delivery mode. | ||
449 | * | ||
450 | * In particular there was a hyperthreading cpu observed to | ||
451 | * deliver interrupts to the wrong hyperthread when only one | ||
452 | * hyperthread was specified in the interrupt desitination. | ||
453 | */ | ||
454 | cpumask_clear(retmask); | ||
455 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
456 | } | ||
457 | |||
458 | static void numaq_setup_portio_remap(void) | 441 | static void numaq_setup_portio_remap(void) |
459 | { | 442 | { |
460 | int num_quads = num_online_nodes(); | 443 | int num_quads = num_online_nodes(); |
@@ -491,7 +474,7 @@ static struct apic __refdata apic_numaq = { | |||
491 | .check_apicid_used = numaq_check_apicid_used, | 474 | .check_apicid_used = numaq_check_apicid_used, |
492 | .check_apicid_present = numaq_check_apicid_present, | 475 | .check_apicid_present = numaq_check_apicid_present, |
493 | 476 | ||
494 | .vector_allocation_domain = numaq_vector_allocation_domain, | 477 | .vector_allocation_domain = flat_vector_allocation_domain, |
495 | .init_apic_ldr = numaq_init_apic_ldr, | 478 | .init_apic_ldr = numaq_init_apic_ldr, |
496 | 479 | ||
497 | .ioapic_phys_id_map = numaq_ioapic_phys_id_map, | 480 | .ioapic_phys_id_map = numaq_ioapic_phys_id_map, |
@@ -509,7 +492,6 @@ static struct apic __refdata apic_numaq = { | |||
509 | .set_apic_id = NULL, | 492 | .set_apic_id = NULL, |
510 | .apic_id_mask = 0x0F << 24, | 493 | .apic_id_mask = 0x0F << 24, |
511 | 494 | ||
512 | .cpu_mask_to_apicid = numaq_cpu_mask_to_apicid, | ||
513 | .cpu_mask_to_apicid_and = numaq_cpu_mask_to_apicid_and, | 495 | .cpu_mask_to_apicid_and = numaq_cpu_mask_to_apicid_and, |
514 | 496 | ||
515 | .send_IPI_mask = numaq_send_IPI_mask, | 497 | .send_IPI_mask = numaq_send_IPI_mask, |
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index 1b291da09e60..eb35ef9ee63f 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c | |||
@@ -66,21 +66,6 @@ static void setup_apic_flat_routing(void) | |||
66 | #endif | 66 | #endif |
67 | } | 67 | } |
68 | 68 | ||
69 | static void default_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
70 | { | ||
71 | /* | ||
72 | * Careful. Some cpus do not strictly honor the set of cpus | ||
73 | * specified in the interrupt destination when using lowest | ||
74 | * priority interrupt delivery mode. | ||
75 | * | ||
76 | * In particular there was a hyperthreading cpu observed to | ||
77 | * deliver interrupts to the wrong hyperthread when only one | ||
78 | * hyperthread was specified in the interrupt desitination. | ||
79 | */ | ||
80 | cpumask_clear(retmask); | ||
81 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
82 | } | ||
83 | |||
84 | /* should be called last. */ | 69 | /* should be called last. */ |
85 | static int probe_default(void) | 70 | static int probe_default(void) |
86 | { | 71 | { |
@@ -105,7 +90,7 @@ static struct apic apic_default = { | |||
105 | .check_apicid_used = default_check_apicid_used, | 90 | .check_apicid_used = default_check_apicid_used, |
106 | .check_apicid_present = default_check_apicid_present, | 91 | .check_apicid_present = default_check_apicid_present, |
107 | 92 | ||
108 | .vector_allocation_domain = default_vector_allocation_domain, | 93 | .vector_allocation_domain = flat_vector_allocation_domain, |
109 | .init_apic_ldr = default_init_apic_ldr, | 94 | .init_apic_ldr = default_init_apic_ldr, |
110 | 95 | ||
111 | .ioapic_phys_id_map = default_ioapic_phys_id_map, | 96 | .ioapic_phys_id_map = default_ioapic_phys_id_map, |
@@ -123,8 +108,7 @@ static struct apic apic_default = { | |||
123 | .set_apic_id = NULL, | 108 | .set_apic_id = NULL, |
124 | .apic_id_mask = 0x0F << 24, | 109 | .apic_id_mask = 0x0F << 24, |
125 | 110 | ||
126 | .cpu_mask_to_apicid = default_cpu_mask_to_apicid, | 111 | .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and, |
127 | .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, | ||
128 | 112 | ||
129 | .send_IPI_mask = default_send_IPI_mask_logical, | 113 | .send_IPI_mask = default_send_IPI_mask_logical, |
130 | .send_IPI_mask_allbutself = default_send_IPI_mask_allbutself_logical, | 114 | .send_IPI_mask_allbutself = default_send_IPI_mask_allbutself_logical, |
@@ -208,6 +192,9 @@ void __init default_setup_apic_routing(void) | |||
208 | 192 | ||
209 | if (apic->setup_apic_routing) | 193 | if (apic->setup_apic_routing) |
210 | apic->setup_apic_routing(); | 194 | apic->setup_apic_routing(); |
195 | |||
196 | if (x86_platform.apic_post_init) | ||
197 | x86_platform.apic_post_init(); | ||
211 | } | 198 | } |
212 | 199 | ||
213 | void __init generic_apic_probe(void) | 200 | void __init generic_apic_probe(void) |
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index 3fe986698929..1793dba7a741 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c | |||
@@ -23,11 +23,6 @@ | |||
23 | #include <asm/ipi.h> | 23 | #include <asm/ipi.h> |
24 | #include <asm/setup.h> | 24 | #include <asm/setup.h> |
25 | 25 | ||
26 | static int apicid_phys_pkg_id(int initial_apic_id, int index_msb) | ||
27 | { | ||
28 | return hard_smp_processor_id() >> index_msb; | ||
29 | } | ||
30 | |||
31 | /* | 26 | /* |
32 | * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. | 27 | * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. |
33 | */ | 28 | */ |
@@ -48,10 +43,8 @@ void __init default_setup_apic_routing(void) | |||
48 | } | 43 | } |
49 | } | 44 | } |
50 | 45 | ||
51 | if (is_vsmp_box()) { | 46 | if (x86_platform.apic_post_init) |
52 | /* need to update phys_pkg_id */ | 47 | x86_platform.apic_post_init(); |
53 | apic->phys_pkg_id = apicid_phys_pkg_id; | ||
54 | } | ||
55 | } | 48 | } |
56 | 49 | ||
57 | /* Same for both flat and physical. */ | 50 | /* Same for both flat and physical. */ |
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c index 659897c00755..77c95c0e1bf7 100644 --- a/arch/x86/kernel/apic/summit_32.c +++ b/arch/x86/kernel/apic/summit_32.c | |||
@@ -26,6 +26,8 @@ | |||
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #define pr_fmt(fmt) "summit: %s: " fmt, __func__ | ||
30 | |||
29 | #include <linux/mm.h> | 31 | #include <linux/mm.h> |
30 | #include <linux/init.h> | 32 | #include <linux/init.h> |
31 | #include <asm/io.h> | 33 | #include <asm/io.h> |
@@ -235,8 +237,8 @@ static int summit_apic_id_registered(void) | |||
235 | 237 | ||
236 | static void summit_setup_apic_routing(void) | 238 | static void summit_setup_apic_routing(void) |
237 | { | 239 | { |
238 | printk("Enabling APIC mode: Summit. Using %d I/O APICs\n", | 240 | pr_info("Enabling APIC mode: Summit. Using %d I/O APICs\n", |
239 | nr_ioapics); | 241 | nr_ioapics); |
240 | } | 242 | } |
241 | 243 | ||
242 | static int summit_cpu_present_to_apicid(int mps_cpu) | 244 | static int summit_cpu_present_to_apicid(int mps_cpu) |
@@ -263,43 +265,48 @@ static int summit_check_phys_apicid_present(int physical_apicid) | |||
263 | return 1; | 265 | return 1; |
264 | } | 266 | } |
265 | 267 | ||
266 | static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask) | 268 | static inline int |
269 | summit_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id) | ||
267 | { | 270 | { |
268 | unsigned int round = 0; | 271 | unsigned int round = 0; |
269 | int cpu, apicid = 0; | 272 | unsigned int cpu, apicid = 0; |
270 | 273 | ||
271 | /* | 274 | /* |
272 | * The cpus in the mask must all be on the apic cluster. | 275 | * The cpus in the mask must all be on the apic cluster. |
273 | */ | 276 | */ |
274 | for_each_cpu(cpu, cpumask) { | 277 | for_each_cpu_and(cpu, cpumask, cpu_online_mask) { |
275 | int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); | 278 | int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu); |
276 | 279 | ||
277 | if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { | 280 | if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) { |
278 | printk("%s: Not a valid mask!\n", __func__); | 281 | pr_err("Not a valid mask!\n"); |
279 | return BAD_APICID; | 282 | return -EINVAL; |
280 | } | 283 | } |
281 | apicid |= new_apicid; | 284 | apicid |= new_apicid; |
282 | round++; | 285 | round++; |
283 | } | 286 | } |
284 | return apicid; | 287 | if (!round) |
288 | return -EINVAL; | ||
289 | *dest_id = apicid; | ||
290 | return 0; | ||
285 | } | 291 | } |
286 | 292 | ||
287 | static unsigned int summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, | 293 | static int |
288 | const struct cpumask *andmask) | 294 | summit_cpu_mask_to_apicid_and(const struct cpumask *inmask, |
295 | const struct cpumask *andmask, | ||
296 | unsigned int *apicid) | ||
289 | { | 297 | { |
290 | int apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); | ||
291 | cpumask_var_t cpumask; | 298 | cpumask_var_t cpumask; |
299 | *apicid = early_per_cpu(x86_cpu_to_logical_apicid, 0); | ||
292 | 300 | ||
293 | if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) | 301 | if (!alloc_cpumask_var(&cpumask, GFP_ATOMIC)) |
294 | return apicid; | 302 | return 0; |
295 | 303 | ||
296 | cpumask_and(cpumask, inmask, andmask); | 304 | cpumask_and(cpumask, inmask, andmask); |
297 | cpumask_and(cpumask, cpumask, cpu_online_mask); | 305 | summit_cpu_mask_to_apicid(cpumask, apicid); |
298 | apicid = summit_cpu_mask_to_apicid(cpumask); | ||
299 | 306 | ||
300 | free_cpumask_var(cpumask); | 307 | free_cpumask_var(cpumask); |
301 | 308 | ||
302 | return apicid; | 309 | return 0; |
303 | } | 310 | } |
304 | 311 | ||
305 | /* | 312 | /* |
@@ -320,20 +327,6 @@ static int probe_summit(void) | |||
320 | return 0; | 327 | return 0; |
321 | } | 328 | } |
322 | 329 | ||
323 | static void summit_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
324 | { | ||
325 | /* Careful. Some cpus do not strictly honor the set of cpus | ||
326 | * specified in the interrupt destination when using lowest | ||
327 | * priority interrupt delivery mode. | ||
328 | * | ||
329 | * In particular there was a hyperthreading cpu observed to | ||
330 | * deliver interrupts to the wrong hyperthread when only one | ||
331 | * hyperthread was specified in the interrupt desitination. | ||
332 | */ | ||
333 | cpumask_clear(retmask); | ||
334 | cpumask_bits(retmask)[0] = APIC_ALL_CPUS; | ||
335 | } | ||
336 | |||
337 | #ifdef CONFIG_X86_SUMMIT_NUMA | 330 | #ifdef CONFIG_X86_SUMMIT_NUMA |
338 | static struct rio_table_hdr *rio_table_hdr; | 331 | static struct rio_table_hdr *rio_table_hdr; |
339 | static struct scal_detail *scal_devs[MAX_NUMNODES]; | 332 | static struct scal_detail *scal_devs[MAX_NUMNODES]; |
@@ -355,7 +348,7 @@ static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) | |||
355 | } | 348 | } |
356 | } | 349 | } |
357 | if (i == rio_table_hdr->num_rio_dev) { | 350 | if (i == rio_table_hdr->num_rio_dev) { |
358 | printk(KERN_ERR "%s: Couldn't find owner Cyclone for Winnipeg!\n", __func__); | 351 | pr_err("Couldn't find owner Cyclone for Winnipeg!\n"); |
359 | return last_bus; | 352 | return last_bus; |
360 | } | 353 | } |
361 | 354 | ||
@@ -366,7 +359,7 @@ static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) | |||
366 | } | 359 | } |
367 | } | 360 | } |
368 | if (i == rio_table_hdr->num_scal_dev) { | 361 | if (i == rio_table_hdr->num_scal_dev) { |
369 | printk(KERN_ERR "%s: Couldn't find owner Twister for Cyclone!\n", __func__); | 362 | pr_err("Couldn't find owner Twister for Cyclone!\n"); |
370 | return last_bus; | 363 | return last_bus; |
371 | } | 364 | } |
372 | 365 | ||
@@ -396,7 +389,7 @@ static int setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus) | |||
396 | num_buses = 9; | 389 | num_buses = 9; |
397 | break; | 390 | break; |
398 | default: | 391 | default: |
399 | printk(KERN_INFO "%s: Unsupported Winnipeg type!\n", __func__); | 392 | pr_info("Unsupported Winnipeg type!\n"); |
400 | return last_bus; | 393 | return last_bus; |
401 | } | 394 | } |
402 | 395 | ||
@@ -411,13 +404,15 @@ static int build_detail_arrays(void) | |||
411 | int i, scal_detail_size, rio_detail_size; | 404 | int i, scal_detail_size, rio_detail_size; |
412 | 405 | ||
413 | if (rio_table_hdr->num_scal_dev > MAX_NUMNODES) { | 406 | if (rio_table_hdr->num_scal_dev > MAX_NUMNODES) { |
414 | printk(KERN_WARNING "%s: MAX_NUMNODES too low! Defined as %d, but system has %d nodes.\n", __func__, MAX_NUMNODES, rio_table_hdr->num_scal_dev); | 407 | pr_warn("MAX_NUMNODES too low! Defined as %d, but system has %d nodes\n", |
408 | MAX_NUMNODES, rio_table_hdr->num_scal_dev); | ||
415 | return 0; | 409 | return 0; |
416 | } | 410 | } |
417 | 411 | ||
418 | switch (rio_table_hdr->version) { | 412 | switch (rio_table_hdr->version) { |
419 | default: | 413 | default: |
420 | printk(KERN_WARNING "%s: Invalid Rio Grande Table Version: %d\n", __func__, rio_table_hdr->version); | 414 | pr_warn("Invalid Rio Grande Table Version: %d\n", |
415 | rio_table_hdr->version); | ||
421 | return 0; | 416 | return 0; |
422 | case 2: | 417 | case 2: |
423 | scal_detail_size = 11; | 418 | scal_detail_size = 11; |
@@ -462,7 +457,7 @@ void setup_summit(void) | |||
462 | offset = *((unsigned short *)(ptr + offset)); | 457 | offset = *((unsigned short *)(ptr + offset)); |
463 | } | 458 | } |
464 | if (!rio_table_hdr) { | 459 | if (!rio_table_hdr) { |
465 | printk(KERN_ERR "%s: Unable to locate Rio Grande Table in EBDA - bailing!\n", __func__); | 460 | pr_err("Unable to locate Rio Grande Table in EBDA - bailing!\n"); |
466 | return; | 461 | return; |
467 | } | 462 | } |
468 | 463 | ||
@@ -509,7 +504,7 @@ static struct apic apic_summit = { | |||
509 | .check_apicid_used = summit_check_apicid_used, | 504 | .check_apicid_used = summit_check_apicid_used, |
510 | .check_apicid_present = summit_check_apicid_present, | 505 | .check_apicid_present = summit_check_apicid_present, |
511 | 506 | ||
512 | .vector_allocation_domain = summit_vector_allocation_domain, | 507 | .vector_allocation_domain = flat_vector_allocation_domain, |
513 | .init_apic_ldr = summit_init_apic_ldr, | 508 | .init_apic_ldr = summit_init_apic_ldr, |
514 | 509 | ||
515 | .ioapic_phys_id_map = summit_ioapic_phys_id_map, | 510 | .ioapic_phys_id_map = summit_ioapic_phys_id_map, |
@@ -527,7 +522,6 @@ static struct apic apic_summit = { | |||
527 | .set_apic_id = NULL, | 522 | .set_apic_id = NULL, |
528 | .apic_id_mask = 0xFF << 24, | 523 | .apic_id_mask = 0xFF << 24, |
529 | 524 | ||
530 | .cpu_mask_to_apicid = summit_cpu_mask_to_apicid, | ||
531 | .cpu_mask_to_apicid_and = summit_cpu_mask_to_apicid_and, | 525 | .cpu_mask_to_apicid_and = summit_cpu_mask_to_apicid_and, |
532 | 526 | ||
533 | .send_IPI_mask = summit_send_IPI_mask, | 527 | .send_IPI_mask = summit_send_IPI_mask, |
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index ff35cff0e1a7..c88baa4ff0e5 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c | |||
@@ -81,7 +81,7 @@ static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) | |||
81 | } | 81 | } |
82 | 82 | ||
83 | static void | 83 | static void |
84 | x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) | 84 | x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) |
85 | { | 85 | { |
86 | __x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT); | 86 | __x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT); |
87 | } | 87 | } |
@@ -96,36 +96,37 @@ static void x2apic_send_IPI_all(int vector) | |||
96 | __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); | 96 | __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); |
97 | } | 97 | } |
98 | 98 | ||
99 | static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) | 99 | static int |
100 | x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | ||
101 | const struct cpumask *andmask, | ||
102 | unsigned int *apicid) | ||
100 | { | 103 | { |
101 | /* | 104 | u32 dest = 0; |
102 | * We're using fixed IRQ delivery, can only return one logical APIC ID. | 105 | u16 cluster; |
103 | * May as well be the first. | 106 | int i; |
104 | */ | ||
105 | int cpu = cpumask_first(cpumask); | ||
106 | 107 | ||
107 | if ((unsigned)cpu < nr_cpu_ids) | 108 | for_each_cpu_and(i, cpumask, andmask) { |
108 | return per_cpu(x86_cpu_to_logical_apicid, cpu); | 109 | if (!cpumask_test_cpu(i, cpu_online_mask)) |
109 | else | 110 | continue; |
110 | return BAD_APICID; | 111 | dest = per_cpu(x86_cpu_to_logical_apicid, i); |
111 | } | 112 | cluster = x2apic_cluster(i); |
113 | break; | ||
114 | } | ||
112 | 115 | ||
113 | static unsigned int | 116 | if (!dest) |
114 | x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 117 | return -EINVAL; |
115 | const struct cpumask *andmask) | ||
116 | { | ||
117 | int cpu; | ||
118 | 118 | ||
119 | /* | 119 | for_each_cpu_and(i, cpumask, andmask) { |
120 | * We're using fixed IRQ delivery, can only return one logical APIC ID. | 120 | if (!cpumask_test_cpu(i, cpu_online_mask)) |
121 | * May as well be the first. | 121 | continue; |
122 | */ | 122 | if (cluster != x2apic_cluster(i)) |
123 | for_each_cpu_and(cpu, cpumask, andmask) { | 123 | continue; |
124 | if (cpumask_test_cpu(cpu, cpu_online_mask)) | 124 | dest |= per_cpu(x86_cpu_to_logical_apicid, i); |
125 | break; | ||
126 | } | 125 | } |
127 | 126 | ||
128 | return per_cpu(x86_cpu_to_logical_apicid, cpu); | 127 | *apicid = dest; |
128 | |||
129 | return 0; | ||
129 | } | 130 | } |
130 | 131 | ||
131 | static void init_x2apic_ldr(void) | 132 | static void init_x2apic_ldr(void) |
@@ -208,6 +209,32 @@ static int x2apic_cluster_probe(void) | |||
208 | return 0; | 209 | return 0; |
209 | } | 210 | } |
210 | 211 | ||
212 | static const struct cpumask *x2apic_cluster_target_cpus(void) | ||
213 | { | ||
214 | return cpu_all_mask; | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * Each x2apic cluster is an allocation domain. | ||
219 | */ | ||
220 | static void cluster_vector_allocation_domain(int cpu, struct cpumask *retmask, | ||
221 | const struct cpumask *mask) | ||
222 | { | ||
223 | /* | ||
224 | * To minimize vector pressure, default case of boot, device bringup | ||
225 | * etc will use a single cpu for the interrupt destination. | ||
226 | * | ||
227 | * On explicit migration requests coming from irqbalance etc, | ||
228 | * interrupts will be routed to the x2apic cluster (cluster-id | ||
229 | * derived from the first cpu in the mask) members specified | ||
230 | * in the mask. | ||
231 | */ | ||
232 | if (mask == x2apic_cluster_target_cpus()) | ||
233 | cpumask_copy(retmask, cpumask_of(cpu)); | ||
234 | else | ||
235 | cpumask_and(retmask, mask, per_cpu(cpus_in_cluster, cpu)); | ||
236 | } | ||
237 | |||
211 | static struct apic apic_x2apic_cluster = { | 238 | static struct apic apic_x2apic_cluster = { |
212 | 239 | ||
213 | .name = "cluster x2apic", | 240 | .name = "cluster x2apic", |
@@ -219,13 +246,13 @@ static struct apic apic_x2apic_cluster = { | |||
219 | .irq_delivery_mode = dest_LowestPrio, | 246 | .irq_delivery_mode = dest_LowestPrio, |
220 | .irq_dest_mode = 1, /* logical */ | 247 | .irq_dest_mode = 1, /* logical */ |
221 | 248 | ||
222 | .target_cpus = x2apic_target_cpus, | 249 | .target_cpus = x2apic_cluster_target_cpus, |
223 | .disable_esr = 0, | 250 | .disable_esr = 0, |
224 | .dest_logical = APIC_DEST_LOGICAL, | 251 | .dest_logical = APIC_DEST_LOGICAL, |
225 | .check_apicid_used = NULL, | 252 | .check_apicid_used = NULL, |
226 | .check_apicid_present = NULL, | 253 | .check_apicid_present = NULL, |
227 | 254 | ||
228 | .vector_allocation_domain = x2apic_vector_allocation_domain, | 255 | .vector_allocation_domain = cluster_vector_allocation_domain, |
229 | .init_apic_ldr = init_x2apic_ldr, | 256 | .init_apic_ldr = init_x2apic_ldr, |
230 | 257 | ||
231 | .ioapic_phys_id_map = NULL, | 258 | .ioapic_phys_id_map = NULL, |
@@ -243,7 +270,6 @@ static struct apic apic_x2apic_cluster = { | |||
243 | .set_apic_id = x2apic_set_apic_id, | 270 | .set_apic_id = x2apic_set_apic_id, |
244 | .apic_id_mask = 0xFFFFFFFFu, | 271 | .apic_id_mask = 0xFFFFFFFFu, |
245 | 272 | ||
246 | .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, | ||
247 | .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, | 273 | .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, |
248 | 274 | ||
249 | .send_IPI_mask = x2apic_send_IPI_mask, | 275 | .send_IPI_mask = x2apic_send_IPI_mask, |
diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index c17e982db275..e03a1e180e81 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c | |||
@@ -76,38 +76,6 @@ static void x2apic_send_IPI_all(int vector) | |||
76 | __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); | 76 | __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); |
77 | } | 77 | } |
78 | 78 | ||
79 | static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) | ||
80 | { | ||
81 | /* | ||
82 | * We're using fixed IRQ delivery, can only return one phys APIC ID. | ||
83 | * May as well be the first. | ||
84 | */ | ||
85 | int cpu = cpumask_first(cpumask); | ||
86 | |||
87 | if ((unsigned)cpu < nr_cpu_ids) | ||
88 | return per_cpu(x86_cpu_to_apicid, cpu); | ||
89 | else | ||
90 | return BAD_APICID; | ||
91 | } | ||
92 | |||
93 | static unsigned int | ||
94 | x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | ||
95 | const struct cpumask *andmask) | ||
96 | { | ||
97 | int cpu; | ||
98 | |||
99 | /* | ||
100 | * We're using fixed IRQ delivery, can only return one phys APIC ID. | ||
101 | * May as well be the first. | ||
102 | */ | ||
103 | for_each_cpu_and(cpu, cpumask, andmask) { | ||
104 | if (cpumask_test_cpu(cpu, cpu_online_mask)) | ||
105 | break; | ||
106 | } | ||
107 | |||
108 | return per_cpu(x86_cpu_to_apicid, cpu); | ||
109 | } | ||
110 | |||
111 | static void init_x2apic_ldr(void) | 79 | static void init_x2apic_ldr(void) |
112 | { | 80 | { |
113 | } | 81 | } |
@@ -131,13 +99,13 @@ static struct apic apic_x2apic_phys = { | |||
131 | .irq_delivery_mode = dest_Fixed, | 99 | .irq_delivery_mode = dest_Fixed, |
132 | .irq_dest_mode = 0, /* physical */ | 100 | .irq_dest_mode = 0, /* physical */ |
133 | 101 | ||
134 | .target_cpus = x2apic_target_cpus, | 102 | .target_cpus = online_target_cpus, |
135 | .disable_esr = 0, | 103 | .disable_esr = 0, |
136 | .dest_logical = 0, | 104 | .dest_logical = 0, |
137 | .check_apicid_used = NULL, | 105 | .check_apicid_used = NULL, |
138 | .check_apicid_present = NULL, | 106 | .check_apicid_present = NULL, |
139 | 107 | ||
140 | .vector_allocation_domain = x2apic_vector_allocation_domain, | 108 | .vector_allocation_domain = default_vector_allocation_domain, |
141 | .init_apic_ldr = init_x2apic_ldr, | 109 | .init_apic_ldr = init_x2apic_ldr, |
142 | 110 | ||
143 | .ioapic_phys_id_map = NULL, | 111 | .ioapic_phys_id_map = NULL, |
@@ -155,8 +123,7 @@ static struct apic apic_x2apic_phys = { | |||
155 | .set_apic_id = x2apic_set_apic_id, | 123 | .set_apic_id = x2apic_set_apic_id, |
156 | .apic_id_mask = 0xFFFFFFFFu, | 124 | .apic_id_mask = 0xFFFFFFFFu, |
157 | 125 | ||
158 | .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, | 126 | .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and, |
159 | .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, | ||
160 | 127 | ||
161 | .send_IPI_mask = x2apic_send_IPI_mask, | 128 | .send_IPI_mask = x2apic_send_IPI_mask, |
162 | .send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself, | 129 | .send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself, |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index c6d03f7a4401..8cfade9510a4 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -185,17 +185,6 @@ EXPORT_SYMBOL_GPL(uv_possible_blades); | |||
185 | unsigned long sn_rtc_cycles_per_second; | 185 | unsigned long sn_rtc_cycles_per_second; |
186 | EXPORT_SYMBOL(sn_rtc_cycles_per_second); | 186 | EXPORT_SYMBOL(sn_rtc_cycles_per_second); |
187 | 187 | ||
188 | static const struct cpumask *uv_target_cpus(void) | ||
189 | { | ||
190 | return cpu_online_mask; | ||
191 | } | ||
192 | |||
193 | static void uv_vector_allocation_domain(int cpu, struct cpumask *retmask) | ||
194 | { | ||
195 | cpumask_clear(retmask); | ||
196 | cpumask_set_cpu(cpu, retmask); | ||
197 | } | ||
198 | |||
199 | static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) | 188 | static int __cpuinit uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) |
200 | { | 189 | { |
201 | #ifdef CONFIG_SMP | 190 | #ifdef CONFIG_SMP |
@@ -280,25 +269,12 @@ static void uv_init_apic_ldr(void) | |||
280 | { | 269 | { |
281 | } | 270 | } |
282 | 271 | ||
283 | static unsigned int uv_cpu_mask_to_apicid(const struct cpumask *cpumask) | 272 | static int |
284 | { | ||
285 | /* | ||
286 | * We're using fixed IRQ delivery, can only return one phys APIC ID. | ||
287 | * May as well be the first. | ||
288 | */ | ||
289 | int cpu = cpumask_first(cpumask); | ||
290 | |||
291 | if ((unsigned)cpu < nr_cpu_ids) | ||
292 | return per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; | ||
293 | else | ||
294 | return BAD_APICID; | ||
295 | } | ||
296 | |||
297 | static unsigned int | ||
298 | uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | 273 | uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, |
299 | const struct cpumask *andmask) | 274 | const struct cpumask *andmask, |
275 | unsigned int *apicid) | ||
300 | { | 276 | { |
301 | int cpu; | 277 | int unsigned cpu; |
302 | 278 | ||
303 | /* | 279 | /* |
304 | * We're using fixed IRQ delivery, can only return one phys APIC ID. | 280 | * We're using fixed IRQ delivery, can only return one phys APIC ID. |
@@ -308,7 +284,13 @@ uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask, | |||
308 | if (cpumask_test_cpu(cpu, cpu_online_mask)) | 284 | if (cpumask_test_cpu(cpu, cpu_online_mask)) |
309 | break; | 285 | break; |
310 | } | 286 | } |
311 | return per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; | 287 | |
288 | if (likely(cpu < nr_cpu_ids)) { | ||
289 | *apicid = per_cpu(x86_cpu_to_apicid, cpu) | uv_apicid_hibits; | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | return -EINVAL; | ||
312 | } | 294 | } |
313 | 295 | ||
314 | static unsigned int x2apic_get_apic_id(unsigned long x) | 296 | static unsigned int x2apic_get_apic_id(unsigned long x) |
@@ -362,13 +344,13 @@ static struct apic __refdata apic_x2apic_uv_x = { | |||
362 | .irq_delivery_mode = dest_Fixed, | 344 | .irq_delivery_mode = dest_Fixed, |
363 | .irq_dest_mode = 0, /* physical */ | 345 | .irq_dest_mode = 0, /* physical */ |
364 | 346 | ||
365 | .target_cpus = uv_target_cpus, | 347 | .target_cpus = online_target_cpus, |
366 | .disable_esr = 0, | 348 | .disable_esr = 0, |
367 | .dest_logical = APIC_DEST_LOGICAL, | 349 | .dest_logical = APIC_DEST_LOGICAL, |
368 | .check_apicid_used = NULL, | 350 | .check_apicid_used = NULL, |
369 | .check_apicid_present = NULL, | 351 | .check_apicid_present = NULL, |
370 | 352 | ||
371 | .vector_allocation_domain = uv_vector_allocation_domain, | 353 | .vector_allocation_domain = default_vector_allocation_domain, |
372 | .init_apic_ldr = uv_init_apic_ldr, | 354 | .init_apic_ldr = uv_init_apic_ldr, |
373 | 355 | ||
374 | .ioapic_phys_id_map = NULL, | 356 | .ioapic_phys_id_map = NULL, |
@@ -386,7 +368,6 @@ static struct apic __refdata apic_x2apic_uv_x = { | |||
386 | .set_apic_id = set_apic_id, | 368 | .set_apic_id = set_apic_id, |
387 | .apic_id_mask = 0xFFFFFFFFu, | 369 | .apic_id_mask = 0xFFFFFFFFu, |
388 | 370 | ||
389 | .cpu_mask_to_apicid = uv_cpu_mask_to_apicid, | ||
390 | .cpu_mask_to_apicid_and = uv_cpu_mask_to_apicid_and, | 371 | .cpu_mask_to_apicid_and = uv_cpu_mask_to_apicid_and, |
391 | 372 | ||
392 | .send_IPI_mask = uv_send_IPI_mask, | 373 | .send_IPI_mask = uv_send_IPI_mask, |
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 07b0c0db466c..d65464e43503 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c | |||
@@ -201,6 +201,8 @@ | |||
201 | * http://www.microsoft.com/whdc/archive/amp_12.mspx] | 201 | * http://www.microsoft.com/whdc/archive/amp_12.mspx] |
202 | */ | 202 | */ |
203 | 203 | ||
204 | #define pr_fmt(fmt) "apm: " fmt | ||
205 | |||
204 | #include <linux/module.h> | 206 | #include <linux/module.h> |
205 | 207 | ||
206 | #include <linux/poll.h> | 208 | #include <linux/poll.h> |
@@ -485,11 +487,11 @@ static void apm_error(char *str, int err) | |||
485 | if (error_table[i].key == err) | 487 | if (error_table[i].key == err) |
486 | break; | 488 | break; |
487 | if (i < ERROR_COUNT) | 489 | if (i < ERROR_COUNT) |
488 | printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg); | 490 | pr_notice("%s: %s\n", str, error_table[i].msg); |
489 | else if (err < 0) | 491 | else if (err < 0) |
490 | printk(KERN_NOTICE "apm: %s: linux error code %i\n", str, err); | 492 | pr_notice("%s: linux error code %i\n", str, err); |
491 | else | 493 | else |
492 | printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n", | 494 | pr_notice("%s: unknown error code %#2.2x\n", |
493 | str, err); | 495 | str, err); |
494 | } | 496 | } |
495 | 497 | ||
@@ -1184,7 +1186,7 @@ static void queue_event(apm_event_t event, struct apm_user *sender) | |||
1184 | static int notified; | 1186 | static int notified; |
1185 | 1187 | ||
1186 | if (notified++ == 0) | 1188 | if (notified++ == 0) |
1187 | printk(KERN_ERR "apm: an event queue overflowed\n"); | 1189 | pr_err("an event queue overflowed\n"); |
1188 | if (++as->event_tail >= APM_MAX_EVENTS) | 1190 | if (++as->event_tail >= APM_MAX_EVENTS) |
1189 | as->event_tail = 0; | 1191 | as->event_tail = 0; |
1190 | } | 1192 | } |
@@ -1447,7 +1449,7 @@ static void apm_mainloop(void) | |||
1447 | static int check_apm_user(struct apm_user *as, const char *func) | 1449 | static int check_apm_user(struct apm_user *as, const char *func) |
1448 | { | 1450 | { |
1449 | if (as == NULL || as->magic != APM_BIOS_MAGIC) { | 1451 | if (as == NULL || as->magic != APM_BIOS_MAGIC) { |
1450 | printk(KERN_ERR "apm: %s passed bad filp\n", func); | 1452 | pr_err("%s passed bad filp\n", func); |
1451 | return 1; | 1453 | return 1; |
1452 | } | 1454 | } |
1453 | return 0; | 1455 | return 0; |
@@ -1586,7 +1588,7 @@ static int do_release(struct inode *inode, struct file *filp) | |||
1586 | as1 = as1->next) | 1588 | as1 = as1->next) |
1587 | ; | 1589 | ; |
1588 | if (as1 == NULL) | 1590 | if (as1 == NULL) |
1589 | printk(KERN_ERR "apm: filp not in user list\n"); | 1591 | pr_err("filp not in user list\n"); |
1590 | else | 1592 | else |
1591 | as1->next = as->next; | 1593 | as1->next = as->next; |
1592 | } | 1594 | } |
@@ -1600,11 +1602,9 @@ static int do_open(struct inode *inode, struct file *filp) | |||
1600 | struct apm_user *as; | 1602 | struct apm_user *as; |
1601 | 1603 | ||
1602 | as = kmalloc(sizeof(*as), GFP_KERNEL); | 1604 | as = kmalloc(sizeof(*as), GFP_KERNEL); |
1603 | if (as == NULL) { | 1605 | if (as == NULL) |
1604 | printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n", | ||
1605 | sizeof(*as)); | ||
1606 | return -ENOMEM; | 1606 | return -ENOMEM; |
1607 | } | 1607 | |
1608 | as->magic = APM_BIOS_MAGIC; | 1608 | as->magic = APM_BIOS_MAGIC; |
1609 | as->event_tail = as->event_head = 0; | 1609 | as->event_tail = as->event_head = 0; |
1610 | as->suspends_pending = as->standbys_pending = 0; | 1610 | as->suspends_pending = as->standbys_pending = 0; |
@@ -2313,16 +2313,16 @@ static int __init apm_init(void) | |||
2313 | } | 2313 | } |
2314 | 2314 | ||
2315 | if (apm_info.disabled) { | 2315 | if (apm_info.disabled) { |
2316 | printk(KERN_NOTICE "apm: disabled on user request.\n"); | 2316 | pr_notice("disabled on user request.\n"); |
2317 | return -ENODEV; | 2317 | return -ENODEV; |
2318 | } | 2318 | } |
2319 | if ((num_online_cpus() > 1) && !power_off && !smp) { | 2319 | if ((num_online_cpus() > 1) && !power_off && !smp) { |
2320 | printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n"); | 2320 | pr_notice("disabled - APM is not SMP safe.\n"); |
2321 | apm_info.disabled = 1; | 2321 | apm_info.disabled = 1; |
2322 | return -ENODEV; | 2322 | return -ENODEV; |
2323 | } | 2323 | } |
2324 | if (!acpi_disabled) { | 2324 | if (!acpi_disabled) { |
2325 | printk(KERN_NOTICE "apm: overridden by ACPI.\n"); | 2325 | pr_notice("overridden by ACPI.\n"); |
2326 | apm_info.disabled = 1; | 2326 | apm_info.disabled = 1; |
2327 | return -ENODEV; | 2327 | return -ENODEV; |
2328 | } | 2328 | } |
@@ -2356,8 +2356,7 @@ static int __init apm_init(void) | |||
2356 | 2356 | ||
2357 | kapmd_task = kthread_create(apm, NULL, "kapmd"); | 2357 | kapmd_task = kthread_create(apm, NULL, "kapmd"); |
2358 | if (IS_ERR(kapmd_task)) { | 2358 | if (IS_ERR(kapmd_task)) { |
2359 | printk(KERN_ERR "apm: disabled - Unable to start kernel " | 2359 | pr_err("disabled - Unable to start kernel thread\n"); |
2360 | "thread.\n"); | ||
2361 | err = PTR_ERR(kapmd_task); | 2360 | err = PTR_ERR(kapmd_task); |
2362 | kapmd_task = NULL; | 2361 | kapmd_task = NULL; |
2363 | remove_proc_entry("apm", NULL); | 2362 | remove_proc_entry("apm", NULL); |
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 6ab6aa2fdfdd..bac4c3804cc7 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
@@ -32,7 +32,9 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o | |||
32 | 32 | ||
33 | ifdef CONFIG_PERF_EVENTS | 33 | ifdef CONFIG_PERF_EVENTS |
34 | obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o | 34 | obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o |
35 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_p4.o perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o | 35 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_p4.o |
36 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o | ||
37 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o | ||
36 | endif | 38 | endif |
37 | 39 | ||
38 | obj-$(CONFIG_X86_MCE) += mcheck/ | 40 | obj-$(CONFIG_X86_MCE) += mcheck/ |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 146bb6218eec..9d92e19039f0 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -19,6 +19,39 @@ | |||
19 | 19 | ||
20 | #include "cpu.h" | 20 | #include "cpu.h" |
21 | 21 | ||
22 | static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) | ||
23 | { | ||
24 | struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); | ||
25 | u32 gprs[8] = { 0 }; | ||
26 | int err; | ||
27 | |||
28 | WARN_ONCE((c->x86 != 0xf), "%s should only be used on K8!\n", __func__); | ||
29 | |||
30 | gprs[1] = msr; | ||
31 | gprs[7] = 0x9c5a203a; | ||
32 | |||
33 | err = rdmsr_safe_regs(gprs); | ||
34 | |||
35 | *p = gprs[0] | ((u64)gprs[2] << 32); | ||
36 | |||
37 | return err; | ||
38 | } | ||
39 | |||
40 | static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) | ||
41 | { | ||
42 | struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); | ||
43 | u32 gprs[8] = { 0 }; | ||
44 | |||
45 | WARN_ONCE((c->x86 != 0xf), "%s should only be used on K8!\n", __func__); | ||
46 | |||
47 | gprs[0] = (u32)val; | ||
48 | gprs[1] = msr; | ||
49 | gprs[2] = val >> 32; | ||
50 | gprs[7] = 0x9c5a203a; | ||
51 | |||
52 | return wrmsr_safe_regs(gprs); | ||
53 | } | ||
54 | |||
22 | #ifdef CONFIG_X86_32 | 55 | #ifdef CONFIG_X86_32 |
23 | /* | 56 | /* |
24 | * B step AMD K6 before B 9730xxxx have hardware bugs that can cause | 57 | * B step AMD K6 before B 9730xxxx have hardware bugs that can cause |
@@ -586,9 +619,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
586 | !cpu_has(c, X86_FEATURE_TOPOEXT)) { | 619 | !cpu_has(c, X86_FEATURE_TOPOEXT)) { |
587 | u64 val; | 620 | u64 val; |
588 | 621 | ||
589 | if (!rdmsrl_amd_safe(0xc0011005, &val)) { | 622 | if (!rdmsrl_safe(0xc0011005, &val)) { |
590 | val |= 1ULL << 54; | 623 | val |= 1ULL << 54; |
591 | wrmsrl_amd_safe(0xc0011005, val); | 624 | wrmsrl_safe(0xc0011005, val); |
592 | rdmsrl(0xc0011005, val); | 625 | rdmsrl(0xc0011005, val); |
593 | if (val & (1ULL << 54)) { | 626 | if (val & (1ULL << 54)) { |
594 | set_cpu_cap(c, X86_FEATURE_TOPOEXT); | 627 | set_cpu_cap(c, X86_FEATURE_TOPOEXT); |
@@ -679,7 +712,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
679 | err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask); | 712 | err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask); |
680 | if (err == 0) { | 713 | if (err == 0) { |
681 | mask |= (1 << 10); | 714 | mask |= (1 << 10); |
682 | checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask); | 715 | wrmsrl_safe(MSR_AMD64_MCx_MASK(4), mask); |
683 | } | 716 | } |
684 | } | 717 | } |
685 | 718 | ||
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 46674fbb62ba..c97bb7b5a9f8 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
@@ -55,8 +55,8 @@ static void __init check_fpu(void) | |||
55 | 55 | ||
56 | if (!boot_cpu_data.hard_math) { | 56 | if (!boot_cpu_data.hard_math) { |
57 | #ifndef CONFIG_MATH_EMULATION | 57 | #ifndef CONFIG_MATH_EMULATION |
58 | printk(KERN_EMERG "No coprocessor found and no math emulation present.\n"); | 58 | pr_emerg("No coprocessor found and no math emulation present\n"); |
59 | printk(KERN_EMERG "Giving up.\n"); | 59 | pr_emerg("Giving up\n"); |
60 | for (;;) ; | 60 | for (;;) ; |
61 | #endif | 61 | #endif |
62 | return; | 62 | return; |
@@ -86,7 +86,7 @@ static void __init check_fpu(void) | |||
86 | 86 | ||
87 | boot_cpu_data.fdiv_bug = fdiv_bug; | 87 | boot_cpu_data.fdiv_bug = fdiv_bug; |
88 | if (boot_cpu_data.fdiv_bug) | 88 | if (boot_cpu_data.fdiv_bug) |
89 | printk(KERN_WARNING "Hmm, FPU with FDIV bug.\n"); | 89 | pr_warn("Hmm, FPU with FDIV bug\n"); |
90 | } | 90 | } |
91 | 91 | ||
92 | static void __init check_hlt(void) | 92 | static void __init check_hlt(void) |
@@ -94,16 +94,16 @@ static void __init check_hlt(void) | |||
94 | if (boot_cpu_data.x86 >= 5 || paravirt_enabled()) | 94 | if (boot_cpu_data.x86 >= 5 || paravirt_enabled()) |
95 | return; | 95 | return; |
96 | 96 | ||
97 | printk(KERN_INFO "Checking 'hlt' instruction... "); | 97 | pr_info("Checking 'hlt' instruction... "); |
98 | if (!boot_cpu_data.hlt_works_ok) { | 98 | if (!boot_cpu_data.hlt_works_ok) { |
99 | printk("disabled\n"); | 99 | pr_cont("disabled\n"); |
100 | return; | 100 | return; |
101 | } | 101 | } |
102 | halt(); | 102 | halt(); |
103 | halt(); | 103 | halt(); |
104 | halt(); | 104 | halt(); |
105 | halt(); | 105 | halt(); |
106 | printk(KERN_CONT "OK.\n"); | 106 | pr_cont("OK\n"); |
107 | } | 107 | } |
108 | 108 | ||
109 | /* | 109 | /* |
@@ -116,7 +116,7 @@ static void __init check_popad(void) | |||
116 | #ifndef CONFIG_X86_POPAD_OK | 116 | #ifndef CONFIG_X86_POPAD_OK |
117 | int res, inp = (int) &res; | 117 | int res, inp = (int) &res; |
118 | 118 | ||
119 | printk(KERN_INFO "Checking for popad bug... "); | 119 | pr_info("Checking for popad bug... "); |
120 | __asm__ __volatile__( | 120 | __asm__ __volatile__( |
121 | "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx " | 121 | "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx " |
122 | : "=&a" (res) | 122 | : "=&a" (res) |
@@ -127,9 +127,9 @@ static void __init check_popad(void) | |||
127 | * CPU hard. Too bad. | 127 | * CPU hard. Too bad. |
128 | */ | 128 | */ |
129 | if (res != 12345678) | 129 | if (res != 12345678) |
130 | printk(KERN_CONT "Buggy.\n"); | 130 | pr_cont("Buggy\n"); |
131 | else | 131 | else |
132 | printk(KERN_CONT "OK.\n"); | 132 | pr_cont("OK\n"); |
133 | #endif | 133 | #endif |
134 | } | 134 | } |
135 | 135 | ||
@@ -161,7 +161,7 @@ void __init check_bugs(void) | |||
161 | { | 161 | { |
162 | identify_boot_cpu(); | 162 | identify_boot_cpu(); |
163 | #ifndef CONFIG_SMP | 163 | #ifndef CONFIG_SMP |
164 | printk(KERN_INFO "CPU: "); | 164 | pr_info("CPU: "); |
165 | print_cpu_info(&boot_cpu_data); | 165 | print_cpu_info(&boot_cpu_data); |
166 | #endif | 166 | #endif |
167 | check_config(); | 167 | check_config(); |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 6b9333b429ba..5bbc082c47ad 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -947,7 +947,7 @@ static void __cpuinit __print_cpu_msr(void) | |||
947 | index_max = msr_range_array[i].max; | 947 | index_max = msr_range_array[i].max; |
948 | 948 | ||
949 | for (index = index_min; index < index_max; index++) { | 949 | for (index = index_min; index < index_max; index++) { |
950 | if (rdmsrl_amd_safe(index, &val)) | 950 | if (rdmsrl_safe(index, &val)) |
951 | continue; | 951 | continue; |
952 | printk(KERN_INFO " MSR%08x: %016llx\n", index, val); | 952 | printk(KERN_INFO " MSR%08x: %016llx\n", index, val); |
953 | } | 953 | } |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index da27c5d2168a..5a5a5dc1ff15 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -7,6 +7,9 @@ | |||
7 | * Copyright 2008 Intel Corporation | 7 | * Copyright 2008 Intel Corporation |
8 | * Author: Andi Kleen | 8 | * Author: Andi Kleen |
9 | */ | 9 | */ |
10 | |||
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
12 | |||
10 | #include <linux/thread_info.h> | 13 | #include <linux/thread_info.h> |
11 | #include <linux/capability.h> | 14 | #include <linux/capability.h> |
12 | #include <linux/miscdevice.h> | 15 | #include <linux/miscdevice.h> |
@@ -210,7 +213,7 @@ static void drain_mcelog_buffer(void) | |||
210 | cpu_relax(); | 213 | cpu_relax(); |
211 | 214 | ||
212 | if (!m->finished && retries >= 4) { | 215 | if (!m->finished && retries >= 4) { |
213 | pr_err("MCE: skipping error being logged currently!\n"); | 216 | pr_err("skipping error being logged currently!\n"); |
214 | break; | 217 | break; |
215 | } | 218 | } |
216 | } | 219 | } |
@@ -1167,8 +1170,9 @@ int memory_failure(unsigned long pfn, int vector, int flags) | |||
1167 | { | 1170 | { |
1168 | /* mce_severity() should not hand us an ACTION_REQUIRED error */ | 1171 | /* mce_severity() should not hand us an ACTION_REQUIRED error */ |
1169 | BUG_ON(flags & MF_ACTION_REQUIRED); | 1172 | BUG_ON(flags & MF_ACTION_REQUIRED); |
1170 | printk(KERN_ERR "Uncorrected memory error in page 0x%lx ignored\n" | 1173 | pr_err("Uncorrected memory error in page 0x%lx ignored\n" |
1171 | "Rebuild kernel with CONFIG_MEMORY_FAILURE=y for smarter handling\n", pfn); | 1174 | "Rebuild kernel with CONFIG_MEMORY_FAILURE=y for smarter handling\n", |
1175 | pfn); | ||
1172 | 1176 | ||
1173 | return 0; | 1177 | return 0; |
1174 | } | 1178 | } |
@@ -1358,11 +1362,10 @@ static int __cpuinit __mcheck_cpu_cap_init(void) | |||
1358 | 1362 | ||
1359 | b = cap & MCG_BANKCNT_MASK; | 1363 | b = cap & MCG_BANKCNT_MASK; |
1360 | if (!banks) | 1364 | if (!banks) |
1361 | printk(KERN_INFO "mce: CPU supports %d MCE banks\n", b); | 1365 | pr_info("CPU supports %d MCE banks\n", b); |
1362 | 1366 | ||
1363 | if (b > MAX_NR_BANKS) { | 1367 | if (b > MAX_NR_BANKS) { |
1364 | printk(KERN_WARNING | 1368 | pr_warn("Using only %u machine check banks out of %u\n", |
1365 | "MCE: Using only %u machine check banks out of %u\n", | ||
1366 | MAX_NR_BANKS, b); | 1369 | MAX_NR_BANKS, b); |
1367 | b = MAX_NR_BANKS; | 1370 | b = MAX_NR_BANKS; |
1368 | } | 1371 | } |
@@ -1419,7 +1422,7 @@ static void __mcheck_cpu_init_generic(void) | |||
1419 | static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) | 1422 | static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) |
1420 | { | 1423 | { |
1421 | if (c->x86_vendor == X86_VENDOR_UNKNOWN) { | 1424 | if (c->x86_vendor == X86_VENDOR_UNKNOWN) { |
1422 | pr_info("MCE: unknown CPU type - not enabling MCE support.\n"); | 1425 | pr_info("unknown CPU type - not enabling MCE support\n"); |
1423 | return -EOPNOTSUPP; | 1426 | return -EOPNOTSUPP; |
1424 | } | 1427 | } |
1425 | 1428 | ||
@@ -1574,7 +1577,7 @@ static void __mcheck_cpu_init_timer(void) | |||
1574 | /* Handle unconfigured int18 (should never happen) */ | 1577 | /* Handle unconfigured int18 (should never happen) */ |
1575 | static void unexpected_machine_check(struct pt_regs *regs, long error_code) | 1578 | static void unexpected_machine_check(struct pt_regs *regs, long error_code) |
1576 | { | 1579 | { |
1577 | printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", | 1580 | pr_err("CPU#%d: Unexpected int18 (Machine Check)\n", |
1578 | smp_processor_id()); | 1581 | smp_processor_id()); |
1579 | } | 1582 | } |
1580 | 1583 | ||
@@ -1893,8 +1896,7 @@ static int __init mcheck_enable(char *str) | |||
1893 | get_option(&str, &monarch_timeout); | 1896 | get_option(&str, &monarch_timeout); |
1894 | } | 1897 | } |
1895 | } else { | 1898 | } else { |
1896 | printk(KERN_INFO "mce argument %s ignored. Please use /sys\n", | 1899 | pr_info("mce argument %s ignored. Please use /sys\n", str); |
1897 | str); | ||
1898 | return 0; | 1900 | return 0; |
1899 | } | 1901 | } |
1900 | return 1; | 1902 | return 1; |
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c index bdda2e6c673b..35ffda5d0727 100644 --- a/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c | |||
@@ -258,11 +258,11 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk, | |||
258 | 258 | ||
259 | /* Compute the maximum size with which we can make a range: */ | 259 | /* Compute the maximum size with which we can make a range: */ |
260 | if (range_startk) | 260 | if (range_startk) |
261 | max_align = ffs(range_startk) - 1; | 261 | max_align = __ffs(range_startk); |
262 | else | 262 | else |
263 | max_align = 32; | 263 | max_align = BITS_PER_LONG - 1; |
264 | 264 | ||
265 | align = fls(range_sizek) - 1; | 265 | align = __fls(range_sizek); |
266 | if (align > max_align) | 266 | if (align > max_align) |
267 | align = max_align; | 267 | align = max_align; |
268 | 268 | ||
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 75772ae6c65f..e9fe907cd249 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c | |||
@@ -361,11 +361,7 @@ static void __init print_mtrr_state(void) | |||
361 | } | 361 | } |
362 | pr_debug("MTRR variable ranges %sabled:\n", | 362 | pr_debug("MTRR variable ranges %sabled:\n", |
363 | mtrr_state.enabled & 2 ? "en" : "dis"); | 363 | mtrr_state.enabled & 2 ? "en" : "dis"); |
364 | if (size_or_mask & 0xffffffffUL) | 364 | high_width = (__ffs64(size_or_mask) - (32 - PAGE_SHIFT) + 3) / 4; |
365 | high_width = ffs(size_or_mask & 0xffffffffUL) - 1; | ||
366 | else | ||
367 | high_width = ffs(size_or_mask>>32) + 32 - 1; | ||
368 | high_width = (high_width - (32 - PAGE_SHIFT) + 3) / 4; | ||
369 | 365 | ||
370 | for (i = 0; i < num_var_ranges; ++i) { | 366 | for (i = 0; i < num_var_ranges; ++i) { |
371 | if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) | 367 | if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index c4706cf9c011..29557aa06dda 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -35,17 +35,6 @@ | |||
35 | 35 | ||
36 | #include "perf_event.h" | 36 | #include "perf_event.h" |
37 | 37 | ||
38 | #if 0 | ||
39 | #undef wrmsrl | ||
40 | #define wrmsrl(msr, val) \ | ||
41 | do { \ | ||
42 | trace_printk("wrmsrl(%lx, %lx)\n", (unsigned long)(msr),\ | ||
43 | (unsigned long)(val)); \ | ||
44 | native_write_msr((msr), (u32)((u64)(val)), \ | ||
45 | (u32)((u64)(val) >> 32)); \ | ||
46 | } while (0) | ||
47 | #endif | ||
48 | |||
49 | struct x86_pmu x86_pmu __read_mostly; | 38 | struct x86_pmu x86_pmu __read_mostly; |
50 | 39 | ||
51 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { | 40 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { |
@@ -74,7 +63,7 @@ u64 x86_perf_event_update(struct perf_event *event) | |||
74 | int idx = hwc->idx; | 63 | int idx = hwc->idx; |
75 | s64 delta; | 64 | s64 delta; |
76 | 65 | ||
77 | if (idx == X86_PMC_IDX_FIXED_BTS) | 66 | if (idx == INTEL_PMC_IDX_FIXED_BTS) |
78 | return 0; | 67 | return 0; |
79 | 68 | ||
80 | /* | 69 | /* |
@@ -86,7 +75,7 @@ u64 x86_perf_event_update(struct perf_event *event) | |||
86 | */ | 75 | */ |
87 | again: | 76 | again: |
88 | prev_raw_count = local64_read(&hwc->prev_count); | 77 | prev_raw_count = local64_read(&hwc->prev_count); |
89 | rdmsrl(hwc->event_base, new_raw_count); | 78 | rdpmcl(hwc->event_base_rdpmc, new_raw_count); |
90 | 79 | ||
91 | if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, | 80 | if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, |
92 | new_raw_count) != prev_raw_count) | 81 | new_raw_count) != prev_raw_count) |
@@ -189,7 +178,7 @@ static void release_pmc_hardware(void) {} | |||
189 | 178 | ||
190 | static bool check_hw_exists(void) | 179 | static bool check_hw_exists(void) |
191 | { | 180 | { |
192 | u64 val, val_new = 0; | 181 | u64 val, val_new = ~0; |
193 | int i, reg, ret = 0; | 182 | int i, reg, ret = 0; |
194 | 183 | ||
195 | /* | 184 | /* |
@@ -222,8 +211,9 @@ static bool check_hw_exists(void) | |||
222 | * that don't trap on the MSR access and always return 0s. | 211 | * that don't trap on the MSR access and always return 0s. |
223 | */ | 212 | */ |
224 | val = 0xabcdUL; | 213 | val = 0xabcdUL; |
225 | ret = checking_wrmsrl(x86_pmu_event_addr(0), val); | 214 | reg = x86_pmu_event_addr(0); |
226 | ret |= rdmsrl_safe(x86_pmu_event_addr(0), &val_new); | 215 | ret = wrmsrl_safe(reg, val); |
216 | ret |= rdmsrl_safe(reg, &val_new); | ||
227 | if (ret || val != val_new) | 217 | if (ret || val != val_new) |
228 | goto msr_fail; | 218 | goto msr_fail; |
229 | 219 | ||
@@ -240,6 +230,7 @@ bios_fail: | |||
240 | 230 | ||
241 | msr_fail: | 231 | msr_fail: |
242 | printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n"); | 232 | printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n"); |
233 | printk(KERN_ERR "Failed to access perfctr msr (MSR %x is %Lx)\n", reg, val_new); | ||
243 | 234 | ||
244 | return false; | 235 | return false; |
245 | } | 236 | } |
@@ -388,7 +379,7 @@ int x86_pmu_hw_config(struct perf_event *event) | |||
388 | int precise = 0; | 379 | int precise = 0; |
389 | 380 | ||
390 | /* Support for constant skid */ | 381 | /* Support for constant skid */ |
391 | if (x86_pmu.pebs_active) { | 382 | if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) { |
392 | precise++; | 383 | precise++; |
393 | 384 | ||
394 | /* Support for IP fixup */ | 385 | /* Support for IP fixup */ |
@@ -637,8 +628,8 @@ static bool __perf_sched_find_counter(struct perf_sched *sched) | |||
637 | c = sched->constraints[sched->state.event]; | 628 | c = sched->constraints[sched->state.event]; |
638 | 629 | ||
639 | /* Prefer fixed purpose counters */ | 630 | /* Prefer fixed purpose counters */ |
640 | if (x86_pmu.num_counters_fixed) { | 631 | if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) { |
641 | idx = X86_PMC_IDX_FIXED; | 632 | idx = INTEL_PMC_IDX_FIXED; |
642 | for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) { | 633 | for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) { |
643 | if (!__test_and_set_bit(idx, sched->state.used)) | 634 | if (!__test_and_set_bit(idx, sched->state.used)) |
644 | goto done; | 635 | goto done; |
@@ -646,7 +637,7 @@ static bool __perf_sched_find_counter(struct perf_sched *sched) | |||
646 | } | 637 | } |
647 | /* Grab the first unused counter starting with idx */ | 638 | /* Grab the first unused counter starting with idx */ |
648 | idx = sched->state.counter; | 639 | idx = sched->state.counter; |
649 | for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_FIXED) { | 640 | for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) { |
650 | if (!__test_and_set_bit(idx, sched->state.used)) | 641 | if (!__test_and_set_bit(idx, sched->state.used)) |
651 | goto done; | 642 | goto done; |
652 | } | 643 | } |
@@ -704,8 +695,8 @@ static bool perf_sched_next_event(struct perf_sched *sched) | |||
704 | /* | 695 | /* |
705 | * Assign a counter for each event. | 696 | * Assign a counter for each event. |
706 | */ | 697 | */ |
707 | static int perf_assign_events(struct event_constraint **constraints, int n, | 698 | int perf_assign_events(struct event_constraint **constraints, int n, |
708 | int wmin, int wmax, int *assign) | 699 | int wmin, int wmax, int *assign) |
709 | { | 700 | { |
710 | struct perf_sched sched; | 701 | struct perf_sched sched; |
711 | 702 | ||
@@ -824,15 +815,17 @@ static inline void x86_assign_hw_event(struct perf_event *event, | |||
824 | hwc->last_cpu = smp_processor_id(); | 815 | hwc->last_cpu = smp_processor_id(); |
825 | hwc->last_tag = ++cpuc->tags[i]; | 816 | hwc->last_tag = ++cpuc->tags[i]; |
826 | 817 | ||
827 | if (hwc->idx == X86_PMC_IDX_FIXED_BTS) { | 818 | if (hwc->idx == INTEL_PMC_IDX_FIXED_BTS) { |
828 | hwc->config_base = 0; | 819 | hwc->config_base = 0; |
829 | hwc->event_base = 0; | 820 | hwc->event_base = 0; |
830 | } else if (hwc->idx >= X86_PMC_IDX_FIXED) { | 821 | } else if (hwc->idx >= INTEL_PMC_IDX_FIXED) { |
831 | hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; | 822 | hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; |
832 | hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - X86_PMC_IDX_FIXED); | 823 | hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - INTEL_PMC_IDX_FIXED); |
824 | hwc->event_base_rdpmc = (hwc->idx - INTEL_PMC_IDX_FIXED) | 1<<30; | ||
833 | } else { | 825 | } else { |
834 | hwc->config_base = x86_pmu_config_addr(hwc->idx); | 826 | hwc->config_base = x86_pmu_config_addr(hwc->idx); |
835 | hwc->event_base = x86_pmu_event_addr(hwc->idx); | 827 | hwc->event_base = x86_pmu_event_addr(hwc->idx); |
828 | hwc->event_base_rdpmc = hwc->idx; | ||
836 | } | 829 | } |
837 | } | 830 | } |
838 | 831 | ||
@@ -930,7 +923,7 @@ int x86_perf_event_set_period(struct perf_event *event) | |||
930 | s64 period = hwc->sample_period; | 923 | s64 period = hwc->sample_period; |
931 | int ret = 0, idx = hwc->idx; | 924 | int ret = 0, idx = hwc->idx; |
932 | 925 | ||
933 | if (idx == X86_PMC_IDX_FIXED_BTS) | 926 | if (idx == INTEL_PMC_IDX_FIXED_BTS) |
934 | return 0; | 927 | return 0; |
935 | 928 | ||
936 | /* | 929 | /* |
@@ -1316,7 +1309,6 @@ static struct attribute_group x86_pmu_format_group = { | |||
1316 | static int __init init_hw_perf_events(void) | 1309 | static int __init init_hw_perf_events(void) |
1317 | { | 1310 | { |
1318 | struct x86_pmu_quirk *quirk; | 1311 | struct x86_pmu_quirk *quirk; |
1319 | struct event_constraint *c; | ||
1320 | int err; | 1312 | int err; |
1321 | 1313 | ||
1322 | pr_info("Performance Events: "); | 1314 | pr_info("Performance Events: "); |
@@ -1347,21 +1339,8 @@ static int __init init_hw_perf_events(void) | |||
1347 | for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next) | 1339 | for (quirk = x86_pmu.quirks; quirk; quirk = quirk->next) |
1348 | quirk->func(); | 1340 | quirk->func(); |
1349 | 1341 | ||
1350 | if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) { | 1342 | if (!x86_pmu.intel_ctrl) |
1351 | WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!", | 1343 | x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1; |
1352 | x86_pmu.num_counters, X86_PMC_MAX_GENERIC); | ||
1353 | x86_pmu.num_counters = X86_PMC_MAX_GENERIC; | ||
1354 | } | ||
1355 | x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1; | ||
1356 | |||
1357 | if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) { | ||
1358 | WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!", | ||
1359 | x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED); | ||
1360 | x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED; | ||
1361 | } | ||
1362 | |||
1363 | x86_pmu.intel_ctrl |= | ||
1364 | ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED; | ||
1365 | 1344 | ||
1366 | perf_events_lapic_init(); | 1345 | perf_events_lapic_init(); |
1367 | register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI"); | 1346 | register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI"); |
@@ -1370,22 +1349,6 @@ static int __init init_hw_perf_events(void) | |||
1370 | __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1, | 1349 | __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1, |
1371 | 0, x86_pmu.num_counters, 0); | 1350 | 0, x86_pmu.num_counters, 0); |
1372 | 1351 | ||
1373 | if (x86_pmu.event_constraints) { | ||
1374 | /* | ||
1375 | * event on fixed counter2 (REF_CYCLES) only works on this | ||
1376 | * counter, so do not extend mask to generic counters | ||
1377 | */ | ||
1378 | for_each_event_constraint(c, x86_pmu.event_constraints) { | ||
1379 | if (c->cmask != X86_RAW_EVENT_MASK | ||
1380 | || c->idxmsk64 == X86_PMC_MSK_FIXED_REF_CYCLES) { | ||
1381 | continue; | ||
1382 | } | ||
1383 | |||
1384 | c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1; | ||
1385 | c->weight += x86_pmu.num_counters; | ||
1386 | } | ||
1387 | } | ||
1388 | |||
1389 | x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ | 1352 | x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ |
1390 | x86_pmu_format_group.attrs = x86_pmu.format_attrs; | 1353 | x86_pmu_format_group.attrs = x86_pmu.format_attrs; |
1391 | 1354 | ||
@@ -1620,8 +1583,8 @@ static int x86_pmu_event_idx(struct perf_event *event) | |||
1620 | if (!x86_pmu.attr_rdpmc) | 1583 | if (!x86_pmu.attr_rdpmc) |
1621 | return 0; | 1584 | return 0; |
1622 | 1585 | ||
1623 | if (x86_pmu.num_counters_fixed && idx >= X86_PMC_IDX_FIXED) { | 1586 | if (x86_pmu.num_counters_fixed && idx >= INTEL_PMC_IDX_FIXED) { |
1624 | idx -= X86_PMC_IDX_FIXED; | 1587 | idx -= INTEL_PMC_IDX_FIXED; |
1625 | idx |= 1 << 30; | 1588 | idx |= 1 << 30; |
1626 | } | 1589 | } |
1627 | 1590 | ||
@@ -1649,7 +1612,12 @@ static ssize_t set_attr_rdpmc(struct device *cdev, | |||
1649 | struct device_attribute *attr, | 1612 | struct device_attribute *attr, |
1650 | const char *buf, size_t count) | 1613 | const char *buf, size_t count) |
1651 | { | 1614 | { |
1652 | unsigned long val = simple_strtoul(buf, NULL, 0); | 1615 | unsigned long val; |
1616 | ssize_t ret; | ||
1617 | |||
1618 | ret = kstrtoul(buf, 0, &val); | ||
1619 | if (ret) | ||
1620 | return ret; | ||
1653 | 1621 | ||
1654 | if (!!val != !!x86_pmu.attr_rdpmc) { | 1622 | if (!!val != !!x86_pmu.attr_rdpmc) { |
1655 | x86_pmu.attr_rdpmc = !!val; | 1623 | x86_pmu.attr_rdpmc = !!val; |
@@ -1682,13 +1650,20 @@ static void x86_pmu_flush_branch_stack(void) | |||
1682 | x86_pmu.flush_branch_stack(); | 1650 | x86_pmu.flush_branch_stack(); |
1683 | } | 1651 | } |
1684 | 1652 | ||
1653 | void perf_check_microcode(void) | ||
1654 | { | ||
1655 | if (x86_pmu.check_microcode) | ||
1656 | x86_pmu.check_microcode(); | ||
1657 | } | ||
1658 | EXPORT_SYMBOL_GPL(perf_check_microcode); | ||
1659 | |||
1685 | static struct pmu pmu = { | 1660 | static struct pmu pmu = { |
1686 | .pmu_enable = x86_pmu_enable, | 1661 | .pmu_enable = x86_pmu_enable, |
1687 | .pmu_disable = x86_pmu_disable, | 1662 | .pmu_disable = x86_pmu_disable, |
1688 | 1663 | ||
1689 | .attr_groups = x86_pmu_attr_groups, | 1664 | .attr_groups = x86_pmu_attr_groups, |
1690 | 1665 | ||
1691 | .event_init = x86_pmu_event_init, | 1666 | .event_init = x86_pmu_event_init, |
1692 | 1667 | ||
1693 | .add = x86_pmu_add, | 1668 | .add = x86_pmu_add, |
1694 | .del = x86_pmu_del, | 1669 | .del = x86_pmu_del, |
@@ -1696,11 +1671,11 @@ static struct pmu pmu = { | |||
1696 | .stop = x86_pmu_stop, | 1671 | .stop = x86_pmu_stop, |
1697 | .read = x86_pmu_read, | 1672 | .read = x86_pmu_read, |
1698 | 1673 | ||
1699 | .start_txn = x86_pmu_start_txn, | 1674 | .start_txn = x86_pmu_start_txn, |
1700 | .cancel_txn = x86_pmu_cancel_txn, | 1675 | .cancel_txn = x86_pmu_cancel_txn, |
1701 | .commit_txn = x86_pmu_commit_txn, | 1676 | .commit_txn = x86_pmu_commit_txn, |
1702 | 1677 | ||
1703 | .event_idx = x86_pmu_event_idx, | 1678 | .event_idx = x86_pmu_event_idx, |
1704 | .flush_branch_stack = x86_pmu_flush_branch_stack, | 1679 | .flush_branch_stack = x86_pmu_flush_branch_stack, |
1705 | }; | 1680 | }; |
1706 | 1681 | ||
@@ -1863,7 +1838,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs) | |||
1863 | else | 1838 | else |
1864 | misc |= PERF_RECORD_MISC_GUEST_KERNEL; | 1839 | misc |= PERF_RECORD_MISC_GUEST_KERNEL; |
1865 | } else { | 1840 | } else { |
1866 | if (user_mode(regs)) | 1841 | if (!kernel_ip(regs->ip)) |
1867 | misc |= PERF_RECORD_MISC_USER; | 1842 | misc |= PERF_RECORD_MISC_USER; |
1868 | else | 1843 | else |
1869 | misc |= PERF_RECORD_MISC_KERNEL; | 1844 | misc |= PERF_RECORD_MISC_KERNEL; |
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 7241e2fc3c17..a15df4be151f 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
@@ -14,6 +14,18 @@ | |||
14 | 14 | ||
15 | #include <linux/perf_event.h> | 15 | #include <linux/perf_event.h> |
16 | 16 | ||
17 | #if 0 | ||
18 | #undef wrmsrl | ||
19 | #define wrmsrl(msr, val) \ | ||
20 | do { \ | ||
21 | unsigned int _msr = (msr); \ | ||
22 | u64 _val = (val); \ | ||
23 | trace_printk("wrmsrl(%x, %Lx)\n", (unsigned int)(_msr), \ | ||
24 | (unsigned long long)(_val)); \ | ||
25 | native_write_msr((_msr), (u32)(_val), (u32)(_val >> 32)); \ | ||
26 | } while (0) | ||
27 | #endif | ||
28 | |||
17 | /* | 29 | /* |
18 | * | NHM/WSM | SNB | | 30 | * | NHM/WSM | SNB | |
19 | * register ------------------------------- | 31 | * register ------------------------------- |
@@ -57,7 +69,7 @@ struct amd_nb { | |||
57 | }; | 69 | }; |
58 | 70 | ||
59 | /* The maximal number of PEBS events: */ | 71 | /* The maximal number of PEBS events: */ |
60 | #define MAX_PEBS_EVENTS 4 | 72 | #define MAX_PEBS_EVENTS 8 |
61 | 73 | ||
62 | /* | 74 | /* |
63 | * A debug store configuration. | 75 | * A debug store configuration. |
@@ -349,6 +361,8 @@ struct x86_pmu { | |||
349 | void (*cpu_starting)(int cpu); | 361 | void (*cpu_starting)(int cpu); |
350 | void (*cpu_dying)(int cpu); | 362 | void (*cpu_dying)(int cpu); |
351 | void (*cpu_dead)(int cpu); | 363 | void (*cpu_dead)(int cpu); |
364 | |||
365 | void (*check_microcode)(void); | ||
352 | void (*flush_branch_stack)(void); | 366 | void (*flush_branch_stack)(void); |
353 | 367 | ||
354 | /* | 368 | /* |
@@ -360,12 +374,16 @@ struct x86_pmu { | |||
360 | /* | 374 | /* |
361 | * Intel DebugStore bits | 375 | * Intel DebugStore bits |
362 | */ | 376 | */ |
363 | int bts, pebs; | 377 | int bts :1, |
364 | int bts_active, pebs_active; | 378 | bts_active :1, |
379 | pebs :1, | ||
380 | pebs_active :1, | ||
381 | pebs_broken :1; | ||
365 | int pebs_record_size; | 382 | int pebs_record_size; |
366 | void (*drain_pebs)(struct pt_regs *regs); | 383 | void (*drain_pebs)(struct pt_regs *regs); |
367 | struct event_constraint *pebs_constraints; | 384 | struct event_constraint *pebs_constraints; |
368 | void (*pebs_aliases)(struct perf_event *event); | 385 | void (*pebs_aliases)(struct perf_event *event); |
386 | int max_pebs_events; | ||
369 | 387 | ||
370 | /* | 388 | /* |
371 | * Intel LBR | 389 | * Intel LBR |
@@ -468,6 +486,8 @@ static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, | |||
468 | 486 | ||
469 | void x86_pmu_enable_all(int added); | 487 | void x86_pmu_enable_all(int added); |
470 | 488 | ||
489 | int perf_assign_events(struct event_constraint **constraints, int n, | ||
490 | int wmin, int wmax, int *assign); | ||
471 | int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign); | 491 | int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign); |
472 | 492 | ||
473 | void x86_pmu_stop(struct perf_event *event, int flags); | 493 | void x86_pmu_stop(struct perf_event *event, int flags); |
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 11a4eb9131d5..4528ae7b6ec4 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c | |||
@@ -366,7 +366,7 @@ static void amd_pmu_cpu_starting(int cpu) | |||
366 | 366 | ||
367 | cpuc->perf_ctr_virt_mask = AMD_PERFMON_EVENTSEL_HOSTONLY; | 367 | cpuc->perf_ctr_virt_mask = AMD_PERFMON_EVENTSEL_HOSTONLY; |
368 | 368 | ||
369 | if (boot_cpu_data.x86_max_cores < 2 || boot_cpu_data.x86 == 0x15) | 369 | if (boot_cpu_data.x86_max_cores < 2) |
370 | return; | 370 | return; |
371 | 371 | ||
372 | nb_id = amd_get_nb_id(cpu); | 372 | nb_id = amd_get_nb_id(cpu); |
@@ -422,35 +422,6 @@ static struct attribute *amd_format_attr[] = { | |||
422 | NULL, | 422 | NULL, |
423 | }; | 423 | }; |
424 | 424 | ||
425 | static __initconst const struct x86_pmu amd_pmu = { | ||
426 | .name = "AMD", | ||
427 | .handle_irq = x86_pmu_handle_irq, | ||
428 | .disable_all = x86_pmu_disable_all, | ||
429 | .enable_all = x86_pmu_enable_all, | ||
430 | .enable = x86_pmu_enable_event, | ||
431 | .disable = x86_pmu_disable_event, | ||
432 | .hw_config = amd_pmu_hw_config, | ||
433 | .schedule_events = x86_schedule_events, | ||
434 | .eventsel = MSR_K7_EVNTSEL0, | ||
435 | .perfctr = MSR_K7_PERFCTR0, | ||
436 | .event_map = amd_pmu_event_map, | ||
437 | .max_events = ARRAY_SIZE(amd_perfmon_event_map), | ||
438 | .num_counters = AMD64_NUM_COUNTERS, | ||
439 | .cntval_bits = 48, | ||
440 | .cntval_mask = (1ULL << 48) - 1, | ||
441 | .apic = 1, | ||
442 | /* use highest bit to detect overflow */ | ||
443 | .max_period = (1ULL << 47) - 1, | ||
444 | .get_event_constraints = amd_get_event_constraints, | ||
445 | .put_event_constraints = amd_put_event_constraints, | ||
446 | |||
447 | .format_attrs = amd_format_attr, | ||
448 | |||
449 | .cpu_prepare = amd_pmu_cpu_prepare, | ||
450 | .cpu_starting = amd_pmu_cpu_starting, | ||
451 | .cpu_dead = amd_pmu_cpu_dead, | ||
452 | }; | ||
453 | |||
454 | /* AMD Family 15h */ | 425 | /* AMD Family 15h */ |
455 | 426 | ||
456 | #define AMD_EVENT_TYPE_MASK 0x000000F0ULL | 427 | #define AMD_EVENT_TYPE_MASK 0x000000F0ULL |
@@ -597,8 +568,8 @@ amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, struct perf_event *ev | |||
597 | } | 568 | } |
598 | } | 569 | } |
599 | 570 | ||
600 | static __initconst const struct x86_pmu amd_pmu_f15h = { | 571 | static __initconst const struct x86_pmu amd_pmu = { |
601 | .name = "AMD Family 15h", | 572 | .name = "AMD", |
602 | .handle_irq = x86_pmu_handle_irq, | 573 | .handle_irq = x86_pmu_handle_irq, |
603 | .disable_all = x86_pmu_disable_all, | 574 | .disable_all = x86_pmu_disable_all, |
604 | .enable_all = x86_pmu_enable_all, | 575 | .enable_all = x86_pmu_enable_all, |
@@ -606,50 +577,68 @@ static __initconst const struct x86_pmu amd_pmu_f15h = { | |||
606 | .disable = x86_pmu_disable_event, | 577 | .disable = x86_pmu_disable_event, |
607 | .hw_config = amd_pmu_hw_config, | 578 | .hw_config = amd_pmu_hw_config, |
608 | .schedule_events = x86_schedule_events, | 579 | .schedule_events = x86_schedule_events, |
609 | .eventsel = MSR_F15H_PERF_CTL, | 580 | .eventsel = MSR_K7_EVNTSEL0, |
610 | .perfctr = MSR_F15H_PERF_CTR, | 581 | .perfctr = MSR_K7_PERFCTR0, |
611 | .event_map = amd_pmu_event_map, | 582 | .event_map = amd_pmu_event_map, |
612 | .max_events = ARRAY_SIZE(amd_perfmon_event_map), | 583 | .max_events = ARRAY_SIZE(amd_perfmon_event_map), |
613 | .num_counters = AMD64_NUM_COUNTERS_F15H, | 584 | .num_counters = AMD64_NUM_COUNTERS, |
614 | .cntval_bits = 48, | 585 | .cntval_bits = 48, |
615 | .cntval_mask = (1ULL << 48) - 1, | 586 | .cntval_mask = (1ULL << 48) - 1, |
616 | .apic = 1, | 587 | .apic = 1, |
617 | /* use highest bit to detect overflow */ | 588 | /* use highest bit to detect overflow */ |
618 | .max_period = (1ULL << 47) - 1, | 589 | .max_period = (1ULL << 47) - 1, |
619 | .get_event_constraints = amd_get_event_constraints_f15h, | 590 | .get_event_constraints = amd_get_event_constraints, |
620 | /* nortbridge counters not yet implemented: */ | ||
621 | #if 0 | ||
622 | .put_event_constraints = amd_put_event_constraints, | 591 | .put_event_constraints = amd_put_event_constraints, |
623 | 592 | ||
593 | .format_attrs = amd_format_attr, | ||
594 | |||
624 | .cpu_prepare = amd_pmu_cpu_prepare, | 595 | .cpu_prepare = amd_pmu_cpu_prepare, |
625 | .cpu_dead = amd_pmu_cpu_dead, | ||
626 | #endif | ||
627 | .cpu_starting = amd_pmu_cpu_starting, | 596 | .cpu_starting = amd_pmu_cpu_starting, |
628 | .format_attrs = amd_format_attr, | 597 | .cpu_dead = amd_pmu_cpu_dead, |
629 | }; | 598 | }; |
630 | 599 | ||
600 | static int setup_event_constraints(void) | ||
601 | { | ||
602 | if (boot_cpu_data.x86 >= 0x15) | ||
603 | x86_pmu.get_event_constraints = amd_get_event_constraints_f15h; | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | static int setup_perfctr_core(void) | ||
608 | { | ||
609 | if (!cpu_has_perfctr_core) { | ||
610 | WARN(x86_pmu.get_event_constraints == amd_get_event_constraints_f15h, | ||
611 | KERN_ERR "Odd, counter constraints enabled but no core perfctrs detected!"); | ||
612 | return -ENODEV; | ||
613 | } | ||
614 | |||
615 | WARN(x86_pmu.get_event_constraints == amd_get_event_constraints, | ||
616 | KERN_ERR "hw perf events core counters need constraints handler!"); | ||
617 | |||
618 | /* | ||
619 | * If core performance counter extensions exists, we must use | ||
620 | * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also | ||
621 | * x86_pmu_addr_offset(). | ||
622 | */ | ||
623 | x86_pmu.eventsel = MSR_F15H_PERF_CTL; | ||
624 | x86_pmu.perfctr = MSR_F15H_PERF_CTR; | ||
625 | x86_pmu.num_counters = AMD64_NUM_COUNTERS_CORE; | ||
626 | |||
627 | printk(KERN_INFO "perf: AMD core performance counters detected\n"); | ||
628 | |||
629 | return 0; | ||
630 | } | ||
631 | |||
631 | __init int amd_pmu_init(void) | 632 | __init int amd_pmu_init(void) |
632 | { | 633 | { |
633 | /* Performance-monitoring supported from K7 and later: */ | 634 | /* Performance-monitoring supported from K7 and later: */ |
634 | if (boot_cpu_data.x86 < 6) | 635 | if (boot_cpu_data.x86 < 6) |
635 | return -ENODEV; | 636 | return -ENODEV; |
636 | 637 | ||
637 | /* | 638 | x86_pmu = amd_pmu; |
638 | * If core performance counter extensions exists, it must be | 639 | |
639 | * family 15h, otherwise fail. See x86_pmu_addr_offset(). | 640 | setup_event_constraints(); |
640 | */ | 641 | setup_perfctr_core(); |
641 | switch (boot_cpu_data.x86) { | ||
642 | case 0x15: | ||
643 | if (!cpu_has_perfctr_core) | ||
644 | return -ENODEV; | ||
645 | x86_pmu = amd_pmu_f15h; | ||
646 | break; | ||
647 | default: | ||
648 | if (cpu_has_perfctr_core) | ||
649 | return -ENODEV; | ||
650 | x86_pmu = amd_pmu; | ||
651 | break; | ||
652 | } | ||
653 | 642 | ||
654 | /* Events are common for all AMDs */ | 643 | /* Events are common for all AMDs */ |
655 | memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, | 644 | memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, |
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 187c294bc658..7a8b9d0abcaa 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -5,6 +5,8 @@ | |||
5 | * among events on a single PMU. | 5 | * among events on a single PMU. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
9 | |||
8 | #include <linux/stddef.h> | 10 | #include <linux/stddef.h> |
9 | #include <linux/types.h> | 11 | #include <linux/types.h> |
10 | #include <linux/init.h> | 12 | #include <linux/init.h> |
@@ -21,14 +23,14 @@ | |||
21 | */ | 23 | */ |
22 | static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly = | 24 | static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly = |
23 | { | 25 | { |
24 | [PERF_COUNT_HW_CPU_CYCLES] = 0x003c, | 26 | [PERF_COUNT_HW_CPU_CYCLES] = 0x003c, |
25 | [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, | 27 | [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, |
26 | [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e, | 28 | [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e, |
27 | [PERF_COUNT_HW_CACHE_MISSES] = 0x412e, | 29 | [PERF_COUNT_HW_CACHE_MISSES] = 0x412e, |
28 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, | 30 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, |
29 | [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, | 31 | [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, |
30 | [PERF_COUNT_HW_BUS_CYCLES] = 0x013c, | 32 | [PERF_COUNT_HW_BUS_CYCLES] = 0x013c, |
31 | [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding */ | 33 | [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding */ |
32 | }; | 34 | }; |
33 | 35 | ||
34 | static struct event_constraint intel_core_event_constraints[] __read_mostly = | 36 | static struct event_constraint intel_core_event_constraints[] __read_mostly = |
@@ -747,7 +749,7 @@ static void intel_pmu_disable_all(void) | |||
747 | 749 | ||
748 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); | 750 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); |
749 | 751 | ||
750 | if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) | 752 | if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) |
751 | intel_pmu_disable_bts(); | 753 | intel_pmu_disable_bts(); |
752 | 754 | ||
753 | intel_pmu_pebs_disable_all(); | 755 | intel_pmu_pebs_disable_all(); |
@@ -763,9 +765,9 @@ static void intel_pmu_enable_all(int added) | |||
763 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, | 765 | wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, |
764 | x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask); | 766 | x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask); |
765 | 767 | ||
766 | if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) { | 768 | if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) { |
767 | struct perf_event *event = | 769 | struct perf_event *event = |
768 | cpuc->events[X86_PMC_IDX_FIXED_BTS]; | 770 | cpuc->events[INTEL_PMC_IDX_FIXED_BTS]; |
769 | 771 | ||
770 | if (WARN_ON_ONCE(!event)) | 772 | if (WARN_ON_ONCE(!event)) |
771 | return; | 773 | return; |
@@ -871,7 +873,7 @@ static inline void intel_pmu_ack_status(u64 ack) | |||
871 | 873 | ||
872 | static void intel_pmu_disable_fixed(struct hw_perf_event *hwc) | 874 | static void intel_pmu_disable_fixed(struct hw_perf_event *hwc) |
873 | { | 875 | { |
874 | int idx = hwc->idx - X86_PMC_IDX_FIXED; | 876 | int idx = hwc->idx - INTEL_PMC_IDX_FIXED; |
875 | u64 ctrl_val, mask; | 877 | u64 ctrl_val, mask; |
876 | 878 | ||
877 | mask = 0xfULL << (idx * 4); | 879 | mask = 0xfULL << (idx * 4); |
@@ -886,7 +888,7 @@ static void intel_pmu_disable_event(struct perf_event *event) | |||
886 | struct hw_perf_event *hwc = &event->hw; | 888 | struct hw_perf_event *hwc = &event->hw; |
887 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 889 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
888 | 890 | ||
889 | if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { | 891 | if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) { |
890 | intel_pmu_disable_bts(); | 892 | intel_pmu_disable_bts(); |
891 | intel_pmu_drain_bts_buffer(); | 893 | intel_pmu_drain_bts_buffer(); |
892 | return; | 894 | return; |
@@ -915,7 +917,7 @@ static void intel_pmu_disable_event(struct perf_event *event) | |||
915 | 917 | ||
916 | static void intel_pmu_enable_fixed(struct hw_perf_event *hwc) | 918 | static void intel_pmu_enable_fixed(struct hw_perf_event *hwc) |
917 | { | 919 | { |
918 | int idx = hwc->idx - X86_PMC_IDX_FIXED; | 920 | int idx = hwc->idx - INTEL_PMC_IDX_FIXED; |
919 | u64 ctrl_val, bits, mask; | 921 | u64 ctrl_val, bits, mask; |
920 | 922 | ||
921 | /* | 923 | /* |
@@ -949,7 +951,7 @@ static void intel_pmu_enable_event(struct perf_event *event) | |||
949 | struct hw_perf_event *hwc = &event->hw; | 951 | struct hw_perf_event *hwc = &event->hw; |
950 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 952 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
951 | 953 | ||
952 | if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { | 954 | if (unlikely(hwc->idx == INTEL_PMC_IDX_FIXED_BTS)) { |
953 | if (!__this_cpu_read(cpu_hw_events.enabled)) | 955 | if (!__this_cpu_read(cpu_hw_events.enabled)) |
954 | return; | 956 | return; |
955 | 957 | ||
@@ -1000,14 +1002,14 @@ static void intel_pmu_reset(void) | |||
1000 | 1002 | ||
1001 | local_irq_save(flags); | 1003 | local_irq_save(flags); |
1002 | 1004 | ||
1003 | printk("clearing PMU state on CPU#%d\n", smp_processor_id()); | 1005 | pr_info("clearing PMU state on CPU#%d\n", smp_processor_id()); |
1004 | 1006 | ||
1005 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { | 1007 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { |
1006 | checking_wrmsrl(x86_pmu_config_addr(idx), 0ull); | 1008 | wrmsrl_safe(x86_pmu_config_addr(idx), 0ull); |
1007 | checking_wrmsrl(x86_pmu_event_addr(idx), 0ull); | 1009 | wrmsrl_safe(x86_pmu_event_addr(idx), 0ull); |
1008 | } | 1010 | } |
1009 | for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) | 1011 | for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) |
1010 | checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); | 1012 | wrmsrl_safe(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); |
1011 | 1013 | ||
1012 | if (ds) | 1014 | if (ds) |
1013 | ds->bts_index = ds->bts_buffer_base; | 1015 | ds->bts_index = ds->bts_buffer_base; |
@@ -1707,16 +1709,61 @@ static __init void intel_clovertown_quirk(void) | |||
1707 | * But taken together it might just make sense to not enable PEBS on | 1709 | * But taken together it might just make sense to not enable PEBS on |
1708 | * these chips. | 1710 | * these chips. |
1709 | */ | 1711 | */ |
1710 | printk(KERN_WARNING "PEBS disabled due to CPU errata.\n"); | 1712 | pr_warn("PEBS disabled due to CPU errata\n"); |
1711 | x86_pmu.pebs = 0; | 1713 | x86_pmu.pebs = 0; |
1712 | x86_pmu.pebs_constraints = NULL; | 1714 | x86_pmu.pebs_constraints = NULL; |
1713 | } | 1715 | } |
1714 | 1716 | ||
1717 | static int intel_snb_pebs_broken(int cpu) | ||
1718 | { | ||
1719 | u32 rev = UINT_MAX; /* default to broken for unknown models */ | ||
1720 | |||
1721 | switch (cpu_data(cpu).x86_model) { | ||
1722 | case 42: /* SNB */ | ||
1723 | rev = 0x28; | ||
1724 | break; | ||
1725 | |||
1726 | case 45: /* SNB-EP */ | ||
1727 | switch (cpu_data(cpu).x86_mask) { | ||
1728 | case 6: rev = 0x618; break; | ||
1729 | case 7: rev = 0x70c; break; | ||
1730 | } | ||
1731 | } | ||
1732 | |||
1733 | return (cpu_data(cpu).microcode < rev); | ||
1734 | } | ||
1735 | |||
1736 | static void intel_snb_check_microcode(void) | ||
1737 | { | ||
1738 | int pebs_broken = 0; | ||
1739 | int cpu; | ||
1740 | |||
1741 | get_online_cpus(); | ||
1742 | for_each_online_cpu(cpu) { | ||
1743 | if ((pebs_broken = intel_snb_pebs_broken(cpu))) | ||
1744 | break; | ||
1745 | } | ||
1746 | put_online_cpus(); | ||
1747 | |||
1748 | if (pebs_broken == x86_pmu.pebs_broken) | ||
1749 | return; | ||
1750 | |||
1751 | /* | ||
1752 | * Serialized by the microcode lock.. | ||
1753 | */ | ||
1754 | if (x86_pmu.pebs_broken) { | ||
1755 | pr_info("PEBS enabled due to microcode update\n"); | ||
1756 | x86_pmu.pebs_broken = 0; | ||
1757 | } else { | ||
1758 | pr_info("PEBS disabled due to CPU errata, please upgrade microcode\n"); | ||
1759 | x86_pmu.pebs_broken = 1; | ||
1760 | } | ||
1761 | } | ||
1762 | |||
1715 | static __init void intel_sandybridge_quirk(void) | 1763 | static __init void intel_sandybridge_quirk(void) |
1716 | { | 1764 | { |
1717 | printk(KERN_WARNING "PEBS disabled due to CPU errata.\n"); | 1765 | x86_pmu.check_microcode = intel_snb_check_microcode; |
1718 | x86_pmu.pebs = 0; | 1766 | intel_snb_check_microcode(); |
1719 | x86_pmu.pebs_constraints = NULL; | ||
1720 | } | 1767 | } |
1721 | 1768 | ||
1722 | static const struct { int id; char *name; } intel_arch_events_map[] __initconst = { | 1769 | static const struct { int id; char *name; } intel_arch_events_map[] __initconst = { |
@@ -1736,8 +1783,8 @@ static __init void intel_arch_events_quirk(void) | |||
1736 | /* disable event that reported as not presend by cpuid */ | 1783 | /* disable event that reported as not presend by cpuid */ |
1737 | for_each_set_bit(bit, x86_pmu.events_mask, ARRAY_SIZE(intel_arch_events_map)) { | 1784 | for_each_set_bit(bit, x86_pmu.events_mask, ARRAY_SIZE(intel_arch_events_map)) { |
1738 | intel_perfmon_event_map[intel_arch_events_map[bit].id] = 0; | 1785 | intel_perfmon_event_map[intel_arch_events_map[bit].id] = 0; |
1739 | printk(KERN_WARNING "CPUID marked event: \'%s\' unavailable\n", | 1786 | pr_warn("CPUID marked event: \'%s\' unavailable\n", |
1740 | intel_arch_events_map[bit].name); | 1787 | intel_arch_events_map[bit].name); |
1741 | } | 1788 | } |
1742 | } | 1789 | } |
1743 | 1790 | ||
@@ -1756,7 +1803,7 @@ static __init void intel_nehalem_quirk(void) | |||
1756 | intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89; | 1803 | intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89; |
1757 | ebx.split.no_branch_misses_retired = 0; | 1804 | ebx.split.no_branch_misses_retired = 0; |
1758 | x86_pmu.events_maskl = ebx.full; | 1805 | x86_pmu.events_maskl = ebx.full; |
1759 | printk(KERN_INFO "CPU erratum AAJ80 worked around\n"); | 1806 | pr_info("CPU erratum AAJ80 worked around\n"); |
1760 | } | 1807 | } |
1761 | } | 1808 | } |
1762 | 1809 | ||
@@ -1765,6 +1812,7 @@ __init int intel_pmu_init(void) | |||
1765 | union cpuid10_edx edx; | 1812 | union cpuid10_edx edx; |
1766 | union cpuid10_eax eax; | 1813 | union cpuid10_eax eax; |
1767 | union cpuid10_ebx ebx; | 1814 | union cpuid10_ebx ebx; |
1815 | struct event_constraint *c; | ||
1768 | unsigned int unused; | 1816 | unsigned int unused; |
1769 | int version; | 1817 | int version; |
1770 | 1818 | ||
@@ -1800,6 +1848,8 @@ __init int intel_pmu_init(void) | |||
1800 | x86_pmu.events_maskl = ebx.full; | 1848 | x86_pmu.events_maskl = ebx.full; |
1801 | x86_pmu.events_mask_len = eax.split.mask_length; | 1849 | x86_pmu.events_mask_len = eax.split.mask_length; |
1802 | 1850 | ||
1851 | x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters); | ||
1852 | |||
1803 | /* | 1853 | /* |
1804 | * Quirk: v2 perfmon does not report fixed-purpose events, so | 1854 | * Quirk: v2 perfmon does not report fixed-purpose events, so |
1805 | * assume at least 3 events: | 1855 | * assume at least 3 events: |
@@ -1951,5 +2001,37 @@ __init int intel_pmu_init(void) | |||
1951 | } | 2001 | } |
1952 | } | 2002 | } |
1953 | 2003 | ||
2004 | if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) { | ||
2005 | WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!", | ||
2006 | x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC); | ||
2007 | x86_pmu.num_counters = INTEL_PMC_MAX_GENERIC; | ||
2008 | } | ||
2009 | x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1; | ||
2010 | |||
2011 | if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED) { | ||
2012 | WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!", | ||
2013 | x86_pmu.num_counters_fixed, INTEL_PMC_MAX_FIXED); | ||
2014 | x86_pmu.num_counters_fixed = INTEL_PMC_MAX_FIXED; | ||
2015 | } | ||
2016 | |||
2017 | x86_pmu.intel_ctrl |= | ||
2018 | ((1LL << x86_pmu.num_counters_fixed)-1) << INTEL_PMC_IDX_FIXED; | ||
2019 | |||
2020 | if (x86_pmu.event_constraints) { | ||
2021 | /* | ||
2022 | * event on fixed counter2 (REF_CYCLES) only works on this | ||
2023 | * counter, so do not extend mask to generic counters | ||
2024 | */ | ||
2025 | for_each_event_constraint(c, x86_pmu.event_constraints) { | ||
2026 | if (c->cmask != X86_RAW_EVENT_MASK | ||
2027 | || c->idxmsk64 == INTEL_PMC_MSK_FIXED_REF_CYCLES) { | ||
2028 | continue; | ||
2029 | } | ||
2030 | |||
2031 | c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1; | ||
2032 | c->weight += x86_pmu.num_counters; | ||
2033 | } | ||
2034 | } | ||
2035 | |||
1954 | return 0; | 2036 | return 0; |
1955 | } | 2037 | } |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 35e2192df9f4..629ae0b7ad90 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
@@ -248,7 +248,7 @@ void reserve_ds_buffers(void) | |||
248 | */ | 248 | */ |
249 | 249 | ||
250 | struct event_constraint bts_constraint = | 250 | struct event_constraint bts_constraint = |
251 | EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0); | 251 | EVENT_CONSTRAINT(0, 1ULL << INTEL_PMC_IDX_FIXED_BTS, 0); |
252 | 252 | ||
253 | void intel_pmu_enable_bts(u64 config) | 253 | void intel_pmu_enable_bts(u64 config) |
254 | { | 254 | { |
@@ -295,7 +295,7 @@ int intel_pmu_drain_bts_buffer(void) | |||
295 | u64 to; | 295 | u64 to; |
296 | u64 flags; | 296 | u64 flags; |
297 | }; | 297 | }; |
298 | struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS]; | 298 | struct perf_event *event = cpuc->events[INTEL_PMC_IDX_FIXED_BTS]; |
299 | struct bts_record *at, *top; | 299 | struct bts_record *at, *top; |
300 | struct perf_output_handle handle; | 300 | struct perf_output_handle handle; |
301 | struct perf_event_header header; | 301 | struct perf_event_header header; |
@@ -620,7 +620,7 @@ static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) | |||
620 | * Should not happen, we program the threshold at 1 and do not | 620 | * Should not happen, we program the threshold at 1 and do not |
621 | * set a reset value. | 621 | * set a reset value. |
622 | */ | 622 | */ |
623 | WARN_ON_ONCE(n > 1); | 623 | WARN_ONCE(n > 1, "bad leftover pebs %d\n", n); |
624 | at += n - 1; | 624 | at += n - 1; |
625 | 625 | ||
626 | __intel_pmu_pebs_event(event, iregs, at); | 626 | __intel_pmu_pebs_event(event, iregs, at); |
@@ -651,10 +651,10 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) | |||
651 | * Should not happen, we program the threshold at 1 and do not | 651 | * Should not happen, we program the threshold at 1 and do not |
652 | * set a reset value. | 652 | * set a reset value. |
653 | */ | 653 | */ |
654 | WARN_ON_ONCE(n > MAX_PEBS_EVENTS); | 654 | WARN_ONCE(n > x86_pmu.max_pebs_events, "Unexpected number of pebs records %d\n", n); |
655 | 655 | ||
656 | for ( ; at < top; at++) { | 656 | for ( ; at < top; at++) { |
657 | for_each_set_bit(bit, (unsigned long *)&at->status, MAX_PEBS_EVENTS) { | 657 | for_each_set_bit(bit, (unsigned long *)&at->status, x86_pmu.max_pebs_events) { |
658 | event = cpuc->events[bit]; | 658 | event = cpuc->events[bit]; |
659 | if (!test_bit(bit, cpuc->active_mask)) | 659 | if (!test_bit(bit, cpuc->active_mask)) |
660 | continue; | 660 | continue; |
@@ -670,7 +670,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs) | |||
670 | break; | 670 | break; |
671 | } | 671 | } |
672 | 672 | ||
673 | if (!event || bit >= MAX_PEBS_EVENTS) | 673 | if (!event || bit >= x86_pmu.max_pebs_events) |
674 | continue; | 674 | continue; |
675 | 675 | ||
676 | __intel_pmu_pebs_event(event, iregs, at); | 676 | __intel_pmu_pebs_event(event, iregs, at); |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c new file mode 100644 index 000000000000..19faffc60886 --- /dev/null +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
@@ -0,0 +1,1850 @@ | |||
1 | #include "perf_event_intel_uncore.h" | ||
2 | |||
3 | static struct intel_uncore_type *empty_uncore[] = { NULL, }; | ||
4 | static struct intel_uncore_type **msr_uncores = empty_uncore; | ||
5 | static struct intel_uncore_type **pci_uncores = empty_uncore; | ||
6 | /* pci bus to socket mapping */ | ||
7 | static int pcibus_to_physid[256] = { [0 ... 255] = -1, }; | ||
8 | |||
9 | static DEFINE_RAW_SPINLOCK(uncore_box_lock); | ||
10 | |||
11 | /* mask of cpus that collect uncore events */ | ||
12 | static cpumask_t uncore_cpu_mask; | ||
13 | |||
14 | /* constraint for the fixed counter */ | ||
15 | static struct event_constraint constraint_fixed = | ||
16 | EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL); | ||
17 | static struct event_constraint constraint_empty = | ||
18 | EVENT_CONSTRAINT(0, 0, 0); | ||
19 | |||
20 | DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); | ||
21 | DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); | ||
22 | DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); | ||
23 | DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); | ||
24 | DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); | ||
25 | DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28"); | ||
26 | DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31"); | ||
27 | DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31"); | ||
28 | DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28"); | ||
29 | DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15"); | ||
30 | DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30"); | ||
31 | DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51"); | ||
32 | DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4"); | ||
33 | DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17"); | ||
34 | DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22"); | ||
35 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31"); | ||
36 | DEFINE_UNCORE_FORMAT_ATTR(filter_brand0, filter_brand0, "config1:0-7"); | ||
37 | DEFINE_UNCORE_FORMAT_ATTR(filter_brand1, filter_brand1, "config1:8-15"); | ||
38 | DEFINE_UNCORE_FORMAT_ATTR(filter_brand2, filter_brand2, "config1:16-23"); | ||
39 | DEFINE_UNCORE_FORMAT_ATTR(filter_brand3, filter_brand3, "config1:24-31"); | ||
40 | |||
41 | /* Sandy Bridge-EP uncore support */ | ||
42 | static struct intel_uncore_type snbep_uncore_cbox; | ||
43 | static struct intel_uncore_type snbep_uncore_pcu; | ||
44 | |||
45 | static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box) | ||
46 | { | ||
47 | struct pci_dev *pdev = box->pci_dev; | ||
48 | int box_ctl = uncore_pci_box_ctl(box); | ||
49 | u32 config; | ||
50 | |||
51 | pci_read_config_dword(pdev, box_ctl, &config); | ||
52 | config |= SNBEP_PMON_BOX_CTL_FRZ; | ||
53 | pci_write_config_dword(pdev, box_ctl, config); | ||
54 | } | ||
55 | |||
56 | static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box) | ||
57 | { | ||
58 | struct pci_dev *pdev = box->pci_dev; | ||
59 | int box_ctl = uncore_pci_box_ctl(box); | ||
60 | u32 config; | ||
61 | |||
62 | pci_read_config_dword(pdev, box_ctl, &config); | ||
63 | config &= ~SNBEP_PMON_BOX_CTL_FRZ; | ||
64 | pci_write_config_dword(pdev, box_ctl, config); | ||
65 | } | ||
66 | |||
67 | static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, | ||
68 | struct perf_event *event) | ||
69 | { | ||
70 | struct pci_dev *pdev = box->pci_dev; | ||
71 | struct hw_perf_event *hwc = &event->hw; | ||
72 | |||
73 | pci_write_config_dword(pdev, hwc->config_base, hwc->config | | ||
74 | SNBEP_PMON_CTL_EN); | ||
75 | } | ||
76 | |||
77 | static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, | ||
78 | struct perf_event *event) | ||
79 | { | ||
80 | struct pci_dev *pdev = box->pci_dev; | ||
81 | struct hw_perf_event *hwc = &event->hw; | ||
82 | |||
83 | pci_write_config_dword(pdev, hwc->config_base, hwc->config); | ||
84 | } | ||
85 | |||
86 | static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, | ||
87 | struct perf_event *event) | ||
88 | { | ||
89 | struct pci_dev *pdev = box->pci_dev; | ||
90 | struct hw_perf_event *hwc = &event->hw; | ||
91 | u64 count; | ||
92 | |||
93 | pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); | ||
94 | pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); | ||
95 | return count; | ||
96 | } | ||
97 | |||
98 | static void snbep_uncore_pci_init_box(struct intel_uncore_box *box) | ||
99 | { | ||
100 | struct pci_dev *pdev = box->pci_dev; | ||
101 | pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, | ||
102 | SNBEP_PMON_BOX_CTL_INT); | ||
103 | } | ||
104 | |||
105 | static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box) | ||
106 | { | ||
107 | u64 config; | ||
108 | unsigned msr; | ||
109 | |||
110 | msr = uncore_msr_box_ctl(box); | ||
111 | if (msr) { | ||
112 | rdmsrl(msr, config); | ||
113 | config |= SNBEP_PMON_BOX_CTL_FRZ; | ||
114 | wrmsrl(msr, config); | ||
115 | return; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box) | ||
120 | { | ||
121 | u64 config; | ||
122 | unsigned msr; | ||
123 | |||
124 | msr = uncore_msr_box_ctl(box); | ||
125 | if (msr) { | ||
126 | rdmsrl(msr, config); | ||
127 | config &= ~SNBEP_PMON_BOX_CTL_FRZ; | ||
128 | wrmsrl(msr, config); | ||
129 | return; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, | ||
134 | struct perf_event *event) | ||
135 | { | ||
136 | struct hw_perf_event *hwc = &event->hw; | ||
137 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
138 | |||
139 | if (reg1->idx != EXTRA_REG_NONE) | ||
140 | wrmsrl(reg1->reg, reg1->config); | ||
141 | |||
142 | wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); | ||
143 | } | ||
144 | |||
145 | static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box, | ||
146 | struct perf_event *event) | ||
147 | { | ||
148 | struct hw_perf_event *hwc = &event->hw; | ||
149 | |||
150 | wrmsrl(hwc->config_base, hwc->config); | ||
151 | } | ||
152 | |||
153 | static u64 snbep_uncore_msr_read_counter(struct intel_uncore_box *box, | ||
154 | struct perf_event *event) | ||
155 | { | ||
156 | struct hw_perf_event *hwc = &event->hw; | ||
157 | u64 count; | ||
158 | |||
159 | rdmsrl(hwc->event_base, count); | ||
160 | return count; | ||
161 | } | ||
162 | |||
163 | static void snbep_uncore_msr_init_box(struct intel_uncore_box *box) | ||
164 | { | ||
165 | unsigned msr = uncore_msr_box_ctl(box); | ||
166 | if (msr) | ||
167 | wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT); | ||
168 | } | ||
169 | |||
170 | static struct event_constraint * | ||
171 | snbep_uncore_get_constraint(struct intel_uncore_box *box, | ||
172 | struct perf_event *event) | ||
173 | { | ||
174 | struct intel_uncore_extra_reg *er; | ||
175 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
176 | unsigned long flags; | ||
177 | bool ok = false; | ||
178 | |||
179 | if (reg1->idx == EXTRA_REG_NONE || (box->phys_id >= 0 && reg1->alloc)) | ||
180 | return NULL; | ||
181 | |||
182 | er = &box->shared_regs[reg1->idx]; | ||
183 | raw_spin_lock_irqsave(&er->lock, flags); | ||
184 | if (!atomic_read(&er->ref) || er->config1 == reg1->config) { | ||
185 | atomic_inc(&er->ref); | ||
186 | er->config1 = reg1->config; | ||
187 | ok = true; | ||
188 | } | ||
189 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
190 | |||
191 | if (ok) { | ||
192 | if (box->phys_id >= 0) | ||
193 | reg1->alloc = 1; | ||
194 | return NULL; | ||
195 | } | ||
196 | return &constraint_empty; | ||
197 | } | ||
198 | |||
199 | static void snbep_uncore_put_constraint(struct intel_uncore_box *box, | ||
200 | struct perf_event *event) | ||
201 | { | ||
202 | struct intel_uncore_extra_reg *er; | ||
203 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
204 | |||
205 | if (box->phys_id < 0 || !reg1->alloc) | ||
206 | return; | ||
207 | |||
208 | er = &box->shared_regs[reg1->idx]; | ||
209 | atomic_dec(&er->ref); | ||
210 | reg1->alloc = 0; | ||
211 | } | ||
212 | |||
213 | static int snbep_uncore_hw_config(struct intel_uncore_box *box, | ||
214 | struct perf_event *event) | ||
215 | { | ||
216 | struct hw_perf_event *hwc = &event->hw; | ||
217 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
218 | |||
219 | if (box->pmu->type == &snbep_uncore_cbox) { | ||
220 | reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER + | ||
221 | SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; | ||
222 | reg1->config = event->attr.config1 & | ||
223 | SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK; | ||
224 | } else if (box->pmu->type == &snbep_uncore_pcu) { | ||
225 | reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER; | ||
226 | reg1->config = event->attr.config1 & | ||
227 | SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK; | ||
228 | } else { | ||
229 | return 0; | ||
230 | } | ||
231 | reg1->idx = 0; | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static struct attribute *snbep_uncore_formats_attr[] = { | ||
236 | &format_attr_event.attr, | ||
237 | &format_attr_umask.attr, | ||
238 | &format_attr_edge.attr, | ||
239 | &format_attr_inv.attr, | ||
240 | &format_attr_thresh8.attr, | ||
241 | NULL, | ||
242 | }; | ||
243 | |||
244 | static struct attribute *snbep_uncore_ubox_formats_attr[] = { | ||
245 | &format_attr_event.attr, | ||
246 | &format_attr_umask.attr, | ||
247 | &format_attr_edge.attr, | ||
248 | &format_attr_inv.attr, | ||
249 | &format_attr_thresh5.attr, | ||
250 | NULL, | ||
251 | }; | ||
252 | |||
253 | static struct attribute *snbep_uncore_cbox_formats_attr[] = { | ||
254 | &format_attr_event.attr, | ||
255 | &format_attr_umask.attr, | ||
256 | &format_attr_edge.attr, | ||
257 | &format_attr_tid_en.attr, | ||
258 | &format_attr_inv.attr, | ||
259 | &format_attr_thresh8.attr, | ||
260 | &format_attr_filter_tid.attr, | ||
261 | &format_attr_filter_nid.attr, | ||
262 | &format_attr_filter_state.attr, | ||
263 | &format_attr_filter_opc.attr, | ||
264 | NULL, | ||
265 | }; | ||
266 | |||
267 | static struct attribute *snbep_uncore_pcu_formats_attr[] = { | ||
268 | &format_attr_event.attr, | ||
269 | &format_attr_occ_sel.attr, | ||
270 | &format_attr_edge.attr, | ||
271 | &format_attr_inv.attr, | ||
272 | &format_attr_thresh5.attr, | ||
273 | &format_attr_occ_invert.attr, | ||
274 | &format_attr_occ_edge.attr, | ||
275 | &format_attr_filter_brand0.attr, | ||
276 | &format_attr_filter_brand1.attr, | ||
277 | &format_attr_filter_brand2.attr, | ||
278 | &format_attr_filter_brand3.attr, | ||
279 | NULL, | ||
280 | }; | ||
281 | |||
282 | static struct uncore_event_desc snbep_uncore_imc_events[] = { | ||
283 | INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"), | ||
284 | INTEL_UNCORE_EVENT_DESC(cas_count_read, "event=0x04,umask=0x03"), | ||
285 | INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"), | ||
286 | { /* end: all zeroes */ }, | ||
287 | }; | ||
288 | |||
289 | static struct uncore_event_desc snbep_uncore_qpi_events[] = { | ||
290 | INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"), | ||
291 | INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"), | ||
292 | INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x02,umask=0x08"), | ||
293 | INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x03,umask=0x04"), | ||
294 | { /* end: all zeroes */ }, | ||
295 | }; | ||
296 | |||
297 | static struct attribute_group snbep_uncore_format_group = { | ||
298 | .name = "format", | ||
299 | .attrs = snbep_uncore_formats_attr, | ||
300 | }; | ||
301 | |||
302 | static struct attribute_group snbep_uncore_ubox_format_group = { | ||
303 | .name = "format", | ||
304 | .attrs = snbep_uncore_ubox_formats_attr, | ||
305 | }; | ||
306 | |||
307 | static struct attribute_group snbep_uncore_cbox_format_group = { | ||
308 | .name = "format", | ||
309 | .attrs = snbep_uncore_cbox_formats_attr, | ||
310 | }; | ||
311 | |||
312 | static struct attribute_group snbep_uncore_pcu_format_group = { | ||
313 | .name = "format", | ||
314 | .attrs = snbep_uncore_pcu_formats_attr, | ||
315 | }; | ||
316 | |||
317 | static struct intel_uncore_ops snbep_uncore_msr_ops = { | ||
318 | .init_box = snbep_uncore_msr_init_box, | ||
319 | .disable_box = snbep_uncore_msr_disable_box, | ||
320 | .enable_box = snbep_uncore_msr_enable_box, | ||
321 | .disable_event = snbep_uncore_msr_disable_event, | ||
322 | .enable_event = snbep_uncore_msr_enable_event, | ||
323 | .read_counter = snbep_uncore_msr_read_counter, | ||
324 | .get_constraint = snbep_uncore_get_constraint, | ||
325 | .put_constraint = snbep_uncore_put_constraint, | ||
326 | .hw_config = snbep_uncore_hw_config, | ||
327 | }; | ||
328 | |||
329 | static struct intel_uncore_ops snbep_uncore_pci_ops = { | ||
330 | .init_box = snbep_uncore_pci_init_box, | ||
331 | .disable_box = snbep_uncore_pci_disable_box, | ||
332 | .enable_box = snbep_uncore_pci_enable_box, | ||
333 | .disable_event = snbep_uncore_pci_disable_event, | ||
334 | .enable_event = snbep_uncore_pci_enable_event, | ||
335 | .read_counter = snbep_uncore_pci_read_counter, | ||
336 | }; | ||
337 | |||
338 | static struct event_constraint snbep_uncore_cbox_constraints[] = { | ||
339 | UNCORE_EVENT_CONSTRAINT(0x01, 0x1), | ||
340 | UNCORE_EVENT_CONSTRAINT(0x02, 0x3), | ||
341 | UNCORE_EVENT_CONSTRAINT(0x04, 0x3), | ||
342 | UNCORE_EVENT_CONSTRAINT(0x05, 0x3), | ||
343 | UNCORE_EVENT_CONSTRAINT(0x07, 0x3), | ||
344 | UNCORE_EVENT_CONSTRAINT(0x11, 0x1), | ||
345 | UNCORE_EVENT_CONSTRAINT(0x12, 0x3), | ||
346 | UNCORE_EVENT_CONSTRAINT(0x13, 0x3), | ||
347 | UNCORE_EVENT_CONSTRAINT(0x1b, 0xc), | ||
348 | UNCORE_EVENT_CONSTRAINT(0x1c, 0xc), | ||
349 | UNCORE_EVENT_CONSTRAINT(0x1d, 0xc), | ||
350 | UNCORE_EVENT_CONSTRAINT(0x1e, 0xc), | ||
351 | EVENT_CONSTRAINT_OVERLAP(0x1f, 0xe, 0xff), | ||
352 | UNCORE_EVENT_CONSTRAINT(0x21, 0x3), | ||
353 | UNCORE_EVENT_CONSTRAINT(0x23, 0x3), | ||
354 | UNCORE_EVENT_CONSTRAINT(0x31, 0x3), | ||
355 | UNCORE_EVENT_CONSTRAINT(0x32, 0x3), | ||
356 | UNCORE_EVENT_CONSTRAINT(0x33, 0x3), | ||
357 | UNCORE_EVENT_CONSTRAINT(0x34, 0x3), | ||
358 | UNCORE_EVENT_CONSTRAINT(0x35, 0x3), | ||
359 | UNCORE_EVENT_CONSTRAINT(0x36, 0x1), | ||
360 | UNCORE_EVENT_CONSTRAINT(0x37, 0x3), | ||
361 | UNCORE_EVENT_CONSTRAINT(0x38, 0x3), | ||
362 | UNCORE_EVENT_CONSTRAINT(0x39, 0x3), | ||
363 | UNCORE_EVENT_CONSTRAINT(0x3b, 0x1), | ||
364 | EVENT_CONSTRAINT_END | ||
365 | }; | ||
366 | |||
367 | static struct event_constraint snbep_uncore_r2pcie_constraints[] = { | ||
368 | UNCORE_EVENT_CONSTRAINT(0x10, 0x3), | ||
369 | UNCORE_EVENT_CONSTRAINT(0x11, 0x3), | ||
370 | UNCORE_EVENT_CONSTRAINT(0x12, 0x1), | ||
371 | UNCORE_EVENT_CONSTRAINT(0x23, 0x3), | ||
372 | UNCORE_EVENT_CONSTRAINT(0x24, 0x3), | ||
373 | UNCORE_EVENT_CONSTRAINT(0x25, 0x3), | ||
374 | UNCORE_EVENT_CONSTRAINT(0x26, 0x3), | ||
375 | UNCORE_EVENT_CONSTRAINT(0x32, 0x3), | ||
376 | UNCORE_EVENT_CONSTRAINT(0x33, 0x3), | ||
377 | UNCORE_EVENT_CONSTRAINT(0x34, 0x3), | ||
378 | EVENT_CONSTRAINT_END | ||
379 | }; | ||
380 | |||
381 | static struct event_constraint snbep_uncore_r3qpi_constraints[] = { | ||
382 | UNCORE_EVENT_CONSTRAINT(0x10, 0x3), | ||
383 | UNCORE_EVENT_CONSTRAINT(0x11, 0x3), | ||
384 | UNCORE_EVENT_CONSTRAINT(0x12, 0x3), | ||
385 | UNCORE_EVENT_CONSTRAINT(0x13, 0x1), | ||
386 | UNCORE_EVENT_CONSTRAINT(0x20, 0x3), | ||
387 | UNCORE_EVENT_CONSTRAINT(0x21, 0x3), | ||
388 | UNCORE_EVENT_CONSTRAINT(0x22, 0x3), | ||
389 | UNCORE_EVENT_CONSTRAINT(0x23, 0x3), | ||
390 | UNCORE_EVENT_CONSTRAINT(0x24, 0x3), | ||
391 | UNCORE_EVENT_CONSTRAINT(0x25, 0x3), | ||
392 | UNCORE_EVENT_CONSTRAINT(0x26, 0x3), | ||
393 | UNCORE_EVENT_CONSTRAINT(0x30, 0x3), | ||
394 | UNCORE_EVENT_CONSTRAINT(0x31, 0x3), | ||
395 | UNCORE_EVENT_CONSTRAINT(0x32, 0x3), | ||
396 | UNCORE_EVENT_CONSTRAINT(0x33, 0x3), | ||
397 | UNCORE_EVENT_CONSTRAINT(0x34, 0x3), | ||
398 | UNCORE_EVENT_CONSTRAINT(0x36, 0x3), | ||
399 | UNCORE_EVENT_CONSTRAINT(0x37, 0x3), | ||
400 | EVENT_CONSTRAINT_END | ||
401 | }; | ||
402 | |||
403 | static struct intel_uncore_type snbep_uncore_ubox = { | ||
404 | .name = "ubox", | ||
405 | .num_counters = 2, | ||
406 | .num_boxes = 1, | ||
407 | .perf_ctr_bits = 44, | ||
408 | .fixed_ctr_bits = 48, | ||
409 | .perf_ctr = SNBEP_U_MSR_PMON_CTR0, | ||
410 | .event_ctl = SNBEP_U_MSR_PMON_CTL0, | ||
411 | .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK, | ||
412 | .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR, | ||
413 | .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL, | ||
414 | .ops = &snbep_uncore_msr_ops, | ||
415 | .format_group = &snbep_uncore_ubox_format_group, | ||
416 | }; | ||
417 | |||
418 | static struct intel_uncore_type snbep_uncore_cbox = { | ||
419 | .name = "cbox", | ||
420 | .num_counters = 4, | ||
421 | .num_boxes = 8, | ||
422 | .perf_ctr_bits = 44, | ||
423 | .event_ctl = SNBEP_C0_MSR_PMON_CTL0, | ||
424 | .perf_ctr = SNBEP_C0_MSR_PMON_CTR0, | ||
425 | .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK, | ||
426 | .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL, | ||
427 | .msr_offset = SNBEP_CBO_MSR_OFFSET, | ||
428 | .num_shared_regs = 1, | ||
429 | .constraints = snbep_uncore_cbox_constraints, | ||
430 | .ops = &snbep_uncore_msr_ops, | ||
431 | .format_group = &snbep_uncore_cbox_format_group, | ||
432 | }; | ||
433 | |||
434 | static struct intel_uncore_type snbep_uncore_pcu = { | ||
435 | .name = "pcu", | ||
436 | .num_counters = 4, | ||
437 | .num_boxes = 1, | ||
438 | .perf_ctr_bits = 48, | ||
439 | .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0, | ||
440 | .event_ctl = SNBEP_PCU_MSR_PMON_CTL0, | ||
441 | .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK, | ||
442 | .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL, | ||
443 | .num_shared_regs = 1, | ||
444 | .ops = &snbep_uncore_msr_ops, | ||
445 | .format_group = &snbep_uncore_pcu_format_group, | ||
446 | }; | ||
447 | |||
448 | static struct intel_uncore_type *snbep_msr_uncores[] = { | ||
449 | &snbep_uncore_ubox, | ||
450 | &snbep_uncore_cbox, | ||
451 | &snbep_uncore_pcu, | ||
452 | NULL, | ||
453 | }; | ||
454 | |||
455 | #define SNBEP_UNCORE_PCI_COMMON_INIT() \ | ||
456 | .perf_ctr = SNBEP_PCI_PMON_CTR0, \ | ||
457 | .event_ctl = SNBEP_PCI_PMON_CTL0, \ | ||
458 | .event_mask = SNBEP_PMON_RAW_EVENT_MASK, \ | ||
459 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \ | ||
460 | .ops = &snbep_uncore_pci_ops, \ | ||
461 | .format_group = &snbep_uncore_format_group | ||
462 | |||
463 | static struct intel_uncore_type snbep_uncore_ha = { | ||
464 | .name = "ha", | ||
465 | .num_counters = 4, | ||
466 | .num_boxes = 1, | ||
467 | .perf_ctr_bits = 48, | ||
468 | SNBEP_UNCORE_PCI_COMMON_INIT(), | ||
469 | }; | ||
470 | |||
471 | static struct intel_uncore_type snbep_uncore_imc = { | ||
472 | .name = "imc", | ||
473 | .num_counters = 4, | ||
474 | .num_boxes = 4, | ||
475 | .perf_ctr_bits = 48, | ||
476 | .fixed_ctr_bits = 48, | ||
477 | .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR, | ||
478 | .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL, | ||
479 | .event_descs = snbep_uncore_imc_events, | ||
480 | SNBEP_UNCORE_PCI_COMMON_INIT(), | ||
481 | }; | ||
482 | |||
483 | static struct intel_uncore_type snbep_uncore_qpi = { | ||
484 | .name = "qpi", | ||
485 | .num_counters = 4, | ||
486 | .num_boxes = 2, | ||
487 | .perf_ctr_bits = 48, | ||
488 | .event_descs = snbep_uncore_qpi_events, | ||
489 | SNBEP_UNCORE_PCI_COMMON_INIT(), | ||
490 | }; | ||
491 | |||
492 | |||
493 | static struct intel_uncore_type snbep_uncore_r2pcie = { | ||
494 | .name = "r2pcie", | ||
495 | .num_counters = 4, | ||
496 | .num_boxes = 1, | ||
497 | .perf_ctr_bits = 44, | ||
498 | .constraints = snbep_uncore_r2pcie_constraints, | ||
499 | SNBEP_UNCORE_PCI_COMMON_INIT(), | ||
500 | }; | ||
501 | |||
502 | static struct intel_uncore_type snbep_uncore_r3qpi = { | ||
503 | .name = "r3qpi", | ||
504 | .num_counters = 3, | ||
505 | .num_boxes = 2, | ||
506 | .perf_ctr_bits = 44, | ||
507 | .constraints = snbep_uncore_r3qpi_constraints, | ||
508 | SNBEP_UNCORE_PCI_COMMON_INIT(), | ||
509 | }; | ||
510 | |||
511 | static struct intel_uncore_type *snbep_pci_uncores[] = { | ||
512 | &snbep_uncore_ha, | ||
513 | &snbep_uncore_imc, | ||
514 | &snbep_uncore_qpi, | ||
515 | &snbep_uncore_r2pcie, | ||
516 | &snbep_uncore_r3qpi, | ||
517 | NULL, | ||
518 | }; | ||
519 | |||
520 | static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { | ||
521 | { /* Home Agent */ | ||
522 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA), | ||
523 | .driver_data = (unsigned long)&snbep_uncore_ha, | ||
524 | }, | ||
525 | { /* MC Channel 0 */ | ||
526 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0), | ||
527 | .driver_data = (unsigned long)&snbep_uncore_imc, | ||
528 | }, | ||
529 | { /* MC Channel 1 */ | ||
530 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1), | ||
531 | .driver_data = (unsigned long)&snbep_uncore_imc, | ||
532 | }, | ||
533 | { /* MC Channel 2 */ | ||
534 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2), | ||
535 | .driver_data = (unsigned long)&snbep_uncore_imc, | ||
536 | }, | ||
537 | { /* MC Channel 3 */ | ||
538 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3), | ||
539 | .driver_data = (unsigned long)&snbep_uncore_imc, | ||
540 | }, | ||
541 | { /* QPI Port 0 */ | ||
542 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0), | ||
543 | .driver_data = (unsigned long)&snbep_uncore_qpi, | ||
544 | }, | ||
545 | { /* QPI Port 1 */ | ||
546 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1), | ||
547 | .driver_data = (unsigned long)&snbep_uncore_qpi, | ||
548 | }, | ||
549 | { /* P2PCIe */ | ||
550 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE), | ||
551 | .driver_data = (unsigned long)&snbep_uncore_r2pcie, | ||
552 | }, | ||
553 | { /* R3QPI Link 0 */ | ||
554 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0), | ||
555 | .driver_data = (unsigned long)&snbep_uncore_r3qpi, | ||
556 | }, | ||
557 | { /* R3QPI Link 1 */ | ||
558 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), | ||
559 | .driver_data = (unsigned long)&snbep_uncore_r3qpi, | ||
560 | }, | ||
561 | { /* end: all zeroes */ } | ||
562 | }; | ||
563 | |||
564 | static struct pci_driver snbep_uncore_pci_driver = { | ||
565 | .name = "snbep_uncore", | ||
566 | .id_table = snbep_uncore_pci_ids, | ||
567 | }; | ||
568 | |||
569 | /* | ||
570 | * build pci bus to socket mapping | ||
571 | */ | ||
572 | static void snbep_pci2phy_map_init(void) | ||
573 | { | ||
574 | struct pci_dev *ubox_dev = NULL; | ||
575 | int i, bus, nodeid; | ||
576 | u32 config; | ||
577 | |||
578 | while (1) { | ||
579 | /* find the UBOX device */ | ||
580 | ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
581 | PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX, | ||
582 | ubox_dev); | ||
583 | if (!ubox_dev) | ||
584 | break; | ||
585 | bus = ubox_dev->bus->number; | ||
586 | /* get the Node ID of the local register */ | ||
587 | pci_read_config_dword(ubox_dev, 0x40, &config); | ||
588 | nodeid = config; | ||
589 | /* get the Node ID mapping */ | ||
590 | pci_read_config_dword(ubox_dev, 0x54, &config); | ||
591 | /* | ||
592 | * every three bits in the Node ID mapping register maps | ||
593 | * to a particular node. | ||
594 | */ | ||
595 | for (i = 0; i < 8; i++) { | ||
596 | if (nodeid == ((config >> (3 * i)) & 0x7)) { | ||
597 | pcibus_to_physid[bus] = i; | ||
598 | break; | ||
599 | } | ||
600 | } | ||
601 | }; | ||
602 | return; | ||
603 | } | ||
604 | /* end of Sandy Bridge-EP uncore support */ | ||
605 | |||
606 | |||
607 | /* Sandy Bridge uncore support */ | ||
608 | static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, | ||
609 | struct perf_event *event) | ||
610 | { | ||
611 | struct hw_perf_event *hwc = &event->hw; | ||
612 | |||
613 | if (hwc->idx < UNCORE_PMC_IDX_FIXED) | ||
614 | wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN); | ||
615 | else | ||
616 | wrmsrl(hwc->config_base, SNB_UNC_CTL_EN); | ||
617 | } | ||
618 | |||
619 | static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, | ||
620 | struct perf_event *event) | ||
621 | { | ||
622 | wrmsrl(event->hw.config_base, 0); | ||
623 | } | ||
624 | |||
625 | static u64 snb_uncore_msr_read_counter(struct intel_uncore_box *box, | ||
626 | struct perf_event *event) | ||
627 | { | ||
628 | u64 count; | ||
629 | rdmsrl(event->hw.event_base, count); | ||
630 | return count; | ||
631 | } | ||
632 | |||
633 | static void snb_uncore_msr_init_box(struct intel_uncore_box *box) | ||
634 | { | ||
635 | if (box->pmu->pmu_idx == 0) { | ||
636 | wrmsrl(SNB_UNC_PERF_GLOBAL_CTL, | ||
637 | SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL); | ||
638 | } | ||
639 | } | ||
640 | |||
641 | static struct attribute *snb_uncore_formats_attr[] = { | ||
642 | &format_attr_event.attr, | ||
643 | &format_attr_umask.attr, | ||
644 | &format_attr_edge.attr, | ||
645 | &format_attr_inv.attr, | ||
646 | &format_attr_cmask5.attr, | ||
647 | NULL, | ||
648 | }; | ||
649 | |||
650 | static struct attribute_group snb_uncore_format_group = { | ||
651 | .name = "format", | ||
652 | .attrs = snb_uncore_formats_attr, | ||
653 | }; | ||
654 | |||
655 | static struct intel_uncore_ops snb_uncore_msr_ops = { | ||
656 | .init_box = snb_uncore_msr_init_box, | ||
657 | .disable_event = snb_uncore_msr_disable_event, | ||
658 | .enable_event = snb_uncore_msr_enable_event, | ||
659 | .read_counter = snb_uncore_msr_read_counter, | ||
660 | }; | ||
661 | |||
662 | static struct event_constraint snb_uncore_cbox_constraints[] = { | ||
663 | UNCORE_EVENT_CONSTRAINT(0x80, 0x1), | ||
664 | UNCORE_EVENT_CONSTRAINT(0x83, 0x1), | ||
665 | EVENT_CONSTRAINT_END | ||
666 | }; | ||
667 | |||
668 | static struct intel_uncore_type snb_uncore_cbox = { | ||
669 | .name = "cbox", | ||
670 | .num_counters = 2, | ||
671 | .num_boxes = 4, | ||
672 | .perf_ctr_bits = 44, | ||
673 | .fixed_ctr_bits = 48, | ||
674 | .perf_ctr = SNB_UNC_CBO_0_PER_CTR0, | ||
675 | .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0, | ||
676 | .fixed_ctr = SNB_UNC_FIXED_CTR, | ||
677 | .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL, | ||
678 | .single_fixed = 1, | ||
679 | .event_mask = SNB_UNC_RAW_EVENT_MASK, | ||
680 | .msr_offset = SNB_UNC_CBO_MSR_OFFSET, | ||
681 | .constraints = snb_uncore_cbox_constraints, | ||
682 | .ops = &snb_uncore_msr_ops, | ||
683 | .format_group = &snb_uncore_format_group, | ||
684 | }; | ||
685 | |||
686 | static struct intel_uncore_type *snb_msr_uncores[] = { | ||
687 | &snb_uncore_cbox, | ||
688 | NULL, | ||
689 | }; | ||
690 | /* end of Sandy Bridge uncore support */ | ||
691 | |||
692 | /* Nehalem uncore support */ | ||
693 | static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box) | ||
694 | { | ||
695 | wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0); | ||
696 | } | ||
697 | |||
698 | static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box) | ||
699 | { | ||
700 | wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, | ||
701 | NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC); | ||
702 | } | ||
703 | |||
704 | static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, | ||
705 | struct perf_event *event) | ||
706 | { | ||
707 | struct hw_perf_event *hwc = &event->hw; | ||
708 | |||
709 | if (hwc->idx < UNCORE_PMC_IDX_FIXED) | ||
710 | wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN); | ||
711 | else | ||
712 | wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN); | ||
713 | } | ||
714 | |||
715 | static struct attribute *nhm_uncore_formats_attr[] = { | ||
716 | &format_attr_event.attr, | ||
717 | &format_attr_umask.attr, | ||
718 | &format_attr_edge.attr, | ||
719 | &format_attr_inv.attr, | ||
720 | &format_attr_cmask8.attr, | ||
721 | NULL, | ||
722 | }; | ||
723 | |||
724 | static struct attribute_group nhm_uncore_format_group = { | ||
725 | .name = "format", | ||
726 | .attrs = nhm_uncore_formats_attr, | ||
727 | }; | ||
728 | |||
729 | static struct uncore_event_desc nhm_uncore_events[] = { | ||
730 | INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"), | ||
731 | INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any, "event=0x2f,umask=0x0f"), | ||
732 | INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any, "event=0x2c,umask=0x0f"), | ||
733 | INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads, "event=0x20,umask=0x01"), | ||
734 | INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes, "event=0x20,umask=0x02"), | ||
735 | INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads, "event=0x20,umask=0x04"), | ||
736 | INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"), | ||
737 | INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads, "event=0x20,umask=0x10"), | ||
738 | INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes, "event=0x20,umask=0x20"), | ||
739 | { /* end: all zeroes */ }, | ||
740 | }; | ||
741 | |||
742 | static struct intel_uncore_ops nhm_uncore_msr_ops = { | ||
743 | .disable_box = nhm_uncore_msr_disable_box, | ||
744 | .enable_box = nhm_uncore_msr_enable_box, | ||
745 | .disable_event = snb_uncore_msr_disable_event, | ||
746 | .enable_event = nhm_uncore_msr_enable_event, | ||
747 | .read_counter = snb_uncore_msr_read_counter, | ||
748 | }; | ||
749 | |||
750 | static struct intel_uncore_type nhm_uncore = { | ||
751 | .name = "", | ||
752 | .num_counters = 8, | ||
753 | .num_boxes = 1, | ||
754 | .perf_ctr_bits = 48, | ||
755 | .fixed_ctr_bits = 48, | ||
756 | .event_ctl = NHM_UNC_PERFEVTSEL0, | ||
757 | .perf_ctr = NHM_UNC_UNCORE_PMC0, | ||
758 | .fixed_ctr = NHM_UNC_FIXED_CTR, | ||
759 | .fixed_ctl = NHM_UNC_FIXED_CTR_CTRL, | ||
760 | .event_mask = NHM_UNC_RAW_EVENT_MASK, | ||
761 | .event_descs = nhm_uncore_events, | ||
762 | .ops = &nhm_uncore_msr_ops, | ||
763 | .format_group = &nhm_uncore_format_group, | ||
764 | }; | ||
765 | |||
766 | static struct intel_uncore_type *nhm_msr_uncores[] = { | ||
767 | &nhm_uncore, | ||
768 | NULL, | ||
769 | }; | ||
770 | /* end of Nehalem uncore support */ | ||
771 | |||
772 | static void uncore_assign_hw_event(struct intel_uncore_box *box, | ||
773 | struct perf_event *event, int idx) | ||
774 | { | ||
775 | struct hw_perf_event *hwc = &event->hw; | ||
776 | |||
777 | hwc->idx = idx; | ||
778 | hwc->last_tag = ++box->tags[idx]; | ||
779 | |||
780 | if (hwc->idx == UNCORE_PMC_IDX_FIXED) { | ||
781 | hwc->event_base = uncore_fixed_ctr(box); | ||
782 | hwc->config_base = uncore_fixed_ctl(box); | ||
783 | return; | ||
784 | } | ||
785 | |||
786 | hwc->config_base = uncore_event_ctl(box, hwc->idx); | ||
787 | hwc->event_base = uncore_perf_ctr(box, hwc->idx); | ||
788 | } | ||
789 | |||
790 | static void uncore_perf_event_update(struct intel_uncore_box *box, | ||
791 | struct perf_event *event) | ||
792 | { | ||
793 | u64 prev_count, new_count, delta; | ||
794 | int shift; | ||
795 | |||
796 | if (event->hw.idx >= UNCORE_PMC_IDX_FIXED) | ||
797 | shift = 64 - uncore_fixed_ctr_bits(box); | ||
798 | else | ||
799 | shift = 64 - uncore_perf_ctr_bits(box); | ||
800 | |||
801 | /* the hrtimer might modify the previous event value */ | ||
802 | again: | ||
803 | prev_count = local64_read(&event->hw.prev_count); | ||
804 | new_count = uncore_read_counter(box, event); | ||
805 | if (local64_xchg(&event->hw.prev_count, new_count) != prev_count) | ||
806 | goto again; | ||
807 | |||
808 | delta = (new_count << shift) - (prev_count << shift); | ||
809 | delta >>= shift; | ||
810 | |||
811 | local64_add(delta, &event->count); | ||
812 | } | ||
813 | |||
814 | /* | ||
815 | * The overflow interrupt is unavailable for SandyBridge-EP, is broken | ||
816 | * for SandyBridge. So we use hrtimer to periodically poll the counter | ||
817 | * to avoid overflow. | ||
818 | */ | ||
819 | static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer) | ||
820 | { | ||
821 | struct intel_uncore_box *box; | ||
822 | unsigned long flags; | ||
823 | int bit; | ||
824 | |||
825 | box = container_of(hrtimer, struct intel_uncore_box, hrtimer); | ||
826 | if (!box->n_active || box->cpu != smp_processor_id()) | ||
827 | return HRTIMER_NORESTART; | ||
828 | /* | ||
829 | * disable local interrupt to prevent uncore_pmu_event_start/stop | ||
830 | * to interrupt the update process | ||
831 | */ | ||
832 | local_irq_save(flags); | ||
833 | |||
834 | for_each_set_bit(bit, box->active_mask, UNCORE_PMC_IDX_MAX) | ||
835 | uncore_perf_event_update(box, box->events[bit]); | ||
836 | |||
837 | local_irq_restore(flags); | ||
838 | |||
839 | hrtimer_forward_now(hrtimer, ns_to_ktime(UNCORE_PMU_HRTIMER_INTERVAL)); | ||
840 | return HRTIMER_RESTART; | ||
841 | } | ||
842 | |||
843 | static void uncore_pmu_start_hrtimer(struct intel_uncore_box *box) | ||
844 | { | ||
845 | __hrtimer_start_range_ns(&box->hrtimer, | ||
846 | ns_to_ktime(UNCORE_PMU_HRTIMER_INTERVAL), 0, | ||
847 | HRTIMER_MODE_REL_PINNED, 0); | ||
848 | } | ||
849 | |||
850 | static void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box) | ||
851 | { | ||
852 | hrtimer_cancel(&box->hrtimer); | ||
853 | } | ||
854 | |||
855 | static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box) | ||
856 | { | ||
857 | hrtimer_init(&box->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
858 | box->hrtimer.function = uncore_pmu_hrtimer; | ||
859 | } | ||
860 | |||
861 | struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, | ||
862 | int cpu) | ||
863 | { | ||
864 | struct intel_uncore_box *box; | ||
865 | int i, size; | ||
866 | |||
867 | size = sizeof(*box) + type->num_shared_regs * | ||
868 | sizeof(struct intel_uncore_extra_reg); | ||
869 | |||
870 | box = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO, cpu_to_node(cpu)); | ||
871 | if (!box) | ||
872 | return NULL; | ||
873 | |||
874 | for (i = 0; i < type->num_shared_regs; i++) | ||
875 | raw_spin_lock_init(&box->shared_regs[i].lock); | ||
876 | |||
877 | uncore_pmu_init_hrtimer(box); | ||
878 | atomic_set(&box->refcnt, 1); | ||
879 | box->cpu = -1; | ||
880 | box->phys_id = -1; | ||
881 | |||
882 | return box; | ||
883 | } | ||
884 | |||
885 | static struct intel_uncore_box * | ||
886 | uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu) | ||
887 | { | ||
888 | static struct intel_uncore_box *box; | ||
889 | |||
890 | box = *per_cpu_ptr(pmu->box, cpu); | ||
891 | if (box) | ||
892 | return box; | ||
893 | |||
894 | raw_spin_lock(&uncore_box_lock); | ||
895 | list_for_each_entry(box, &pmu->box_list, list) { | ||
896 | if (box->phys_id == topology_physical_package_id(cpu)) { | ||
897 | atomic_inc(&box->refcnt); | ||
898 | *per_cpu_ptr(pmu->box, cpu) = box; | ||
899 | break; | ||
900 | } | ||
901 | } | ||
902 | raw_spin_unlock(&uncore_box_lock); | ||
903 | |||
904 | return *per_cpu_ptr(pmu->box, cpu); | ||
905 | } | ||
906 | |||
907 | static struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) | ||
908 | { | ||
909 | return container_of(event->pmu, struct intel_uncore_pmu, pmu); | ||
910 | } | ||
911 | |||
912 | static struct intel_uncore_box *uncore_event_to_box(struct perf_event *event) | ||
913 | { | ||
914 | /* | ||
915 | * perf core schedules event on the basis of cpu, uncore events are | ||
916 | * collected by one of the cpus inside a physical package. | ||
917 | */ | ||
918 | return uncore_pmu_to_box(uncore_event_to_pmu(event), | ||
919 | smp_processor_id()); | ||
920 | } | ||
921 | |||
922 | static int uncore_collect_events(struct intel_uncore_box *box, | ||
923 | struct perf_event *leader, bool dogrp) | ||
924 | { | ||
925 | struct perf_event *event; | ||
926 | int n, max_count; | ||
927 | |||
928 | max_count = box->pmu->type->num_counters; | ||
929 | if (box->pmu->type->fixed_ctl) | ||
930 | max_count++; | ||
931 | |||
932 | if (box->n_events >= max_count) | ||
933 | return -EINVAL; | ||
934 | |||
935 | n = box->n_events; | ||
936 | box->event_list[n] = leader; | ||
937 | n++; | ||
938 | if (!dogrp) | ||
939 | return n; | ||
940 | |||
941 | list_for_each_entry(event, &leader->sibling_list, group_entry) { | ||
942 | if (event->state <= PERF_EVENT_STATE_OFF) | ||
943 | continue; | ||
944 | |||
945 | if (n >= max_count) | ||
946 | return -EINVAL; | ||
947 | |||
948 | box->event_list[n] = event; | ||
949 | n++; | ||
950 | } | ||
951 | return n; | ||
952 | } | ||
953 | |||
954 | static struct event_constraint * | ||
955 | uncore_get_event_constraint(struct intel_uncore_box *box, | ||
956 | struct perf_event *event) | ||
957 | { | ||
958 | struct intel_uncore_type *type = box->pmu->type; | ||
959 | struct event_constraint *c; | ||
960 | |||
961 | if (type->ops->get_constraint) { | ||
962 | c = type->ops->get_constraint(box, event); | ||
963 | if (c) | ||
964 | return c; | ||
965 | } | ||
966 | |||
967 | if (event->hw.config == ~0ULL) | ||
968 | return &constraint_fixed; | ||
969 | |||
970 | if (type->constraints) { | ||
971 | for_each_event_constraint(c, type->constraints) { | ||
972 | if ((event->hw.config & c->cmask) == c->code) | ||
973 | return c; | ||
974 | } | ||
975 | } | ||
976 | |||
977 | return &type->unconstrainted; | ||
978 | } | ||
979 | |||
980 | static void uncore_put_event_constraint(struct intel_uncore_box *box, | ||
981 | struct perf_event *event) | ||
982 | { | ||
983 | if (box->pmu->type->ops->put_constraint) | ||
984 | box->pmu->type->ops->put_constraint(box, event); | ||
985 | } | ||
986 | |||
987 | static int uncore_assign_events(struct intel_uncore_box *box, | ||
988 | int assign[], int n) | ||
989 | { | ||
990 | unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; | ||
991 | struct event_constraint *c, *constraints[UNCORE_PMC_IDX_MAX]; | ||
992 | int i, wmin, wmax, ret = 0; | ||
993 | struct hw_perf_event *hwc; | ||
994 | |||
995 | bitmap_zero(used_mask, UNCORE_PMC_IDX_MAX); | ||
996 | |||
997 | for (i = 0, wmin = UNCORE_PMC_IDX_MAX, wmax = 0; i < n; i++) { | ||
998 | c = uncore_get_event_constraint(box, box->event_list[i]); | ||
999 | constraints[i] = c; | ||
1000 | wmin = min(wmin, c->weight); | ||
1001 | wmax = max(wmax, c->weight); | ||
1002 | } | ||
1003 | |||
1004 | /* fastpath, try to reuse previous register */ | ||
1005 | for (i = 0; i < n; i++) { | ||
1006 | hwc = &box->event_list[i]->hw; | ||
1007 | c = constraints[i]; | ||
1008 | |||
1009 | /* never assigned */ | ||
1010 | if (hwc->idx == -1) | ||
1011 | break; | ||
1012 | |||
1013 | /* constraint still honored */ | ||
1014 | if (!test_bit(hwc->idx, c->idxmsk)) | ||
1015 | break; | ||
1016 | |||
1017 | /* not already used */ | ||
1018 | if (test_bit(hwc->idx, used_mask)) | ||
1019 | break; | ||
1020 | |||
1021 | __set_bit(hwc->idx, used_mask); | ||
1022 | if (assign) | ||
1023 | assign[i] = hwc->idx; | ||
1024 | } | ||
1025 | /* slow path */ | ||
1026 | if (i != n) | ||
1027 | ret = perf_assign_events(constraints, n, wmin, wmax, assign); | ||
1028 | |||
1029 | if (!assign || ret) { | ||
1030 | for (i = 0; i < n; i++) | ||
1031 | uncore_put_event_constraint(box, box->event_list[i]); | ||
1032 | } | ||
1033 | return ret ? -EINVAL : 0; | ||
1034 | } | ||
1035 | |||
1036 | static void uncore_pmu_event_start(struct perf_event *event, int flags) | ||
1037 | { | ||
1038 | struct intel_uncore_box *box = uncore_event_to_box(event); | ||
1039 | int idx = event->hw.idx; | ||
1040 | |||
1041 | if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) | ||
1042 | return; | ||
1043 | |||
1044 | if (WARN_ON_ONCE(idx == -1 || idx >= UNCORE_PMC_IDX_MAX)) | ||
1045 | return; | ||
1046 | |||
1047 | event->hw.state = 0; | ||
1048 | box->events[idx] = event; | ||
1049 | box->n_active++; | ||
1050 | __set_bit(idx, box->active_mask); | ||
1051 | |||
1052 | local64_set(&event->hw.prev_count, uncore_read_counter(box, event)); | ||
1053 | uncore_enable_event(box, event); | ||
1054 | |||
1055 | if (box->n_active == 1) { | ||
1056 | uncore_enable_box(box); | ||
1057 | uncore_pmu_start_hrtimer(box); | ||
1058 | } | ||
1059 | } | ||
1060 | |||
1061 | static void uncore_pmu_event_stop(struct perf_event *event, int flags) | ||
1062 | { | ||
1063 | struct intel_uncore_box *box = uncore_event_to_box(event); | ||
1064 | struct hw_perf_event *hwc = &event->hw; | ||
1065 | |||
1066 | if (__test_and_clear_bit(hwc->idx, box->active_mask)) { | ||
1067 | uncore_disable_event(box, event); | ||
1068 | box->n_active--; | ||
1069 | box->events[hwc->idx] = NULL; | ||
1070 | WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); | ||
1071 | hwc->state |= PERF_HES_STOPPED; | ||
1072 | |||
1073 | if (box->n_active == 0) { | ||
1074 | uncore_disable_box(box); | ||
1075 | uncore_pmu_cancel_hrtimer(box); | ||
1076 | } | ||
1077 | } | ||
1078 | |||
1079 | if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { | ||
1080 | /* | ||
1081 | * Drain the remaining delta count out of a event | ||
1082 | * that we are disabling: | ||
1083 | */ | ||
1084 | uncore_perf_event_update(box, event); | ||
1085 | hwc->state |= PERF_HES_UPTODATE; | ||
1086 | } | ||
1087 | } | ||
1088 | |||
1089 | static int uncore_pmu_event_add(struct perf_event *event, int flags) | ||
1090 | { | ||
1091 | struct intel_uncore_box *box = uncore_event_to_box(event); | ||
1092 | struct hw_perf_event *hwc = &event->hw; | ||
1093 | int assign[UNCORE_PMC_IDX_MAX]; | ||
1094 | int i, n, ret; | ||
1095 | |||
1096 | if (!box) | ||
1097 | return -ENODEV; | ||
1098 | |||
1099 | ret = n = uncore_collect_events(box, event, false); | ||
1100 | if (ret < 0) | ||
1101 | return ret; | ||
1102 | |||
1103 | hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; | ||
1104 | if (!(flags & PERF_EF_START)) | ||
1105 | hwc->state |= PERF_HES_ARCH; | ||
1106 | |||
1107 | ret = uncore_assign_events(box, assign, n); | ||
1108 | if (ret) | ||
1109 | return ret; | ||
1110 | |||
1111 | /* save events moving to new counters */ | ||
1112 | for (i = 0; i < box->n_events; i++) { | ||
1113 | event = box->event_list[i]; | ||
1114 | hwc = &event->hw; | ||
1115 | |||
1116 | if (hwc->idx == assign[i] && | ||
1117 | hwc->last_tag == box->tags[assign[i]]) | ||
1118 | continue; | ||
1119 | /* | ||
1120 | * Ensure we don't accidentally enable a stopped | ||
1121 | * counter simply because we rescheduled. | ||
1122 | */ | ||
1123 | if (hwc->state & PERF_HES_STOPPED) | ||
1124 | hwc->state |= PERF_HES_ARCH; | ||
1125 | |||
1126 | uncore_pmu_event_stop(event, PERF_EF_UPDATE); | ||
1127 | } | ||
1128 | |||
1129 | /* reprogram moved events into new counters */ | ||
1130 | for (i = 0; i < n; i++) { | ||
1131 | event = box->event_list[i]; | ||
1132 | hwc = &event->hw; | ||
1133 | |||
1134 | if (hwc->idx != assign[i] || | ||
1135 | hwc->last_tag != box->tags[assign[i]]) | ||
1136 | uncore_assign_hw_event(box, event, assign[i]); | ||
1137 | else if (i < box->n_events) | ||
1138 | continue; | ||
1139 | |||
1140 | if (hwc->state & PERF_HES_ARCH) | ||
1141 | continue; | ||
1142 | |||
1143 | uncore_pmu_event_start(event, 0); | ||
1144 | } | ||
1145 | box->n_events = n; | ||
1146 | |||
1147 | return 0; | ||
1148 | } | ||
1149 | |||
1150 | static void uncore_pmu_event_del(struct perf_event *event, int flags) | ||
1151 | { | ||
1152 | struct intel_uncore_box *box = uncore_event_to_box(event); | ||
1153 | int i; | ||
1154 | |||
1155 | uncore_pmu_event_stop(event, PERF_EF_UPDATE); | ||
1156 | |||
1157 | for (i = 0; i < box->n_events; i++) { | ||
1158 | if (event == box->event_list[i]) { | ||
1159 | uncore_put_event_constraint(box, event); | ||
1160 | |||
1161 | while (++i < box->n_events) | ||
1162 | box->event_list[i - 1] = box->event_list[i]; | ||
1163 | |||
1164 | --box->n_events; | ||
1165 | break; | ||
1166 | } | ||
1167 | } | ||
1168 | |||
1169 | event->hw.idx = -1; | ||
1170 | event->hw.last_tag = ~0ULL; | ||
1171 | } | ||
1172 | |||
1173 | static void uncore_pmu_event_read(struct perf_event *event) | ||
1174 | { | ||
1175 | struct intel_uncore_box *box = uncore_event_to_box(event); | ||
1176 | uncore_perf_event_update(box, event); | ||
1177 | } | ||
1178 | |||
1179 | /* | ||
1180 | * validation ensures the group can be loaded onto the | ||
1181 | * PMU if it was the only group available. | ||
1182 | */ | ||
1183 | static int uncore_validate_group(struct intel_uncore_pmu *pmu, | ||
1184 | struct perf_event *event) | ||
1185 | { | ||
1186 | struct perf_event *leader = event->group_leader; | ||
1187 | struct intel_uncore_box *fake_box; | ||
1188 | int ret = -EINVAL, n; | ||
1189 | |||
1190 | fake_box = uncore_alloc_box(pmu->type, smp_processor_id()); | ||
1191 | if (!fake_box) | ||
1192 | return -ENOMEM; | ||
1193 | |||
1194 | fake_box->pmu = pmu; | ||
1195 | /* | ||
1196 | * the event is not yet connected with its | ||
1197 | * siblings therefore we must first collect | ||
1198 | * existing siblings, then add the new event | ||
1199 | * before we can simulate the scheduling | ||
1200 | */ | ||
1201 | n = uncore_collect_events(fake_box, leader, true); | ||
1202 | if (n < 0) | ||
1203 | goto out; | ||
1204 | |||
1205 | fake_box->n_events = n; | ||
1206 | n = uncore_collect_events(fake_box, event, false); | ||
1207 | if (n < 0) | ||
1208 | goto out; | ||
1209 | |||
1210 | fake_box->n_events = n; | ||
1211 | |||
1212 | ret = uncore_assign_events(fake_box, NULL, n); | ||
1213 | out: | ||
1214 | kfree(fake_box); | ||
1215 | return ret; | ||
1216 | } | ||
1217 | |||
1218 | int uncore_pmu_event_init(struct perf_event *event) | ||
1219 | { | ||
1220 | struct intel_uncore_pmu *pmu; | ||
1221 | struct intel_uncore_box *box; | ||
1222 | struct hw_perf_event *hwc = &event->hw; | ||
1223 | int ret; | ||
1224 | |||
1225 | if (event->attr.type != event->pmu->type) | ||
1226 | return -ENOENT; | ||
1227 | |||
1228 | pmu = uncore_event_to_pmu(event); | ||
1229 | /* no device found for this pmu */ | ||
1230 | if (pmu->func_id < 0) | ||
1231 | return -ENOENT; | ||
1232 | |||
1233 | /* | ||
1234 | * Uncore PMU does measure at all privilege level all the time. | ||
1235 | * So it doesn't make sense to specify any exclude bits. | ||
1236 | */ | ||
1237 | if (event->attr.exclude_user || event->attr.exclude_kernel || | ||
1238 | event->attr.exclude_hv || event->attr.exclude_idle) | ||
1239 | return -EINVAL; | ||
1240 | |||
1241 | /* Sampling not supported yet */ | ||
1242 | if (hwc->sample_period) | ||
1243 | return -EINVAL; | ||
1244 | |||
1245 | /* | ||
1246 | * Place all uncore events for a particular physical package | ||
1247 | * onto a single cpu | ||
1248 | */ | ||
1249 | if (event->cpu < 0) | ||
1250 | return -EINVAL; | ||
1251 | box = uncore_pmu_to_box(pmu, event->cpu); | ||
1252 | if (!box || box->cpu < 0) | ||
1253 | return -EINVAL; | ||
1254 | event->cpu = box->cpu; | ||
1255 | |||
1256 | event->hw.idx = -1; | ||
1257 | event->hw.last_tag = ~0ULL; | ||
1258 | event->hw.extra_reg.idx = EXTRA_REG_NONE; | ||
1259 | |||
1260 | if (event->attr.config == UNCORE_FIXED_EVENT) { | ||
1261 | /* no fixed counter */ | ||
1262 | if (!pmu->type->fixed_ctl) | ||
1263 | return -EINVAL; | ||
1264 | /* | ||
1265 | * if there is only one fixed counter, only the first pmu | ||
1266 | * can access the fixed counter | ||
1267 | */ | ||
1268 | if (pmu->type->single_fixed && pmu->pmu_idx > 0) | ||
1269 | return -EINVAL; | ||
1270 | hwc->config = ~0ULL; | ||
1271 | } else { | ||
1272 | hwc->config = event->attr.config & pmu->type->event_mask; | ||
1273 | if (pmu->type->ops->hw_config) { | ||
1274 | ret = pmu->type->ops->hw_config(box, event); | ||
1275 | if (ret) | ||
1276 | return ret; | ||
1277 | } | ||
1278 | } | ||
1279 | |||
1280 | if (event->group_leader != event) | ||
1281 | ret = uncore_validate_group(pmu, event); | ||
1282 | else | ||
1283 | ret = 0; | ||
1284 | |||
1285 | return ret; | ||
1286 | } | ||
1287 | |||
1288 | static int __init uncore_pmu_register(struct intel_uncore_pmu *pmu) | ||
1289 | { | ||
1290 | int ret; | ||
1291 | |||
1292 | pmu->pmu = (struct pmu) { | ||
1293 | .attr_groups = pmu->type->attr_groups, | ||
1294 | .task_ctx_nr = perf_invalid_context, | ||
1295 | .event_init = uncore_pmu_event_init, | ||
1296 | .add = uncore_pmu_event_add, | ||
1297 | .del = uncore_pmu_event_del, | ||
1298 | .start = uncore_pmu_event_start, | ||
1299 | .stop = uncore_pmu_event_stop, | ||
1300 | .read = uncore_pmu_event_read, | ||
1301 | }; | ||
1302 | |||
1303 | if (pmu->type->num_boxes == 1) { | ||
1304 | if (strlen(pmu->type->name) > 0) | ||
1305 | sprintf(pmu->name, "uncore_%s", pmu->type->name); | ||
1306 | else | ||
1307 | sprintf(pmu->name, "uncore"); | ||
1308 | } else { | ||
1309 | sprintf(pmu->name, "uncore_%s_%d", pmu->type->name, | ||
1310 | pmu->pmu_idx); | ||
1311 | } | ||
1312 | |||
1313 | ret = perf_pmu_register(&pmu->pmu, pmu->name, -1); | ||
1314 | return ret; | ||
1315 | } | ||
1316 | |||
1317 | static void __init uncore_type_exit(struct intel_uncore_type *type) | ||
1318 | { | ||
1319 | int i; | ||
1320 | |||
1321 | for (i = 0; i < type->num_boxes; i++) | ||
1322 | free_percpu(type->pmus[i].box); | ||
1323 | kfree(type->pmus); | ||
1324 | type->pmus = NULL; | ||
1325 | kfree(type->attr_groups[1]); | ||
1326 | type->attr_groups[1] = NULL; | ||
1327 | } | ||
1328 | |||
1329 | static void uncore_types_exit(struct intel_uncore_type **types) | ||
1330 | { | ||
1331 | int i; | ||
1332 | for (i = 0; types[i]; i++) | ||
1333 | uncore_type_exit(types[i]); | ||
1334 | } | ||
1335 | |||
1336 | static int __init uncore_type_init(struct intel_uncore_type *type) | ||
1337 | { | ||
1338 | struct intel_uncore_pmu *pmus; | ||
1339 | struct attribute_group *events_group; | ||
1340 | struct attribute **attrs; | ||
1341 | int i, j; | ||
1342 | |||
1343 | pmus = kzalloc(sizeof(*pmus) * type->num_boxes, GFP_KERNEL); | ||
1344 | if (!pmus) | ||
1345 | return -ENOMEM; | ||
1346 | |||
1347 | type->unconstrainted = (struct event_constraint) | ||
1348 | __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1, | ||
1349 | 0, type->num_counters, 0); | ||
1350 | |||
1351 | for (i = 0; i < type->num_boxes; i++) { | ||
1352 | pmus[i].func_id = -1; | ||
1353 | pmus[i].pmu_idx = i; | ||
1354 | pmus[i].type = type; | ||
1355 | INIT_LIST_HEAD(&pmus[i].box_list); | ||
1356 | pmus[i].box = alloc_percpu(struct intel_uncore_box *); | ||
1357 | if (!pmus[i].box) | ||
1358 | goto fail; | ||
1359 | } | ||
1360 | |||
1361 | if (type->event_descs) { | ||
1362 | i = 0; | ||
1363 | while (type->event_descs[i].attr.attr.name) | ||
1364 | i++; | ||
1365 | |||
1366 | events_group = kzalloc(sizeof(struct attribute *) * (i + 1) + | ||
1367 | sizeof(*events_group), GFP_KERNEL); | ||
1368 | if (!events_group) | ||
1369 | goto fail; | ||
1370 | |||
1371 | attrs = (struct attribute **)(events_group + 1); | ||
1372 | events_group->name = "events"; | ||
1373 | events_group->attrs = attrs; | ||
1374 | |||
1375 | for (j = 0; j < i; j++) | ||
1376 | attrs[j] = &type->event_descs[j].attr.attr; | ||
1377 | |||
1378 | type->attr_groups[1] = events_group; | ||
1379 | } | ||
1380 | |||
1381 | type->pmus = pmus; | ||
1382 | return 0; | ||
1383 | fail: | ||
1384 | uncore_type_exit(type); | ||
1385 | return -ENOMEM; | ||
1386 | } | ||
1387 | |||
1388 | static int __init uncore_types_init(struct intel_uncore_type **types) | ||
1389 | { | ||
1390 | int i, ret; | ||
1391 | |||
1392 | for (i = 0; types[i]; i++) { | ||
1393 | ret = uncore_type_init(types[i]); | ||
1394 | if (ret) | ||
1395 | goto fail; | ||
1396 | } | ||
1397 | return 0; | ||
1398 | fail: | ||
1399 | while (--i >= 0) | ||
1400 | uncore_type_exit(types[i]); | ||
1401 | return ret; | ||
1402 | } | ||
1403 | |||
1404 | static struct pci_driver *uncore_pci_driver; | ||
1405 | static bool pcidrv_registered; | ||
1406 | |||
1407 | /* | ||
1408 | * add a pci uncore device | ||
1409 | */ | ||
1410 | static int __devinit uncore_pci_add(struct intel_uncore_type *type, | ||
1411 | struct pci_dev *pdev) | ||
1412 | { | ||
1413 | struct intel_uncore_pmu *pmu; | ||
1414 | struct intel_uncore_box *box; | ||
1415 | int i, phys_id; | ||
1416 | |||
1417 | phys_id = pcibus_to_physid[pdev->bus->number]; | ||
1418 | if (phys_id < 0) | ||
1419 | return -ENODEV; | ||
1420 | |||
1421 | box = uncore_alloc_box(type, 0); | ||
1422 | if (!box) | ||
1423 | return -ENOMEM; | ||
1424 | |||
1425 | /* | ||
1426 | * for performance monitoring unit with multiple boxes, | ||
1427 | * each box has a different function id. | ||
1428 | */ | ||
1429 | for (i = 0; i < type->num_boxes; i++) { | ||
1430 | pmu = &type->pmus[i]; | ||
1431 | if (pmu->func_id == pdev->devfn) | ||
1432 | break; | ||
1433 | if (pmu->func_id < 0) { | ||
1434 | pmu->func_id = pdev->devfn; | ||
1435 | break; | ||
1436 | } | ||
1437 | pmu = NULL; | ||
1438 | } | ||
1439 | |||
1440 | if (!pmu) { | ||
1441 | kfree(box); | ||
1442 | return -EINVAL; | ||
1443 | } | ||
1444 | |||
1445 | box->phys_id = phys_id; | ||
1446 | box->pci_dev = pdev; | ||
1447 | box->pmu = pmu; | ||
1448 | uncore_box_init(box); | ||
1449 | pci_set_drvdata(pdev, box); | ||
1450 | |||
1451 | raw_spin_lock(&uncore_box_lock); | ||
1452 | list_add_tail(&box->list, &pmu->box_list); | ||
1453 | raw_spin_unlock(&uncore_box_lock); | ||
1454 | |||
1455 | return 0; | ||
1456 | } | ||
1457 | |||
1458 | static void uncore_pci_remove(struct pci_dev *pdev) | ||
1459 | { | ||
1460 | struct intel_uncore_box *box = pci_get_drvdata(pdev); | ||
1461 | struct intel_uncore_pmu *pmu = box->pmu; | ||
1462 | int cpu, phys_id = pcibus_to_physid[pdev->bus->number]; | ||
1463 | |||
1464 | if (WARN_ON_ONCE(phys_id != box->phys_id)) | ||
1465 | return; | ||
1466 | |||
1467 | raw_spin_lock(&uncore_box_lock); | ||
1468 | list_del(&box->list); | ||
1469 | raw_spin_unlock(&uncore_box_lock); | ||
1470 | |||
1471 | for_each_possible_cpu(cpu) { | ||
1472 | if (*per_cpu_ptr(pmu->box, cpu) == box) { | ||
1473 | *per_cpu_ptr(pmu->box, cpu) = NULL; | ||
1474 | atomic_dec(&box->refcnt); | ||
1475 | } | ||
1476 | } | ||
1477 | |||
1478 | WARN_ON_ONCE(atomic_read(&box->refcnt) != 1); | ||
1479 | kfree(box); | ||
1480 | } | ||
1481 | |||
1482 | static int __devinit uncore_pci_probe(struct pci_dev *pdev, | ||
1483 | const struct pci_device_id *id) | ||
1484 | { | ||
1485 | struct intel_uncore_type *type; | ||
1486 | |||
1487 | type = (struct intel_uncore_type *)id->driver_data; | ||
1488 | return uncore_pci_add(type, pdev); | ||
1489 | } | ||
1490 | |||
1491 | static int __init uncore_pci_init(void) | ||
1492 | { | ||
1493 | int ret; | ||
1494 | |||
1495 | switch (boot_cpu_data.x86_model) { | ||
1496 | case 45: /* Sandy Bridge-EP */ | ||
1497 | pci_uncores = snbep_pci_uncores; | ||
1498 | uncore_pci_driver = &snbep_uncore_pci_driver; | ||
1499 | snbep_pci2phy_map_init(); | ||
1500 | break; | ||
1501 | default: | ||
1502 | return 0; | ||
1503 | } | ||
1504 | |||
1505 | ret = uncore_types_init(pci_uncores); | ||
1506 | if (ret) | ||
1507 | return ret; | ||
1508 | |||
1509 | uncore_pci_driver->probe = uncore_pci_probe; | ||
1510 | uncore_pci_driver->remove = uncore_pci_remove; | ||
1511 | |||
1512 | ret = pci_register_driver(uncore_pci_driver); | ||
1513 | if (ret == 0) | ||
1514 | pcidrv_registered = true; | ||
1515 | else | ||
1516 | uncore_types_exit(pci_uncores); | ||
1517 | |||
1518 | return ret; | ||
1519 | } | ||
1520 | |||
1521 | static void __init uncore_pci_exit(void) | ||
1522 | { | ||
1523 | if (pcidrv_registered) { | ||
1524 | pcidrv_registered = false; | ||
1525 | pci_unregister_driver(uncore_pci_driver); | ||
1526 | uncore_types_exit(pci_uncores); | ||
1527 | } | ||
1528 | } | ||
1529 | |||
1530 | static void __cpuinit uncore_cpu_dying(int cpu) | ||
1531 | { | ||
1532 | struct intel_uncore_type *type; | ||
1533 | struct intel_uncore_pmu *pmu; | ||
1534 | struct intel_uncore_box *box; | ||
1535 | int i, j; | ||
1536 | |||
1537 | for (i = 0; msr_uncores[i]; i++) { | ||
1538 | type = msr_uncores[i]; | ||
1539 | for (j = 0; j < type->num_boxes; j++) { | ||
1540 | pmu = &type->pmus[j]; | ||
1541 | box = *per_cpu_ptr(pmu->box, cpu); | ||
1542 | *per_cpu_ptr(pmu->box, cpu) = NULL; | ||
1543 | if (box && atomic_dec_and_test(&box->refcnt)) | ||
1544 | kfree(box); | ||
1545 | } | ||
1546 | } | ||
1547 | } | ||
1548 | |||
1549 | static int __cpuinit uncore_cpu_starting(int cpu) | ||
1550 | { | ||
1551 | struct intel_uncore_type *type; | ||
1552 | struct intel_uncore_pmu *pmu; | ||
1553 | struct intel_uncore_box *box, *exist; | ||
1554 | int i, j, k, phys_id; | ||
1555 | |||
1556 | phys_id = topology_physical_package_id(cpu); | ||
1557 | |||
1558 | for (i = 0; msr_uncores[i]; i++) { | ||
1559 | type = msr_uncores[i]; | ||
1560 | for (j = 0; j < type->num_boxes; j++) { | ||
1561 | pmu = &type->pmus[j]; | ||
1562 | box = *per_cpu_ptr(pmu->box, cpu); | ||
1563 | /* called by uncore_cpu_init? */ | ||
1564 | if (box && box->phys_id >= 0) { | ||
1565 | uncore_box_init(box); | ||
1566 | continue; | ||
1567 | } | ||
1568 | |||
1569 | for_each_online_cpu(k) { | ||
1570 | exist = *per_cpu_ptr(pmu->box, k); | ||
1571 | if (exist && exist->phys_id == phys_id) { | ||
1572 | atomic_inc(&exist->refcnt); | ||
1573 | *per_cpu_ptr(pmu->box, cpu) = exist; | ||
1574 | kfree(box); | ||
1575 | box = NULL; | ||
1576 | break; | ||
1577 | } | ||
1578 | } | ||
1579 | |||
1580 | if (box) { | ||
1581 | box->phys_id = phys_id; | ||
1582 | uncore_box_init(box); | ||
1583 | } | ||
1584 | } | ||
1585 | } | ||
1586 | return 0; | ||
1587 | } | ||
1588 | |||
1589 | static int __cpuinit uncore_cpu_prepare(int cpu, int phys_id) | ||
1590 | { | ||
1591 | struct intel_uncore_type *type; | ||
1592 | struct intel_uncore_pmu *pmu; | ||
1593 | struct intel_uncore_box *box; | ||
1594 | int i, j; | ||
1595 | |||
1596 | for (i = 0; msr_uncores[i]; i++) { | ||
1597 | type = msr_uncores[i]; | ||
1598 | for (j = 0; j < type->num_boxes; j++) { | ||
1599 | pmu = &type->pmus[j]; | ||
1600 | if (pmu->func_id < 0) | ||
1601 | pmu->func_id = j; | ||
1602 | |||
1603 | box = uncore_alloc_box(type, cpu); | ||
1604 | if (!box) | ||
1605 | return -ENOMEM; | ||
1606 | |||
1607 | box->pmu = pmu; | ||
1608 | box->phys_id = phys_id; | ||
1609 | *per_cpu_ptr(pmu->box, cpu) = box; | ||
1610 | } | ||
1611 | } | ||
1612 | return 0; | ||
1613 | } | ||
1614 | |||
1615 | static void __cpuinit uncore_change_context(struct intel_uncore_type **uncores, | ||
1616 | int old_cpu, int new_cpu) | ||
1617 | { | ||
1618 | struct intel_uncore_type *type; | ||
1619 | struct intel_uncore_pmu *pmu; | ||
1620 | struct intel_uncore_box *box; | ||
1621 | int i, j; | ||
1622 | |||
1623 | for (i = 0; uncores[i]; i++) { | ||
1624 | type = uncores[i]; | ||
1625 | for (j = 0; j < type->num_boxes; j++) { | ||
1626 | pmu = &type->pmus[j]; | ||
1627 | if (old_cpu < 0) | ||
1628 | box = uncore_pmu_to_box(pmu, new_cpu); | ||
1629 | else | ||
1630 | box = uncore_pmu_to_box(pmu, old_cpu); | ||
1631 | if (!box) | ||
1632 | continue; | ||
1633 | |||
1634 | if (old_cpu < 0) { | ||
1635 | WARN_ON_ONCE(box->cpu != -1); | ||
1636 | box->cpu = new_cpu; | ||
1637 | continue; | ||
1638 | } | ||
1639 | |||
1640 | WARN_ON_ONCE(box->cpu != old_cpu); | ||
1641 | if (new_cpu >= 0) { | ||
1642 | uncore_pmu_cancel_hrtimer(box); | ||
1643 | perf_pmu_migrate_context(&pmu->pmu, | ||
1644 | old_cpu, new_cpu); | ||
1645 | box->cpu = new_cpu; | ||
1646 | } else { | ||
1647 | box->cpu = -1; | ||
1648 | } | ||
1649 | } | ||
1650 | } | ||
1651 | } | ||
1652 | |||
1653 | static void __cpuinit uncore_event_exit_cpu(int cpu) | ||
1654 | { | ||
1655 | int i, phys_id, target; | ||
1656 | |||
1657 | /* if exiting cpu is used for collecting uncore events */ | ||
1658 | if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask)) | ||
1659 | return; | ||
1660 | |||
1661 | /* find a new cpu to collect uncore events */ | ||
1662 | phys_id = topology_physical_package_id(cpu); | ||
1663 | target = -1; | ||
1664 | for_each_online_cpu(i) { | ||
1665 | if (i == cpu) | ||
1666 | continue; | ||
1667 | if (phys_id == topology_physical_package_id(i)) { | ||
1668 | target = i; | ||
1669 | break; | ||
1670 | } | ||
1671 | } | ||
1672 | |||
1673 | /* migrate uncore events to the new cpu */ | ||
1674 | if (target >= 0) | ||
1675 | cpumask_set_cpu(target, &uncore_cpu_mask); | ||
1676 | |||
1677 | uncore_change_context(msr_uncores, cpu, target); | ||
1678 | uncore_change_context(pci_uncores, cpu, target); | ||
1679 | } | ||
1680 | |||
1681 | static void __cpuinit uncore_event_init_cpu(int cpu) | ||
1682 | { | ||
1683 | int i, phys_id; | ||
1684 | |||
1685 | phys_id = topology_physical_package_id(cpu); | ||
1686 | for_each_cpu(i, &uncore_cpu_mask) { | ||
1687 | if (phys_id == topology_physical_package_id(i)) | ||
1688 | return; | ||
1689 | } | ||
1690 | |||
1691 | cpumask_set_cpu(cpu, &uncore_cpu_mask); | ||
1692 | |||
1693 | uncore_change_context(msr_uncores, -1, cpu); | ||
1694 | uncore_change_context(pci_uncores, -1, cpu); | ||
1695 | } | ||
1696 | |||
1697 | static int __cpuinit uncore_cpu_notifier(struct notifier_block *self, | ||
1698 | unsigned long action, void *hcpu) | ||
1699 | { | ||
1700 | unsigned int cpu = (long)hcpu; | ||
1701 | |||
1702 | /* allocate/free data structure for uncore box */ | ||
1703 | switch (action & ~CPU_TASKS_FROZEN) { | ||
1704 | case CPU_UP_PREPARE: | ||
1705 | uncore_cpu_prepare(cpu, -1); | ||
1706 | break; | ||
1707 | case CPU_STARTING: | ||
1708 | uncore_cpu_starting(cpu); | ||
1709 | break; | ||
1710 | case CPU_UP_CANCELED: | ||
1711 | case CPU_DYING: | ||
1712 | uncore_cpu_dying(cpu); | ||
1713 | break; | ||
1714 | default: | ||
1715 | break; | ||
1716 | } | ||
1717 | |||
1718 | /* select the cpu that collects uncore events */ | ||
1719 | switch (action & ~CPU_TASKS_FROZEN) { | ||
1720 | case CPU_DOWN_FAILED: | ||
1721 | case CPU_STARTING: | ||
1722 | uncore_event_init_cpu(cpu); | ||
1723 | break; | ||
1724 | case CPU_DOWN_PREPARE: | ||
1725 | uncore_event_exit_cpu(cpu); | ||
1726 | break; | ||
1727 | default: | ||
1728 | break; | ||
1729 | } | ||
1730 | |||
1731 | return NOTIFY_OK; | ||
1732 | } | ||
1733 | |||
1734 | static struct notifier_block uncore_cpu_nb __cpuinitdata = { | ||
1735 | .notifier_call = uncore_cpu_notifier, | ||
1736 | /* | ||
1737 | * to migrate uncore events, our notifier should be executed | ||
1738 | * before perf core's notifier. | ||
1739 | */ | ||
1740 | .priority = CPU_PRI_PERF + 1, | ||
1741 | }; | ||
1742 | |||
1743 | static void __init uncore_cpu_setup(void *dummy) | ||
1744 | { | ||
1745 | uncore_cpu_starting(smp_processor_id()); | ||
1746 | } | ||
1747 | |||
1748 | static int __init uncore_cpu_init(void) | ||
1749 | { | ||
1750 | int ret, cpu, max_cores; | ||
1751 | |||
1752 | max_cores = boot_cpu_data.x86_max_cores; | ||
1753 | switch (boot_cpu_data.x86_model) { | ||
1754 | case 26: /* Nehalem */ | ||
1755 | case 30: | ||
1756 | case 37: /* Westmere */ | ||
1757 | case 44: | ||
1758 | msr_uncores = nhm_msr_uncores; | ||
1759 | break; | ||
1760 | case 42: /* Sandy Bridge */ | ||
1761 | if (snb_uncore_cbox.num_boxes > max_cores) | ||
1762 | snb_uncore_cbox.num_boxes = max_cores; | ||
1763 | msr_uncores = snb_msr_uncores; | ||
1764 | break; | ||
1765 | case 45: /* Sandy Birdge-EP */ | ||
1766 | if (snbep_uncore_cbox.num_boxes > max_cores) | ||
1767 | snbep_uncore_cbox.num_boxes = max_cores; | ||
1768 | msr_uncores = snbep_msr_uncores; | ||
1769 | break; | ||
1770 | default: | ||
1771 | return 0; | ||
1772 | } | ||
1773 | |||
1774 | ret = uncore_types_init(msr_uncores); | ||
1775 | if (ret) | ||
1776 | return ret; | ||
1777 | |||
1778 | get_online_cpus(); | ||
1779 | |||
1780 | for_each_online_cpu(cpu) { | ||
1781 | int i, phys_id = topology_physical_package_id(cpu); | ||
1782 | |||
1783 | for_each_cpu(i, &uncore_cpu_mask) { | ||
1784 | if (phys_id == topology_physical_package_id(i)) { | ||
1785 | phys_id = -1; | ||
1786 | break; | ||
1787 | } | ||
1788 | } | ||
1789 | if (phys_id < 0) | ||
1790 | continue; | ||
1791 | |||
1792 | uncore_cpu_prepare(cpu, phys_id); | ||
1793 | uncore_event_init_cpu(cpu); | ||
1794 | } | ||
1795 | on_each_cpu(uncore_cpu_setup, NULL, 1); | ||
1796 | |||
1797 | register_cpu_notifier(&uncore_cpu_nb); | ||
1798 | |||
1799 | put_online_cpus(); | ||
1800 | |||
1801 | return 0; | ||
1802 | } | ||
1803 | |||
1804 | static int __init uncore_pmus_register(void) | ||
1805 | { | ||
1806 | struct intel_uncore_pmu *pmu; | ||
1807 | struct intel_uncore_type *type; | ||
1808 | int i, j; | ||
1809 | |||
1810 | for (i = 0; msr_uncores[i]; i++) { | ||
1811 | type = msr_uncores[i]; | ||
1812 | for (j = 0; j < type->num_boxes; j++) { | ||
1813 | pmu = &type->pmus[j]; | ||
1814 | uncore_pmu_register(pmu); | ||
1815 | } | ||
1816 | } | ||
1817 | |||
1818 | for (i = 0; pci_uncores[i]; i++) { | ||
1819 | type = pci_uncores[i]; | ||
1820 | for (j = 0; j < type->num_boxes; j++) { | ||
1821 | pmu = &type->pmus[j]; | ||
1822 | uncore_pmu_register(pmu); | ||
1823 | } | ||
1824 | } | ||
1825 | |||
1826 | return 0; | ||
1827 | } | ||
1828 | |||
1829 | static int __init intel_uncore_init(void) | ||
1830 | { | ||
1831 | int ret; | ||
1832 | |||
1833 | if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) | ||
1834 | return -ENODEV; | ||
1835 | |||
1836 | ret = uncore_pci_init(); | ||
1837 | if (ret) | ||
1838 | goto fail; | ||
1839 | ret = uncore_cpu_init(); | ||
1840 | if (ret) { | ||
1841 | uncore_pci_exit(); | ||
1842 | goto fail; | ||
1843 | } | ||
1844 | |||
1845 | uncore_pmus_register(); | ||
1846 | return 0; | ||
1847 | fail: | ||
1848 | return ret; | ||
1849 | } | ||
1850 | device_initcall(intel_uncore_init); | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h new file mode 100644 index 000000000000..b13e9ea81def --- /dev/null +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h | |||
@@ -0,0 +1,424 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/slab.h> | ||
3 | #include <linux/pci.h> | ||
4 | #include <linux/perf_event.h> | ||
5 | #include "perf_event.h" | ||
6 | |||
7 | #define UNCORE_PMU_NAME_LEN 32 | ||
8 | #define UNCORE_BOX_HASH_SIZE 8 | ||
9 | |||
10 | #define UNCORE_PMU_HRTIMER_INTERVAL (60 * NSEC_PER_SEC) | ||
11 | |||
12 | #define UNCORE_FIXED_EVENT 0xff | ||
13 | #define UNCORE_PMC_IDX_MAX_GENERIC 8 | ||
14 | #define UNCORE_PMC_IDX_FIXED UNCORE_PMC_IDX_MAX_GENERIC | ||
15 | #define UNCORE_PMC_IDX_MAX (UNCORE_PMC_IDX_FIXED + 1) | ||
16 | |||
17 | #define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) | ||
18 | |||
19 | /* SNB event control */ | ||
20 | #define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff | ||
21 | #define SNB_UNC_CTL_UMASK_MASK 0x0000ff00 | ||
22 | #define SNB_UNC_CTL_EDGE_DET (1 << 18) | ||
23 | #define SNB_UNC_CTL_EN (1 << 22) | ||
24 | #define SNB_UNC_CTL_INVERT (1 << 23) | ||
25 | #define SNB_UNC_CTL_CMASK_MASK 0x1f000000 | ||
26 | #define NHM_UNC_CTL_CMASK_MASK 0xff000000 | ||
27 | #define NHM_UNC_FIXED_CTR_CTL_EN (1 << 0) | ||
28 | |||
29 | #define SNB_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ | ||
30 | SNB_UNC_CTL_UMASK_MASK | \ | ||
31 | SNB_UNC_CTL_EDGE_DET | \ | ||
32 | SNB_UNC_CTL_INVERT | \ | ||
33 | SNB_UNC_CTL_CMASK_MASK) | ||
34 | |||
35 | #define NHM_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ | ||
36 | SNB_UNC_CTL_UMASK_MASK | \ | ||
37 | SNB_UNC_CTL_EDGE_DET | \ | ||
38 | SNB_UNC_CTL_INVERT | \ | ||
39 | NHM_UNC_CTL_CMASK_MASK) | ||
40 | |||
41 | /* SNB global control register */ | ||
42 | #define SNB_UNC_PERF_GLOBAL_CTL 0x391 | ||
43 | #define SNB_UNC_FIXED_CTR_CTRL 0x394 | ||
44 | #define SNB_UNC_FIXED_CTR 0x395 | ||
45 | |||
46 | /* SNB uncore global control */ | ||
47 | #define SNB_UNC_GLOBAL_CTL_CORE_ALL ((1 << 4) - 1) | ||
48 | #define SNB_UNC_GLOBAL_CTL_EN (1 << 29) | ||
49 | |||
50 | /* SNB Cbo register */ | ||
51 | #define SNB_UNC_CBO_0_PERFEVTSEL0 0x700 | ||
52 | #define SNB_UNC_CBO_0_PER_CTR0 0x706 | ||
53 | #define SNB_UNC_CBO_MSR_OFFSET 0x10 | ||
54 | |||
55 | /* NHM global control register */ | ||
56 | #define NHM_UNC_PERF_GLOBAL_CTL 0x391 | ||
57 | #define NHM_UNC_FIXED_CTR 0x394 | ||
58 | #define NHM_UNC_FIXED_CTR_CTRL 0x395 | ||
59 | |||
60 | /* NHM uncore global control */ | ||
61 | #define NHM_UNC_GLOBAL_CTL_EN_PC_ALL ((1ULL << 8) - 1) | ||
62 | #define NHM_UNC_GLOBAL_CTL_EN_FC (1ULL << 32) | ||
63 | |||
64 | /* NHM uncore register */ | ||
65 | #define NHM_UNC_PERFEVTSEL0 0x3c0 | ||
66 | #define NHM_UNC_UNCORE_PMC0 0x3b0 | ||
67 | |||
68 | /* SNB-EP Box level control */ | ||
69 | #define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0) | ||
70 | #define SNBEP_PMON_BOX_CTL_RST_CTRS (1 << 1) | ||
71 | #define SNBEP_PMON_BOX_CTL_FRZ (1 << 8) | ||
72 | #define SNBEP_PMON_BOX_CTL_FRZ_EN (1 << 16) | ||
73 | #define SNBEP_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \ | ||
74 | SNBEP_PMON_BOX_CTL_RST_CTRS | \ | ||
75 | SNBEP_PMON_BOX_CTL_FRZ_EN) | ||
76 | /* SNB-EP event control */ | ||
77 | #define SNBEP_PMON_CTL_EV_SEL_MASK 0x000000ff | ||
78 | #define SNBEP_PMON_CTL_UMASK_MASK 0x0000ff00 | ||
79 | #define SNBEP_PMON_CTL_RST (1 << 17) | ||
80 | #define SNBEP_PMON_CTL_EDGE_DET (1 << 18) | ||
81 | #define SNBEP_PMON_CTL_EV_SEL_EXT (1 << 21) /* only for QPI */ | ||
82 | #define SNBEP_PMON_CTL_EN (1 << 22) | ||
83 | #define SNBEP_PMON_CTL_INVERT (1 << 23) | ||
84 | #define SNBEP_PMON_CTL_TRESH_MASK 0xff000000 | ||
85 | #define SNBEP_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \ | ||
86 | SNBEP_PMON_CTL_UMASK_MASK | \ | ||
87 | SNBEP_PMON_CTL_EDGE_DET | \ | ||
88 | SNBEP_PMON_CTL_INVERT | \ | ||
89 | SNBEP_PMON_CTL_TRESH_MASK) | ||
90 | |||
91 | /* SNB-EP Ubox event control */ | ||
92 | #define SNBEP_U_MSR_PMON_CTL_TRESH_MASK 0x1f000000 | ||
93 | #define SNBEP_U_MSR_PMON_RAW_EVENT_MASK \ | ||
94 | (SNBEP_PMON_CTL_EV_SEL_MASK | \ | ||
95 | SNBEP_PMON_CTL_UMASK_MASK | \ | ||
96 | SNBEP_PMON_CTL_EDGE_DET | \ | ||
97 | SNBEP_PMON_CTL_INVERT | \ | ||
98 | SNBEP_U_MSR_PMON_CTL_TRESH_MASK) | ||
99 | |||
100 | #define SNBEP_CBO_PMON_CTL_TID_EN (1 << 19) | ||
101 | #define SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK (SNBEP_PMON_RAW_EVENT_MASK | \ | ||
102 | SNBEP_CBO_PMON_CTL_TID_EN) | ||
103 | |||
104 | /* SNB-EP PCU event control */ | ||
105 | #define SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK 0x0000c000 | ||
106 | #define SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK 0x1f000000 | ||
107 | #define SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT (1 << 30) | ||
108 | #define SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET (1 << 31) | ||
109 | #define SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK \ | ||
110 | (SNBEP_PMON_CTL_EV_SEL_MASK | \ | ||
111 | SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ | ||
112 | SNBEP_PMON_CTL_EDGE_DET | \ | ||
113 | SNBEP_PMON_CTL_INVERT | \ | ||
114 | SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ | ||
115 | SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ | ||
116 | SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) | ||
117 | |||
118 | /* SNB-EP pci control register */ | ||
119 | #define SNBEP_PCI_PMON_BOX_CTL 0xf4 | ||
120 | #define SNBEP_PCI_PMON_CTL0 0xd8 | ||
121 | /* SNB-EP pci counter register */ | ||
122 | #define SNBEP_PCI_PMON_CTR0 0xa0 | ||
123 | |||
124 | /* SNB-EP home agent register */ | ||
125 | #define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH0 0x40 | ||
126 | #define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH1 0x44 | ||
127 | #define SNBEP_HA_PCI_PMON_BOX_OPCODEMATCH 0x48 | ||
128 | /* SNB-EP memory controller register */ | ||
129 | #define SNBEP_MC_CHy_PCI_PMON_FIXED_CTL 0xf0 | ||
130 | #define SNBEP_MC_CHy_PCI_PMON_FIXED_CTR 0xd0 | ||
131 | /* SNB-EP QPI register */ | ||
132 | #define SNBEP_Q_Py_PCI_PMON_PKT_MATCH0 0x228 | ||
133 | #define SNBEP_Q_Py_PCI_PMON_PKT_MATCH1 0x22c | ||
134 | #define SNBEP_Q_Py_PCI_PMON_PKT_MASK0 0x238 | ||
135 | #define SNBEP_Q_Py_PCI_PMON_PKT_MASK1 0x23c | ||
136 | |||
137 | /* SNB-EP Ubox register */ | ||
138 | #define SNBEP_U_MSR_PMON_CTR0 0xc16 | ||
139 | #define SNBEP_U_MSR_PMON_CTL0 0xc10 | ||
140 | |||
141 | #define SNBEP_U_MSR_PMON_UCLK_FIXED_CTL 0xc08 | ||
142 | #define SNBEP_U_MSR_PMON_UCLK_FIXED_CTR 0xc09 | ||
143 | |||
144 | /* SNB-EP Cbo register */ | ||
145 | #define SNBEP_C0_MSR_PMON_CTR0 0xd16 | ||
146 | #define SNBEP_C0_MSR_PMON_CTL0 0xd10 | ||
147 | #define SNBEP_C0_MSR_PMON_BOX_CTL 0xd04 | ||
148 | #define SNBEP_C0_MSR_PMON_BOX_FILTER 0xd14 | ||
149 | #define SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK 0xfffffc1f | ||
150 | #define SNBEP_CBO_MSR_OFFSET 0x20 | ||
151 | |||
152 | /* SNB-EP PCU register */ | ||
153 | #define SNBEP_PCU_MSR_PMON_CTR0 0xc36 | ||
154 | #define SNBEP_PCU_MSR_PMON_CTL0 0xc30 | ||
155 | #define SNBEP_PCU_MSR_PMON_BOX_CTL 0xc24 | ||
156 | #define SNBEP_PCU_MSR_PMON_BOX_FILTER 0xc34 | ||
157 | #define SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK 0xffffffff | ||
158 | #define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc | ||
159 | #define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd | ||
160 | |||
161 | struct intel_uncore_ops; | ||
162 | struct intel_uncore_pmu; | ||
163 | struct intel_uncore_box; | ||
164 | struct uncore_event_desc; | ||
165 | |||
166 | struct intel_uncore_type { | ||
167 | const char *name; | ||
168 | int num_counters; | ||
169 | int num_boxes; | ||
170 | int perf_ctr_bits; | ||
171 | int fixed_ctr_bits; | ||
172 | unsigned perf_ctr; | ||
173 | unsigned event_ctl; | ||
174 | unsigned event_mask; | ||
175 | unsigned fixed_ctr; | ||
176 | unsigned fixed_ctl; | ||
177 | unsigned box_ctl; | ||
178 | unsigned msr_offset; | ||
179 | unsigned num_shared_regs:8; | ||
180 | unsigned single_fixed:1; | ||
181 | struct event_constraint unconstrainted; | ||
182 | struct event_constraint *constraints; | ||
183 | struct intel_uncore_pmu *pmus; | ||
184 | struct intel_uncore_ops *ops; | ||
185 | struct uncore_event_desc *event_descs; | ||
186 | const struct attribute_group *attr_groups[3]; | ||
187 | }; | ||
188 | |||
189 | #define format_group attr_groups[0] | ||
190 | |||
191 | struct intel_uncore_ops { | ||
192 | void (*init_box)(struct intel_uncore_box *); | ||
193 | void (*disable_box)(struct intel_uncore_box *); | ||
194 | void (*enable_box)(struct intel_uncore_box *); | ||
195 | void (*disable_event)(struct intel_uncore_box *, struct perf_event *); | ||
196 | void (*enable_event)(struct intel_uncore_box *, struct perf_event *); | ||
197 | u64 (*read_counter)(struct intel_uncore_box *, struct perf_event *); | ||
198 | int (*hw_config)(struct intel_uncore_box *, struct perf_event *); | ||
199 | struct event_constraint *(*get_constraint)(struct intel_uncore_box *, | ||
200 | struct perf_event *); | ||
201 | void (*put_constraint)(struct intel_uncore_box *, struct perf_event *); | ||
202 | }; | ||
203 | |||
204 | struct intel_uncore_pmu { | ||
205 | struct pmu pmu; | ||
206 | char name[UNCORE_PMU_NAME_LEN]; | ||
207 | int pmu_idx; | ||
208 | int func_id; | ||
209 | struct intel_uncore_type *type; | ||
210 | struct intel_uncore_box ** __percpu box; | ||
211 | struct list_head box_list; | ||
212 | }; | ||
213 | |||
214 | struct intel_uncore_extra_reg { | ||
215 | raw_spinlock_t lock; | ||
216 | u64 config1; | ||
217 | atomic_t ref; | ||
218 | }; | ||
219 | |||
220 | struct intel_uncore_box { | ||
221 | int phys_id; | ||
222 | int n_active; /* number of active events */ | ||
223 | int n_events; | ||
224 | int cpu; /* cpu to collect events */ | ||
225 | unsigned long flags; | ||
226 | atomic_t refcnt; | ||
227 | struct perf_event *events[UNCORE_PMC_IDX_MAX]; | ||
228 | struct perf_event *event_list[UNCORE_PMC_IDX_MAX]; | ||
229 | unsigned long active_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)]; | ||
230 | u64 tags[UNCORE_PMC_IDX_MAX]; | ||
231 | struct pci_dev *pci_dev; | ||
232 | struct intel_uncore_pmu *pmu; | ||
233 | struct hrtimer hrtimer; | ||
234 | struct list_head list; | ||
235 | struct intel_uncore_extra_reg shared_regs[0]; | ||
236 | }; | ||
237 | |||
238 | #define UNCORE_BOX_FLAG_INITIATED 0 | ||
239 | |||
240 | struct uncore_event_desc { | ||
241 | struct kobj_attribute attr; | ||
242 | const char *config; | ||
243 | }; | ||
244 | |||
245 | #define INTEL_UNCORE_EVENT_DESC(_name, _config) \ | ||
246 | { \ | ||
247 | .attr = __ATTR(_name, 0444, uncore_event_show, NULL), \ | ||
248 | .config = _config, \ | ||
249 | } | ||
250 | |||
251 | #define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \ | ||
252 | static ssize_t __uncore_##_var##_show(struct kobject *kobj, \ | ||
253 | struct kobj_attribute *attr, \ | ||
254 | char *page) \ | ||
255 | { \ | ||
256 | BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ | ||
257 | return sprintf(page, _format "\n"); \ | ||
258 | } \ | ||
259 | static struct kobj_attribute format_attr_##_var = \ | ||
260 | __ATTR(_name, 0444, __uncore_##_var##_show, NULL) | ||
261 | |||
262 | |||
263 | static ssize_t uncore_event_show(struct kobject *kobj, | ||
264 | struct kobj_attribute *attr, char *buf) | ||
265 | { | ||
266 | struct uncore_event_desc *event = | ||
267 | container_of(attr, struct uncore_event_desc, attr); | ||
268 | return sprintf(buf, "%s", event->config); | ||
269 | } | ||
270 | |||
271 | static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box) | ||
272 | { | ||
273 | return box->pmu->type->box_ctl; | ||
274 | } | ||
275 | |||
276 | static inline unsigned uncore_pci_fixed_ctl(struct intel_uncore_box *box) | ||
277 | { | ||
278 | return box->pmu->type->fixed_ctl; | ||
279 | } | ||
280 | |||
281 | static inline unsigned uncore_pci_fixed_ctr(struct intel_uncore_box *box) | ||
282 | { | ||
283 | return box->pmu->type->fixed_ctr; | ||
284 | } | ||
285 | |||
286 | static inline | ||
287 | unsigned uncore_pci_event_ctl(struct intel_uncore_box *box, int idx) | ||
288 | { | ||
289 | return idx * 4 + box->pmu->type->event_ctl; | ||
290 | } | ||
291 | |||
292 | static inline | ||
293 | unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx) | ||
294 | { | ||
295 | return idx * 8 + box->pmu->type->perf_ctr; | ||
296 | } | ||
297 | |||
298 | static inline | ||
299 | unsigned uncore_msr_box_ctl(struct intel_uncore_box *box) | ||
300 | { | ||
301 | if (!box->pmu->type->box_ctl) | ||
302 | return 0; | ||
303 | return box->pmu->type->box_ctl + | ||
304 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | ||
305 | } | ||
306 | |||
307 | static inline | ||
308 | unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box) | ||
309 | { | ||
310 | if (!box->pmu->type->fixed_ctl) | ||
311 | return 0; | ||
312 | return box->pmu->type->fixed_ctl + | ||
313 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | ||
314 | } | ||
315 | |||
316 | static inline | ||
317 | unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box) | ||
318 | { | ||
319 | return box->pmu->type->fixed_ctr + | ||
320 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | ||
321 | } | ||
322 | |||
323 | static inline | ||
324 | unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) | ||
325 | { | ||
326 | return idx + box->pmu->type->event_ctl + | ||
327 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | ||
328 | } | ||
329 | |||
330 | static inline | ||
331 | unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) | ||
332 | { | ||
333 | return idx + box->pmu->type->perf_ctr + | ||
334 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | ||
335 | } | ||
336 | |||
337 | static inline | ||
338 | unsigned uncore_fixed_ctl(struct intel_uncore_box *box) | ||
339 | { | ||
340 | if (box->pci_dev) | ||
341 | return uncore_pci_fixed_ctl(box); | ||
342 | else | ||
343 | return uncore_msr_fixed_ctl(box); | ||
344 | } | ||
345 | |||
346 | static inline | ||
347 | unsigned uncore_fixed_ctr(struct intel_uncore_box *box) | ||
348 | { | ||
349 | if (box->pci_dev) | ||
350 | return uncore_pci_fixed_ctr(box); | ||
351 | else | ||
352 | return uncore_msr_fixed_ctr(box); | ||
353 | } | ||
354 | |||
355 | static inline | ||
356 | unsigned uncore_event_ctl(struct intel_uncore_box *box, int idx) | ||
357 | { | ||
358 | if (box->pci_dev) | ||
359 | return uncore_pci_event_ctl(box, idx); | ||
360 | else | ||
361 | return uncore_msr_event_ctl(box, idx); | ||
362 | } | ||
363 | |||
364 | static inline | ||
365 | unsigned uncore_perf_ctr(struct intel_uncore_box *box, int idx) | ||
366 | { | ||
367 | if (box->pci_dev) | ||
368 | return uncore_pci_perf_ctr(box, idx); | ||
369 | else | ||
370 | return uncore_msr_perf_ctr(box, idx); | ||
371 | } | ||
372 | |||
373 | static inline int uncore_perf_ctr_bits(struct intel_uncore_box *box) | ||
374 | { | ||
375 | return box->pmu->type->perf_ctr_bits; | ||
376 | } | ||
377 | |||
378 | static inline int uncore_fixed_ctr_bits(struct intel_uncore_box *box) | ||
379 | { | ||
380 | return box->pmu->type->fixed_ctr_bits; | ||
381 | } | ||
382 | |||
383 | static inline int uncore_num_counters(struct intel_uncore_box *box) | ||
384 | { | ||
385 | return box->pmu->type->num_counters; | ||
386 | } | ||
387 | |||
388 | static inline void uncore_disable_box(struct intel_uncore_box *box) | ||
389 | { | ||
390 | if (box->pmu->type->ops->disable_box) | ||
391 | box->pmu->type->ops->disable_box(box); | ||
392 | } | ||
393 | |||
394 | static inline void uncore_enable_box(struct intel_uncore_box *box) | ||
395 | { | ||
396 | if (box->pmu->type->ops->enable_box) | ||
397 | box->pmu->type->ops->enable_box(box); | ||
398 | } | ||
399 | |||
400 | static inline void uncore_disable_event(struct intel_uncore_box *box, | ||
401 | struct perf_event *event) | ||
402 | { | ||
403 | box->pmu->type->ops->disable_event(box, event); | ||
404 | } | ||
405 | |||
406 | static inline void uncore_enable_event(struct intel_uncore_box *box, | ||
407 | struct perf_event *event) | ||
408 | { | ||
409 | box->pmu->type->ops->enable_event(box, event); | ||
410 | } | ||
411 | |||
412 | static inline u64 uncore_read_counter(struct intel_uncore_box *box, | ||
413 | struct perf_event *event) | ||
414 | { | ||
415 | return box->pmu->type->ops->read_counter(box, event); | ||
416 | } | ||
417 | |||
418 | static inline void uncore_box_init(struct intel_uncore_box *box) | ||
419 | { | ||
420 | if (!test_and_set_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) { | ||
421 | if (box->pmu->type->ops->init_box) | ||
422 | box->pmu->type->ops->init_box(box); | ||
423 | } | ||
424 | } | ||
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 47124a73dd73..92c7e39a079f 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c | |||
@@ -895,8 +895,8 @@ static void p4_pmu_disable_pebs(void) | |||
895 | * So at moment let leave metrics turned on forever -- it's | 895 | * So at moment let leave metrics turned on forever -- it's |
896 | * ok for now but need to be revisited! | 896 | * ok for now but need to be revisited! |
897 | * | 897 | * |
898 | * (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)0); | 898 | * (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)0); |
899 | * (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)0); | 899 | * (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)0); |
900 | */ | 900 | */ |
901 | } | 901 | } |
902 | 902 | ||
@@ -909,7 +909,7 @@ static inline void p4_pmu_disable_event(struct perf_event *event) | |||
909 | * state we need to clear P4_CCCR_OVF, otherwise interrupt get | 909 | * state we need to clear P4_CCCR_OVF, otherwise interrupt get |
910 | * asserted again and again | 910 | * asserted again and again |
911 | */ | 911 | */ |
912 | (void)checking_wrmsrl(hwc->config_base, | 912 | (void)wrmsrl_safe(hwc->config_base, |
913 | (u64)(p4_config_unpack_cccr(hwc->config)) & | 913 | (u64)(p4_config_unpack_cccr(hwc->config)) & |
914 | ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED); | 914 | ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED); |
915 | } | 915 | } |
@@ -943,8 +943,8 @@ static void p4_pmu_enable_pebs(u64 config) | |||
943 | 943 | ||
944 | bind = &p4_pebs_bind_map[idx]; | 944 | bind = &p4_pebs_bind_map[idx]; |
945 | 945 | ||
946 | (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs); | 946 | (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)bind->metric_pebs); |
947 | (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert); | 947 | (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)bind->metric_vert); |
948 | } | 948 | } |
949 | 949 | ||
950 | static void p4_pmu_enable_event(struct perf_event *event) | 950 | static void p4_pmu_enable_event(struct perf_event *event) |
@@ -978,8 +978,8 @@ static void p4_pmu_enable_event(struct perf_event *event) | |||
978 | */ | 978 | */ |
979 | p4_pmu_enable_pebs(hwc->config); | 979 | p4_pmu_enable_pebs(hwc->config); |
980 | 980 | ||
981 | (void)checking_wrmsrl(escr_addr, escr_conf); | 981 | (void)wrmsrl_safe(escr_addr, escr_conf); |
982 | (void)checking_wrmsrl(hwc->config_base, | 982 | (void)wrmsrl_safe(hwc->config_base, |
983 | (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE); | 983 | (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE); |
984 | } | 984 | } |
985 | 985 | ||
@@ -1325,7 +1325,7 @@ __init int p4_pmu_init(void) | |||
1325 | unsigned int low, high; | 1325 | unsigned int low, high; |
1326 | 1326 | ||
1327 | /* If we get stripped -- indexing fails */ | 1327 | /* If we get stripped -- indexing fails */ |
1328 | BUILD_BUG_ON(ARCH_P4_MAX_CCCR > X86_PMC_MAX_GENERIC); | 1328 | BUILD_BUG_ON(ARCH_P4_MAX_CCCR > INTEL_PMC_MAX_GENERIC); |
1329 | 1329 | ||
1330 | rdmsr(MSR_IA32_MISC_ENABLE, low, high); | 1330 | rdmsr(MSR_IA32_MISC_ENABLE, low, high); |
1331 | if (!(low & (1 << 7))) { | 1331 | if (!(low & (1 << 7))) { |
diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index 32bcfc7dd230..e4dd0f7a0453 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c | |||
@@ -71,7 +71,7 @@ p6_pmu_disable_event(struct perf_event *event) | |||
71 | if (cpuc->enabled) | 71 | if (cpuc->enabled) |
72 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; | 72 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; |
73 | 73 | ||
74 | (void)checking_wrmsrl(hwc->config_base, val); | 74 | (void)wrmsrl_safe(hwc->config_base, val); |
75 | } | 75 | } |
76 | 76 | ||
77 | static void p6_pmu_enable_event(struct perf_event *event) | 77 | static void p6_pmu_enable_event(struct perf_event *event) |
@@ -84,7 +84,7 @@ static void p6_pmu_enable_event(struct perf_event *event) | |||
84 | if (cpuc->enabled) | 84 | if (cpuc->enabled) |
85 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; | 85 | val |= ARCH_PERFMON_EVENTSEL_ENABLE; |
86 | 86 | ||
87 | (void)checking_wrmsrl(hwc->config_base, val); | 87 | (void)wrmsrl_safe(hwc->config_base, val); |
88 | } | 88 | } |
89 | 89 | ||
90 | PMU_FORMAT_ATTR(event, "config:0-7" ); | 90 | PMU_FORMAT_ATTR(event, "config:0-7" ); |
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 571246d81edf..ae42418bc50f 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
@@ -27,8 +27,8 @@ static int die_counter; | |||
27 | 27 | ||
28 | void printk_address(unsigned long address, int reliable) | 28 | void printk_address(unsigned long address, int reliable) |
29 | { | 29 | { |
30 | printk(" [<%p>] %s%pB\n", (void *) address, | 30 | pr_cont(" [<%p>] %s%pB\n", |
31 | reliable ? "" : "? ", (void *) address); | 31 | (void *)address, reliable ? "" : "? ", (void *)address); |
32 | } | 32 | } |
33 | 33 | ||
34 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 34 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
@@ -271,6 +271,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) | |||
271 | current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP) | 271 | current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP) |
272 | return 1; | 272 | return 1; |
273 | 273 | ||
274 | print_modules(); | ||
274 | show_regs(regs); | 275 | show_regs(regs); |
275 | #ifdef CONFIG_X86_32 | 276 | #ifdef CONFIG_X86_32 |
276 | if (user_mode_vm(regs)) { | 277 | if (user_mode_vm(regs)) { |
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index e0b1d783daab..1038a417ea53 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
@@ -73,11 +73,11 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
73 | if (kstack_end(stack)) | 73 | if (kstack_end(stack)) |
74 | break; | 74 | break; |
75 | if (i && ((i % STACKSLOTS_PER_LINE) == 0)) | 75 | if (i && ((i % STACKSLOTS_PER_LINE) == 0)) |
76 | printk(KERN_CONT "\n"); | 76 | pr_cont("\n"); |
77 | printk(KERN_CONT " %08lx", *stack++); | 77 | pr_cont(" %08lx", *stack++); |
78 | touch_nmi_watchdog(); | 78 | touch_nmi_watchdog(); |
79 | } | 79 | } |
80 | printk(KERN_CONT "\n"); | 80 | pr_cont("\n"); |
81 | show_trace_log_lvl(task, regs, sp, bp, log_lvl); | 81 | show_trace_log_lvl(task, regs, sp, bp, log_lvl); |
82 | } | 82 | } |
83 | 83 | ||
@@ -86,12 +86,11 @@ void show_regs(struct pt_regs *regs) | |||
86 | { | 86 | { |
87 | int i; | 87 | int i; |
88 | 88 | ||
89 | print_modules(); | ||
90 | __show_regs(regs, !user_mode_vm(regs)); | 89 | __show_regs(regs, !user_mode_vm(regs)); |
91 | 90 | ||
92 | printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n", | 91 | pr_emerg("Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n", |
93 | TASK_COMM_LEN, current->comm, task_pid_nr(current), | 92 | TASK_COMM_LEN, current->comm, task_pid_nr(current), |
94 | current_thread_info(), current, task_thread_info(current)); | 93 | current_thread_info(), current, task_thread_info(current)); |
95 | /* | 94 | /* |
96 | * When in-kernel, we also print out the stack and code at the | 95 | * When in-kernel, we also print out the stack and code at the |
97 | * time of the fault.. | 96 | * time of the fault.. |
@@ -102,10 +101,10 @@ void show_regs(struct pt_regs *regs) | |||
102 | unsigned char c; | 101 | unsigned char c; |
103 | u8 *ip; | 102 | u8 *ip; |
104 | 103 | ||
105 | printk(KERN_EMERG "Stack:\n"); | 104 | pr_emerg("Stack:\n"); |
106 | show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG); | 105 | show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG); |
107 | 106 | ||
108 | printk(KERN_EMERG "Code: "); | 107 | pr_emerg("Code:"); |
109 | 108 | ||
110 | ip = (u8 *)regs->ip - code_prologue; | 109 | ip = (u8 *)regs->ip - code_prologue; |
111 | if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { | 110 | if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { |
@@ -116,16 +115,16 @@ void show_regs(struct pt_regs *regs) | |||
116 | for (i = 0; i < code_len; i++, ip++) { | 115 | for (i = 0; i < code_len; i++, ip++) { |
117 | if (ip < (u8 *)PAGE_OFFSET || | 116 | if (ip < (u8 *)PAGE_OFFSET || |
118 | probe_kernel_address(ip, c)) { | 117 | probe_kernel_address(ip, c)) { |
119 | printk(KERN_CONT " Bad EIP value."); | 118 | pr_cont(" Bad EIP value."); |
120 | break; | 119 | break; |
121 | } | 120 | } |
122 | if (ip == (u8 *)regs->ip) | 121 | if (ip == (u8 *)regs->ip) |
123 | printk(KERN_CONT "<%02x> ", c); | 122 | pr_cont(" <%02x>", c); |
124 | else | 123 | else |
125 | printk(KERN_CONT "%02x ", c); | 124 | pr_cont(" %02x", c); |
126 | } | 125 | } |
127 | } | 126 | } |
128 | printk(KERN_CONT "\n"); | 127 | pr_cont("\n"); |
129 | } | 128 | } |
130 | 129 | ||
131 | int is_valid_bugaddr(unsigned long ip) | 130 | int is_valid_bugaddr(unsigned long ip) |
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 791b76122aa8..b653675d5288 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -228,20 +228,20 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
228 | if (stack >= irq_stack && stack <= irq_stack_end) { | 228 | if (stack >= irq_stack && stack <= irq_stack_end) { |
229 | if (stack == irq_stack_end) { | 229 | if (stack == irq_stack_end) { |
230 | stack = (unsigned long *) (irq_stack_end[-1]); | 230 | stack = (unsigned long *) (irq_stack_end[-1]); |
231 | printk(KERN_CONT " <EOI> "); | 231 | pr_cont(" <EOI> "); |
232 | } | 232 | } |
233 | } else { | 233 | } else { |
234 | if (((long) stack & (THREAD_SIZE-1)) == 0) | 234 | if (((long) stack & (THREAD_SIZE-1)) == 0) |
235 | break; | 235 | break; |
236 | } | 236 | } |
237 | if (i && ((i % STACKSLOTS_PER_LINE) == 0)) | 237 | if (i && ((i % STACKSLOTS_PER_LINE) == 0)) |
238 | printk(KERN_CONT "\n"); | 238 | pr_cont("\n"); |
239 | printk(KERN_CONT " %016lx", *stack++); | 239 | pr_cont(" %016lx", *stack++); |
240 | touch_nmi_watchdog(); | 240 | touch_nmi_watchdog(); |
241 | } | 241 | } |
242 | preempt_enable(); | 242 | preempt_enable(); |
243 | 243 | ||
244 | printk(KERN_CONT "\n"); | 244 | pr_cont("\n"); |
245 | show_trace_log_lvl(task, regs, sp, bp, log_lvl); | 245 | show_trace_log_lvl(task, regs, sp, bp, log_lvl); |
246 | } | 246 | } |
247 | 247 | ||
@@ -254,10 +254,9 @@ void show_regs(struct pt_regs *regs) | |||
254 | 254 | ||
255 | sp = regs->sp; | 255 | sp = regs->sp; |
256 | printk("CPU %d ", cpu); | 256 | printk("CPU %d ", cpu); |
257 | print_modules(); | ||
258 | __show_regs(regs, 1); | 257 | __show_regs(regs, 1); |
259 | printk("Process %s (pid: %d, threadinfo %p, task %p)\n", | 258 | printk(KERN_DEFAULT "Process %s (pid: %d, threadinfo %p, task %p)\n", |
260 | cur->comm, cur->pid, task_thread_info(cur), cur); | 259 | cur->comm, cur->pid, task_thread_info(cur), cur); |
261 | 260 | ||
262 | /* | 261 | /* |
263 | * When in-kernel, we also print out the stack and code at the | 262 | * When in-kernel, we also print out the stack and code at the |
@@ -284,16 +283,16 @@ void show_regs(struct pt_regs *regs) | |||
284 | for (i = 0; i < code_len; i++, ip++) { | 283 | for (i = 0; i < code_len; i++, ip++) { |
285 | if (ip < (u8 *)PAGE_OFFSET || | 284 | if (ip < (u8 *)PAGE_OFFSET || |
286 | probe_kernel_address(ip, c)) { | 285 | probe_kernel_address(ip, c)) { |
287 | printk(KERN_CONT " Bad RIP value."); | 286 | pr_cont(" Bad RIP value."); |
288 | break; | 287 | break; |
289 | } | 288 | } |
290 | if (ip == (u8 *)regs->ip) | 289 | if (ip == (u8 *)regs->ip) |
291 | printk(KERN_CONT "<%02x> ", c); | 290 | pr_cont("<%02x> ", c); |
292 | else | 291 | else |
293 | printk(KERN_CONT "%02x ", c); | 292 | pr_cont("%02x ", c); |
294 | } | 293 | } |
295 | } | 294 | } |
296 | printk(KERN_CONT "\n"); | 295 | pr_cont("\n"); |
297 | } | 296 | } |
298 | 297 | ||
299 | int is_valid_bugaddr(unsigned long ip) | 298 | int is_valid_bugaddr(unsigned long ip) |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 7d65133b51be..111f6bbd8b38 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -1758,10 +1758,30 @@ end_repeat_nmi: | |||
1758 | */ | 1758 | */ |
1759 | call save_paranoid | 1759 | call save_paranoid |
1760 | DEFAULT_FRAME 0 | 1760 | DEFAULT_FRAME 0 |
1761 | |||
1762 | /* | ||
1763 | * Save off the CR2 register. If we take a page fault in the NMI then | ||
1764 | * it could corrupt the CR2 value. If the NMI preempts a page fault | ||
1765 | * handler before it was able to read the CR2 register, and then the | ||
1766 | * NMI itself takes a page fault, the page fault that was preempted | ||
1767 | * will read the information from the NMI page fault and not the | ||
1768 | * origin fault. Save it off and restore it if it changes. | ||
1769 | * Use the r12 callee-saved register. | ||
1770 | */ | ||
1771 | movq %cr2, %r12 | ||
1772 | |||
1761 | /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ | 1773 | /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ |
1762 | movq %rsp,%rdi | 1774 | movq %rsp,%rdi |
1763 | movq $-1,%rsi | 1775 | movq $-1,%rsi |
1764 | call do_nmi | 1776 | call do_nmi |
1777 | |||
1778 | /* Did the NMI take a page fault? Restore cr2 if it did */ | ||
1779 | movq %cr2, %rcx | ||
1780 | cmpq %rcx, %r12 | ||
1781 | je 1f | ||
1782 | movq %r12, %cr2 | ||
1783 | 1: | ||
1784 | |||
1765 | testl %ebx,%ebx /* swapgs needed? */ | 1785 | testl %ebx,%ebx /* swapgs needed? */ |
1766 | jnz nmi_restore | 1786 | jnz nmi_restore |
1767 | nmi_swapgs: | 1787 | nmi_swapgs: |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 3dafc6003b7c..1f5f1d5d2a02 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
@@ -294,9 +294,9 @@ void fixup_irqs(void) | |||
294 | raw_spin_unlock(&desc->lock); | 294 | raw_spin_unlock(&desc->lock); |
295 | 295 | ||
296 | if (break_affinity && set_affinity) | 296 | if (break_affinity && set_affinity) |
297 | printk("Broke affinity for irq %i\n", irq); | 297 | pr_notice("Broke affinity for irq %i\n", irq); |
298 | else if (!set_affinity) | 298 | else if (!set_affinity) |
299 | printk("Cannot set affinity for irq %i\n", irq); | 299 | pr_notice("Cannot set affinity for irq %i\n", irq); |
300 | } | 300 | } |
301 | 301 | ||
302 | /* | 302 | /* |
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index fbdfc6917180..4873e62db6a1 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c | |||
@@ -87,6 +87,7 @@ | |||
87 | #include <asm/microcode.h> | 87 | #include <asm/microcode.h> |
88 | #include <asm/processor.h> | 88 | #include <asm/processor.h> |
89 | #include <asm/cpu_device_id.h> | 89 | #include <asm/cpu_device_id.h> |
90 | #include <asm/perf_event.h> | ||
90 | 91 | ||
91 | MODULE_DESCRIPTION("Microcode Update Driver"); | 92 | MODULE_DESCRIPTION("Microcode Update Driver"); |
92 | MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); | 93 | MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); |
@@ -277,7 +278,6 @@ static int reload_for_cpu(int cpu) | |||
277 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 278 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
278 | int err = 0; | 279 | int err = 0; |
279 | 280 | ||
280 | mutex_lock(µcode_mutex); | ||
281 | if (uci->valid) { | 281 | if (uci->valid) { |
282 | enum ucode_state ustate; | 282 | enum ucode_state ustate; |
283 | 283 | ||
@@ -288,7 +288,6 @@ static int reload_for_cpu(int cpu) | |||
288 | if (ustate == UCODE_ERROR) | 288 | if (ustate == UCODE_ERROR) |
289 | err = -EINVAL; | 289 | err = -EINVAL; |
290 | } | 290 | } |
291 | mutex_unlock(µcode_mutex); | ||
292 | 291 | ||
293 | return err; | 292 | return err; |
294 | } | 293 | } |
@@ -298,19 +297,31 @@ static ssize_t reload_store(struct device *dev, | |||
298 | const char *buf, size_t size) | 297 | const char *buf, size_t size) |
299 | { | 298 | { |
300 | unsigned long val; | 299 | unsigned long val; |
301 | int cpu = dev->id; | 300 | int cpu; |
302 | ssize_t ret = 0; | 301 | ssize_t ret = 0, tmp_ret; |
303 | 302 | ||
304 | ret = kstrtoul(buf, 0, &val); | 303 | ret = kstrtoul(buf, 0, &val); |
305 | if (ret) | 304 | if (ret) |
306 | return ret; | 305 | return ret; |
307 | 306 | ||
308 | if (val == 1) { | 307 | if (val != 1) |
309 | get_online_cpus(); | 308 | return size; |
310 | if (cpu_online(cpu)) | 309 | |
311 | ret = reload_for_cpu(cpu); | 310 | get_online_cpus(); |
312 | put_online_cpus(); | 311 | mutex_lock(µcode_mutex); |
312 | for_each_online_cpu(cpu) { | ||
313 | tmp_ret = reload_for_cpu(cpu); | ||
314 | if (tmp_ret != 0) | ||
315 | pr_warn("Error reloading microcode on CPU %d\n", cpu); | ||
316 | |||
317 | /* save retval of the first encountered reload error */ | ||
318 | if (!ret) | ||
319 | ret = tmp_ret; | ||
313 | } | 320 | } |
321 | if (!ret) | ||
322 | perf_check_microcode(); | ||
323 | mutex_unlock(µcode_mutex); | ||
324 | put_online_cpus(); | ||
314 | 325 | ||
315 | if (!ret) | 326 | if (!ret) |
316 | ret = size; | 327 | ret = size; |
@@ -339,7 +350,6 @@ static DEVICE_ATTR(version, 0400, version_show, NULL); | |||
339 | static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL); | 350 | static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL); |
340 | 351 | ||
341 | static struct attribute *mc_default_attrs[] = { | 352 | static struct attribute *mc_default_attrs[] = { |
342 | &dev_attr_reload.attr, | ||
343 | &dev_attr_version.attr, | 353 | &dev_attr_version.attr, |
344 | &dev_attr_processor_flags.attr, | 354 | &dev_attr_processor_flags.attr, |
345 | NULL | 355 | NULL |
@@ -504,7 +514,7 @@ static struct notifier_block __refdata mc_cpu_notifier = { | |||
504 | 514 | ||
505 | #ifdef MODULE | 515 | #ifdef MODULE |
506 | /* Autoload on Intel and AMD systems */ | 516 | /* Autoload on Intel and AMD systems */ |
507 | static const struct x86_cpu_id microcode_id[] = { | 517 | static const struct x86_cpu_id __initconst microcode_id[] = { |
508 | #ifdef CONFIG_MICROCODE_INTEL | 518 | #ifdef CONFIG_MICROCODE_INTEL |
509 | { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, }, | 519 | { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, }, |
510 | #endif | 520 | #endif |
@@ -516,6 +526,16 @@ static const struct x86_cpu_id microcode_id[] = { | |||
516 | MODULE_DEVICE_TABLE(x86cpu, microcode_id); | 526 | MODULE_DEVICE_TABLE(x86cpu, microcode_id); |
517 | #endif | 527 | #endif |
518 | 528 | ||
529 | static struct attribute *cpu_root_microcode_attrs[] = { | ||
530 | &dev_attr_reload.attr, | ||
531 | NULL | ||
532 | }; | ||
533 | |||
534 | static struct attribute_group cpu_root_microcode_group = { | ||
535 | .name = "microcode", | ||
536 | .attrs = cpu_root_microcode_attrs, | ||
537 | }; | ||
538 | |||
519 | static int __init microcode_init(void) | 539 | static int __init microcode_init(void) |
520 | { | 540 | { |
521 | struct cpuinfo_x86 *c = &cpu_data(0); | 541 | struct cpuinfo_x86 *c = &cpu_data(0); |
@@ -540,16 +560,25 @@ static int __init microcode_init(void) | |||
540 | mutex_lock(µcode_mutex); | 560 | mutex_lock(µcode_mutex); |
541 | 561 | ||
542 | error = subsys_interface_register(&mc_cpu_interface); | 562 | error = subsys_interface_register(&mc_cpu_interface); |
543 | 563 | if (!error) | |
564 | perf_check_microcode(); | ||
544 | mutex_unlock(µcode_mutex); | 565 | mutex_unlock(µcode_mutex); |
545 | put_online_cpus(); | 566 | put_online_cpus(); |
546 | 567 | ||
547 | if (error) | 568 | if (error) |
548 | goto out_pdev; | 569 | goto out_pdev; |
549 | 570 | ||
571 | error = sysfs_create_group(&cpu_subsys.dev_root->kobj, | ||
572 | &cpu_root_microcode_group); | ||
573 | |||
574 | if (error) { | ||
575 | pr_err("Error creating microcode group!\n"); | ||
576 | goto out_driver; | ||
577 | } | ||
578 | |||
550 | error = microcode_dev_init(); | 579 | error = microcode_dev_init(); |
551 | if (error) | 580 | if (error) |
552 | goto out_driver; | 581 | goto out_ucode_group; |
553 | 582 | ||
554 | register_syscore_ops(&mc_syscore_ops); | 583 | register_syscore_ops(&mc_syscore_ops); |
555 | register_hotcpu_notifier(&mc_cpu_notifier); | 584 | register_hotcpu_notifier(&mc_cpu_notifier); |
@@ -559,7 +588,11 @@ static int __init microcode_init(void) | |||
559 | 588 | ||
560 | return 0; | 589 | return 0; |
561 | 590 | ||
562 | out_driver: | 591 | out_ucode_group: |
592 | sysfs_remove_group(&cpu_subsys.dev_root->kobj, | ||
593 | &cpu_root_microcode_group); | ||
594 | |||
595 | out_driver: | ||
563 | get_online_cpus(); | 596 | get_online_cpus(); |
564 | mutex_lock(µcode_mutex); | 597 | mutex_lock(µcode_mutex); |
565 | 598 | ||
@@ -568,7 +601,7 @@ out_driver: | |||
568 | mutex_unlock(µcode_mutex); | 601 | mutex_unlock(µcode_mutex); |
569 | put_online_cpus(); | 602 | put_online_cpus(); |
570 | 603 | ||
571 | out_pdev: | 604 | out_pdev: |
572 | platform_device_unregister(microcode_pdev); | 605 | platform_device_unregister(microcode_pdev); |
573 | return error; | 606 | return error; |
574 | 607 | ||
@@ -584,6 +617,9 @@ static void __exit microcode_exit(void) | |||
584 | unregister_hotcpu_notifier(&mc_cpu_notifier); | 617 | unregister_hotcpu_notifier(&mc_cpu_notifier); |
585 | unregister_syscore_ops(&mc_syscore_ops); | 618 | unregister_syscore_ops(&mc_syscore_ops); |
586 | 619 | ||
620 | sysfs_remove_group(&cpu_subsys.dev_root->kobj, | ||
621 | &cpu_root_microcode_group); | ||
622 | |||
587 | get_online_cpus(); | 623 | get_online_cpus(); |
588 | mutex_lock(µcode_mutex); | 624 | mutex_lock(µcode_mutex); |
589 | 625 | ||
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index f21fd94ac897..202494d2ec6e 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c | |||
@@ -15,6 +15,9 @@ | |||
15 | along with this program; if not, write to the Free Software | 15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | |||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
18 | #include <linux/moduleloader.h> | 21 | #include <linux/moduleloader.h> |
19 | #include <linux/elf.h> | 22 | #include <linux/elf.h> |
20 | #include <linux/vmalloc.h> | 23 | #include <linux/vmalloc.h> |
@@ -30,9 +33,14 @@ | |||
30 | #include <asm/pgtable.h> | 33 | #include <asm/pgtable.h> |
31 | 34 | ||
32 | #if 0 | 35 | #if 0 |
33 | #define DEBUGP printk | 36 | #define DEBUGP(fmt, ...) \ |
37 | printk(KERN_DEBUG fmt, ##__VA_ARGS__) | ||
34 | #else | 38 | #else |
35 | #define DEBUGP(fmt...) | 39 | #define DEBUGP(fmt, ...) \ |
40 | do { \ | ||
41 | if (0) \ | ||
42 | printk(KERN_DEBUG fmt, ##__VA_ARGS__); \ | ||
43 | } while (0) | ||
36 | #endif | 44 | #endif |
37 | 45 | ||
38 | void *module_alloc(unsigned long size) | 46 | void *module_alloc(unsigned long size) |
@@ -56,8 +64,8 @@ int apply_relocate(Elf32_Shdr *sechdrs, | |||
56 | Elf32_Sym *sym; | 64 | Elf32_Sym *sym; |
57 | uint32_t *location; | 65 | uint32_t *location; |
58 | 66 | ||
59 | DEBUGP("Applying relocate section %u to %u\n", relsec, | 67 | DEBUGP("Applying relocate section %u to %u\n", |
60 | sechdrs[relsec].sh_info); | 68 | relsec, sechdrs[relsec].sh_info); |
61 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { | 69 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { |
62 | /* This is where to make the change */ | 70 | /* This is where to make the change */ |
63 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr | 71 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr |
@@ -77,7 +85,7 @@ int apply_relocate(Elf32_Shdr *sechdrs, | |||
77 | *location += sym->st_value - (uint32_t)location; | 85 | *location += sym->st_value - (uint32_t)location; |
78 | break; | 86 | break; |
79 | default: | 87 | default: |
80 | printk(KERN_ERR "module %s: Unknown relocation: %u\n", | 88 | pr_err("%s: Unknown relocation: %u\n", |
81 | me->name, ELF32_R_TYPE(rel[i].r_info)); | 89 | me->name, ELF32_R_TYPE(rel[i].r_info)); |
82 | return -ENOEXEC; | 90 | return -ENOEXEC; |
83 | } | 91 | } |
@@ -97,8 +105,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
97 | void *loc; | 105 | void *loc; |
98 | u64 val; | 106 | u64 val; |
99 | 107 | ||
100 | DEBUGP("Applying relocate section %u to %u\n", relsec, | 108 | DEBUGP("Applying relocate section %u to %u\n", |
101 | sechdrs[relsec].sh_info); | 109 | relsec, sechdrs[relsec].sh_info); |
102 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { | 110 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { |
103 | /* This is where to make the change */ | 111 | /* This is where to make the change */ |
104 | loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr | 112 | loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr |
@@ -110,8 +118,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
110 | + ELF64_R_SYM(rel[i].r_info); | 118 | + ELF64_R_SYM(rel[i].r_info); |
111 | 119 | ||
112 | DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n", | 120 | DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n", |
113 | (int)ELF64_R_TYPE(rel[i].r_info), | 121 | (int)ELF64_R_TYPE(rel[i].r_info), |
114 | sym->st_value, rel[i].r_addend, (u64)loc); | 122 | sym->st_value, rel[i].r_addend, (u64)loc); |
115 | 123 | ||
116 | val = sym->st_value + rel[i].r_addend; | 124 | val = sym->st_value + rel[i].r_addend; |
117 | 125 | ||
@@ -140,7 +148,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
140 | #endif | 148 | #endif |
141 | break; | 149 | break; |
142 | default: | 150 | default: |
143 | printk(KERN_ERR "module %s: Unknown rela relocation: %llu\n", | 151 | pr_err("%s: Unknown rela relocation: %llu\n", |
144 | me->name, ELF64_R_TYPE(rel[i].r_info)); | 152 | me->name, ELF64_R_TYPE(rel[i].r_info)); |
145 | return -ENOEXEC; | 153 | return -ENOEXEC; |
146 | } | 154 | } |
@@ -148,9 +156,9 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | |||
148 | return 0; | 156 | return 0; |
149 | 157 | ||
150 | overflow: | 158 | overflow: |
151 | printk(KERN_ERR "overflow in relocation type %d val %Lx\n", | 159 | pr_err("overflow in relocation type %d val %Lx\n", |
152 | (int)ELF64_R_TYPE(rel[i].r_info), val); | 160 | (int)ELF64_R_TYPE(rel[i].r_info), val); |
153 | printk(KERN_ERR "`%s' likely not compiled with -mcmodel=kernel\n", | 161 | pr_err("`%s' likely not compiled with -mcmodel=kernel\n", |
154 | me->name); | 162 | me->name); |
155 | return -ENOEXEC; | 163 | return -ENOEXEC; |
156 | } | 164 | } |
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index a0b2f84457be..f84f5c57de35 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c | |||
@@ -365,8 +365,9 @@ static __kprobes void default_do_nmi(struct pt_regs *regs) | |||
365 | #ifdef CONFIG_X86_32 | 365 | #ifdef CONFIG_X86_32 |
366 | /* | 366 | /* |
367 | * For i386, NMIs use the same stack as the kernel, and we can | 367 | * For i386, NMIs use the same stack as the kernel, and we can |
368 | * add a workaround to the iret problem in C. Simply have 3 states | 368 | * add a workaround to the iret problem in C (preventing nested |
369 | * the NMI can be in. | 369 | * NMIs if an NMI takes a trap). Simply have 3 states the NMI |
370 | * can be in: | ||
370 | * | 371 | * |
371 | * 1) not running | 372 | * 1) not running |
372 | * 2) executing | 373 | * 2) executing |
@@ -383,32 +384,50 @@ static __kprobes void default_do_nmi(struct pt_regs *regs) | |||
383 | * If an NMI hits a breakpoint that executes an iret, another | 384 | * If an NMI hits a breakpoint that executes an iret, another |
384 | * NMI can preempt it. We do not want to allow this new NMI | 385 | * NMI can preempt it. We do not want to allow this new NMI |
385 | * to run, but we want to execute it when the first one finishes. | 386 | * to run, but we want to execute it when the first one finishes. |
386 | * We set the state to "latched", and the first NMI will perform | 387 | * We set the state to "latched", and the exit of the first NMI will |
387 | * an cmpxchg on the state, and if it doesn't successfully | 388 | * perform a dec_return, if the result is zero (NOT_RUNNING), then |
388 | * reset the state to "not running" it will restart the next | 389 | * it will simply exit the NMI handler. If not, the dec_return |
389 | * NMI. | 390 | * would have set the state to NMI_EXECUTING (what we want it to |
391 | * be when we are running). In this case, we simply jump back | ||
392 | * to rerun the NMI handler again, and restart the 'latched' NMI. | ||
393 | * | ||
394 | * No trap (breakpoint or page fault) should be hit before nmi_restart, | ||
395 | * thus there is no race between the first check of state for NOT_RUNNING | ||
396 | * and setting it to NMI_EXECUTING. The HW will prevent nested NMIs | ||
397 | * at this point. | ||
398 | * | ||
399 | * In case the NMI takes a page fault, we need to save off the CR2 | ||
400 | * because the NMI could have preempted another page fault and corrupt | ||
401 | * the CR2 that is about to be read. As nested NMIs must be restarted | ||
402 | * and they can not take breakpoints or page faults, the update of the | ||
403 | * CR2 must be done before converting the nmi state back to NOT_RUNNING. | ||
404 | * Otherwise, there would be a race of another nested NMI coming in | ||
405 | * after setting state to NOT_RUNNING but before updating the nmi_cr2. | ||
390 | */ | 406 | */ |
391 | enum nmi_states { | 407 | enum nmi_states { |
392 | NMI_NOT_RUNNING, | 408 | NMI_NOT_RUNNING = 0, |
393 | NMI_EXECUTING, | 409 | NMI_EXECUTING, |
394 | NMI_LATCHED, | 410 | NMI_LATCHED, |
395 | }; | 411 | }; |
396 | static DEFINE_PER_CPU(enum nmi_states, nmi_state); | 412 | static DEFINE_PER_CPU(enum nmi_states, nmi_state); |
413 | static DEFINE_PER_CPU(unsigned long, nmi_cr2); | ||
397 | 414 | ||
398 | #define nmi_nesting_preprocess(regs) \ | 415 | #define nmi_nesting_preprocess(regs) \ |
399 | do { \ | 416 | do { \ |
400 | if (__get_cpu_var(nmi_state) != NMI_NOT_RUNNING) { \ | 417 | if (this_cpu_read(nmi_state) != NMI_NOT_RUNNING) { \ |
401 | __get_cpu_var(nmi_state) = NMI_LATCHED; \ | 418 | this_cpu_write(nmi_state, NMI_LATCHED); \ |
402 | return; \ | 419 | return; \ |
403 | } \ | 420 | } \ |
404 | nmi_restart: \ | 421 | this_cpu_write(nmi_state, NMI_EXECUTING); \ |
405 | __get_cpu_var(nmi_state) = NMI_EXECUTING; \ | 422 | this_cpu_write(nmi_cr2, read_cr2()); \ |
406 | } while (0) | 423 | } while (0); \ |
424 | nmi_restart: | ||
407 | 425 | ||
408 | #define nmi_nesting_postprocess() \ | 426 | #define nmi_nesting_postprocess() \ |
409 | do { \ | 427 | do { \ |
410 | if (cmpxchg(&__get_cpu_var(nmi_state), \ | 428 | if (unlikely(this_cpu_read(nmi_cr2) != read_cr2())) \ |
411 | NMI_EXECUTING, NMI_NOT_RUNNING) != NMI_EXECUTING) \ | 429 | write_cr2(this_cpu_read(nmi_cr2)); \ |
430 | if (this_cpu_dec_return(nmi_state)) \ | ||
412 | goto nmi_restart; \ | 431 | goto nmi_restart; \ |
413 | } while (0) | 432 | } while (0) |
414 | #else /* x86_64 */ | 433 | #else /* x86_64 */ |
diff --git a/arch/x86/kernel/nmi_selftest.c b/arch/x86/kernel/nmi_selftest.c index 149b8d9c6ad4..6d9582ec0324 100644 --- a/arch/x86/kernel/nmi_selftest.c +++ b/arch/x86/kernel/nmi_selftest.c | |||
@@ -42,7 +42,8 @@ static int __init nmi_unk_cb(unsigned int val, struct pt_regs *regs) | |||
42 | static void __init init_nmi_testsuite(void) | 42 | static void __init init_nmi_testsuite(void) |
43 | { | 43 | { |
44 | /* trap all the unknown NMIs we may generate */ | 44 | /* trap all the unknown NMIs we may generate */ |
45 | register_nmi_handler_initonly(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk"); | 45 | register_nmi_handler(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk", |
46 | __initdata); | ||
46 | } | 47 | } |
47 | 48 | ||
48 | static void __init cleanup_nmi_testsuite(void) | 49 | static void __init cleanup_nmi_testsuite(void) |
@@ -64,8 +65,8 @@ static void __init test_nmi_ipi(struct cpumask *mask) | |||
64 | { | 65 | { |
65 | unsigned long timeout; | 66 | unsigned long timeout; |
66 | 67 | ||
67 | if (register_nmi_handler_initonly(NMI_LOCAL, test_nmi_ipi_callback, | 68 | if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback, |
68 | NMI_FLAG_FIRST, "nmi_selftest")) { | 69 | NMI_FLAG_FIRST, "nmi_selftest", __initdata)) { |
69 | nmi_fail = FAILURE; | 70 | nmi_fail = FAILURE; |
70 | return; | 71 | return; |
71 | } | 72 | } |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 9ce885996fd7..17fff18a1031 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -352,9 +352,7 @@ struct pv_cpu_ops pv_cpu_ops = { | |||
352 | #endif | 352 | #endif |
353 | .wbinvd = native_wbinvd, | 353 | .wbinvd = native_wbinvd, |
354 | .read_msr = native_read_msr_safe, | 354 | .read_msr = native_read_msr_safe, |
355 | .rdmsr_regs = native_rdmsr_safe_regs, | ||
356 | .write_msr = native_write_msr_safe, | 355 | .write_msr = native_write_msr_safe, |
357 | .wrmsr_regs = native_wrmsr_safe_regs, | ||
358 | .read_tsc = native_read_tsc, | 356 | .read_tsc = native_read_tsc, |
359 | .read_pmc = native_read_pmc, | 357 | .read_pmc = native_read_pmc, |
360 | .read_tscp = native_read_tscp, | 358 | .read_tscp = native_read_tscp, |
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index b72838bae64a..299d49302e7d 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c | |||
@@ -22,6 +22,8 @@ | |||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #define pr_fmt(fmt) "Calgary: " fmt | ||
26 | |||
25 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
26 | #include <linux/init.h> | 28 | #include <linux/init.h> |
27 | #include <linux/types.h> | 29 | #include <linux/types.h> |
@@ -245,7 +247,7 @@ static unsigned long iommu_range_alloc(struct device *dev, | |||
245 | offset = iommu_area_alloc(tbl->it_map, tbl->it_size, 0, | 247 | offset = iommu_area_alloc(tbl->it_map, tbl->it_size, 0, |
246 | npages, 0, boundary_size, 0); | 248 | npages, 0, boundary_size, 0); |
247 | if (offset == ~0UL) { | 249 | if (offset == ~0UL) { |
248 | printk(KERN_WARNING "Calgary: IOMMU full.\n"); | 250 | pr_warn("IOMMU full\n"); |
249 | spin_unlock_irqrestore(&tbl->it_lock, flags); | 251 | spin_unlock_irqrestore(&tbl->it_lock, flags); |
250 | if (panic_on_overflow) | 252 | if (panic_on_overflow) |
251 | panic("Calgary: fix the allocator.\n"); | 253 | panic("Calgary: fix the allocator.\n"); |
@@ -271,8 +273,8 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl, | |||
271 | entry = iommu_range_alloc(dev, tbl, npages); | 273 | entry = iommu_range_alloc(dev, tbl, npages); |
272 | 274 | ||
273 | if (unlikely(entry == DMA_ERROR_CODE)) { | 275 | if (unlikely(entry == DMA_ERROR_CODE)) { |
274 | printk(KERN_WARNING "Calgary: failed to allocate %u pages in " | 276 | pr_warn("failed to allocate %u pages in iommu %p\n", |
275 | "iommu %p\n", npages, tbl); | 277 | npages, tbl); |
276 | return DMA_ERROR_CODE; | 278 | return DMA_ERROR_CODE; |
277 | } | 279 | } |
278 | 280 | ||
@@ -561,8 +563,7 @@ static void calgary_tce_cache_blast(struct iommu_table *tbl) | |||
561 | i++; | 563 | i++; |
562 | } while ((val & 0xff) != 0xff && i < 100); | 564 | } while ((val & 0xff) != 0xff && i < 100); |
563 | if (i == 100) | 565 | if (i == 100) |
564 | printk(KERN_WARNING "Calgary: PCI bus not quiesced, " | 566 | pr_warn("PCI bus not quiesced, continuing anyway\n"); |
565 | "continuing anyway\n"); | ||
566 | 567 | ||
567 | /* invalidate TCE cache */ | 568 | /* invalidate TCE cache */ |
568 | target = calgary_reg(bbar, tar_offset(tbl->it_busno)); | 569 | target = calgary_reg(bbar, tar_offset(tbl->it_busno)); |
@@ -604,8 +605,7 @@ begin: | |||
604 | i++; | 605 | i++; |
605 | } while ((val64 & 0xff) != 0xff && i < 100); | 606 | } while ((val64 & 0xff) != 0xff && i < 100); |
606 | if (i == 100) | 607 | if (i == 100) |
607 | printk(KERN_WARNING "CalIOC2: PCI bus not quiesced, " | 608 | pr_warn("CalIOC2: PCI bus not quiesced, continuing anyway\n"); |
608 | "continuing anyway\n"); | ||
609 | 609 | ||
610 | /* 3. poll Page Migration DEBUG for SoftStopFault */ | 610 | /* 3. poll Page Migration DEBUG for SoftStopFault */ |
611 | target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_DEBUG); | 611 | target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_DEBUG); |
@@ -617,8 +617,7 @@ begin: | |||
617 | if (++count < 100) | 617 | if (++count < 100) |
618 | goto begin; | 618 | goto begin; |
619 | else { | 619 | else { |
620 | printk(KERN_WARNING "CalIOC2: too many SoftStopFaults, " | 620 | pr_warn("CalIOC2: too many SoftStopFaults, aborting TCE cache flush sequence!\n"); |
621 | "aborting TCE cache flush sequence!\n"); | ||
622 | return; /* pray for the best */ | 621 | return; /* pray for the best */ |
623 | } | 622 | } |
624 | } | 623 | } |
@@ -840,8 +839,8 @@ static void calgary_dump_error_regs(struct iommu_table *tbl) | |||
840 | plssr = be32_to_cpu(readl(target)); | 839 | plssr = be32_to_cpu(readl(target)); |
841 | 840 | ||
842 | /* If no error, the agent ID in the CSR is not valid */ | 841 | /* If no error, the agent ID in the CSR is not valid */ |
843 | printk(KERN_EMERG "Calgary: DMA error on Calgary PHB 0x%x, " | 842 | pr_emerg("DMA error on Calgary PHB 0x%x, 0x%08x@CSR 0x%08x@PLSSR\n", |
844 | "0x%08x@CSR 0x%08x@PLSSR\n", tbl->it_busno, csr, plssr); | 843 | tbl->it_busno, csr, plssr); |
845 | } | 844 | } |
846 | 845 | ||
847 | static void calioc2_dump_error_regs(struct iommu_table *tbl) | 846 | static void calioc2_dump_error_regs(struct iommu_table *tbl) |
@@ -867,22 +866,21 @@ static void calioc2_dump_error_regs(struct iommu_table *tbl) | |||
867 | target = calgary_reg(bbar, phboff | 0x800); | 866 | target = calgary_reg(bbar, phboff | 0x800); |
868 | mck = be32_to_cpu(readl(target)); | 867 | mck = be32_to_cpu(readl(target)); |
869 | 868 | ||
870 | printk(KERN_EMERG "Calgary: DMA error on CalIOC2 PHB 0x%x\n", | 869 | pr_emerg("DMA error on CalIOC2 PHB 0x%x\n", tbl->it_busno); |
871 | tbl->it_busno); | ||
872 | 870 | ||
873 | printk(KERN_EMERG "Calgary: 0x%08x@CSR 0x%08x@PLSSR 0x%08x@CSMR 0x%08x@MCK\n", | 871 | pr_emerg("0x%08x@CSR 0x%08x@PLSSR 0x%08x@CSMR 0x%08x@MCK\n", |
874 | csr, plssr, csmr, mck); | 872 | csr, plssr, csmr, mck); |
875 | 873 | ||
876 | /* dump rest of error regs */ | 874 | /* dump rest of error regs */ |
877 | printk(KERN_EMERG "Calgary: "); | 875 | pr_emerg(""); |
878 | for (i = 0; i < ARRAY_SIZE(errregs); i++) { | 876 | for (i = 0; i < ARRAY_SIZE(errregs); i++) { |
879 | /* err regs are at 0x810 - 0x870 */ | 877 | /* err regs are at 0x810 - 0x870 */ |
880 | erroff = (0x810 + (i * 0x10)); | 878 | erroff = (0x810 + (i * 0x10)); |
881 | target = calgary_reg(bbar, phboff | erroff); | 879 | target = calgary_reg(bbar, phboff | erroff); |
882 | errregs[i] = be32_to_cpu(readl(target)); | 880 | errregs[i] = be32_to_cpu(readl(target)); |
883 | printk("0x%08x@0x%lx ", errregs[i], erroff); | 881 | pr_cont("0x%08x@0x%lx ", errregs[i], erroff); |
884 | } | 882 | } |
885 | printk("\n"); | 883 | pr_cont("\n"); |
886 | 884 | ||
887 | /* root complex status */ | 885 | /* root complex status */ |
888 | target = calgary_reg(bbar, phboff | PHB_ROOT_COMPLEX_STATUS); | 886 | target = calgary_reg(bbar, phboff | PHB_ROOT_COMPLEX_STATUS); |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 735279e54e59..ef6a8456f719 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -1,3 +1,5 @@ | |||
1 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
2 | |||
1 | #include <linux/errno.h> | 3 | #include <linux/errno.h> |
2 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
3 | #include <linux/mm.h> | 5 | #include <linux/mm.h> |
@@ -145,16 +147,14 @@ void show_regs_common(void) | |||
145 | /* Board Name is optional */ | 147 | /* Board Name is optional */ |
146 | board = dmi_get_system_info(DMI_BOARD_NAME); | 148 | board = dmi_get_system_info(DMI_BOARD_NAME); |
147 | 149 | ||
148 | printk(KERN_CONT "\n"); | 150 | printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s %s%s%s\n", |
149 | printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s", | 151 | current->pid, current->comm, print_tainted(), |
150 | current->pid, current->comm, print_tainted(), | 152 | init_utsname()->release, |
151 | init_utsname()->release, | 153 | (int)strcspn(init_utsname()->version, " "), |
152 | (int)strcspn(init_utsname()->version, " "), | 154 | init_utsname()->version, |
153 | init_utsname()->version); | 155 | vendor, product, |
154 | printk(KERN_CONT " %s %s", vendor, product); | 156 | board ? "/" : "", |
155 | if (board) | 157 | board ? board : ""); |
156 | printk(KERN_CONT "/%s", board); | ||
157 | printk(KERN_CONT "\n"); | ||
158 | } | 158 | } |
159 | 159 | ||
160 | void flush_thread(void) | 160 | void flush_thread(void) |
@@ -645,7 +645,7 @@ static void amd_e400_idle(void) | |||
645 | amd_e400_c1e_detected = true; | 645 | amd_e400_c1e_detected = true; |
646 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) | 646 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) |
647 | mark_tsc_unstable("TSC halt in AMD C1E"); | 647 | mark_tsc_unstable("TSC halt in AMD C1E"); |
648 | printk(KERN_INFO "System has AMD C1E enabled\n"); | 648 | pr_info("System has AMD C1E enabled\n"); |
649 | } | 649 | } |
650 | } | 650 | } |
651 | 651 | ||
@@ -659,8 +659,7 @@ static void amd_e400_idle(void) | |||
659 | */ | 659 | */ |
660 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, | 660 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, |
661 | &cpu); | 661 | &cpu); |
662 | printk(KERN_INFO "Switch to broadcast mode on CPU%d\n", | 662 | pr_info("Switch to broadcast mode on CPU%d\n", cpu); |
663 | cpu); | ||
664 | } | 663 | } |
665 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); | 664 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); |
666 | 665 | ||
@@ -681,8 +680,7 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) | |||
681 | { | 680 | { |
682 | #ifdef CONFIG_SMP | 681 | #ifdef CONFIG_SMP |
683 | if (pm_idle == poll_idle && smp_num_siblings > 1) { | 682 | if (pm_idle == poll_idle && smp_num_siblings > 1) { |
684 | printk_once(KERN_WARNING "WARNING: polling idle and HT enabled," | 683 | pr_warn_once("WARNING: polling idle and HT enabled, performance may degrade\n"); |
685 | " performance may degrade.\n"); | ||
686 | } | 684 | } |
687 | #endif | 685 | #endif |
688 | if (pm_idle) | 686 | if (pm_idle) |
@@ -692,11 +690,11 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) | |||
692 | /* | 690 | /* |
693 | * One CPU supports mwait => All CPUs supports mwait | 691 | * One CPU supports mwait => All CPUs supports mwait |
694 | */ | 692 | */ |
695 | printk(KERN_INFO "using mwait in idle threads.\n"); | 693 | pr_info("using mwait in idle threads\n"); |
696 | pm_idle = mwait_idle; | 694 | pm_idle = mwait_idle; |
697 | } else if (cpu_has_amd_erratum(amd_erratum_400)) { | 695 | } else if (cpu_has_amd_erratum(amd_erratum_400)) { |
698 | /* E400: APIC timer interrupt does not wake up CPU from C1e */ | 696 | /* E400: APIC timer interrupt does not wake up CPU from C1e */ |
699 | printk(KERN_INFO "using AMD E400 aware idle routine\n"); | 697 | pr_info("using AMD E400 aware idle routine\n"); |
700 | pm_idle = amd_e400_idle; | 698 | pm_idle = amd_e400_idle; |
701 | } else | 699 | } else |
702 | pm_idle = default_idle; | 700 | pm_idle = default_idle; |
@@ -715,7 +713,7 @@ static int __init idle_setup(char *str) | |||
715 | return -EINVAL; | 713 | return -EINVAL; |
716 | 714 | ||
717 | if (!strcmp(str, "poll")) { | 715 | if (!strcmp(str, "poll")) { |
718 | printk("using polling idle threads.\n"); | 716 | pr_info("using polling idle threads\n"); |
719 | pm_idle = poll_idle; | 717 | pm_idle = poll_idle; |
720 | boot_option_idle_override = IDLE_POLL; | 718 | boot_option_idle_override = IDLE_POLL; |
721 | } else if (!strcmp(str, "mwait")) { | 719 | } else if (!strcmp(str, "mwait")) { |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 61cdf7fdf099..0a980c9d7cb8 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -117,10 +117,10 @@ void release_thread(struct task_struct *dead_task) | |||
117 | { | 117 | { |
118 | if (dead_task->mm) { | 118 | if (dead_task->mm) { |
119 | if (dead_task->mm->context.size) { | 119 | if (dead_task->mm->context.size) { |
120 | printk("WARNING: dead process %8s still has LDT? <%p/%d>\n", | 120 | pr_warn("WARNING: dead process %8s still has LDT? <%p/%d>\n", |
121 | dead_task->comm, | 121 | dead_task->comm, |
122 | dead_task->mm->context.ldt, | 122 | dead_task->mm->context.ldt, |
123 | dead_task->mm->context.size); | 123 | dead_task->mm->context.size); |
124 | BUG(); | 124 | BUG(); |
125 | } | 125 | } |
126 | } | 126 | } |
@@ -466,7 +466,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) | |||
466 | task->thread.gs = addr; | 466 | task->thread.gs = addr; |
467 | if (doit) { | 467 | if (doit) { |
468 | load_gs_index(0); | 468 | load_gs_index(0); |
469 | ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); | 469 | ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr); |
470 | } | 470 | } |
471 | } | 471 | } |
472 | put_cpu(); | 472 | put_cpu(); |
@@ -494,7 +494,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) | |||
494 | /* set the selector to 0 to not confuse | 494 | /* set the selector to 0 to not confuse |
495 | __switch_to */ | 495 | __switch_to */ |
496 | loadsegment(fs, 0); | 496 | loadsegment(fs, 0); |
497 | ret = checking_wrmsrl(MSR_FS_BASE, addr); | 497 | ret = wrmsrl_safe(MSR_FS_BASE, addr); |
498 | } | 498 | } |
499 | } | 499 | } |
500 | put_cpu(); | 500 | put_cpu(); |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 5de92f1abd76..52190a938b4a 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -1,3 +1,5 @@ | |||
1 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
2 | |||
1 | #include <linux/module.h> | 3 | #include <linux/module.h> |
2 | #include <linux/reboot.h> | 4 | #include <linux/reboot.h> |
3 | #include <linux/init.h> | 5 | #include <linux/init.h> |
@@ -20,14 +22,12 @@ | |||
20 | #include <asm/virtext.h> | 22 | #include <asm/virtext.h> |
21 | #include <asm/cpu.h> | 23 | #include <asm/cpu.h> |
22 | #include <asm/nmi.h> | 24 | #include <asm/nmi.h> |
25 | #include <asm/smp.h> | ||
23 | 26 | ||
24 | #ifdef CONFIG_X86_32 | 27 | #include <linux/ctype.h> |
25 | # include <linux/ctype.h> | 28 | #include <linux/mc146818rtc.h> |
26 | # include <linux/mc146818rtc.h> | 29 | #include <asm/realmode.h> |
27 | # include <asm/realmode.h> | 30 | #include <asm/x86_init.h> |
28 | #else | ||
29 | # include <asm/x86_init.h> | ||
30 | #endif | ||
31 | 31 | ||
32 | /* | 32 | /* |
33 | * Power off function, if any | 33 | * Power off function, if any |
@@ -49,7 +49,7 @@ int reboot_force; | |||
49 | */ | 49 | */ |
50 | static int reboot_default = 1; | 50 | static int reboot_default = 1; |
51 | 51 | ||
52 | #if defined(CONFIG_X86_32) && defined(CONFIG_SMP) | 52 | #ifdef CONFIG_SMP |
53 | static int reboot_cpu = -1; | 53 | static int reboot_cpu = -1; |
54 | #endif | 54 | #endif |
55 | 55 | ||
@@ -67,8 +67,8 @@ bool port_cf9_safe = false; | |||
67 | * reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci] | 67 | * reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci] |
68 | * warm Don't set the cold reboot flag | 68 | * warm Don't set the cold reboot flag |
69 | * cold Set the cold reboot flag | 69 | * cold Set the cold reboot flag |
70 | * bios Reboot by jumping through the BIOS (only for X86_32) | 70 | * bios Reboot by jumping through the BIOS |
71 | * smp Reboot by executing reset on BSP or other CPU (only for X86_32) | 71 | * smp Reboot by executing reset on BSP or other CPU |
72 | * triple Force a triple fault (init) | 72 | * triple Force a triple fault (init) |
73 | * kbd Use the keyboard controller. cold reset (default) | 73 | * kbd Use the keyboard controller. cold reset (default) |
74 | * acpi Use the RESET_REG in the FADT | 74 | * acpi Use the RESET_REG in the FADT |
@@ -95,7 +95,6 @@ static int __init reboot_setup(char *str) | |||
95 | reboot_mode = 0; | 95 | reboot_mode = 0; |
96 | break; | 96 | break; |
97 | 97 | ||
98 | #ifdef CONFIG_X86_32 | ||
99 | #ifdef CONFIG_SMP | 98 | #ifdef CONFIG_SMP |
100 | case 's': | 99 | case 's': |
101 | if (isdigit(*(str+1))) { | 100 | if (isdigit(*(str+1))) { |
@@ -112,7 +111,6 @@ static int __init reboot_setup(char *str) | |||
112 | #endif /* CONFIG_SMP */ | 111 | #endif /* CONFIG_SMP */ |
113 | 112 | ||
114 | case 'b': | 113 | case 'b': |
115 | #endif | ||
116 | case 'a': | 114 | case 'a': |
117 | case 'k': | 115 | case 'k': |
118 | case 't': | 116 | case 't': |
@@ -138,7 +136,6 @@ static int __init reboot_setup(char *str) | |||
138 | __setup("reboot=", reboot_setup); | 136 | __setup("reboot=", reboot_setup); |
139 | 137 | ||
140 | 138 | ||
141 | #ifdef CONFIG_X86_32 | ||
142 | /* | 139 | /* |
143 | * Reboot options and system auto-detection code provided by | 140 | * Reboot options and system auto-detection code provided by |
144 | * Dell Inc. so their systems "just work". :-) | 141 | * Dell Inc. so their systems "just work". :-) |
@@ -152,16 +149,14 @@ static int __init set_bios_reboot(const struct dmi_system_id *d) | |||
152 | { | 149 | { |
153 | if (reboot_type != BOOT_BIOS) { | 150 | if (reboot_type != BOOT_BIOS) { |
154 | reboot_type = BOOT_BIOS; | 151 | reboot_type = BOOT_BIOS; |
155 | printk(KERN_INFO "%s series board detected. Selecting BIOS-method for reboots.\n", d->ident); | 152 | pr_info("%s series board detected. Selecting %s-method for reboots.\n", |
153 | "BIOS", d->ident); | ||
156 | } | 154 | } |
157 | return 0; | 155 | return 0; |
158 | } | 156 | } |
159 | 157 | ||
160 | void machine_real_restart(unsigned int type) | 158 | void __noreturn machine_real_restart(unsigned int type) |
161 | { | 159 | { |
162 | void (*restart_lowmem)(unsigned int) = (void (*)(unsigned int)) | ||
163 | real_mode_header->machine_real_restart_asm; | ||
164 | |||
165 | local_irq_disable(); | 160 | local_irq_disable(); |
166 | 161 | ||
167 | /* | 162 | /* |
@@ -181,25 +176,28 @@ void machine_real_restart(unsigned int type) | |||
181 | /* | 176 | /* |
182 | * Switch back to the initial page table. | 177 | * Switch back to the initial page table. |
183 | */ | 178 | */ |
179 | #ifdef CONFIG_X86_32 | ||
184 | load_cr3(initial_page_table); | 180 | load_cr3(initial_page_table); |
185 | 181 | #else | |
186 | /* | 182 | write_cr3(real_mode_header->trampoline_pgd); |
187 | * Write 0x1234 to absolute memory location 0x472. The BIOS reads | 183 | #endif |
188 | * this on booting to tell it to "Bypass memory test (also warm | ||
189 | * boot)". This seems like a fairly standard thing that gets set by | ||
190 | * REBOOT.COM programs, and the previous reset routine did this | ||
191 | * too. */ | ||
192 | *((unsigned short *)0x472) = reboot_mode; | ||
193 | 184 | ||
194 | /* Jump to the identity-mapped low memory code */ | 185 | /* Jump to the identity-mapped low memory code */ |
195 | restart_lowmem(type); | 186 | #ifdef CONFIG_X86_32 |
187 | asm volatile("jmpl *%0" : : | ||
188 | "rm" (real_mode_header->machine_real_restart_asm), | ||
189 | "a" (type)); | ||
190 | #else | ||
191 | asm volatile("ljmpl *%0" : : | ||
192 | "m" (real_mode_header->machine_real_restart_asm), | ||
193 | "D" (type)); | ||
194 | #endif | ||
195 | unreachable(); | ||
196 | } | 196 | } |
197 | #ifdef CONFIG_APM_MODULE | 197 | #ifdef CONFIG_APM_MODULE |
198 | EXPORT_SYMBOL(machine_real_restart); | 198 | EXPORT_SYMBOL(machine_real_restart); |
199 | #endif | 199 | #endif |
200 | 200 | ||
201 | #endif /* CONFIG_X86_32 */ | ||
202 | |||
203 | /* | 201 | /* |
204 | * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot | 202 | * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot |
205 | */ | 203 | */ |
@@ -207,8 +205,8 @@ static int __init set_pci_reboot(const struct dmi_system_id *d) | |||
207 | { | 205 | { |
208 | if (reboot_type != BOOT_CF9) { | 206 | if (reboot_type != BOOT_CF9) { |
209 | reboot_type = BOOT_CF9; | 207 | reboot_type = BOOT_CF9; |
210 | printk(KERN_INFO "%s series board detected. " | 208 | pr_info("%s series board detected. Selecting %s-method for reboots.\n", |
211 | "Selecting PCI-method for reboots.\n", d->ident); | 209 | "PCI", d->ident); |
212 | } | 210 | } |
213 | return 0; | 211 | return 0; |
214 | } | 212 | } |
@@ -217,17 +215,16 @@ static int __init set_kbd_reboot(const struct dmi_system_id *d) | |||
217 | { | 215 | { |
218 | if (reboot_type != BOOT_KBD) { | 216 | if (reboot_type != BOOT_KBD) { |
219 | reboot_type = BOOT_KBD; | 217 | reboot_type = BOOT_KBD; |
220 | printk(KERN_INFO "%s series board detected. Selecting KBD-method for reboot.\n", d->ident); | 218 | pr_info("%s series board detected. Selecting %s-method for reboot.\n", |
219 | "KBD", d->ident); | ||
221 | } | 220 | } |
222 | return 0; | 221 | return 0; |
223 | } | 222 | } |
224 | 223 | ||
225 | /* | 224 | /* |
226 | * This is a single dmi_table handling all reboot quirks. Note that | 225 | * This is a single dmi_table handling all reboot quirks. |
227 | * REBOOT_BIOS is only available for 32bit | ||
228 | */ | 226 | */ |
229 | static struct dmi_system_id __initdata reboot_dmi_table[] = { | 227 | static struct dmi_system_id __initdata reboot_dmi_table[] = { |
230 | #ifdef CONFIG_X86_32 | ||
231 | { /* Handle problems with rebooting on Dell E520's */ | 228 | { /* Handle problems with rebooting on Dell E520's */ |
232 | .callback = set_bios_reboot, | 229 | .callback = set_bios_reboot, |
233 | .ident = "Dell E520", | 230 | .ident = "Dell E520", |
@@ -377,7 +374,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
377 | DMI_MATCH(DMI_BOARD_NAME, "P4S800"), | 374 | DMI_MATCH(DMI_BOARD_NAME, "P4S800"), |
378 | }, | 375 | }, |
379 | }, | 376 | }, |
380 | #endif /* CONFIG_X86_32 */ | ||
381 | 377 | ||
382 | { /* Handle reboot issue on Acer Aspire one */ | 378 | { /* Handle reboot issue on Acer Aspire one */ |
383 | .callback = set_kbd_reboot, | 379 | .callback = set_kbd_reboot, |
@@ -584,13 +580,11 @@ static void native_machine_emergency_restart(void) | |||
584 | reboot_type = BOOT_KBD; | 580 | reboot_type = BOOT_KBD; |
585 | break; | 581 | break; |
586 | 582 | ||
587 | #ifdef CONFIG_X86_32 | ||
588 | case BOOT_BIOS: | 583 | case BOOT_BIOS: |
589 | machine_real_restart(MRR_BIOS); | 584 | machine_real_restart(MRR_BIOS); |
590 | 585 | ||
591 | reboot_type = BOOT_KBD; | 586 | reboot_type = BOOT_KBD; |
592 | break; | 587 | break; |
593 | #endif | ||
594 | 588 | ||
595 | case BOOT_ACPI: | 589 | case BOOT_ACPI: |
596 | acpi_reboot(); | 590 | acpi_reboot(); |
@@ -632,12 +626,10 @@ void native_machine_shutdown(void) | |||
632 | /* The boot cpu is always logical cpu 0 */ | 626 | /* The boot cpu is always logical cpu 0 */ |
633 | int reboot_cpu_id = 0; | 627 | int reboot_cpu_id = 0; |
634 | 628 | ||
635 | #ifdef CONFIG_X86_32 | ||
636 | /* See if there has been given a command line override */ | 629 | /* See if there has been given a command line override */ |
637 | if ((reboot_cpu != -1) && (reboot_cpu < nr_cpu_ids) && | 630 | if ((reboot_cpu != -1) && (reboot_cpu < nr_cpu_ids) && |
638 | cpu_online(reboot_cpu)) | 631 | cpu_online(reboot_cpu)) |
639 | reboot_cpu_id = reboot_cpu; | 632 | reboot_cpu_id = reboot_cpu; |
640 | #endif | ||
641 | 633 | ||
642 | /* Make certain the cpu I'm about to reboot on is online */ | 634 | /* Make certain the cpu I'm about to reboot on is online */ |
643 | if (!cpu_online(reboot_cpu_id)) | 635 | if (!cpu_online(reboot_cpu_id)) |
@@ -678,7 +670,7 @@ static void __machine_emergency_restart(int emergency) | |||
678 | 670 | ||
679 | static void native_machine_restart(char *__unused) | 671 | static void native_machine_restart(char *__unused) |
680 | { | 672 | { |
681 | printk("machine restart\n"); | 673 | pr_notice("machine restart\n"); |
682 | 674 | ||
683 | if (!reboot_force) | 675 | if (!reboot_force) |
684 | machine_shutdown(); | 676 | machine_shutdown(); |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 16be6dc14db1..f4b9b80e1b95 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -1031,8 +1031,6 @@ void __init setup_arch(char **cmdline_p) | |||
1031 | 1031 | ||
1032 | x86_init.timers.wallclock_init(); | 1032 | x86_init.timers.wallclock_init(); |
1033 | 1033 | ||
1034 | x86_platform.wallclock_init(); | ||
1035 | |||
1036 | mcheck_init(); | 1034 | mcheck_init(); |
1037 | 1035 | ||
1038 | arch_init_ideal_nops(); | 1036 | arch_init_ideal_nops(); |
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 21af737053aa..b280908a376e 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -6,6 +6,9 @@ | |||
6 | * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes | 6 | * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes |
7 | * 2000-2002 x86-64 support by Andi Kleen | 7 | * 2000-2002 x86-64 support by Andi Kleen |
8 | */ | 8 | */ |
9 | |||
10 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
11 | |||
9 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
10 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
11 | #include <linux/smp.h> | 14 | #include <linux/smp.h> |
@@ -814,7 +817,7 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where) | |||
814 | me->comm, me->pid, where, frame, | 817 | me->comm, me->pid, where, frame, |
815 | regs->ip, regs->sp, regs->orig_ax); | 818 | regs->ip, regs->sp, regs->orig_ax); |
816 | print_vma_addr(" in ", regs->ip); | 819 | print_vma_addr(" in ", regs->ip); |
817 | printk(KERN_CONT "\n"); | 820 | pr_cont("\n"); |
818 | } | 821 | } |
819 | 822 | ||
820 | force_sig(SIGSEGV, me); | 823 | force_sig(SIGSEGV, me); |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 7bd8a0823654..c1a310fb8309 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * x86 SMP booting functions | 2 | * x86 SMP booting functions |
3 | * | 3 | * |
4 | * (c) 1995 Alan Cox, Building #3 <alan@lxorguk.ukuu.org.uk> | 4 | * (c) 1995 Alan Cox, Building #3 <alan@lxorguk.ukuu.org.uk> |
@@ -39,6 +39,8 @@ | |||
39 | * Glauber Costa : i386 and x86_64 integration | 39 | * Glauber Costa : i386 and x86_64 integration |
40 | */ | 40 | */ |
41 | 41 | ||
42 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
43 | |||
42 | #include <linux/init.h> | 44 | #include <linux/init.h> |
43 | #include <linux/smp.h> | 45 | #include <linux/smp.h> |
44 | #include <linux/module.h> | 46 | #include <linux/module.h> |
@@ -184,7 +186,7 @@ static void __cpuinit smp_callin(void) | |||
184 | * boards) | 186 | * boards) |
185 | */ | 187 | */ |
186 | 188 | ||
187 | pr_debug("CALLIN, before setup_local_APIC().\n"); | 189 | pr_debug("CALLIN, before setup_local_APIC()\n"); |
188 | if (apic->smp_callin_clear_local_apic) | 190 | if (apic->smp_callin_clear_local_apic) |
189 | apic->smp_callin_clear_local_apic(); | 191 | apic->smp_callin_clear_local_apic(); |
190 | setup_local_APIC(); | 192 | setup_local_APIC(); |
@@ -255,22 +257,13 @@ notrace static void __cpuinit start_secondary(void *unused) | |||
255 | check_tsc_sync_target(); | 257 | check_tsc_sync_target(); |
256 | 258 | ||
257 | /* | 259 | /* |
258 | * We need to hold call_lock, so there is no inconsistency | ||
259 | * between the time smp_call_function() determines number of | ||
260 | * IPI recipients, and the time when the determination is made | ||
261 | * for which cpus receive the IPI. Holding this | ||
262 | * lock helps us to not include this cpu in a currently in progress | ||
263 | * smp_call_function(). | ||
264 | * | ||
265 | * We need to hold vector_lock so there the set of online cpus | 260 | * We need to hold vector_lock so there the set of online cpus |
266 | * does not change while we are assigning vectors to cpus. Holding | 261 | * does not change while we are assigning vectors to cpus. Holding |
267 | * this lock ensures we don't half assign or remove an irq from a cpu. | 262 | * this lock ensures we don't half assign or remove an irq from a cpu. |
268 | */ | 263 | */ |
269 | ipi_call_lock(); | ||
270 | lock_vector_lock(); | 264 | lock_vector_lock(); |
271 | set_cpu_online(smp_processor_id(), true); | 265 | set_cpu_online(smp_processor_id(), true); |
272 | unlock_vector_lock(); | 266 | unlock_vector_lock(); |
273 | ipi_call_unlock(); | ||
274 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | 267 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; |
275 | x86_platform.nmi_init(); | 268 | x86_platform.nmi_init(); |
276 | 269 | ||
@@ -432,17 +425,16 @@ static void impress_friends(void) | |||
432 | /* | 425 | /* |
433 | * Allow the user to impress friends. | 426 | * Allow the user to impress friends. |
434 | */ | 427 | */ |
435 | pr_debug("Before bogomips.\n"); | 428 | pr_debug("Before bogomips\n"); |
436 | for_each_possible_cpu(cpu) | 429 | for_each_possible_cpu(cpu) |
437 | if (cpumask_test_cpu(cpu, cpu_callout_mask)) | 430 | if (cpumask_test_cpu(cpu, cpu_callout_mask)) |
438 | bogosum += cpu_data(cpu).loops_per_jiffy; | 431 | bogosum += cpu_data(cpu).loops_per_jiffy; |
439 | printk(KERN_INFO | 432 | pr_info("Total of %d processors activated (%lu.%02lu BogoMIPS)\n", |
440 | "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", | ||
441 | num_online_cpus(), | 433 | num_online_cpus(), |
442 | bogosum/(500000/HZ), | 434 | bogosum/(500000/HZ), |
443 | (bogosum/(5000/HZ))%100); | 435 | (bogosum/(5000/HZ))%100); |
444 | 436 | ||
445 | pr_debug("Before bogocount - setting activated=1.\n"); | 437 | pr_debug("Before bogocount - setting activated=1\n"); |
446 | } | 438 | } |
447 | 439 | ||
448 | void __inquire_remote_apic(int apicid) | 440 | void __inquire_remote_apic(int apicid) |
@@ -452,18 +444,17 @@ void __inquire_remote_apic(int apicid) | |||
452 | int timeout; | 444 | int timeout; |
453 | u32 status; | 445 | u32 status; |
454 | 446 | ||
455 | printk(KERN_INFO "Inquiring remote APIC 0x%x...\n", apicid); | 447 | pr_info("Inquiring remote APIC 0x%x...\n", apicid); |
456 | 448 | ||
457 | for (i = 0; i < ARRAY_SIZE(regs); i++) { | 449 | for (i = 0; i < ARRAY_SIZE(regs); i++) { |
458 | printk(KERN_INFO "... APIC 0x%x %s: ", apicid, names[i]); | 450 | pr_info("... APIC 0x%x %s: ", apicid, names[i]); |
459 | 451 | ||
460 | /* | 452 | /* |
461 | * Wait for idle. | 453 | * Wait for idle. |
462 | */ | 454 | */ |
463 | status = safe_apic_wait_icr_idle(); | 455 | status = safe_apic_wait_icr_idle(); |
464 | if (status) | 456 | if (status) |
465 | printk(KERN_CONT | 457 | pr_cont("a previous APIC delivery may have failed\n"); |
466 | "a previous APIC delivery may have failed\n"); | ||
467 | 458 | ||
468 | apic_icr_write(APIC_DM_REMRD | regs[i], apicid); | 459 | apic_icr_write(APIC_DM_REMRD | regs[i], apicid); |
469 | 460 | ||
@@ -476,10 +467,10 @@ void __inquire_remote_apic(int apicid) | |||
476 | switch (status) { | 467 | switch (status) { |
477 | case APIC_ICR_RR_VALID: | 468 | case APIC_ICR_RR_VALID: |
478 | status = apic_read(APIC_RRR); | 469 | status = apic_read(APIC_RRR); |
479 | printk(KERN_CONT "%08x\n", status); | 470 | pr_cont("%08x\n", status); |
480 | break; | 471 | break; |
481 | default: | 472 | default: |
482 | printk(KERN_CONT "failed\n"); | 473 | pr_cont("failed\n"); |
483 | } | 474 | } |
484 | } | 475 | } |
485 | } | 476 | } |
@@ -513,12 +504,12 @@ wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip) | |||
513 | apic_write(APIC_ESR, 0); | 504 | apic_write(APIC_ESR, 0); |
514 | accept_status = (apic_read(APIC_ESR) & 0xEF); | 505 | accept_status = (apic_read(APIC_ESR) & 0xEF); |
515 | } | 506 | } |
516 | pr_debug("NMI sent.\n"); | 507 | pr_debug("NMI sent\n"); |
517 | 508 | ||
518 | if (send_status) | 509 | if (send_status) |
519 | printk(KERN_ERR "APIC never delivered???\n"); | 510 | pr_err("APIC never delivered???\n"); |
520 | if (accept_status) | 511 | if (accept_status) |
521 | printk(KERN_ERR "APIC delivery error (%lx).\n", accept_status); | 512 | pr_err("APIC delivery error (%lx)\n", accept_status); |
522 | 513 | ||
523 | return (send_status | accept_status); | 514 | return (send_status | accept_status); |
524 | } | 515 | } |
@@ -540,7 +531,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) | |||
540 | apic_read(APIC_ESR); | 531 | apic_read(APIC_ESR); |
541 | } | 532 | } |
542 | 533 | ||
543 | pr_debug("Asserting INIT.\n"); | 534 | pr_debug("Asserting INIT\n"); |
544 | 535 | ||
545 | /* | 536 | /* |
546 | * Turn INIT on target chip | 537 | * Turn INIT on target chip |
@@ -556,7 +547,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) | |||
556 | 547 | ||
557 | mdelay(10); | 548 | mdelay(10); |
558 | 549 | ||
559 | pr_debug("Deasserting INIT.\n"); | 550 | pr_debug("Deasserting INIT\n"); |
560 | 551 | ||
561 | /* Target chip */ | 552 | /* Target chip */ |
562 | /* Send IPI */ | 553 | /* Send IPI */ |
@@ -589,14 +580,14 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) | |||
589 | /* | 580 | /* |
590 | * Run STARTUP IPI loop. | 581 | * Run STARTUP IPI loop. |
591 | */ | 582 | */ |
592 | pr_debug("#startup loops: %d.\n", num_starts); | 583 | pr_debug("#startup loops: %d\n", num_starts); |
593 | 584 | ||
594 | for (j = 1; j <= num_starts; j++) { | 585 | for (j = 1; j <= num_starts; j++) { |
595 | pr_debug("Sending STARTUP #%d.\n", j); | 586 | pr_debug("Sending STARTUP #%d\n", j); |
596 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ | 587 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ |
597 | apic_write(APIC_ESR, 0); | 588 | apic_write(APIC_ESR, 0); |
598 | apic_read(APIC_ESR); | 589 | apic_read(APIC_ESR); |
599 | pr_debug("After apic_write.\n"); | 590 | pr_debug("After apic_write\n"); |
600 | 591 | ||
601 | /* | 592 | /* |
602 | * STARTUP IPI | 593 | * STARTUP IPI |
@@ -613,7 +604,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) | |||
613 | */ | 604 | */ |
614 | udelay(300); | 605 | udelay(300); |
615 | 606 | ||
616 | pr_debug("Startup point 1.\n"); | 607 | pr_debug("Startup point 1\n"); |
617 | 608 | ||
618 | pr_debug("Waiting for send to finish...\n"); | 609 | pr_debug("Waiting for send to finish...\n"); |
619 | send_status = safe_apic_wait_icr_idle(); | 610 | send_status = safe_apic_wait_icr_idle(); |
@@ -628,12 +619,12 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) | |||
628 | if (send_status || accept_status) | 619 | if (send_status || accept_status) |
629 | break; | 620 | break; |
630 | } | 621 | } |
631 | pr_debug("After Startup.\n"); | 622 | pr_debug("After Startup\n"); |
632 | 623 | ||
633 | if (send_status) | 624 | if (send_status) |
634 | printk(KERN_ERR "APIC never delivered???\n"); | 625 | pr_err("APIC never delivered???\n"); |
635 | if (accept_status) | 626 | if (accept_status) |
636 | printk(KERN_ERR "APIC delivery error (%lx).\n", accept_status); | 627 | pr_err("APIC delivery error (%lx)\n", accept_status); |
637 | 628 | ||
638 | return (send_status | accept_status); | 629 | return (send_status | accept_status); |
639 | } | 630 | } |
@@ -647,11 +638,11 @@ static void __cpuinit announce_cpu(int cpu, int apicid) | |||
647 | if (system_state == SYSTEM_BOOTING) { | 638 | if (system_state == SYSTEM_BOOTING) { |
648 | if (node != current_node) { | 639 | if (node != current_node) { |
649 | if (current_node > (-1)) | 640 | if (current_node > (-1)) |
650 | pr_cont(" Ok.\n"); | 641 | pr_cont(" OK\n"); |
651 | current_node = node; | 642 | current_node = node; |
652 | pr_info("Booting Node %3d, Processors ", node); | 643 | pr_info("Booting Node %3d, Processors ", node); |
653 | } | 644 | } |
654 | pr_cont(" #%d%s", cpu, cpu == (nr_cpu_ids - 1) ? " Ok.\n" : ""); | 645 | pr_cont(" #%d%s", cpu, cpu == (nr_cpu_ids - 1) ? " OK\n" : ""); |
655 | return; | 646 | return; |
656 | } else | 647 | } else |
657 | pr_info("Booting Node %d Processor %d APIC 0x%x\n", | 648 | pr_info("Booting Node %d Processor %d APIC 0x%x\n", |
@@ -731,9 +722,9 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle) | |||
731 | /* | 722 | /* |
732 | * allow APs to start initializing. | 723 | * allow APs to start initializing. |
733 | */ | 724 | */ |
734 | pr_debug("Before Callout %d.\n", cpu); | 725 | pr_debug("Before Callout %d\n", cpu); |
735 | cpumask_set_cpu(cpu, cpu_callout_mask); | 726 | cpumask_set_cpu(cpu, cpu_callout_mask); |
736 | pr_debug("After Callout %d.\n", cpu); | 727 | pr_debug("After Callout %d\n", cpu); |
737 | 728 | ||
738 | /* | 729 | /* |
739 | * Wait 5s total for a response | 730 | * Wait 5s total for a response |
@@ -761,7 +752,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle) | |||
761 | pr_err("CPU%d: Stuck ??\n", cpu); | 752 | pr_err("CPU%d: Stuck ??\n", cpu); |
762 | else | 753 | else |
763 | /* trampoline code not run */ | 754 | /* trampoline code not run */ |
764 | pr_err("CPU%d: Not responding.\n", cpu); | 755 | pr_err("CPU%d: Not responding\n", cpu); |
765 | if (apic->inquire_remote_apic) | 756 | if (apic->inquire_remote_apic) |
766 | apic->inquire_remote_apic(apicid); | 757 | apic->inquire_remote_apic(apicid); |
767 | } | 758 | } |
@@ -806,7 +797,7 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle) | |||
806 | if (apicid == BAD_APICID || apicid == boot_cpu_physical_apicid || | 797 | if (apicid == BAD_APICID || apicid == boot_cpu_physical_apicid || |
807 | !physid_isset(apicid, phys_cpu_present_map) || | 798 | !physid_isset(apicid, phys_cpu_present_map) || |
808 | !apic->apic_id_valid(apicid)) { | 799 | !apic->apic_id_valid(apicid)) { |
809 | printk(KERN_ERR "%s: bad cpu %d\n", __func__, cpu); | 800 | pr_err("%s: bad cpu %d\n", __func__, cpu); |
810 | return -EINVAL; | 801 | return -EINVAL; |
811 | } | 802 | } |
812 | 803 | ||
@@ -887,9 +878,8 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
887 | unsigned int cpu; | 878 | unsigned int cpu; |
888 | unsigned nr; | 879 | unsigned nr; |
889 | 880 | ||
890 | printk(KERN_WARNING | 881 | pr_warn("More than 8 CPUs detected - skipping them\n" |
891 | "More than 8 CPUs detected - skipping them.\n" | 882 | "Use CONFIG_X86_BIGSMP\n"); |
892 | "Use CONFIG_X86_BIGSMP.\n"); | ||
893 | 883 | ||
894 | nr = 0; | 884 | nr = 0; |
895 | for_each_present_cpu(cpu) { | 885 | for_each_present_cpu(cpu) { |
@@ -910,8 +900,7 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
910 | #endif | 900 | #endif |
911 | 901 | ||
912 | if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { | 902 | if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { |
913 | printk(KERN_WARNING | 903 | pr_warn("weird, boot CPU (#%d) not listed by the BIOS\n", |
914 | "weird, boot CPU (#%d) not listed by the BIOS.\n", | ||
915 | hard_smp_processor_id()); | 904 | hard_smp_processor_id()); |
916 | 905 | ||
917 | physid_set(hard_smp_processor_id(), phys_cpu_present_map); | 906 | physid_set(hard_smp_processor_id(), phys_cpu_present_map); |
@@ -923,11 +912,10 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
923 | */ | 912 | */ |
924 | if (!smp_found_config && !acpi_lapic) { | 913 | if (!smp_found_config && !acpi_lapic) { |
925 | preempt_enable(); | 914 | preempt_enable(); |
926 | printk(KERN_NOTICE "SMP motherboard not detected.\n"); | 915 | pr_notice("SMP motherboard not detected\n"); |
927 | disable_smp(); | 916 | disable_smp(); |
928 | if (APIC_init_uniprocessor()) | 917 | if (APIC_init_uniprocessor()) |
929 | printk(KERN_NOTICE "Local APIC not detected." | 918 | pr_notice("Local APIC not detected. Using dummy APIC emulation.\n"); |
930 | " Using dummy APIC emulation.\n"); | ||
931 | return -1; | 919 | return -1; |
932 | } | 920 | } |
933 | 921 | ||
@@ -936,9 +924,8 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
936 | * CPU too, but we do it for the sake of robustness anyway. | 924 | * CPU too, but we do it for the sake of robustness anyway. |
937 | */ | 925 | */ |
938 | if (!apic->check_phys_apicid_present(boot_cpu_physical_apicid)) { | 926 | if (!apic->check_phys_apicid_present(boot_cpu_physical_apicid)) { |
939 | printk(KERN_NOTICE | 927 | pr_notice("weird, boot CPU (#%d) not listed by the BIOS\n", |
940 | "weird, boot CPU (#%d) not listed by the BIOS.\n", | 928 | boot_cpu_physical_apicid); |
941 | boot_cpu_physical_apicid); | ||
942 | physid_set(hard_smp_processor_id(), phys_cpu_present_map); | 929 | physid_set(hard_smp_processor_id(), phys_cpu_present_map); |
943 | } | 930 | } |
944 | preempt_enable(); | 931 | preempt_enable(); |
@@ -951,8 +938,7 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
951 | if (!disable_apic) { | 938 | if (!disable_apic) { |
952 | pr_err("BIOS bug, local APIC #%d not detected!...\n", | 939 | pr_err("BIOS bug, local APIC #%d not detected!...\n", |
953 | boot_cpu_physical_apicid); | 940 | boot_cpu_physical_apicid); |
954 | pr_err("... forcing use of dummy APIC emulation." | 941 | pr_err("... forcing use of dummy APIC emulation (tell your hw vendor)\n"); |
955 | "(tell your hw vendor)\n"); | ||
956 | } | 942 | } |
957 | smpboot_clear_io_apic(); | 943 | smpboot_clear_io_apic(); |
958 | disable_ioapic_support(); | 944 | disable_ioapic_support(); |
@@ -965,7 +951,7 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
965 | * If SMP should be disabled, then really disable it! | 951 | * If SMP should be disabled, then really disable it! |
966 | */ | 952 | */ |
967 | if (!max_cpus) { | 953 | if (!max_cpus) { |
968 | printk(KERN_INFO "SMP mode deactivated.\n"); | 954 | pr_info("SMP mode deactivated\n"); |
969 | smpboot_clear_io_apic(); | 955 | smpboot_clear_io_apic(); |
970 | 956 | ||
971 | connect_bsp_APIC(); | 957 | connect_bsp_APIC(); |
@@ -1017,7 +1003,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) | |||
1017 | 1003 | ||
1018 | 1004 | ||
1019 | if (smp_sanity_check(max_cpus) < 0) { | 1005 | if (smp_sanity_check(max_cpus) < 0) { |
1020 | printk(KERN_INFO "SMP disabled\n"); | 1006 | pr_info("SMP disabled\n"); |
1021 | disable_smp(); | 1007 | disable_smp(); |
1022 | goto out; | 1008 | goto out; |
1023 | } | 1009 | } |
@@ -1055,7 +1041,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) | |||
1055 | * Set up local APIC timer on boot CPU. | 1041 | * Set up local APIC timer on boot CPU. |
1056 | */ | 1042 | */ |
1057 | 1043 | ||
1058 | printk(KERN_INFO "CPU%d: ", 0); | 1044 | pr_info("CPU%d: ", 0); |
1059 | print_cpu_info(&cpu_data(0)); | 1045 | print_cpu_info(&cpu_data(0)); |
1060 | x86_init.timers.setup_percpu_clockev(); | 1046 | x86_init.timers.setup_percpu_clockev(); |
1061 | 1047 | ||
@@ -1105,7 +1091,7 @@ void __init native_smp_prepare_boot_cpu(void) | |||
1105 | 1091 | ||
1106 | void __init native_smp_cpus_done(unsigned int max_cpus) | 1092 | void __init native_smp_cpus_done(unsigned int max_cpus) |
1107 | { | 1093 | { |
1108 | pr_debug("Boot done.\n"); | 1094 | pr_debug("Boot done\n"); |
1109 | 1095 | ||
1110 | nmi_selftest(); | 1096 | nmi_selftest(); |
1111 | impress_friends(); | 1097 | impress_friends(); |
@@ -1166,8 +1152,7 @@ __init void prefill_possible_map(void) | |||
1166 | 1152 | ||
1167 | /* nr_cpu_ids could be reduced via nr_cpus= */ | 1153 | /* nr_cpu_ids could be reduced via nr_cpus= */ |
1168 | if (possible > nr_cpu_ids) { | 1154 | if (possible > nr_cpu_ids) { |
1169 | printk(KERN_WARNING | 1155 | pr_warn("%d Processors exceeds NR_CPUS limit of %d\n", |
1170 | "%d Processors exceeds NR_CPUS limit of %d\n", | ||
1171 | possible, nr_cpu_ids); | 1156 | possible, nr_cpu_ids); |
1172 | possible = nr_cpu_ids; | 1157 | possible = nr_cpu_ids; |
1173 | } | 1158 | } |
@@ -1176,13 +1161,12 @@ __init void prefill_possible_map(void) | |||
1176 | if (!setup_max_cpus) | 1161 | if (!setup_max_cpus) |
1177 | #endif | 1162 | #endif |
1178 | if (possible > i) { | 1163 | if (possible > i) { |
1179 | printk(KERN_WARNING | 1164 | pr_warn("%d Processors exceeds max_cpus limit of %u\n", |
1180 | "%d Processors exceeds max_cpus limit of %u\n", | ||
1181 | possible, setup_max_cpus); | 1165 | possible, setup_max_cpus); |
1182 | possible = i; | 1166 | possible = i; |
1183 | } | 1167 | } |
1184 | 1168 | ||
1185 | printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", | 1169 | pr_info("Allowing %d CPUs, %d hotplug CPUs\n", |
1186 | possible, max_t(int, possible - num_processors, 0)); | 1170 | possible, max_t(int, possible - num_processors, 0)); |
1187 | 1171 | ||
1188 | for (i = 0; i < possible; i++) | 1172 | for (i = 0; i < possible; i++) |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 05b31d92f69c..b481341c9369 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -9,6 +9,9 @@ | |||
9 | /* | 9 | /* |
10 | * Handle hardware traps and faults. | 10 | * Handle hardware traps and faults. |
11 | */ | 11 | */ |
12 | |||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
14 | |||
12 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
13 | #include <linux/kallsyms.h> | 16 | #include <linux/kallsyms.h> |
14 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
@@ -143,12 +146,11 @@ trap_signal: | |||
143 | #ifdef CONFIG_X86_64 | 146 | #ifdef CONFIG_X86_64 |
144 | if (show_unhandled_signals && unhandled_signal(tsk, signr) && | 147 | if (show_unhandled_signals && unhandled_signal(tsk, signr) && |
145 | printk_ratelimit()) { | 148 | printk_ratelimit()) { |
146 | printk(KERN_INFO | 149 | pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx", |
147 | "%s[%d] trap %s ip:%lx sp:%lx error:%lx", | 150 | tsk->comm, tsk->pid, str, |
148 | tsk->comm, tsk->pid, str, | 151 | regs->ip, regs->sp, error_code); |
149 | regs->ip, regs->sp, error_code); | ||
150 | print_vma_addr(" in ", regs->ip); | 152 | print_vma_addr(" in ", regs->ip); |
151 | printk("\n"); | 153 | pr_cont("\n"); |
152 | } | 154 | } |
153 | #endif | 155 | #endif |
154 | 156 | ||
@@ -269,12 +271,11 @@ do_general_protection(struct pt_regs *regs, long error_code) | |||
269 | 271 | ||
270 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && | 272 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && |
271 | printk_ratelimit()) { | 273 | printk_ratelimit()) { |
272 | printk(KERN_INFO | 274 | pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx", |
273 | "%s[%d] general protection ip:%lx sp:%lx error:%lx", | ||
274 | tsk->comm, task_pid_nr(tsk), | 275 | tsk->comm, task_pid_nr(tsk), |
275 | regs->ip, regs->sp, error_code); | 276 | regs->ip, regs->sp, error_code); |
276 | print_vma_addr(" in ", regs->ip); | 277 | print_vma_addr(" in ", regs->ip); |
277 | printk("\n"); | 278 | pr_cont("\n"); |
278 | } | 279 | } |
279 | 280 | ||
280 | force_sig(SIGSEGV, tsk); | 281 | force_sig(SIGSEGV, tsk); |
@@ -570,7 +571,7 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) | |||
570 | conditional_sti(regs); | 571 | conditional_sti(regs); |
571 | #if 0 | 572 | #if 0 |
572 | /* No need to warn about this any longer. */ | 573 | /* No need to warn about this any longer. */ |
573 | printk(KERN_INFO "Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); | 574 | pr_info("Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); |
574 | #endif | 575 | #endif |
575 | } | 576 | } |
576 | 577 | ||
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index fc0a147e3727..cfa5d4f7ca56 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -1,3 +1,5 @@ | |||
1 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
2 | |||
1 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
2 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
3 | #include <linux/init.h> | 5 | #include <linux/init.h> |
@@ -84,8 +86,7 @@ EXPORT_SYMBOL_GPL(check_tsc_unstable); | |||
84 | #ifdef CONFIG_X86_TSC | 86 | #ifdef CONFIG_X86_TSC |
85 | int __init notsc_setup(char *str) | 87 | int __init notsc_setup(char *str) |
86 | { | 88 | { |
87 | printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " | 89 | pr_warn("Kernel compiled with CONFIG_X86_TSC, cannot disable TSC completely\n"); |
88 | "cannot disable TSC completely.\n"); | ||
89 | tsc_disabled = 1; | 90 | tsc_disabled = 1; |
90 | return 1; | 91 | return 1; |
91 | } | 92 | } |
@@ -373,7 +374,7 @@ static unsigned long quick_pit_calibrate(void) | |||
373 | goto success; | 374 | goto success; |
374 | } | 375 | } |
375 | } | 376 | } |
376 | printk("Fast TSC calibration failed\n"); | 377 | pr_err("Fast TSC calibration failed\n"); |
377 | return 0; | 378 | return 0; |
378 | 379 | ||
379 | success: | 380 | success: |
@@ -392,7 +393,7 @@ success: | |||
392 | */ | 393 | */ |
393 | delta *= PIT_TICK_RATE; | 394 | delta *= PIT_TICK_RATE; |
394 | do_div(delta, i*256*1000); | 395 | do_div(delta, i*256*1000); |
395 | printk("Fast TSC calibration using PIT\n"); | 396 | pr_info("Fast TSC calibration using PIT\n"); |
396 | return delta; | 397 | return delta; |
397 | } | 398 | } |
398 | 399 | ||
@@ -487,9 +488,8 @@ unsigned long native_calibrate_tsc(void) | |||
487 | * use the reference value, as it is more precise. | 488 | * use the reference value, as it is more precise. |
488 | */ | 489 | */ |
489 | if (delta >= 90 && delta <= 110) { | 490 | if (delta >= 90 && delta <= 110) { |
490 | printk(KERN_INFO | 491 | pr_info("PIT calibration matches %s. %d loops\n", |
491 | "TSC: PIT calibration matches %s. %d loops\n", | 492 | hpet ? "HPET" : "PMTIMER", i + 1); |
492 | hpet ? "HPET" : "PMTIMER", i + 1); | ||
493 | return tsc_ref_min; | 493 | return tsc_ref_min; |
494 | } | 494 | } |
495 | 495 | ||
@@ -511,38 +511,36 @@ unsigned long native_calibrate_tsc(void) | |||
511 | */ | 511 | */ |
512 | if (tsc_pit_min == ULONG_MAX) { | 512 | if (tsc_pit_min == ULONG_MAX) { |
513 | /* PIT gave no useful value */ | 513 | /* PIT gave no useful value */ |
514 | printk(KERN_WARNING "TSC: Unable to calibrate against PIT\n"); | 514 | pr_warn("Unable to calibrate against PIT\n"); |
515 | 515 | ||
516 | /* We don't have an alternative source, disable TSC */ | 516 | /* We don't have an alternative source, disable TSC */ |
517 | if (!hpet && !ref1 && !ref2) { | 517 | if (!hpet && !ref1 && !ref2) { |
518 | printk("TSC: No reference (HPET/PMTIMER) available\n"); | 518 | pr_notice("No reference (HPET/PMTIMER) available\n"); |
519 | return 0; | 519 | return 0; |
520 | } | 520 | } |
521 | 521 | ||
522 | /* The alternative source failed as well, disable TSC */ | 522 | /* The alternative source failed as well, disable TSC */ |
523 | if (tsc_ref_min == ULONG_MAX) { | 523 | if (tsc_ref_min == ULONG_MAX) { |
524 | printk(KERN_WARNING "TSC: HPET/PMTIMER calibration " | 524 | pr_warn("HPET/PMTIMER calibration failed\n"); |
525 | "failed.\n"); | ||
526 | return 0; | 525 | return 0; |
527 | } | 526 | } |
528 | 527 | ||
529 | /* Use the alternative source */ | 528 | /* Use the alternative source */ |
530 | printk(KERN_INFO "TSC: using %s reference calibration\n", | 529 | pr_info("using %s reference calibration\n", |
531 | hpet ? "HPET" : "PMTIMER"); | 530 | hpet ? "HPET" : "PMTIMER"); |
532 | 531 | ||
533 | return tsc_ref_min; | 532 | return tsc_ref_min; |
534 | } | 533 | } |
535 | 534 | ||
536 | /* We don't have an alternative source, use the PIT calibration value */ | 535 | /* We don't have an alternative source, use the PIT calibration value */ |
537 | if (!hpet && !ref1 && !ref2) { | 536 | if (!hpet && !ref1 && !ref2) { |
538 | printk(KERN_INFO "TSC: Using PIT calibration value\n"); | 537 | pr_info("Using PIT calibration value\n"); |
539 | return tsc_pit_min; | 538 | return tsc_pit_min; |
540 | } | 539 | } |
541 | 540 | ||
542 | /* The alternative source failed, use the PIT calibration value */ | 541 | /* The alternative source failed, use the PIT calibration value */ |
543 | if (tsc_ref_min == ULONG_MAX) { | 542 | if (tsc_ref_min == ULONG_MAX) { |
544 | printk(KERN_WARNING "TSC: HPET/PMTIMER calibration failed. " | 543 | pr_warn("HPET/PMTIMER calibration failed. Using PIT calibration.\n"); |
545 | "Using PIT calibration\n"); | ||
546 | return tsc_pit_min; | 544 | return tsc_pit_min; |
547 | } | 545 | } |
548 | 546 | ||
@@ -551,9 +549,9 @@ unsigned long native_calibrate_tsc(void) | |||
551 | * the PIT value as we know that there are PMTIMERs around | 549 | * the PIT value as we know that there are PMTIMERs around |
552 | * running at double speed. At least we let the user know: | 550 | * running at double speed. At least we let the user know: |
553 | */ | 551 | */ |
554 | printk(KERN_WARNING "TSC: PIT calibration deviates from %s: %lu %lu.\n", | 552 | pr_warn("PIT calibration deviates from %s: %lu %lu\n", |
555 | hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min); | 553 | hpet ? "HPET" : "PMTIMER", tsc_pit_min, tsc_ref_min); |
556 | printk(KERN_INFO "TSC: Using PIT calibration value\n"); | 554 | pr_info("Using PIT calibration value\n"); |
557 | return tsc_pit_min; | 555 | return tsc_pit_min; |
558 | } | 556 | } |
559 | 557 | ||
@@ -785,7 +783,7 @@ void mark_tsc_unstable(char *reason) | |||
785 | tsc_unstable = 1; | 783 | tsc_unstable = 1; |
786 | sched_clock_stable = 0; | 784 | sched_clock_stable = 0; |
787 | disable_sched_clock_irqtime(); | 785 | disable_sched_clock_irqtime(); |
788 | printk(KERN_INFO "Marking TSC unstable due to %s\n", reason); | 786 | pr_info("Marking TSC unstable due to %s\n", reason); |
789 | /* Change only the rating, when not registered */ | 787 | /* Change only the rating, when not registered */ |
790 | if (clocksource_tsc.mult) | 788 | if (clocksource_tsc.mult) |
791 | clocksource_mark_unstable(&clocksource_tsc); | 789 | clocksource_mark_unstable(&clocksource_tsc); |
@@ -912,9 +910,9 @@ static void tsc_refine_calibration_work(struct work_struct *work) | |||
912 | goto out; | 910 | goto out; |
913 | 911 | ||
914 | tsc_khz = freq; | 912 | tsc_khz = freq; |
915 | printk(KERN_INFO "Refined TSC clocksource calibration: " | 913 | pr_info("Refined TSC clocksource calibration: %lu.%03lu MHz\n", |
916 | "%lu.%03lu MHz.\n", (unsigned long)tsc_khz / 1000, | 914 | (unsigned long)tsc_khz / 1000, |
917 | (unsigned long)tsc_khz % 1000); | 915 | (unsigned long)tsc_khz % 1000); |
918 | 916 | ||
919 | out: | 917 | out: |
920 | clocksource_register_khz(&clocksource_tsc, tsc_khz); | 918 | clocksource_register_khz(&clocksource_tsc, tsc_khz); |
@@ -970,9 +968,9 @@ void __init tsc_init(void) | |||
970 | return; | 968 | return; |
971 | } | 969 | } |
972 | 970 | ||
973 | printk("Detected %lu.%03lu MHz processor.\n", | 971 | pr_info("Detected %lu.%03lu MHz processor\n", |
974 | (unsigned long)cpu_khz / 1000, | 972 | (unsigned long)cpu_khz / 1000, |
975 | (unsigned long)cpu_khz % 1000); | 973 | (unsigned long)cpu_khz % 1000); |
976 | 974 | ||
977 | /* | 975 | /* |
978 | * Secondary CPUs do not run through tsc_init(), so set up | 976 | * Secondary CPUs do not run through tsc_init(), so set up |
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index dc4e910a7d96..36fd42091fa7 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c | |||
@@ -409,9 +409,10 @@ static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm, | |||
409 | * arch_uprobe_analyze_insn - instruction analysis including validity and fixups. | 409 | * arch_uprobe_analyze_insn - instruction analysis including validity and fixups. |
410 | * @mm: the probed address space. | 410 | * @mm: the probed address space. |
411 | * @arch_uprobe: the probepoint information. | 411 | * @arch_uprobe: the probepoint information. |
412 | * @addr: virtual address at which to install the probepoint | ||
412 | * Return 0 on success or a -ve number on error. | 413 | * Return 0 on success or a -ve number on error. |
413 | */ | 414 | */ |
414 | int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm) | 415 | int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long addr) |
415 | { | 416 | { |
416 | int ret; | 417 | int ret; |
417 | struct insn insn; | 418 | struct insn insn; |
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index 255f58ae71e8..54abcc0baf23 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c | |||
@@ -28,6 +28,8 @@ | |||
28 | * | 28 | * |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
32 | |||
31 | #include <linux/capability.h> | 33 | #include <linux/capability.h> |
32 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
33 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
@@ -137,14 +139,14 @@ struct pt_regs *save_v86_state(struct kernel_vm86_regs *regs) | |||
137 | local_irq_enable(); | 139 | local_irq_enable(); |
138 | 140 | ||
139 | if (!current->thread.vm86_info) { | 141 | if (!current->thread.vm86_info) { |
140 | printk("no vm86_info: BAD\n"); | 142 | pr_alert("no vm86_info: BAD\n"); |
141 | do_exit(SIGSEGV); | 143 | do_exit(SIGSEGV); |
142 | } | 144 | } |
143 | set_flags(regs->pt.flags, VEFLAGS, X86_EFLAGS_VIF | current->thread.v86mask); | 145 | set_flags(regs->pt.flags, VEFLAGS, X86_EFLAGS_VIF | current->thread.v86mask); |
144 | tmp = copy_vm86_regs_to_user(¤t->thread.vm86_info->regs, regs); | 146 | tmp = copy_vm86_regs_to_user(¤t->thread.vm86_info->regs, regs); |
145 | tmp += put_user(current->thread.screen_bitmap, ¤t->thread.vm86_info->screen_bitmap); | 147 | tmp += put_user(current->thread.screen_bitmap, ¤t->thread.vm86_info->screen_bitmap); |
146 | if (tmp) { | 148 | if (tmp) { |
147 | printk("vm86: could not access userspace vm86_info\n"); | 149 | pr_alert("could not access userspace vm86_info\n"); |
148 | do_exit(SIGSEGV); | 150 | do_exit(SIGSEGV); |
149 | } | 151 | } |
150 | 152 | ||
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index 8eeb55a551b4..992f890283e9 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/pci_ids.h> | 16 | #include <linux/pci_ids.h> |
17 | #include <linux/pci_regs.h> | 17 | #include <linux/pci_regs.h> |
18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
19 | #include <linux/irq.h> | ||
19 | 20 | ||
20 | #include <asm/apic.h> | 21 | #include <asm/apic.h> |
21 | #include <asm/pci-direct.h> | 22 | #include <asm/pci-direct.h> |
@@ -95,6 +96,18 @@ static void __init set_vsmp_pv_ops(void) | |||
95 | ctl = readl(address + 4); | 96 | ctl = readl(address + 4); |
96 | printk(KERN_INFO "vSMP CTL: capabilities:0x%08x control:0x%08x\n", | 97 | printk(KERN_INFO "vSMP CTL: capabilities:0x%08x control:0x%08x\n", |
97 | cap, ctl); | 98 | cap, ctl); |
99 | |||
100 | /* If possible, let the vSMP foundation route the interrupt optimally */ | ||
101 | #ifdef CONFIG_SMP | ||
102 | if (cap & ctl & BIT(8)) { | ||
103 | ctl &= ~BIT(8); | ||
104 | #ifdef CONFIG_PROC_FS | ||
105 | /* Don't let users change irq affinity via procfs */ | ||
106 | no_irq_affinity = 1; | ||
107 | #endif | ||
108 | } | ||
109 | #endif | ||
110 | |||
98 | if (cap & ctl & (1 << 4)) { | 111 | if (cap & ctl & (1 << 4)) { |
99 | /* Setup irq ops and turn on vSMP IRQ fastpath handling */ | 112 | /* Setup irq ops and turn on vSMP IRQ fastpath handling */ |
100 | pv_irq_ops.irq_disable = PV_CALLEE_SAVE(vsmp_irq_disable); | 113 | pv_irq_ops.irq_disable = PV_CALLEE_SAVE(vsmp_irq_disable); |
@@ -102,12 +115,11 @@ static void __init set_vsmp_pv_ops(void) | |||
102 | pv_irq_ops.save_fl = PV_CALLEE_SAVE(vsmp_save_fl); | 115 | pv_irq_ops.save_fl = PV_CALLEE_SAVE(vsmp_save_fl); |
103 | pv_irq_ops.restore_fl = PV_CALLEE_SAVE(vsmp_restore_fl); | 116 | pv_irq_ops.restore_fl = PV_CALLEE_SAVE(vsmp_restore_fl); |
104 | pv_init_ops.patch = vsmp_patch; | 117 | pv_init_ops.patch = vsmp_patch; |
105 | |||
106 | ctl &= ~(1 << 4); | 118 | ctl &= ~(1 << 4); |
107 | writel(ctl, address + 4); | ||
108 | ctl = readl(address + 4); | ||
109 | printk(KERN_INFO "vSMP CTL: control set to:0x%08x\n", ctl); | ||
110 | } | 119 | } |
120 | writel(ctl, address + 4); | ||
121 | ctl = readl(address + 4); | ||
122 | pr_info("vSMP CTL: control set to:0x%08x\n", ctl); | ||
111 | 123 | ||
112 | early_iounmap(address, 8); | 124 | early_iounmap(address, 8); |
113 | } | 125 | } |
@@ -187,12 +199,36 @@ static void __init vsmp_cap_cpus(void) | |||
187 | #endif | 199 | #endif |
188 | } | 200 | } |
189 | 201 | ||
202 | static int apicid_phys_pkg_id(int initial_apic_id, int index_msb) | ||
203 | { | ||
204 | return hard_smp_processor_id() >> index_msb; | ||
205 | } | ||
206 | |||
207 | /* | ||
208 | * In vSMP, all cpus should be capable of handling interrupts, regardless of | ||
209 | * the APIC used. | ||
210 | */ | ||
211 | static void fill_vector_allocation_domain(int cpu, struct cpumask *retmask, | ||
212 | const struct cpumask *mask) | ||
213 | { | ||
214 | cpumask_setall(retmask); | ||
215 | } | ||
216 | |||
217 | static void vsmp_apic_post_init(void) | ||
218 | { | ||
219 | /* need to update phys_pkg_id */ | ||
220 | apic->phys_pkg_id = apicid_phys_pkg_id; | ||
221 | apic->vector_allocation_domain = fill_vector_allocation_domain; | ||
222 | } | ||
223 | |||
190 | void __init vsmp_init(void) | 224 | void __init vsmp_init(void) |
191 | { | 225 | { |
192 | detect_vsmp_box(); | 226 | detect_vsmp_box(); |
193 | if (!is_vsmp_box()) | 227 | if (!is_vsmp_box()) |
194 | return; | 228 | return; |
195 | 229 | ||
230 | x86_platform.apic_post_init = vsmp_apic_post_init; | ||
231 | |||
196 | vsmp_cap_cpus(); | 232 | vsmp_cap_cpus(); |
197 | 233 | ||
198 | set_vsmp_pv_ops(); | 234 | set_vsmp_pv_ops(); |
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 5db36caf4289..8d141b309046 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c | |||
@@ -18,6 +18,8 @@ | |||
18 | * use the vDSO. | 18 | * use the vDSO. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
22 | |||
21 | #include <linux/time.h> | 23 | #include <linux/time.h> |
22 | #include <linux/init.h> | 24 | #include <linux/init.h> |
23 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
@@ -111,18 +113,13 @@ void update_vsyscall(struct timespec *wall_time, struct timespec *wtm, | |||
111 | static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, | 113 | static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, |
112 | const char *message) | 114 | const char *message) |
113 | { | 115 | { |
114 | static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); | 116 | if (!show_unhandled_signals) |
115 | struct task_struct *tsk; | ||
116 | |||
117 | if (!show_unhandled_signals || !__ratelimit(&rs)) | ||
118 | return; | 117 | return; |
119 | 118 | ||
120 | tsk = current; | 119 | pr_notice_ratelimited("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n", |
121 | 120 | level, current->comm, task_pid_nr(current), | |
122 | printk("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n", | 121 | message, regs->ip, regs->cs, |
123 | level, tsk->comm, task_pid_nr(tsk), | 122 | regs->sp, regs->ax, regs->si, regs->di); |
124 | message, regs->ip, regs->cs, | ||
125 | regs->sp, regs->ax, regs->si, regs->di); | ||
126 | } | 123 | } |
127 | 124 | ||
128 | static int addr_to_vsyscall_nr(unsigned long addr) | 125 | static int addr_to_vsyscall_nr(unsigned long addr) |
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index 9796c2f3d074..6020f6f5927c 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c | |||
@@ -28,6 +28,7 @@ EXPORT_SYMBOL(__put_user_8); | |||
28 | 28 | ||
29 | EXPORT_SYMBOL(copy_user_generic_string); | 29 | EXPORT_SYMBOL(copy_user_generic_string); |
30 | EXPORT_SYMBOL(copy_user_generic_unrolled); | 30 | EXPORT_SYMBOL(copy_user_generic_unrolled); |
31 | EXPORT_SYMBOL(copy_user_enhanced_fast_string); | ||
31 | EXPORT_SYMBOL(__copy_user_nocache); | 32 | EXPORT_SYMBOL(__copy_user_nocache); |
32 | EXPORT_SYMBOL(_copy_from_user); | 33 | EXPORT_SYMBOL(_copy_from_user); |
33 | EXPORT_SYMBOL(_copy_to_user); | 34 | EXPORT_SYMBOL(_copy_to_user); |
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index 35c5e543f550..9f3167e891ef 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c | |||
@@ -29,7 +29,6 @@ void __init x86_init_uint_noop(unsigned int unused) { } | |||
29 | void __init x86_init_pgd_noop(pgd_t *unused) { } | 29 | void __init x86_init_pgd_noop(pgd_t *unused) { } |
30 | int __init iommu_init_noop(void) { return 0; } | 30 | int __init iommu_init_noop(void) { return 0; } |
31 | void iommu_shutdown_noop(void) { } | 31 | void iommu_shutdown_noop(void) { } |
32 | void wallclock_init_noop(void) { } | ||
33 | 32 | ||
34 | /* | 33 | /* |
35 | * The platform setup functions are preset with the default functions | 34 | * The platform setup functions are preset with the default functions |
@@ -101,7 +100,6 @@ static int default_i8042_detect(void) { return 1; }; | |||
101 | 100 | ||
102 | struct x86_platform_ops x86_platform = { | 101 | struct x86_platform_ops x86_platform = { |
103 | .calibrate_tsc = native_calibrate_tsc, | 102 | .calibrate_tsc = native_calibrate_tsc, |
104 | .wallclock_init = wallclock_init_noop, | ||
105 | .get_wallclock = mach_get_cmos_time, | 103 | .get_wallclock = mach_get_cmos_time, |
106 | .set_wallclock = mach_set_rtc_mmss, | 104 | .set_wallclock = mach_set_rtc_mmss, |
107 | .iommu_shutdown = iommu_shutdown_noop, | 105 | .iommu_shutdown = iommu_shutdown_noop, |
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index bd18149b2b0f..3d3e20709119 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c | |||
@@ -3,6 +3,9 @@ | |||
3 | * | 3 | * |
4 | * Author: Suresh Siddha <suresh.b.siddha@intel.com> | 4 | * Author: Suresh Siddha <suresh.b.siddha@intel.com> |
5 | */ | 5 | */ |
6 | |||
7 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
8 | |||
6 | #include <linux/bootmem.h> | 9 | #include <linux/bootmem.h> |
7 | #include <linux/compat.h> | 10 | #include <linux/compat.h> |
8 | #include <asm/i387.h> | 11 | #include <asm/i387.h> |
@@ -162,7 +165,7 @@ int save_i387_xstate(void __user *buf) | |||
162 | BUG_ON(sig_xstate_size < xstate_size); | 165 | BUG_ON(sig_xstate_size < xstate_size); |
163 | 166 | ||
164 | if ((unsigned long)buf % 64) | 167 | if ((unsigned long)buf % 64) |
165 | printk("save_i387_xstate: bad fpstate %p\n", buf); | 168 | pr_err("%s: bad fpstate %p\n", __func__, buf); |
166 | 169 | ||
167 | if (!used_math()) | 170 | if (!used_math()) |
168 | return 0; | 171 | return 0; |
@@ -422,7 +425,7 @@ static void __init xstate_enable_boot_cpu(void) | |||
422 | pcntxt_mask = eax + ((u64)edx << 32); | 425 | pcntxt_mask = eax + ((u64)edx << 32); |
423 | 426 | ||
424 | if ((pcntxt_mask & XSTATE_FPSSE) != XSTATE_FPSSE) { | 427 | if ((pcntxt_mask & XSTATE_FPSSE) != XSTATE_FPSSE) { |
425 | printk(KERN_ERR "FP/SSE not shown under xsave features 0x%llx\n", | 428 | pr_err("FP/SSE not shown under xsave features 0x%llx\n", |
426 | pcntxt_mask); | 429 | pcntxt_mask); |
427 | BUG(); | 430 | BUG(); |
428 | } | 431 | } |
@@ -445,9 +448,8 @@ static void __init xstate_enable_boot_cpu(void) | |||
445 | 448 | ||
446 | setup_xstate_init(); | 449 | setup_xstate_init(); |
447 | 450 | ||
448 | printk(KERN_INFO "xsave/xrstor: enabled xstate_bv 0x%llx, " | 451 | pr_info("enabled xstate_bv 0x%llx, cntxt size 0x%x\n", |
449 | "cntxt size 0x%x\n", | 452 | pcntxt_mask, xstate_size); |
450 | pcntxt_mask, xstate_size); | ||
451 | } | 453 | } |
452 | 454 | ||
453 | /* | 455 | /* |
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index 2e88438ffd83..9b7ec1150ab0 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c | |||
@@ -80,10 +80,10 @@ static inline struct kvm_pmc *get_fixed_pmc_idx(struct kvm_pmu *pmu, int idx) | |||
80 | 80 | ||
81 | static struct kvm_pmc *global_idx_to_pmc(struct kvm_pmu *pmu, int idx) | 81 | static struct kvm_pmc *global_idx_to_pmc(struct kvm_pmu *pmu, int idx) |
82 | { | 82 | { |
83 | if (idx < X86_PMC_IDX_FIXED) | 83 | if (idx < INTEL_PMC_IDX_FIXED) |
84 | return get_gp_pmc(pmu, MSR_P6_EVNTSEL0 + idx, MSR_P6_EVNTSEL0); | 84 | return get_gp_pmc(pmu, MSR_P6_EVNTSEL0 + idx, MSR_P6_EVNTSEL0); |
85 | else | 85 | else |
86 | return get_fixed_pmc_idx(pmu, idx - X86_PMC_IDX_FIXED); | 86 | return get_fixed_pmc_idx(pmu, idx - INTEL_PMC_IDX_FIXED); |
87 | } | 87 | } |
88 | 88 | ||
89 | void kvm_deliver_pmi(struct kvm_vcpu *vcpu) | 89 | void kvm_deliver_pmi(struct kvm_vcpu *vcpu) |
@@ -291,7 +291,7 @@ static void reprogram_idx(struct kvm_pmu *pmu, int idx) | |||
291 | if (pmc_is_gp(pmc)) | 291 | if (pmc_is_gp(pmc)) |
292 | reprogram_gp_counter(pmc, pmc->eventsel); | 292 | reprogram_gp_counter(pmc, pmc->eventsel); |
293 | else { | 293 | else { |
294 | int fidx = idx - X86_PMC_IDX_FIXED; | 294 | int fidx = idx - INTEL_PMC_IDX_FIXED; |
295 | reprogram_fixed_counter(pmc, | 295 | reprogram_fixed_counter(pmc, |
296 | fixed_en_pmi(pmu->fixed_ctr_ctrl, fidx), fidx); | 296 | fixed_en_pmi(pmu->fixed_ctr_ctrl, fidx), fidx); |
297 | } | 297 | } |
@@ -452,7 +452,7 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu) | |||
452 | return; | 452 | return; |
453 | 453 | ||
454 | pmu->nr_arch_gp_counters = min((int)(entry->eax >> 8) & 0xff, | 454 | pmu->nr_arch_gp_counters = min((int)(entry->eax >> 8) & 0xff, |
455 | X86_PMC_MAX_GENERIC); | 455 | INTEL_PMC_MAX_GENERIC); |
456 | pmu->counter_bitmask[KVM_PMC_GP] = | 456 | pmu->counter_bitmask[KVM_PMC_GP] = |
457 | ((u64)1 << ((entry->eax >> 16) & 0xff)) - 1; | 457 | ((u64)1 << ((entry->eax >> 16) & 0xff)) - 1; |
458 | bitmap_len = (entry->eax >> 24) & 0xff; | 458 | bitmap_len = (entry->eax >> 24) & 0xff; |
@@ -462,13 +462,13 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu) | |||
462 | pmu->nr_arch_fixed_counters = 0; | 462 | pmu->nr_arch_fixed_counters = 0; |
463 | } else { | 463 | } else { |
464 | pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), | 464 | pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), |
465 | X86_PMC_MAX_FIXED); | 465 | INTEL_PMC_MAX_FIXED); |
466 | pmu->counter_bitmask[KVM_PMC_FIXED] = | 466 | pmu->counter_bitmask[KVM_PMC_FIXED] = |
467 | ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; | 467 | ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; |
468 | } | 468 | } |
469 | 469 | ||
470 | pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) | | 470 | pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) | |
471 | (((1ull << pmu->nr_arch_fixed_counters) - 1) << X86_PMC_IDX_FIXED); | 471 | (((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED); |
472 | pmu->global_ctrl_mask = ~pmu->global_ctrl; | 472 | pmu->global_ctrl_mask = ~pmu->global_ctrl; |
473 | } | 473 | } |
474 | 474 | ||
@@ -478,15 +478,15 @@ void kvm_pmu_init(struct kvm_vcpu *vcpu) | |||
478 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | 478 | struct kvm_pmu *pmu = &vcpu->arch.pmu; |
479 | 479 | ||
480 | memset(pmu, 0, sizeof(*pmu)); | 480 | memset(pmu, 0, sizeof(*pmu)); |
481 | for (i = 0; i < X86_PMC_MAX_GENERIC; i++) { | 481 | for (i = 0; i < INTEL_PMC_MAX_GENERIC; i++) { |
482 | pmu->gp_counters[i].type = KVM_PMC_GP; | 482 | pmu->gp_counters[i].type = KVM_PMC_GP; |
483 | pmu->gp_counters[i].vcpu = vcpu; | 483 | pmu->gp_counters[i].vcpu = vcpu; |
484 | pmu->gp_counters[i].idx = i; | 484 | pmu->gp_counters[i].idx = i; |
485 | } | 485 | } |
486 | for (i = 0; i < X86_PMC_MAX_FIXED; i++) { | 486 | for (i = 0; i < INTEL_PMC_MAX_FIXED; i++) { |
487 | pmu->fixed_counters[i].type = KVM_PMC_FIXED; | 487 | pmu->fixed_counters[i].type = KVM_PMC_FIXED; |
488 | pmu->fixed_counters[i].vcpu = vcpu; | 488 | pmu->fixed_counters[i].vcpu = vcpu; |
489 | pmu->fixed_counters[i].idx = i + X86_PMC_IDX_FIXED; | 489 | pmu->fixed_counters[i].idx = i + INTEL_PMC_IDX_FIXED; |
490 | } | 490 | } |
491 | init_irq_work(&pmu->irq_work, trigger_pmi); | 491 | init_irq_work(&pmu->irq_work, trigger_pmi); |
492 | kvm_pmu_cpuid_update(vcpu); | 492 | kvm_pmu_cpuid_update(vcpu); |
@@ -498,13 +498,13 @@ void kvm_pmu_reset(struct kvm_vcpu *vcpu) | |||
498 | int i; | 498 | int i; |
499 | 499 | ||
500 | irq_work_sync(&pmu->irq_work); | 500 | irq_work_sync(&pmu->irq_work); |
501 | for (i = 0; i < X86_PMC_MAX_GENERIC; i++) { | 501 | for (i = 0; i < INTEL_PMC_MAX_GENERIC; i++) { |
502 | struct kvm_pmc *pmc = &pmu->gp_counters[i]; | 502 | struct kvm_pmc *pmc = &pmu->gp_counters[i]; |
503 | stop_counter(pmc); | 503 | stop_counter(pmc); |
504 | pmc->counter = pmc->eventsel = 0; | 504 | pmc->counter = pmc->eventsel = 0; |
505 | } | 505 | } |
506 | 506 | ||
507 | for (i = 0; i < X86_PMC_MAX_FIXED; i++) | 507 | for (i = 0; i < INTEL_PMC_MAX_FIXED; i++) |
508 | stop_counter(&pmu->fixed_counters[i]); | 508 | stop_counter(&pmu->fixed_counters[i]); |
509 | 509 | ||
510 | pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status = | 510 | pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status = |
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 911d2641f14c..62d02e3c3ed6 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h | |||
@@ -710,16 +710,6 @@ TRACE_EVENT(kvm_skinit, | |||
710 | __entry->rip, __entry->slb) | 710 | __entry->rip, __entry->slb) |
711 | ); | 711 | ); |
712 | 712 | ||
713 | #define __print_insn(insn, ilen) ({ \ | ||
714 | int i; \ | ||
715 | const char *ret = p->buffer + p->len; \ | ||
716 | \ | ||
717 | for (i = 0; i < ilen; ++i) \ | ||
718 | trace_seq_printf(p, " %02x", insn[i]); \ | ||
719 | trace_seq_printf(p, "%c", 0); \ | ||
720 | ret; \ | ||
721 | }) | ||
722 | |||
723 | #define KVM_EMUL_INSN_F_CR0_PE (1 << 0) | 713 | #define KVM_EMUL_INSN_F_CR0_PE (1 << 0) |
724 | #define KVM_EMUL_INSN_F_EFL_VM (1 << 1) | 714 | #define KVM_EMUL_INSN_F_EFL_VM (1 << 1) |
725 | #define KVM_EMUL_INSN_F_CS_D (1 << 2) | 715 | #define KVM_EMUL_INSN_F_CS_D (1 << 2) |
@@ -786,7 +776,7 @@ TRACE_EVENT(kvm_emulate_insn, | |||
786 | 776 | ||
787 | TP_printk("%x:%llx:%s (%s)%s", | 777 | TP_printk("%x:%llx:%s (%s)%s", |
788 | __entry->csbase, __entry->rip, | 778 | __entry->csbase, __entry->rip, |
789 | __print_insn(__entry->insn, __entry->len), | 779 | __print_hex(__entry->insn, __entry->len), |
790 | __print_symbolic(__entry->flags, | 780 | __print_symbolic(__entry->flags, |
791 | kvm_trace_symbol_emul_flags), | 781 | kvm_trace_symbol_emul_flags), |
792 | __entry->failed ? " failed" : "" | 782 | __entry->failed ? " failed" : "" |
diff --git a/arch/x86/lib/msr-reg-export.c b/arch/x86/lib/msr-reg-export.c index a311cc59b65d..8d6ef78b5d01 100644 --- a/arch/x86/lib/msr-reg-export.c +++ b/arch/x86/lib/msr-reg-export.c | |||
@@ -1,5 +1,5 @@ | |||
1 | #include <linux/module.h> | 1 | #include <linux/module.h> |
2 | #include <asm/msr.h> | 2 | #include <asm/msr.h> |
3 | 3 | ||
4 | EXPORT_SYMBOL(native_rdmsr_safe_regs); | 4 | EXPORT_SYMBOL(rdmsr_safe_regs); |
5 | EXPORT_SYMBOL(native_wrmsr_safe_regs); | 5 | EXPORT_SYMBOL(wrmsr_safe_regs); |
diff --git a/arch/x86/lib/msr-reg.S b/arch/x86/lib/msr-reg.S index 69fa10623f21..f6d13eefad10 100644 --- a/arch/x86/lib/msr-reg.S +++ b/arch/x86/lib/msr-reg.S | |||
@@ -6,13 +6,13 @@ | |||
6 | 6 | ||
7 | #ifdef CONFIG_X86_64 | 7 | #ifdef CONFIG_X86_64 |
8 | /* | 8 | /* |
9 | * int native_{rdmsr,wrmsr}_safe_regs(u32 gprs[8]); | 9 | * int {rdmsr,wrmsr}_safe_regs(u32 gprs[8]); |
10 | * | 10 | * |
11 | * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] | 11 | * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi] |
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | .macro op_safe_regs op | 14 | .macro op_safe_regs op |
15 | ENTRY(native_\op\()_safe_regs) | 15 | ENTRY(\op\()_safe_regs) |
16 | CFI_STARTPROC | 16 | CFI_STARTPROC |
17 | pushq_cfi %rbx | 17 | pushq_cfi %rbx |
18 | pushq_cfi %rbp | 18 | pushq_cfi %rbp |
@@ -45,13 +45,13 @@ ENTRY(native_\op\()_safe_regs) | |||
45 | 45 | ||
46 | _ASM_EXTABLE(1b, 3b) | 46 | _ASM_EXTABLE(1b, 3b) |
47 | CFI_ENDPROC | 47 | CFI_ENDPROC |
48 | ENDPROC(native_\op\()_safe_regs) | 48 | ENDPROC(\op\()_safe_regs) |
49 | .endm | 49 | .endm |
50 | 50 | ||
51 | #else /* X86_32 */ | 51 | #else /* X86_32 */ |
52 | 52 | ||
53 | .macro op_safe_regs op | 53 | .macro op_safe_regs op |
54 | ENTRY(native_\op\()_safe_regs) | 54 | ENTRY(\op\()_safe_regs) |
55 | CFI_STARTPROC | 55 | CFI_STARTPROC |
56 | pushl_cfi %ebx | 56 | pushl_cfi %ebx |
57 | pushl_cfi %ebp | 57 | pushl_cfi %ebp |
@@ -92,7 +92,7 @@ ENTRY(native_\op\()_safe_regs) | |||
92 | 92 | ||
93 | _ASM_EXTABLE(1b, 3b) | 93 | _ASM_EXTABLE(1b, 3b) |
94 | CFI_ENDPROC | 94 | CFI_ENDPROC |
95 | ENDPROC(native_\op\()_safe_regs) | 95 | ENDPROC(\op\()_safe_regs) |
96 | .endm | 96 | .endm |
97 | 97 | ||
98 | #endif | 98 | #endif |
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index bc4e9d84157f..e0e6990723e9 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
@@ -385,7 +385,7 @@ void free_initmem(void) | |||
385 | } | 385 | } |
386 | 386 | ||
387 | #ifdef CONFIG_BLK_DEV_INITRD | 387 | #ifdef CONFIG_BLK_DEV_INITRD |
388 | void free_initrd_mem(unsigned long start, unsigned long end) | 388 | void __init free_initrd_mem(unsigned long start, unsigned long end) |
389 | { | 389 | { |
390 | /* | 390 | /* |
391 | * end could be not aligned, and We can not align that, | 391 | * end could be not aligned, and We can not align that, |
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 303f08637826..b2b94438ff05 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
@@ -312,7 +312,7 @@ static int op_amd_fill_in_addresses(struct op_msrs * const msrs) | |||
312 | goto fail; | 312 | goto fail; |
313 | } | 313 | } |
314 | /* both registers must be reserved */ | 314 | /* both registers must be reserved */ |
315 | if (num_counters == AMD64_NUM_COUNTERS_F15H) { | 315 | if (num_counters == AMD64_NUM_COUNTERS_CORE) { |
316 | msrs->counters[i].addr = MSR_F15H_PERF_CTR + (i << 1); | 316 | msrs->counters[i].addr = MSR_F15H_PERF_CTR + (i << 1); |
317 | msrs->controls[i].addr = MSR_F15H_PERF_CTL + (i << 1); | 317 | msrs->controls[i].addr = MSR_F15H_PERF_CTL + (i << 1); |
318 | } else { | 318 | } else { |
@@ -514,7 +514,7 @@ static int op_amd_init(struct oprofile_operations *ops) | |||
514 | ops->create_files = setup_ibs_files; | 514 | ops->create_files = setup_ibs_files; |
515 | 515 | ||
516 | if (boot_cpu_data.x86 == 0x15) { | 516 | if (boot_cpu_data.x86 == 0x15) { |
517 | num_counters = AMD64_NUM_COUNTERS_F15H; | 517 | num_counters = AMD64_NUM_COUNTERS_CORE; |
518 | } else { | 518 | } else { |
519 | num_counters = AMD64_NUM_COUNTERS; | 519 | num_counters = AMD64_NUM_COUNTERS; |
520 | } | 520 | } |
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index 59880afa851f..71b5d5a07d7b 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SGI UltraViolet TLB flush routines. | 2 | * SGI UltraViolet TLB flush routines. |
3 | * | 3 | * |
4 | * (c) 2008-2011 Cliff Wickman <cpw@sgi.com>, SGI. | 4 | * (c) 2008-2012 Cliff Wickman <cpw@sgi.com>, SGI. |
5 | * | 5 | * |
6 | * This code is released under the GNU General Public License version 2 or | 6 | * This code is released under the GNU General Public License version 2 or |
7 | * later. | 7 | * later. |
@@ -38,8 +38,7 @@ static int timeout_base_ns[] = { | |||
38 | 38 | ||
39 | static int timeout_us; | 39 | static int timeout_us; |
40 | static int nobau; | 40 | static int nobau; |
41 | static int baudisabled; | 41 | static int nobau_perm; |
42 | static spinlock_t disable_lock; | ||
43 | static cycles_t congested_cycles; | 42 | static cycles_t congested_cycles; |
44 | 43 | ||
45 | /* tunables: */ | 44 | /* tunables: */ |
@@ -47,12 +46,13 @@ static int max_concurr = MAX_BAU_CONCURRENT; | |||
47 | static int max_concurr_const = MAX_BAU_CONCURRENT; | 46 | static int max_concurr_const = MAX_BAU_CONCURRENT; |
48 | static int plugged_delay = PLUGGED_DELAY; | 47 | static int plugged_delay = PLUGGED_DELAY; |
49 | static int plugsb4reset = PLUGSB4RESET; | 48 | static int plugsb4reset = PLUGSB4RESET; |
49 | static int giveup_limit = GIVEUP_LIMIT; | ||
50 | static int timeoutsb4reset = TIMEOUTSB4RESET; | 50 | static int timeoutsb4reset = TIMEOUTSB4RESET; |
51 | static int ipi_reset_limit = IPI_RESET_LIMIT; | 51 | static int ipi_reset_limit = IPI_RESET_LIMIT; |
52 | static int complete_threshold = COMPLETE_THRESHOLD; | 52 | static int complete_threshold = COMPLETE_THRESHOLD; |
53 | static int congested_respns_us = CONGESTED_RESPONSE_US; | 53 | static int congested_respns_us = CONGESTED_RESPONSE_US; |
54 | static int congested_reps = CONGESTED_REPS; | 54 | static int congested_reps = CONGESTED_REPS; |
55 | static int congested_period = CONGESTED_PERIOD; | 55 | static int disabled_period = DISABLED_PERIOD; |
56 | 56 | ||
57 | static struct tunables tunables[] = { | 57 | static struct tunables tunables[] = { |
58 | {&max_concurr, MAX_BAU_CONCURRENT}, /* must be [0] */ | 58 | {&max_concurr, MAX_BAU_CONCURRENT}, /* must be [0] */ |
@@ -63,7 +63,8 @@ static struct tunables tunables[] = { | |||
63 | {&complete_threshold, COMPLETE_THRESHOLD}, | 63 | {&complete_threshold, COMPLETE_THRESHOLD}, |
64 | {&congested_respns_us, CONGESTED_RESPONSE_US}, | 64 | {&congested_respns_us, CONGESTED_RESPONSE_US}, |
65 | {&congested_reps, CONGESTED_REPS}, | 65 | {&congested_reps, CONGESTED_REPS}, |
66 | {&congested_period, CONGESTED_PERIOD} | 66 | {&disabled_period, DISABLED_PERIOD}, |
67 | {&giveup_limit, GIVEUP_LIMIT} | ||
67 | }; | 68 | }; |
68 | 69 | ||
69 | static struct dentry *tunables_dir; | 70 | static struct dentry *tunables_dir; |
@@ -120,6 +121,40 @@ static DEFINE_PER_CPU(struct ptc_stats, ptcstats); | |||
120 | static DEFINE_PER_CPU(struct bau_control, bau_control); | 121 | static DEFINE_PER_CPU(struct bau_control, bau_control); |
121 | static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask); | 122 | static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask); |
122 | 123 | ||
124 | static void | ||
125 | set_bau_on(void) | ||
126 | { | ||
127 | int cpu; | ||
128 | struct bau_control *bcp; | ||
129 | |||
130 | if (nobau_perm) { | ||
131 | pr_info("BAU not initialized; cannot be turned on\n"); | ||
132 | return; | ||
133 | } | ||
134 | nobau = 0; | ||
135 | for_each_present_cpu(cpu) { | ||
136 | bcp = &per_cpu(bau_control, cpu); | ||
137 | bcp->nobau = 0; | ||
138 | } | ||
139 | pr_info("BAU turned on\n"); | ||
140 | return; | ||
141 | } | ||
142 | |||
143 | static void | ||
144 | set_bau_off(void) | ||
145 | { | ||
146 | int cpu; | ||
147 | struct bau_control *bcp; | ||
148 | |||
149 | nobau = 1; | ||
150 | for_each_present_cpu(cpu) { | ||
151 | bcp = &per_cpu(bau_control, cpu); | ||
152 | bcp->nobau = 1; | ||
153 | } | ||
154 | pr_info("BAU turned off\n"); | ||
155 | return; | ||
156 | } | ||
157 | |||
123 | /* | 158 | /* |
124 | * Determine the first node on a uvhub. 'Nodes' are used for kernel | 159 | * Determine the first node on a uvhub. 'Nodes' are used for kernel |
125 | * memory allocation. | 160 | * memory allocation. |
@@ -278,7 +313,7 @@ static void bau_process_message(struct msg_desc *mdp, struct bau_control *bcp, | |||
278 | * Both sockets dump their completed count total into | 313 | * Both sockets dump their completed count total into |
279 | * the message's count. | 314 | * the message's count. |
280 | */ | 315 | */ |
281 | smaster->socket_acknowledge_count[mdp->msg_slot] = 0; | 316 | *sp = 0; |
282 | asp = (struct atomic_short *)&msg->acknowledge_count; | 317 | asp = (struct atomic_short *)&msg->acknowledge_count; |
283 | msg_ack_count = atom_asr(socket_ack_count, asp); | 318 | msg_ack_count = atom_asr(socket_ack_count, asp); |
284 | 319 | ||
@@ -491,16 +526,15 @@ static int uv1_wait_completion(struct bau_desc *bau_desc, | |||
491 | } | 526 | } |
492 | 527 | ||
493 | /* | 528 | /* |
494 | * UV2 has an extra bit of status in the ACTIVATION_STATUS_2 register. | 529 | * UV2 could have an extra bit of status in the ACTIVATION_STATUS_2 register. |
530 | * But not currently used. | ||
495 | */ | 531 | */ |
496 | static unsigned long uv2_read_status(unsigned long offset, int rshft, int desc) | 532 | static unsigned long uv2_read_status(unsigned long offset, int rshft, int desc) |
497 | { | 533 | { |
498 | unsigned long descriptor_status; | 534 | unsigned long descriptor_status; |
499 | unsigned long descriptor_status2; | ||
500 | 535 | ||
501 | descriptor_status = ((read_lmmr(offset) >> rshft) & UV_ACT_STATUS_MASK); | 536 | descriptor_status = |
502 | descriptor_status2 = (read_mmr_uv2_status() >> desc) & 0x1UL; | 537 | ((read_lmmr(offset) >> rshft) & UV_ACT_STATUS_MASK) << 1; |
503 | descriptor_status = (descriptor_status << 1) | descriptor_status2; | ||
504 | return descriptor_status; | 538 | return descriptor_status; |
505 | } | 539 | } |
506 | 540 | ||
@@ -531,87 +565,11 @@ int normal_busy(struct bau_control *bcp) | |||
531 | */ | 565 | */ |
532 | int handle_uv2_busy(struct bau_control *bcp) | 566 | int handle_uv2_busy(struct bau_control *bcp) |
533 | { | 567 | { |
534 | int busy_one = bcp->using_desc; | ||
535 | int normal = bcp->uvhub_cpu; | ||
536 | int selected = -1; | ||
537 | int i; | ||
538 | unsigned long descriptor_status; | ||
539 | unsigned long status; | ||
540 | int mmr_offset; | ||
541 | struct bau_desc *bau_desc_old; | ||
542 | struct bau_desc *bau_desc_new; | ||
543 | struct bau_control *hmaster = bcp->uvhub_master; | ||
544 | struct ptc_stats *stat = bcp->statp; | 568 | struct ptc_stats *stat = bcp->statp; |
545 | cycles_t ttm; | ||
546 | 569 | ||
547 | stat->s_uv2_wars++; | 570 | stat->s_uv2_wars++; |
548 | spin_lock(&hmaster->uvhub_lock); | 571 | bcp->busy = 1; |
549 | /* try for the original first */ | 572 | return FLUSH_GIVEUP; |
550 | if (busy_one != normal) { | ||
551 | if (!normal_busy(bcp)) | ||
552 | selected = normal; | ||
553 | } | ||
554 | if (selected < 0) { | ||
555 | /* can't use the normal, select an alternate */ | ||
556 | mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1; | ||
557 | descriptor_status = read_lmmr(mmr_offset); | ||
558 | |||
559 | /* scan available descriptors 32-63 */ | ||
560 | for (i = 0; i < UV_CPUS_PER_AS; i++) { | ||
561 | if ((hmaster->inuse_map & (1 << i)) == 0) { | ||
562 | status = ((descriptor_status >> | ||
563 | (i * UV_ACT_STATUS_SIZE)) & | ||
564 | UV_ACT_STATUS_MASK) << 1; | ||
565 | if (status != UV2H_DESC_BUSY) { | ||
566 | selected = i + UV_CPUS_PER_AS; | ||
567 | break; | ||
568 | } | ||
569 | } | ||
570 | } | ||
571 | } | ||
572 | |||
573 | if (busy_one != normal) | ||
574 | /* mark the busy alternate as not in-use */ | ||
575 | hmaster->inuse_map &= ~(1 << (busy_one - UV_CPUS_PER_AS)); | ||
576 | |||
577 | if (selected >= 0) { | ||
578 | /* switch to the selected descriptor */ | ||
579 | if (selected != normal) { | ||
580 | /* set the selected alternate as in-use */ | ||
581 | hmaster->inuse_map |= | ||
582 | (1 << (selected - UV_CPUS_PER_AS)); | ||
583 | if (selected > stat->s_uv2_wars_hw) | ||
584 | stat->s_uv2_wars_hw = selected; | ||
585 | } | ||
586 | bau_desc_old = bcp->descriptor_base; | ||
587 | bau_desc_old += (ITEMS_PER_DESC * busy_one); | ||
588 | bcp->using_desc = selected; | ||
589 | bau_desc_new = bcp->descriptor_base; | ||
590 | bau_desc_new += (ITEMS_PER_DESC * selected); | ||
591 | *bau_desc_new = *bau_desc_old; | ||
592 | } else { | ||
593 | /* | ||
594 | * All are busy. Wait for the normal one for this cpu to | ||
595 | * free up. | ||
596 | */ | ||
597 | stat->s_uv2_war_waits++; | ||
598 | spin_unlock(&hmaster->uvhub_lock); | ||
599 | ttm = get_cycles(); | ||
600 | do { | ||
601 | cpu_relax(); | ||
602 | } while (normal_busy(bcp)); | ||
603 | spin_lock(&hmaster->uvhub_lock); | ||
604 | /* switch to the original descriptor */ | ||
605 | bcp->using_desc = normal; | ||
606 | bau_desc_old = bcp->descriptor_base; | ||
607 | bau_desc_old += (ITEMS_PER_DESC * bcp->using_desc); | ||
608 | bcp->using_desc = (ITEMS_PER_DESC * normal); | ||
609 | bau_desc_new = bcp->descriptor_base; | ||
610 | bau_desc_new += (ITEMS_PER_DESC * normal); | ||
611 | *bau_desc_new = *bau_desc_old; /* copy the entire descriptor */ | ||
612 | } | ||
613 | spin_unlock(&hmaster->uvhub_lock); | ||
614 | return FLUSH_RETRY_BUSYBUG; | ||
615 | } | 573 | } |
616 | 574 | ||
617 | static int uv2_wait_completion(struct bau_desc *bau_desc, | 575 | static int uv2_wait_completion(struct bau_desc *bau_desc, |
@@ -620,7 +578,7 @@ static int uv2_wait_completion(struct bau_desc *bau_desc, | |||
620 | { | 578 | { |
621 | unsigned long descriptor_stat; | 579 | unsigned long descriptor_stat; |
622 | cycles_t ttm; | 580 | cycles_t ttm; |
623 | int desc = bcp->using_desc; | 581 | int desc = bcp->uvhub_cpu; |
624 | long busy_reps = 0; | 582 | long busy_reps = 0; |
625 | struct ptc_stats *stat = bcp->statp; | 583 | struct ptc_stats *stat = bcp->statp; |
626 | 584 | ||
@@ -628,24 +586,38 @@ static int uv2_wait_completion(struct bau_desc *bau_desc, | |||
628 | 586 | ||
629 | /* spin on the status MMR, waiting for it to go idle */ | 587 | /* spin on the status MMR, waiting for it to go idle */ |
630 | while (descriptor_stat != UV2H_DESC_IDLE) { | 588 | while (descriptor_stat != UV2H_DESC_IDLE) { |
631 | /* | 589 | if ((descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT)) { |
632 | * Our software ack messages may be blocked because | 590 | /* |
633 | * there are no swack resources available. As long | 591 | * A h/w bug on the destination side may |
634 | * as none of them has timed out hardware will NACK | 592 | * have prevented the message being marked |
635 | * our message and its state will stay IDLE. | 593 | * pending, thus it doesn't get replied to |
636 | */ | 594 | * and gets continually nacked until it times |
637 | if ((descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT) || | 595 | * out with a SOURCE_TIMEOUT. |
638 | (descriptor_stat == UV2H_DESC_DEST_PUT_ERR)) { | 596 | */ |
639 | stat->s_stimeout++; | 597 | stat->s_stimeout++; |
640 | return FLUSH_GIVEUP; | 598 | return FLUSH_GIVEUP; |
641 | } else if (descriptor_stat == UV2H_DESC_DEST_STRONG_NACK) { | ||
642 | stat->s_strongnacks++; | ||
643 | bcp->conseccompletes = 0; | ||
644 | return FLUSH_GIVEUP; | ||
645 | } else if (descriptor_stat == UV2H_DESC_DEST_TIMEOUT) { | 599 | } else if (descriptor_stat == UV2H_DESC_DEST_TIMEOUT) { |
600 | ttm = get_cycles(); | ||
601 | |||
602 | /* | ||
603 | * Our retries may be blocked by all destination | ||
604 | * swack resources being consumed, and a timeout | ||
605 | * pending. In that case hardware returns the | ||
606 | * ERROR that looks like a destination timeout. | ||
607 | * Without using the extended status we have to | ||
608 | * deduce from the short time that this was a | ||
609 | * strong nack. | ||
610 | */ | ||
611 | if (cycles_2_us(ttm - bcp->send_message) < timeout_us) { | ||
612 | bcp->conseccompletes = 0; | ||
613 | stat->s_plugged++; | ||
614 | /* FLUSH_RETRY_PLUGGED causes hang on boot */ | ||
615 | return FLUSH_GIVEUP; | ||
616 | } | ||
646 | stat->s_dtimeout++; | 617 | stat->s_dtimeout++; |
647 | bcp->conseccompletes = 0; | 618 | bcp->conseccompletes = 0; |
648 | return FLUSH_RETRY_TIMEOUT; | 619 | /* FLUSH_RETRY_TIMEOUT causes hang on boot */ |
620 | return FLUSH_GIVEUP; | ||
649 | } else { | 621 | } else { |
650 | busy_reps++; | 622 | busy_reps++; |
651 | if (busy_reps > 1000000) { | 623 | if (busy_reps > 1000000) { |
@@ -653,9 +625,8 @@ static int uv2_wait_completion(struct bau_desc *bau_desc, | |||
653 | busy_reps = 0; | 625 | busy_reps = 0; |
654 | ttm = get_cycles(); | 626 | ttm = get_cycles(); |
655 | if ((ttm - bcp->send_message) > | 627 | if ((ttm - bcp->send_message) > |
656 | (bcp->clocks_per_100_usec)) { | 628 | bcp->timeout_interval) |
657 | return handle_uv2_busy(bcp); | 629 | return handle_uv2_busy(bcp); |
658 | } | ||
659 | } | 630 | } |
660 | /* | 631 | /* |
661 | * descriptor_stat is still BUSY | 632 | * descriptor_stat is still BUSY |
@@ -679,7 +650,7 @@ static int wait_completion(struct bau_desc *bau_desc, | |||
679 | { | 650 | { |
680 | int right_shift; | 651 | int right_shift; |
681 | unsigned long mmr_offset; | 652 | unsigned long mmr_offset; |
682 | int desc = bcp->using_desc; | 653 | int desc = bcp->uvhub_cpu; |
683 | 654 | ||
684 | if (desc < UV_CPUS_PER_AS) { | 655 | if (desc < UV_CPUS_PER_AS) { |
685 | mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0; | 656 | mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0; |
@@ -758,33 +729,31 @@ static void destination_timeout(struct bau_desc *bau_desc, | |||
758 | } | 729 | } |
759 | 730 | ||
760 | /* | 731 | /* |
761 | * Completions are taking a very long time due to a congested numalink | 732 | * Stop all cpus on a uvhub from using the BAU for a period of time. |
762 | * network. | 733 | * This is reversed by check_enable. |
763 | */ | 734 | */ |
764 | static void disable_for_congestion(struct bau_control *bcp, | 735 | static void disable_for_period(struct bau_control *bcp, struct ptc_stats *stat) |
765 | struct ptc_stats *stat) | ||
766 | { | 736 | { |
767 | /* let only one cpu do this disabling */ | 737 | int tcpu; |
768 | spin_lock(&disable_lock); | 738 | struct bau_control *tbcp; |
769 | 739 | struct bau_control *hmaster; | |
770 | if (!baudisabled && bcp->period_requests && | 740 | cycles_t tm1; |
771 | ((bcp->period_time / bcp->period_requests) > congested_cycles)) { | 741 | |
772 | int tcpu; | 742 | hmaster = bcp->uvhub_master; |
773 | struct bau_control *tbcp; | 743 | spin_lock(&hmaster->disable_lock); |
774 | /* it becomes this cpu's job to turn on the use of the | 744 | if (!bcp->baudisabled) { |
775 | BAU again */ | ||
776 | baudisabled = 1; | ||
777 | bcp->set_bau_off = 1; | ||
778 | bcp->set_bau_on_time = get_cycles(); | ||
779 | bcp->set_bau_on_time += sec_2_cycles(bcp->cong_period); | ||
780 | stat->s_bau_disabled++; | 745 | stat->s_bau_disabled++; |
746 | tm1 = get_cycles(); | ||
781 | for_each_present_cpu(tcpu) { | 747 | for_each_present_cpu(tcpu) { |
782 | tbcp = &per_cpu(bau_control, tcpu); | 748 | tbcp = &per_cpu(bau_control, tcpu); |
783 | tbcp->baudisabled = 1; | 749 | if (tbcp->uvhub_master == hmaster) { |
750 | tbcp->baudisabled = 1; | ||
751 | tbcp->set_bau_on_time = | ||
752 | tm1 + bcp->disabled_period; | ||
753 | } | ||
784 | } | 754 | } |
785 | } | 755 | } |
786 | 756 | spin_unlock(&hmaster->disable_lock); | |
787 | spin_unlock(&disable_lock); | ||
788 | } | 757 | } |
789 | 758 | ||
790 | static void count_max_concurr(int stat, struct bau_control *bcp, | 759 | static void count_max_concurr(int stat, struct bau_control *bcp, |
@@ -815,16 +784,30 @@ static void record_send_stats(cycles_t time1, cycles_t time2, | |||
815 | bcp->period_requests++; | 784 | bcp->period_requests++; |
816 | bcp->period_time += elapsed; | 785 | bcp->period_time += elapsed; |
817 | if ((elapsed > congested_cycles) && | 786 | if ((elapsed > congested_cycles) && |
818 | (bcp->period_requests > bcp->cong_reps)) | 787 | (bcp->period_requests > bcp->cong_reps) && |
819 | disable_for_congestion(bcp, stat); | 788 | ((bcp->period_time / bcp->period_requests) > |
789 | congested_cycles)) { | ||
790 | stat->s_congested++; | ||
791 | disable_for_period(bcp, stat); | ||
792 | } | ||
820 | } | 793 | } |
821 | } else | 794 | } else |
822 | stat->s_requestor--; | 795 | stat->s_requestor--; |
823 | 796 | ||
824 | if (completion_status == FLUSH_COMPLETE && try > 1) | 797 | if (completion_status == FLUSH_COMPLETE && try > 1) |
825 | stat->s_retriesok++; | 798 | stat->s_retriesok++; |
826 | else if (completion_status == FLUSH_GIVEUP) | 799 | else if (completion_status == FLUSH_GIVEUP) { |
827 | stat->s_giveup++; | 800 | stat->s_giveup++; |
801 | if (get_cycles() > bcp->period_end) | ||
802 | bcp->period_giveups = 0; | ||
803 | bcp->period_giveups++; | ||
804 | if (bcp->period_giveups == 1) | ||
805 | bcp->period_end = get_cycles() + bcp->disabled_period; | ||
806 | if (bcp->period_giveups > bcp->giveup_limit) { | ||
807 | disable_for_period(bcp, stat); | ||
808 | stat->s_giveuplimit++; | ||
809 | } | ||
810 | } | ||
828 | } | 811 | } |
829 | 812 | ||
830 | /* | 813 | /* |
@@ -868,7 +851,8 @@ static void handle_cmplt(int completion_status, struct bau_desc *bau_desc, | |||
868 | * Returns 1 if it gives up entirely and the original cpu mask is to be | 851 | * Returns 1 if it gives up entirely and the original cpu mask is to be |
869 | * returned to the kernel. | 852 | * returned to the kernel. |
870 | */ | 853 | */ |
871 | int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp) | 854 | int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp, |
855 | struct bau_desc *bau_desc) | ||
872 | { | 856 | { |
873 | int seq_number = 0; | 857 | int seq_number = 0; |
874 | int completion_stat = 0; | 858 | int completion_stat = 0; |
@@ -881,24 +865,23 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp) | |||
881 | struct bau_control *hmaster = bcp->uvhub_master; | 865 | struct bau_control *hmaster = bcp->uvhub_master; |
882 | struct uv1_bau_msg_header *uv1_hdr = NULL; | 866 | struct uv1_bau_msg_header *uv1_hdr = NULL; |
883 | struct uv2_bau_msg_header *uv2_hdr = NULL; | 867 | struct uv2_bau_msg_header *uv2_hdr = NULL; |
884 | struct bau_desc *bau_desc; | ||
885 | 868 | ||
886 | if (bcp->uvhub_version == 1) | 869 | if (bcp->uvhub_version == 1) { |
870 | uv1 = 1; | ||
887 | uv1_throttle(hmaster, stat); | 871 | uv1_throttle(hmaster, stat); |
872 | } | ||
888 | 873 | ||
889 | while (hmaster->uvhub_quiesce) | 874 | while (hmaster->uvhub_quiesce) |
890 | cpu_relax(); | 875 | cpu_relax(); |
891 | 876 | ||
892 | time1 = get_cycles(); | 877 | time1 = get_cycles(); |
878 | if (uv1) | ||
879 | uv1_hdr = &bau_desc->header.uv1_hdr; | ||
880 | else | ||
881 | uv2_hdr = &bau_desc->header.uv2_hdr; | ||
882 | |||
893 | do { | 883 | do { |
894 | bau_desc = bcp->descriptor_base; | 884 | if (try == 0) { |
895 | bau_desc += (ITEMS_PER_DESC * bcp->using_desc); | ||
896 | if (bcp->uvhub_version == 1) { | ||
897 | uv1 = 1; | ||
898 | uv1_hdr = &bau_desc->header.uv1_hdr; | ||
899 | } else | ||
900 | uv2_hdr = &bau_desc->header.uv2_hdr; | ||
901 | if ((try == 0) || (completion_stat == FLUSH_RETRY_BUSYBUG)) { | ||
902 | if (uv1) | 885 | if (uv1) |
903 | uv1_hdr->msg_type = MSG_REGULAR; | 886 | uv1_hdr->msg_type = MSG_REGULAR; |
904 | else | 887 | else |
@@ -916,25 +899,24 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp) | |||
916 | uv1_hdr->sequence = seq_number; | 899 | uv1_hdr->sequence = seq_number; |
917 | else | 900 | else |
918 | uv2_hdr->sequence = seq_number; | 901 | uv2_hdr->sequence = seq_number; |
919 | index = (1UL << AS_PUSH_SHIFT) | bcp->using_desc; | 902 | index = (1UL << AS_PUSH_SHIFT) | bcp->uvhub_cpu; |
920 | bcp->send_message = get_cycles(); | 903 | bcp->send_message = get_cycles(); |
921 | 904 | ||
922 | write_mmr_activation(index); | 905 | write_mmr_activation(index); |
923 | 906 | ||
924 | try++; | 907 | try++; |
925 | completion_stat = wait_completion(bau_desc, bcp, try); | 908 | completion_stat = wait_completion(bau_desc, bcp, try); |
926 | /* UV2: wait_completion() may change the bcp->using_desc */ | ||
927 | 909 | ||
928 | handle_cmplt(completion_stat, bau_desc, bcp, hmaster, stat); | 910 | handle_cmplt(completion_stat, bau_desc, bcp, hmaster, stat); |
929 | 911 | ||
930 | if (bcp->ipi_attempts >= bcp->ipi_reset_limit) { | 912 | if (bcp->ipi_attempts >= bcp->ipi_reset_limit) { |
931 | bcp->ipi_attempts = 0; | 913 | bcp->ipi_attempts = 0; |
914 | stat->s_overipilimit++; | ||
932 | completion_stat = FLUSH_GIVEUP; | 915 | completion_stat = FLUSH_GIVEUP; |
933 | break; | 916 | break; |
934 | } | 917 | } |
935 | cpu_relax(); | 918 | cpu_relax(); |
936 | } while ((completion_stat == FLUSH_RETRY_PLUGGED) || | 919 | } while ((completion_stat == FLUSH_RETRY_PLUGGED) || |
937 | (completion_stat == FLUSH_RETRY_BUSYBUG) || | ||
938 | (completion_stat == FLUSH_RETRY_TIMEOUT)); | 920 | (completion_stat == FLUSH_RETRY_TIMEOUT)); |
939 | 921 | ||
940 | time2 = get_cycles(); | 922 | time2 = get_cycles(); |
@@ -955,28 +937,33 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp) | |||
955 | } | 937 | } |
956 | 938 | ||
957 | /* | 939 | /* |
958 | * The BAU is disabled. When the disabled time period has expired, the cpu | 940 | * The BAU is disabled for this uvhub. When the disabled time period has |
959 | * that disabled it must re-enable it. | 941 | * expired re-enable it. |
960 | * Return 0 if it is re-enabled for all cpus. | 942 | * Return 0 if it is re-enabled for all cpus on this uvhub. |
961 | */ | 943 | */ |
962 | static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) | 944 | static int check_enable(struct bau_control *bcp, struct ptc_stats *stat) |
963 | { | 945 | { |
964 | int tcpu; | 946 | int tcpu; |
965 | struct bau_control *tbcp; | 947 | struct bau_control *tbcp; |
948 | struct bau_control *hmaster; | ||
966 | 949 | ||
967 | if (bcp->set_bau_off) { | 950 | hmaster = bcp->uvhub_master; |
968 | if (get_cycles() >= bcp->set_bau_on_time) { | 951 | spin_lock(&hmaster->disable_lock); |
969 | stat->s_bau_reenabled++; | 952 | if (bcp->baudisabled && (get_cycles() >= bcp->set_bau_on_time)) { |
970 | baudisabled = 0; | 953 | stat->s_bau_reenabled++; |
971 | for_each_present_cpu(tcpu) { | 954 | for_each_present_cpu(tcpu) { |
972 | tbcp = &per_cpu(bau_control, tcpu); | 955 | tbcp = &per_cpu(bau_control, tcpu); |
956 | if (tbcp->uvhub_master == hmaster) { | ||
973 | tbcp->baudisabled = 0; | 957 | tbcp->baudisabled = 0; |
974 | tbcp->period_requests = 0; | 958 | tbcp->period_requests = 0; |
975 | tbcp->period_time = 0; | 959 | tbcp->period_time = 0; |
960 | tbcp->period_giveups = 0; | ||
976 | } | 961 | } |
977 | return 0; | ||
978 | } | 962 | } |
963 | spin_unlock(&hmaster->disable_lock); | ||
964 | return 0; | ||
979 | } | 965 | } |
966 | spin_unlock(&hmaster->disable_lock); | ||
980 | return -1; | 967 | return -1; |
981 | } | 968 | } |
982 | 969 | ||
@@ -1078,18 +1065,32 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | |||
1078 | struct cpumask *flush_mask; | 1065 | struct cpumask *flush_mask; |
1079 | struct ptc_stats *stat; | 1066 | struct ptc_stats *stat; |
1080 | struct bau_control *bcp; | 1067 | struct bau_control *bcp; |
1081 | 1068 | unsigned long descriptor_status; | |
1082 | /* kernel was booted 'nobau' */ | 1069 | unsigned long status; |
1083 | if (nobau) | ||
1084 | return cpumask; | ||
1085 | 1070 | ||
1086 | bcp = &per_cpu(bau_control, cpu); | 1071 | bcp = &per_cpu(bau_control, cpu); |
1087 | stat = bcp->statp; | 1072 | stat = bcp->statp; |
1073 | stat->s_enters++; | ||
1074 | |||
1075 | if (bcp->nobau) | ||
1076 | return cpumask; | ||
1077 | |||
1078 | if (bcp->busy) { | ||
1079 | descriptor_status = | ||
1080 | read_lmmr(UVH_LB_BAU_SB_ACTIVATION_STATUS_0); | ||
1081 | status = ((descriptor_status >> (bcp->uvhub_cpu * | ||
1082 | UV_ACT_STATUS_SIZE)) & UV_ACT_STATUS_MASK) << 1; | ||
1083 | if (status == UV2H_DESC_BUSY) | ||
1084 | return cpumask; | ||
1085 | bcp->busy = 0; | ||
1086 | } | ||
1088 | 1087 | ||
1089 | /* bau was disabled due to slow response */ | 1088 | /* bau was disabled due to slow response */ |
1090 | if (bcp->baudisabled) { | 1089 | if (bcp->baudisabled) { |
1091 | if (check_enable(bcp, stat)) | 1090 | if (check_enable(bcp, stat)) { |
1091 | stat->s_ipifordisabled++; | ||
1092 | return cpumask; | 1092 | return cpumask; |
1093 | } | ||
1093 | } | 1094 | } |
1094 | 1095 | ||
1095 | /* | 1096 | /* |
@@ -1105,7 +1106,7 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | |||
1105 | stat->s_ntargself++; | 1106 | stat->s_ntargself++; |
1106 | 1107 | ||
1107 | bau_desc = bcp->descriptor_base; | 1108 | bau_desc = bcp->descriptor_base; |
1108 | bau_desc += (ITEMS_PER_DESC * bcp->using_desc); | 1109 | bau_desc += (ITEMS_PER_DESC * bcp->uvhub_cpu); |
1109 | bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); | 1110 | bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); |
1110 | if (set_distrib_bits(flush_mask, bcp, bau_desc, &locals, &remotes)) | 1111 | if (set_distrib_bits(flush_mask, bcp, bau_desc, &locals, &remotes)) |
1111 | return NULL; | 1112 | return NULL; |
@@ -1118,25 +1119,27 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, | |||
1118 | * uv_flush_send_and_wait returns 0 if all cpu's were messaged, | 1119 | * uv_flush_send_and_wait returns 0 if all cpu's were messaged, |
1119 | * or 1 if it gave up and the original cpumask should be returned. | 1120 | * or 1 if it gave up and the original cpumask should be returned. |
1120 | */ | 1121 | */ |
1121 | if (!uv_flush_send_and_wait(flush_mask, bcp)) | 1122 | if (!uv_flush_send_and_wait(flush_mask, bcp, bau_desc)) |
1122 | return NULL; | 1123 | return NULL; |
1123 | else | 1124 | else |
1124 | return cpumask; | 1125 | return cpumask; |
1125 | } | 1126 | } |
1126 | 1127 | ||
1127 | /* | 1128 | /* |
1128 | * Search the message queue for any 'other' message with the same software | 1129 | * Search the message queue for any 'other' unprocessed message with the |
1129 | * acknowledge resource bit vector. | 1130 | * same software acknowledge resource bit vector as the 'msg' message. |
1130 | */ | 1131 | */ |
1131 | struct bau_pq_entry *find_another_by_swack(struct bau_pq_entry *msg, | 1132 | struct bau_pq_entry *find_another_by_swack(struct bau_pq_entry *msg, |
1132 | struct bau_control *bcp, unsigned char swack_vec) | 1133 | struct bau_control *bcp) |
1133 | { | 1134 | { |
1134 | struct bau_pq_entry *msg_next = msg + 1; | 1135 | struct bau_pq_entry *msg_next = msg + 1; |
1136 | unsigned char swack_vec = msg->swack_vec; | ||
1135 | 1137 | ||
1136 | if (msg_next > bcp->queue_last) | 1138 | if (msg_next > bcp->queue_last) |
1137 | msg_next = bcp->queue_first; | 1139 | msg_next = bcp->queue_first; |
1138 | while ((msg_next->swack_vec != 0) && (msg_next != msg)) { | 1140 | while (msg_next != msg) { |
1139 | if (msg_next->swack_vec == swack_vec) | 1141 | if ((msg_next->canceled == 0) && (msg_next->replied_to == 0) && |
1142 | (msg_next->swack_vec == swack_vec)) | ||
1140 | return msg_next; | 1143 | return msg_next; |
1141 | msg_next++; | 1144 | msg_next++; |
1142 | if (msg_next > bcp->queue_last) | 1145 | if (msg_next > bcp->queue_last) |
@@ -1165,32 +1168,30 @@ void process_uv2_message(struct msg_desc *mdp, struct bau_control *bcp) | |||
1165 | * This message was assigned a swack resource, but no | 1168 | * This message was assigned a swack resource, but no |
1166 | * reserved acknowlegment is pending. | 1169 | * reserved acknowlegment is pending. |
1167 | * The bug has prevented this message from setting the MMR. | 1170 | * The bug has prevented this message from setting the MMR. |
1168 | * And no other message has used the same sw_ack resource. | ||
1169 | * Do the requested shootdown but do not reply to the msg. | ||
1170 | * (the 0 means make no acknowledge) | ||
1171 | */ | 1171 | */ |
1172 | bau_process_message(mdp, bcp, 0); | ||
1173 | return; | ||
1174 | } | ||
1175 | |||
1176 | /* | ||
1177 | * Some message has set the MMR 'pending' bit; it might have been | ||
1178 | * another message. Look for that message. | ||
1179 | */ | ||
1180 | other_msg = find_another_by_swack(msg, bcp, msg->swack_vec); | ||
1181 | if (other_msg) { | ||
1182 | /* There is another. Do not ack the current one. */ | ||
1183 | bau_process_message(mdp, bcp, 0); | ||
1184 | /* | 1172 | /* |
1185 | * Let the natural processing of that message acknowledge | 1173 | * Some message has set the MMR 'pending' bit; it might have |
1186 | * it. Don't get the processing of sw_ack's out of order. | 1174 | * been another message. Look for that message. |
1187 | */ | 1175 | */ |
1188 | return; | 1176 | other_msg = find_another_by_swack(msg, bcp); |
1177 | if (other_msg) { | ||
1178 | /* | ||
1179 | * There is another. Process this one but do not | ||
1180 | * ack it. | ||
1181 | */ | ||
1182 | bau_process_message(mdp, bcp, 0); | ||
1183 | /* | ||
1184 | * Let the natural processing of that other message | ||
1185 | * acknowledge it. Don't get the processing of sw_ack's | ||
1186 | * out of order. | ||
1187 | */ | ||
1188 | return; | ||
1189 | } | ||
1189 | } | 1190 | } |
1190 | 1191 | ||
1191 | /* | 1192 | /* |
1192 | * There is no other message using this sw_ack, so it is safe to | 1193 | * Either the MMR shows this one pending a reply or there is no |
1193 | * acknowledge it. | 1194 | * other message using this sw_ack, so it is safe to acknowledge it. |
1194 | */ | 1195 | */ |
1195 | bau_process_message(mdp, bcp, 1); | 1196 | bau_process_message(mdp, bcp, 1); |
1196 | 1197 | ||
@@ -1295,7 +1296,8 @@ static void __init enable_timeouts(void) | |||
1295 | */ | 1296 | */ |
1296 | mmr_image |= (1L << SOFTACK_MSHIFT); | 1297 | mmr_image |= (1L << SOFTACK_MSHIFT); |
1297 | if (is_uv2_hub()) { | 1298 | if (is_uv2_hub()) { |
1298 | mmr_image |= (1L << UV2_EXT_SHFT); | 1299 | /* hw bug workaround; do not use extended status */ |
1300 | mmr_image &= ~(1L << UV2_EXT_SHFT); | ||
1299 | } | 1301 | } |
1300 | write_mmr_misc_control(pnode, mmr_image); | 1302 | write_mmr_misc_control(pnode, mmr_image); |
1301 | } | 1303 | } |
@@ -1338,29 +1340,34 @@ static inline unsigned long long usec_2_cycles(unsigned long microsec) | |||
1338 | static int ptc_seq_show(struct seq_file *file, void *data) | 1340 | static int ptc_seq_show(struct seq_file *file, void *data) |
1339 | { | 1341 | { |
1340 | struct ptc_stats *stat; | 1342 | struct ptc_stats *stat; |
1343 | struct bau_control *bcp; | ||
1341 | int cpu; | 1344 | int cpu; |
1342 | 1345 | ||
1343 | cpu = *(loff_t *)data; | 1346 | cpu = *(loff_t *)data; |
1344 | if (!cpu) { | 1347 | if (!cpu) { |
1345 | seq_printf(file, | 1348 | seq_printf(file, |
1346 | "# cpu sent stime self locals remotes ncpus localhub "); | 1349 | "# cpu bauoff sent stime self locals remotes ncpus localhub "); |
1347 | seq_printf(file, | 1350 | seq_printf(file, |
1348 | "remotehub numuvhubs numuvhubs16 numuvhubs8 "); | 1351 | "remotehub numuvhubs numuvhubs16 numuvhubs8 "); |
1349 | seq_printf(file, | 1352 | seq_printf(file, |
1350 | "numuvhubs4 numuvhubs2 numuvhubs1 dto snacks retries rok "); | 1353 | "numuvhubs4 numuvhubs2 numuvhubs1 dto snacks retries "); |
1354 | seq_printf(file, | ||
1355 | "rok resetp resett giveup sto bz throt disable "); | ||
1351 | seq_printf(file, | 1356 | seq_printf(file, |
1352 | "resetp resett giveup sto bz throt swack recv rtime "); | 1357 | "enable wars warshw warwaits enters ipidis plugged "); |
1353 | seq_printf(file, | 1358 | seq_printf(file, |
1354 | "all one mult none retry canc nocan reset rcan "); | 1359 | "ipiover glim cong swack recv rtime all one mult "); |
1355 | seq_printf(file, | 1360 | seq_printf(file, |
1356 | "disable enable wars warshw warwaits\n"); | 1361 | "none retry canc nocan reset rcan\n"); |
1357 | } | 1362 | } |
1358 | if (cpu < num_possible_cpus() && cpu_online(cpu)) { | 1363 | if (cpu < num_possible_cpus() && cpu_online(cpu)) { |
1359 | stat = &per_cpu(ptcstats, cpu); | 1364 | bcp = &per_cpu(bau_control, cpu); |
1365 | stat = bcp->statp; | ||
1360 | /* source side statistics */ | 1366 | /* source side statistics */ |
1361 | seq_printf(file, | 1367 | seq_printf(file, |
1362 | "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", | 1368 | "cpu %d %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", |
1363 | cpu, stat->s_requestor, cycles_2_us(stat->s_time), | 1369 | cpu, bcp->nobau, stat->s_requestor, |
1370 | cycles_2_us(stat->s_time), | ||
1364 | stat->s_ntargself, stat->s_ntarglocals, | 1371 | stat->s_ntargself, stat->s_ntarglocals, |
1365 | stat->s_ntargremotes, stat->s_ntargcpu, | 1372 | stat->s_ntargremotes, stat->s_ntargcpu, |
1366 | stat->s_ntarglocaluvhub, stat->s_ntargremoteuvhub, | 1373 | stat->s_ntarglocaluvhub, stat->s_ntargremoteuvhub, |
@@ -1374,20 +1381,23 @@ static int ptc_seq_show(struct seq_file *file, void *data) | |||
1374 | stat->s_resets_plug, stat->s_resets_timeout, | 1381 | stat->s_resets_plug, stat->s_resets_timeout, |
1375 | stat->s_giveup, stat->s_stimeout, | 1382 | stat->s_giveup, stat->s_stimeout, |
1376 | stat->s_busy, stat->s_throttles); | 1383 | stat->s_busy, stat->s_throttles); |
1384 | seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", | ||
1385 | stat->s_bau_disabled, stat->s_bau_reenabled, | ||
1386 | stat->s_uv2_wars, stat->s_uv2_wars_hw, | ||
1387 | stat->s_uv2_war_waits, stat->s_enters, | ||
1388 | stat->s_ipifordisabled, stat->s_plugged, | ||
1389 | stat->s_overipilimit, stat->s_giveuplimit, | ||
1390 | stat->s_congested); | ||
1377 | 1391 | ||
1378 | /* destination side statistics */ | 1392 | /* destination side statistics */ |
1379 | seq_printf(file, | 1393 | seq_printf(file, |
1380 | "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ", | 1394 | "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", |
1381 | read_gmmr_sw_ack(uv_cpu_to_pnode(cpu)), | 1395 | read_gmmr_sw_ack(uv_cpu_to_pnode(cpu)), |
1382 | stat->d_requestee, cycles_2_us(stat->d_time), | 1396 | stat->d_requestee, cycles_2_us(stat->d_time), |
1383 | stat->d_alltlb, stat->d_onetlb, stat->d_multmsg, | 1397 | stat->d_alltlb, stat->d_onetlb, stat->d_multmsg, |
1384 | stat->d_nomsg, stat->d_retries, stat->d_canceled, | 1398 | stat->d_nomsg, stat->d_retries, stat->d_canceled, |
1385 | stat->d_nocanceled, stat->d_resets, | 1399 | stat->d_nocanceled, stat->d_resets, |
1386 | stat->d_rcanceled); | 1400 | stat->d_rcanceled); |
1387 | seq_printf(file, "%ld %ld %ld %ld %ld\n", | ||
1388 | stat->s_bau_disabled, stat->s_bau_reenabled, | ||
1389 | stat->s_uv2_wars, stat->s_uv2_wars_hw, | ||
1390 | stat->s_uv2_war_waits); | ||
1391 | } | 1401 | } |
1392 | return 0; | 1402 | return 0; |
1393 | } | 1403 | } |
@@ -1401,13 +1411,14 @@ static ssize_t tunables_read(struct file *file, char __user *userbuf, | |||
1401 | char *buf; | 1411 | char *buf; |
1402 | int ret; | 1412 | int ret; |
1403 | 1413 | ||
1404 | buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d\n", | 1414 | buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d %d\n", |
1405 | "max_concur plugged_delay plugsb4reset", | 1415 | "max_concur plugged_delay plugsb4reset timeoutsb4reset", |
1406 | "timeoutsb4reset ipi_reset_limit complete_threshold", | 1416 | "ipi_reset_limit complete_threshold congested_response_us", |
1407 | "congested_response_us congested_reps congested_period", | 1417 | "congested_reps disabled_period giveup_limit", |
1408 | max_concurr, plugged_delay, plugsb4reset, | 1418 | max_concurr, plugged_delay, plugsb4reset, |
1409 | timeoutsb4reset, ipi_reset_limit, complete_threshold, | 1419 | timeoutsb4reset, ipi_reset_limit, complete_threshold, |
1410 | congested_respns_us, congested_reps, congested_period); | 1420 | congested_respns_us, congested_reps, disabled_period, |
1421 | giveup_limit); | ||
1411 | 1422 | ||
1412 | if (!buf) | 1423 | if (!buf) |
1413 | return -ENOMEM; | 1424 | return -ENOMEM; |
@@ -1438,6 +1449,14 @@ static ssize_t ptc_proc_write(struct file *file, const char __user *user, | |||
1438 | return -EFAULT; | 1449 | return -EFAULT; |
1439 | optstr[count - 1] = '\0'; | 1450 | optstr[count - 1] = '\0'; |
1440 | 1451 | ||
1452 | if (!strcmp(optstr, "on")) { | ||
1453 | set_bau_on(); | ||
1454 | return count; | ||
1455 | } else if (!strcmp(optstr, "off")) { | ||
1456 | set_bau_off(); | ||
1457 | return count; | ||
1458 | } | ||
1459 | |||
1441 | if (strict_strtol(optstr, 10, &input_arg) < 0) { | 1460 | if (strict_strtol(optstr, 10, &input_arg) < 0) { |
1442 | printk(KERN_DEBUG "%s is invalid\n", optstr); | 1461 | printk(KERN_DEBUG "%s is invalid\n", optstr); |
1443 | return -EINVAL; | 1462 | return -EINVAL; |
@@ -1570,7 +1589,8 @@ static ssize_t tunables_write(struct file *file, const char __user *user, | |||
1570 | bcp->complete_threshold = complete_threshold; | 1589 | bcp->complete_threshold = complete_threshold; |
1571 | bcp->cong_response_us = congested_respns_us; | 1590 | bcp->cong_response_us = congested_respns_us; |
1572 | bcp->cong_reps = congested_reps; | 1591 | bcp->cong_reps = congested_reps; |
1573 | bcp->cong_period = congested_period; | 1592 | bcp->disabled_period = sec_2_cycles(disabled_period); |
1593 | bcp->giveup_limit = giveup_limit; | ||
1574 | } | 1594 | } |
1575 | return count; | 1595 | return count; |
1576 | } | 1596 | } |
@@ -1699,6 +1719,10 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode) | |||
1699 | * fairness chaining multilevel count replied_to | 1719 | * fairness chaining multilevel count replied_to |
1700 | */ | 1720 | */ |
1701 | } else { | 1721 | } else { |
1722 | /* | ||
1723 | * BIOS uses legacy mode, but UV2 hardware always | ||
1724 | * uses native mode for selective broadcasts. | ||
1725 | */ | ||
1702 | uv2_hdr = &bd2->header.uv2_hdr; | 1726 | uv2_hdr = &bd2->header.uv2_hdr; |
1703 | uv2_hdr->swack_flag = 1; | 1727 | uv2_hdr->swack_flag = 1; |
1704 | uv2_hdr->base_dest_nasid = | 1728 | uv2_hdr->base_dest_nasid = |
@@ -1811,8 +1835,8 @@ static int calculate_destination_timeout(void) | |||
1811 | index = (mmr_image >> BAU_URGENCY_7_SHIFT) & BAU_URGENCY_7_MASK; | 1835 | index = (mmr_image >> BAU_URGENCY_7_SHIFT) & BAU_URGENCY_7_MASK; |
1812 | mmr_image = uv_read_local_mmr(UVH_TRANSACTION_TIMEOUT); | 1836 | mmr_image = uv_read_local_mmr(UVH_TRANSACTION_TIMEOUT); |
1813 | mult2 = (mmr_image >> BAU_TRANS_SHIFT) & BAU_TRANS_MASK; | 1837 | mult2 = (mmr_image >> BAU_TRANS_SHIFT) & BAU_TRANS_MASK; |
1814 | base = timeout_base_ns[index]; | 1838 | ts_ns = timeout_base_ns[index]; |
1815 | ts_ns = base * mult1 * mult2; | 1839 | ts_ns *= (mult1 * mult2); |
1816 | ret = ts_ns / 1000; | 1840 | ret = ts_ns / 1000; |
1817 | } else { | 1841 | } else { |
1818 | /* 4 bits 0/1 for 10/80us base, 3 bits of multiplier */ | 1842 | /* 4 bits 0/1 for 10/80us base, 3 bits of multiplier */ |
@@ -1836,6 +1860,8 @@ static void __init init_per_cpu_tunables(void) | |||
1836 | for_each_present_cpu(cpu) { | 1860 | for_each_present_cpu(cpu) { |
1837 | bcp = &per_cpu(bau_control, cpu); | 1861 | bcp = &per_cpu(bau_control, cpu); |
1838 | bcp->baudisabled = 0; | 1862 | bcp->baudisabled = 0; |
1863 | if (nobau) | ||
1864 | bcp->nobau = 1; | ||
1839 | bcp->statp = &per_cpu(ptcstats, cpu); | 1865 | bcp->statp = &per_cpu(ptcstats, cpu); |
1840 | /* time interval to catch a hardware stay-busy bug */ | 1866 | /* time interval to catch a hardware stay-busy bug */ |
1841 | bcp->timeout_interval = usec_2_cycles(2*timeout_us); | 1867 | bcp->timeout_interval = usec_2_cycles(2*timeout_us); |
@@ -1848,10 +1874,11 @@ static void __init init_per_cpu_tunables(void) | |||
1848 | bcp->complete_threshold = complete_threshold; | 1874 | bcp->complete_threshold = complete_threshold; |
1849 | bcp->cong_response_us = congested_respns_us; | 1875 | bcp->cong_response_us = congested_respns_us; |
1850 | bcp->cong_reps = congested_reps; | 1876 | bcp->cong_reps = congested_reps; |
1851 | bcp->cong_period = congested_period; | 1877 | bcp->disabled_period = sec_2_cycles(disabled_period); |
1852 | bcp->clocks_per_100_usec = usec_2_cycles(100); | 1878 | bcp->giveup_limit = giveup_limit; |
1853 | spin_lock_init(&bcp->queue_lock); | 1879 | spin_lock_init(&bcp->queue_lock); |
1854 | spin_lock_init(&bcp->uvhub_lock); | 1880 | spin_lock_init(&bcp->uvhub_lock); |
1881 | spin_lock_init(&bcp->disable_lock); | ||
1855 | } | 1882 | } |
1856 | } | 1883 | } |
1857 | 1884 | ||
@@ -1972,7 +1999,6 @@ static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp, | |||
1972 | } | 1999 | } |
1973 | bcp->uvhub_master = *hmasterp; | 2000 | bcp->uvhub_master = *hmasterp; |
1974 | bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->blade_processor_id; | 2001 | bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->blade_processor_id; |
1975 | bcp->using_desc = bcp->uvhub_cpu; | ||
1976 | if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) { | 2002 | if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) { |
1977 | printk(KERN_EMERG "%d cpus per uvhub invalid\n", | 2003 | printk(KERN_EMERG "%d cpus per uvhub invalid\n", |
1978 | bcp->uvhub_cpu); | 2004 | bcp->uvhub_cpu); |
@@ -2069,16 +2095,12 @@ static int __init uv_bau_init(void) | |||
2069 | if (!is_uv_system()) | 2095 | if (!is_uv_system()) |
2070 | return 0; | 2096 | return 0; |
2071 | 2097 | ||
2072 | if (nobau) | ||
2073 | return 0; | ||
2074 | |||
2075 | for_each_possible_cpu(cur_cpu) { | 2098 | for_each_possible_cpu(cur_cpu) { |
2076 | mask = &per_cpu(uv_flush_tlb_mask, cur_cpu); | 2099 | mask = &per_cpu(uv_flush_tlb_mask, cur_cpu); |
2077 | zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu)); | 2100 | zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu)); |
2078 | } | 2101 | } |
2079 | 2102 | ||
2080 | nuvhubs = uv_num_possible_blades(); | 2103 | nuvhubs = uv_num_possible_blades(); |
2081 | spin_lock_init(&disable_lock); | ||
2082 | congested_cycles = usec_2_cycles(congested_respns_us); | 2104 | congested_cycles = usec_2_cycles(congested_respns_us); |
2083 | 2105 | ||
2084 | uv_base_pnode = 0x7fffffff; | 2106 | uv_base_pnode = 0x7fffffff; |
@@ -2091,7 +2113,8 @@ static int __init uv_bau_init(void) | |||
2091 | enable_timeouts(); | 2113 | enable_timeouts(); |
2092 | 2114 | ||
2093 | if (init_per_cpu(nuvhubs, uv_base_pnode)) { | 2115 | if (init_per_cpu(nuvhubs, uv_base_pnode)) { |
2094 | nobau = 1; | 2116 | set_bau_off(); |
2117 | nobau_perm = 1; | ||
2095 | return 0; | 2118 | return 0; |
2096 | } | 2119 | } |
2097 | 2120 | ||
diff --git a/arch/x86/platform/uv/uv_irq.c b/arch/x86/platform/uv/uv_irq.c index f25c2765a5c9..acf7752da952 100644 --- a/arch/x86/platform/uv/uv_irq.c +++ b/arch/x86/platform/uv/uv_irq.c | |||
@@ -135,6 +135,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, | |||
135 | unsigned long mmr_value; | 135 | unsigned long mmr_value; |
136 | struct uv_IO_APIC_route_entry *entry; | 136 | struct uv_IO_APIC_route_entry *entry; |
137 | int mmr_pnode, err; | 137 | int mmr_pnode, err; |
138 | unsigned int dest; | ||
138 | 139 | ||
139 | BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != | 140 | BUILD_BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != |
140 | sizeof(unsigned long)); | 141 | sizeof(unsigned long)); |
@@ -143,6 +144,10 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, | |||
143 | if (err != 0) | 144 | if (err != 0) |
144 | return err; | 145 | return err; |
145 | 146 | ||
147 | err = apic->cpu_mask_to_apicid_and(eligible_cpu, eligible_cpu, &dest); | ||
148 | if (err != 0) | ||
149 | return err; | ||
150 | |||
146 | if (limit == UV_AFFINITY_CPU) | 151 | if (limit == UV_AFFINITY_CPU) |
147 | irq_set_status_flags(irq, IRQ_NO_BALANCING); | 152 | irq_set_status_flags(irq, IRQ_NO_BALANCING); |
148 | else | 153 | else |
@@ -159,7 +164,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, | |||
159 | entry->polarity = 0; | 164 | entry->polarity = 0; |
160 | entry->trigger = 0; | 165 | entry->trigger = 0; |
161 | entry->mask = 0; | 166 | entry->mask = 0; |
162 | entry->dest = apic->cpu_mask_to_apicid(eligible_cpu); | 167 | entry->dest = dest; |
163 | 168 | ||
164 | mmr_pnode = uv_blade_to_pnode(mmr_blade); | 169 | mmr_pnode = uv_blade_to_pnode(mmr_blade); |
165 | uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); | 170 | uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value); |
@@ -222,7 +227,7 @@ uv_set_irq_affinity(struct irq_data *data, const struct cpumask *mask, | |||
222 | if (cfg->move_in_progress) | 227 | if (cfg->move_in_progress) |
223 | send_cleanup_vector(cfg); | 228 | send_cleanup_vector(cfg); |
224 | 229 | ||
225 | return 0; | 230 | return IRQ_SET_MASK_OK_NOCOPY; |
226 | } | 231 | } |
227 | 232 | ||
228 | /* | 233 | /* |
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile index 5b84a2d30888..b2d534cab25f 100644 --- a/arch/x86/realmode/rm/Makefile +++ b/arch/x86/realmode/rm/Makefile | |||
@@ -22,7 +22,7 @@ wakeup-objs += video-bios.o | |||
22 | realmode-y += header.o | 22 | realmode-y += header.o |
23 | realmode-y += trampoline_$(BITS).o | 23 | realmode-y += trampoline_$(BITS).o |
24 | realmode-y += stack.o | 24 | realmode-y += stack.o |
25 | realmode-$(CONFIG_X86_32) += reboot_32.o | 25 | realmode-y += reboot.o |
26 | realmode-$(CONFIG_ACPI_SLEEP) += $(wakeup-objs) | 26 | realmode-$(CONFIG_ACPI_SLEEP) += $(wakeup-objs) |
27 | 27 | ||
28 | targets += $(realmode-y) | 28 | targets += $(realmode-y) |
diff --git a/arch/x86/realmode/rm/header.S b/arch/x86/realmode/rm/header.S index fadf48378ada..a28221d94e69 100644 --- a/arch/x86/realmode/rm/header.S +++ b/arch/x86/realmode/rm/header.S | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | #include <linux/linkage.h> | 7 | #include <linux/linkage.h> |
8 | #include <asm/page_types.h> | 8 | #include <asm/page_types.h> |
9 | #include <asm/segment.h> | ||
9 | 10 | ||
10 | #include "realmode.h" | 11 | #include "realmode.h" |
11 | 12 | ||
@@ -28,8 +29,9 @@ GLOBAL(real_mode_header) | |||
28 | .long pa_wakeup_header | 29 | .long pa_wakeup_header |
29 | #endif | 30 | #endif |
30 | /* APM/BIOS reboot */ | 31 | /* APM/BIOS reboot */ |
31 | #ifdef CONFIG_X86_32 | ||
32 | .long pa_machine_real_restart_asm | 32 | .long pa_machine_real_restart_asm |
33 | #ifdef CONFIG_X86_64 | ||
34 | .long __KERNEL32_CS | ||
33 | #endif | 35 | #endif |
34 | END(real_mode_header) | 36 | END(real_mode_header) |
35 | 37 | ||
diff --git a/arch/x86/realmode/rm/reboot_32.S b/arch/x86/realmode/rm/reboot.S index 114044876b3d..f932ea61d1c8 100644 --- a/arch/x86/realmode/rm/reboot_32.S +++ b/arch/x86/realmode/rm/reboot.S | |||
@@ -2,6 +2,8 @@ | |||
2 | #include <linux/init.h> | 2 | #include <linux/init.h> |
3 | #include <asm/segment.h> | 3 | #include <asm/segment.h> |
4 | #include <asm/page_types.h> | 4 | #include <asm/page_types.h> |
5 | #include <asm/processor-flags.h> | ||
6 | #include <asm/msr-index.h> | ||
5 | #include "realmode.h" | 7 | #include "realmode.h" |
6 | 8 | ||
7 | /* | 9 | /* |
@@ -12,13 +14,35 @@ | |||
12 | * doesn't work with at least one type of 486 motherboard. It is easy | 14 | * doesn't work with at least one type of 486 motherboard. It is easy |
13 | * to stop this code working; hence the copious comments. | 15 | * to stop this code working; hence the copious comments. |
14 | * | 16 | * |
15 | * This code is called with the restart type (0 = BIOS, 1 = APM) in %eax. | 17 | * This code is called with the restart type (0 = BIOS, 1 = APM) in |
18 | * the primary argument register (%eax for 32 bit, %edi for 64 bit). | ||
16 | */ | 19 | */ |
17 | .section ".text32", "ax" | 20 | .section ".text32", "ax" |
18 | .code32 | 21 | .code32 |
19 | |||
20 | .balign 16 | ||
21 | ENTRY(machine_real_restart_asm) | 22 | ENTRY(machine_real_restart_asm) |
23 | |||
24 | #ifdef CONFIG_X86_64 | ||
25 | /* Switch to trampoline GDT as it is guaranteed < 4 GiB */ | ||
26 | movl $__KERNEL_DS, %eax | ||
27 | movl %eax, %ds | ||
28 | lgdtl pa_tr_gdt | ||
29 | |||
30 | /* Disable paging to drop us out of long mode */ | ||
31 | movl %cr0, %eax | ||
32 | andl $~X86_CR0_PG, %eax | ||
33 | movl %eax, %cr0 | ||
34 | ljmpl $__KERNEL32_CS, $pa_machine_real_restart_paging_off | ||
35 | |||
36 | GLOBAL(machine_real_restart_paging_off) | ||
37 | xorl %eax, %eax | ||
38 | xorl %edx, %edx | ||
39 | movl $MSR_EFER, %ecx | ||
40 | wrmsr | ||
41 | |||
42 | movl %edi, %eax | ||
43 | |||
44 | #endif /* CONFIG_X86_64 */ | ||
45 | |||
22 | /* Set up the IDT for real mode. */ | 46 | /* Set up the IDT for real mode. */ |
23 | lidtl pa_machine_real_restart_idt | 47 | lidtl pa_machine_real_restart_idt |
24 | 48 | ||
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c index 66e6d9359826..0faad646f5fd 100644 --- a/arch/x86/vdso/vdso32-setup.c +++ b/arch/x86/vdso/vdso32-setup.c | |||
@@ -205,9 +205,9 @@ void syscall32_cpu_init(void) | |||
205 | { | 205 | { |
206 | /* Load these always in case some future AMD CPU supports | 206 | /* Load these always in case some future AMD CPU supports |
207 | SYSENTER from compat mode too. */ | 207 | SYSENTER from compat mode too. */ |
208 | checking_wrmsrl(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); | 208 | wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS); |
209 | checking_wrmsrl(MSR_IA32_SYSENTER_ESP, 0ULL); | 209 | wrmsrl_safe(MSR_IA32_SYSENTER_ESP, 0ULL); |
210 | checking_wrmsrl(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target); | 210 | wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)ia32_sysenter_target); |
211 | 211 | ||
212 | wrmsrl(MSR_CSTAR, ia32_cstar_target); | 212 | wrmsrl(MSR_CSTAR, ia32_cstar_target); |
213 | } | 213 | } |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index ff962d4b821e..ed7d54985d0c 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1124,9 +1124,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { | |||
1124 | .wbinvd = native_wbinvd, | 1124 | .wbinvd = native_wbinvd, |
1125 | 1125 | ||
1126 | .read_msr = native_read_msr_safe, | 1126 | .read_msr = native_read_msr_safe, |
1127 | .rdmsr_regs = native_rdmsr_safe_regs, | ||
1128 | .write_msr = xen_write_msr_safe, | 1127 | .write_msr = xen_write_msr_safe, |
1129 | .wrmsr_regs = native_wrmsr_safe_regs, | ||
1130 | 1128 | ||
1131 | .read_tsc = native_read_tsc, | 1129 | .read_tsc = native_read_tsc, |
1132 | .read_pmc = native_read_pmc, | 1130 | .read_pmc = native_read_pmc, |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index afb250d22a6b..f58dca7a6e52 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -80,9 +80,7 @@ static void __cpuinit cpu_bringup(void) | |||
80 | 80 | ||
81 | notify_cpu_starting(cpu); | 81 | notify_cpu_starting(cpu); |
82 | 82 | ||
83 | ipi_call_lock(); | ||
84 | set_cpu_online(cpu, true); | 83 | set_cpu_online(cpu, true); |
85 | ipi_call_unlock(); | ||
86 | 84 | ||
87 | this_cpu_write(cpu_state, CPU_ONLINE); | 85 | this_cpu_write(cpu_state, CPU_ONLINE); |
88 | 86 | ||
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index dcb8a6e48692..4b01ab3d2c24 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/wait.h> | 24 | #include <linux/wait.h> |
25 | #include <linux/async.h> | 25 | #include <linux/async.h> |
26 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
27 | #include <scsi/scsi_scan.h> | ||
27 | 28 | ||
28 | #include "base.h" | 29 | #include "base.h" |
29 | #include "power/power.h" | 30 | #include "power/power.h" |
@@ -332,6 +333,7 @@ void wait_for_device_probe(void) | |||
332 | /* wait for the known devices to complete their probing */ | 333 | /* wait for the known devices to complete their probing */ |
333 | wait_event(probe_waitqueue, atomic_read(&probe_count) == 0); | 334 | wait_event(probe_waitqueue, atomic_read(&probe_count) == 0); |
334 | async_synchronize_full(); | 335 | async_synchronize_full(); |
336 | scsi_complete_async_scans(); | ||
335 | } | 337 | } |
336 | EXPORT_SYMBOL_GPL(wait_for_device_probe); | 338 | EXPORT_SYMBOL_GPL(wait_for_device_probe); |
337 | 339 | ||
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 65665c9c42c6..8f428a8ab003 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -499,7 +499,7 @@ static int rbd_header_from_disk(struct rbd_image_header *header, | |||
499 | / sizeof (*ondisk)) | 499 | / sizeof (*ondisk)) |
500 | return -EINVAL; | 500 | return -EINVAL; |
501 | header->snapc = kmalloc(sizeof(struct ceph_snap_context) + | 501 | header->snapc = kmalloc(sizeof(struct ceph_snap_context) + |
502 | snap_count * sizeof (*ondisk), | 502 | snap_count * sizeof(u64), |
503 | gfp_flags); | 503 | gfp_flags); |
504 | if (!header->snapc) | 504 | if (!header->snapc) |
505 | return -ENOMEM; | 505 | return -ENOMEM; |
@@ -977,7 +977,7 @@ static void rbd_req_cb(struct ceph_osd_request *req, struct ceph_msg *msg) | |||
977 | op = (void *)(replyhead + 1); | 977 | op = (void *)(replyhead + 1); |
978 | rc = le32_to_cpu(replyhead->result); | 978 | rc = le32_to_cpu(replyhead->result); |
979 | bytes = le64_to_cpu(op->extent.length); | 979 | bytes = le64_to_cpu(op->extent.length); |
980 | read_op = (le32_to_cpu(op->op) == CEPH_OSD_OP_READ); | 980 | read_op = (le16_to_cpu(op->op) == CEPH_OSD_OP_READ); |
981 | 981 | ||
982 | dout("rbd_req_cb bytes=%lld readop=%d rc=%d\n", bytes, read_op, rc); | 982 | dout("rbd_req_cb bytes=%lld readop=%d rc=%d\n", bytes, read_op, rc); |
983 | 983 | ||
diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index 8f05652d53e6..0fcec2aae19c 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c | |||
@@ -345,31 +345,30 @@ static struct frac_rate_tbl gen_rtbl[] = { | |||
345 | /* clock parents */ | 345 | /* clock parents */ |
346 | static const char *vco_parents[] = { "osc_24m_clk", "osc_25m_clk", }; | 346 | static const char *vco_parents[] = { "osc_24m_clk", "osc_25m_clk", }; |
347 | static const char *gpt_parents[] = { "osc_24m_clk", "apb_clk", }; | 347 | static const char *gpt_parents[] = { "osc_24m_clk", "apb_clk", }; |
348 | static const char *uart0_parents[] = { "pll5_clk", "uart_synth_gate_clk", }; | 348 | static const char *uart0_parents[] = { "pll5_clk", "uart_syn_gclk", }; |
349 | static const char *c3_parents[] = { "pll5_clk", "c3_synth_gate_clk", }; | 349 | static const char *c3_parents[] = { "pll5_clk", "c3_syn_gclk", }; |
350 | static const char *gmac_phy_input_parents[] = { "gmii_125m_pad_clk", "pll2_clk", | 350 | static const char *gmac_phy_input_parents[] = { "gmii_pad_clk", "pll2_clk", |
351 | "osc_25m_clk", }; | 351 | "osc_25m_clk", }; |
352 | static const char *gmac_phy_parents[] = { "gmac_phy_input_mux_clk", | 352 | static const char *gmac_phy_parents[] = { "phy_input_mclk", "phy_syn_gclk", }; |
353 | "gmac_phy_synth_gate_clk", }; | ||
354 | static const char *clcd_synth_parents[] = { "vco1div4_clk", "pll2_clk", }; | 353 | static const char *clcd_synth_parents[] = { "vco1div4_clk", "pll2_clk", }; |
355 | static const char *clcd_pixel_parents[] = { "pll5_clk", "clcd_synth_clk", }; | 354 | static const char *clcd_pixel_parents[] = { "pll5_clk", "clcd_syn_clk", }; |
356 | static const char *i2s_src_parents[] = { "vco1div2_clk", "none", "pll3_clk", | 355 | static const char *i2s_src_parents[] = { "vco1div2_clk", "none", "pll3_clk", |
357 | "i2s_src_pad_clk", }; | 356 | "i2s_src_pad_clk", }; |
358 | static const char *i2s_ref_parents[] = { "i2s_src_mux_clk", "i2s_prs1_clk", }; | 357 | static const char *i2s_ref_parents[] = { "i2s_src_mclk", "i2s_prs1_clk", }; |
359 | static const char *gen_synth0_1_parents[] = { "vco1div4_clk", "vco3div2_clk", | 358 | static const char *gen_synth0_1_parents[] = { "vco1div4_clk", "vco3div2_clk", |
360 | "pll3_clk", }; | 359 | "pll3_clk", }; |
361 | static const char *gen_synth2_3_parents[] = { "vco1div4_clk", "vco3div2_clk", | 360 | static const char *gen_synth2_3_parents[] = { "vco1div4_clk", "vco3div2_clk", |
362 | "pll2_clk", }; | 361 | "pll2_clk", }; |
363 | static const char *rmii_phy_parents[] = { "ras_tx50_clk", "none", | 362 | static const char *rmii_phy_parents[] = { "ras_tx50_clk", "none", |
364 | "ras_pll2_clk", "ras_synth0_clk", }; | 363 | "ras_pll2_clk", "ras_syn0_clk", }; |
365 | static const char *smii_rgmii_phy_parents[] = { "none", "ras_tx125_clk", | 364 | static const char *smii_rgmii_phy_parents[] = { "none", "ras_tx125_clk", |
366 | "ras_pll2_clk", "ras_synth0_clk", }; | 365 | "ras_pll2_clk", "ras_syn0_clk", }; |
367 | static const char *uart_parents[] = { "ras_apb_clk", "gen_synth3_clk", }; | 366 | static const char *uart_parents[] = { "ras_apb_clk", "gen_syn3_clk", }; |
368 | static const char *i2c_parents[] = { "ras_apb_clk", "gen_synth1_clk", }; | 367 | static const char *i2c_parents[] = { "ras_apb_clk", "gen_syn1_clk", }; |
369 | static const char *ssp1_parents[] = { "ras_apb_clk", "gen_synth1_clk", | 368 | static const char *ssp1_parents[] = { "ras_apb_clk", "gen_syn1_clk", |
370 | "ras_plclk0_clk", }; | 369 | "ras_plclk0_clk", }; |
371 | static const char *pci_parents[] = { "ras_pll3_clk", "gen_synth2_clk", }; | 370 | static const char *pci_parents[] = { "ras_pll3_clk", "gen_syn2_clk", }; |
372 | static const char *tdm_parents[] = { "ras_pll3_clk", "gen_synth1_clk", }; | 371 | static const char *tdm_parents[] = { "ras_pll3_clk", "gen_syn1_clk", }; |
373 | 372 | ||
374 | void __init spear1310_clk_init(void) | 373 | void __init spear1310_clk_init(void) |
375 | { | 374 | { |
@@ -390,9 +389,9 @@ void __init spear1310_clk_init(void) | |||
390 | 25000000); | 389 | 25000000); |
391 | clk_register_clkdev(clk, "osc_25m_clk", NULL); | 390 | clk_register_clkdev(clk, "osc_25m_clk", NULL); |
392 | 391 | ||
393 | clk = clk_register_fixed_rate(NULL, "gmii_125m_pad_clk", NULL, | 392 | clk = clk_register_fixed_rate(NULL, "gmii_pad_clk", NULL, CLK_IS_ROOT, |
394 | CLK_IS_ROOT, 125000000); | 393 | 125000000); |
395 | clk_register_clkdev(clk, "gmii_125m_pad_clk", NULL); | 394 | clk_register_clkdev(clk, "gmii_pad_clk", NULL); |
396 | 395 | ||
397 | clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, | 396 | clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, |
398 | CLK_IS_ROOT, 12288000); | 397 | CLK_IS_ROOT, 12288000); |
@@ -406,34 +405,34 @@ void __init spear1310_clk_init(void) | |||
406 | 405 | ||
407 | /* clock derived from 24 or 25 MHz osc clk */ | 406 | /* clock derived from 24 or 25 MHz osc clk */ |
408 | /* vco-pll */ | 407 | /* vco-pll */ |
409 | clk = clk_register_mux(NULL, "vco1_mux_clk", vco_parents, | 408 | clk = clk_register_mux(NULL, "vco1_mclk", vco_parents, |
410 | ARRAY_SIZE(vco_parents), 0, SPEAR1310_PLL_CFG, | 409 | ARRAY_SIZE(vco_parents), 0, SPEAR1310_PLL_CFG, |
411 | SPEAR1310_PLL1_CLK_SHIFT, SPEAR1310_PLL_CLK_MASK, 0, | 410 | SPEAR1310_PLL1_CLK_SHIFT, SPEAR1310_PLL_CLK_MASK, 0, |
412 | &_lock); | 411 | &_lock); |
413 | clk_register_clkdev(clk, "vco1_mux_clk", NULL); | 412 | clk_register_clkdev(clk, "vco1_mclk", NULL); |
414 | clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "vco1_mux_clk", | 413 | clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "vco1_mclk", |
415 | 0, SPEAR1310_PLL1_CTR, SPEAR1310_PLL1_FRQ, pll_rtbl, | 414 | 0, SPEAR1310_PLL1_CTR, SPEAR1310_PLL1_FRQ, pll_rtbl, |
416 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); | 415 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); |
417 | clk_register_clkdev(clk, "vco1_clk", NULL); | 416 | clk_register_clkdev(clk, "vco1_clk", NULL); |
418 | clk_register_clkdev(clk1, "pll1_clk", NULL); | 417 | clk_register_clkdev(clk1, "pll1_clk", NULL); |
419 | 418 | ||
420 | clk = clk_register_mux(NULL, "vco2_mux_clk", vco_parents, | 419 | clk = clk_register_mux(NULL, "vco2_mclk", vco_parents, |
421 | ARRAY_SIZE(vco_parents), 0, SPEAR1310_PLL_CFG, | 420 | ARRAY_SIZE(vco_parents), 0, SPEAR1310_PLL_CFG, |
422 | SPEAR1310_PLL2_CLK_SHIFT, SPEAR1310_PLL_CLK_MASK, 0, | 421 | SPEAR1310_PLL2_CLK_SHIFT, SPEAR1310_PLL_CLK_MASK, 0, |
423 | &_lock); | 422 | &_lock); |
424 | clk_register_clkdev(clk, "vco2_mux_clk", NULL); | 423 | clk_register_clkdev(clk, "vco2_mclk", NULL); |
425 | clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "vco2_mux_clk", | 424 | clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "vco2_mclk", |
426 | 0, SPEAR1310_PLL2_CTR, SPEAR1310_PLL2_FRQ, pll_rtbl, | 425 | 0, SPEAR1310_PLL2_CTR, SPEAR1310_PLL2_FRQ, pll_rtbl, |
427 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); | 426 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); |
428 | clk_register_clkdev(clk, "vco2_clk", NULL); | 427 | clk_register_clkdev(clk, "vco2_clk", NULL); |
429 | clk_register_clkdev(clk1, "pll2_clk", NULL); | 428 | clk_register_clkdev(clk1, "pll2_clk", NULL); |
430 | 429 | ||
431 | clk = clk_register_mux(NULL, "vco3_mux_clk", vco_parents, | 430 | clk = clk_register_mux(NULL, "vco3_mclk", vco_parents, |
432 | ARRAY_SIZE(vco_parents), 0, SPEAR1310_PLL_CFG, | 431 | ARRAY_SIZE(vco_parents), 0, SPEAR1310_PLL_CFG, |
433 | SPEAR1310_PLL3_CLK_SHIFT, SPEAR1310_PLL_CLK_MASK, 0, | 432 | SPEAR1310_PLL3_CLK_SHIFT, SPEAR1310_PLL_CLK_MASK, 0, |
434 | &_lock); | 433 | &_lock); |
435 | clk_register_clkdev(clk, "vco3_mux_clk", NULL); | 434 | clk_register_clkdev(clk, "vco3_mclk", NULL); |
436 | clk = clk_register_vco_pll("vco3_clk", "pll3_clk", NULL, "vco3_mux_clk", | 435 | clk = clk_register_vco_pll("vco3_clk", "pll3_clk", NULL, "vco3_mclk", |
437 | 0, SPEAR1310_PLL3_CTR, SPEAR1310_PLL3_FRQ, pll_rtbl, | 436 | 0, SPEAR1310_PLL3_CTR, SPEAR1310_PLL3_FRQ, pll_rtbl, |
438 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); | 437 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); |
439 | clk_register_clkdev(clk, "vco3_clk", NULL); | 438 | clk_register_clkdev(clk, "vco3_clk", NULL); |
@@ -473,7 +472,7 @@ void __init spear1310_clk_init(void) | |||
473 | /* peripherals */ | 472 | /* peripherals */ |
474 | clk_register_fixed_factor(NULL, "thermal_clk", "osc_24m_clk", 0, 1, | 473 | clk_register_fixed_factor(NULL, "thermal_clk", "osc_24m_clk", 0, 1, |
475 | 128); | 474 | 128); |
476 | clk = clk_register_gate(NULL, "thermal_gate_clk", "thermal_clk", 0, | 475 | clk = clk_register_gate(NULL, "thermal_gclk", "thermal_clk", 0, |
477 | SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_THSENS_CLK_ENB, 0, | 476 | SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_THSENS_CLK_ENB, 0, |
478 | &_lock); | 477 | &_lock); |
479 | clk_register_clkdev(clk, NULL, "spear_thermal"); | 478 | clk_register_clkdev(clk, NULL, "spear_thermal"); |
@@ -500,177 +499,176 @@ void __init spear1310_clk_init(void) | |||
500 | clk_register_clkdev(clk, "apb_clk", NULL); | 499 | clk_register_clkdev(clk, "apb_clk", NULL); |
501 | 500 | ||
502 | /* gpt clocks */ | 501 | /* gpt clocks */ |
503 | clk = clk_register_mux(NULL, "gpt0_mux_clk", gpt_parents, | 502 | clk = clk_register_mux(NULL, "gpt0_mclk", gpt_parents, |
504 | ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG, | 503 | ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG, |
505 | SPEAR1310_GPT0_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0, | 504 | SPEAR1310_GPT0_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0, |
506 | &_lock); | 505 | &_lock); |
507 | clk_register_clkdev(clk, "gpt0_mux_clk", NULL); | 506 | clk_register_clkdev(clk, "gpt0_mclk", NULL); |
508 | clk = clk_register_gate(NULL, "gpt0_clk", "gpt0_mux_clk", 0, | 507 | clk = clk_register_gate(NULL, "gpt0_clk", "gpt0_mclk", 0, |
509 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_GPT0_CLK_ENB, 0, | 508 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_GPT0_CLK_ENB, 0, |
510 | &_lock); | 509 | &_lock); |
511 | clk_register_clkdev(clk, NULL, "gpt0"); | 510 | clk_register_clkdev(clk, NULL, "gpt0"); |
512 | 511 | ||
513 | clk = clk_register_mux(NULL, "gpt1_mux_clk", gpt_parents, | 512 | clk = clk_register_mux(NULL, "gpt1_mclk", gpt_parents, |
514 | ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG, | 513 | ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG, |
515 | SPEAR1310_GPT1_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0, | 514 | SPEAR1310_GPT1_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0, |
516 | &_lock); | 515 | &_lock); |
517 | clk_register_clkdev(clk, "gpt1_mux_clk", NULL); | 516 | clk_register_clkdev(clk, "gpt1_mclk", NULL); |
518 | clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mux_clk", 0, | 517 | clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0, |
519 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_GPT1_CLK_ENB, 0, | 518 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_GPT1_CLK_ENB, 0, |
520 | &_lock); | 519 | &_lock); |
521 | clk_register_clkdev(clk, NULL, "gpt1"); | 520 | clk_register_clkdev(clk, NULL, "gpt1"); |
522 | 521 | ||
523 | clk = clk_register_mux(NULL, "gpt2_mux_clk", gpt_parents, | 522 | clk = clk_register_mux(NULL, "gpt2_mclk", gpt_parents, |
524 | ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG, | 523 | ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG, |
525 | SPEAR1310_GPT2_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0, | 524 | SPEAR1310_GPT2_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0, |
526 | &_lock); | 525 | &_lock); |
527 | clk_register_clkdev(clk, "gpt2_mux_clk", NULL); | 526 | clk_register_clkdev(clk, "gpt2_mclk", NULL); |
528 | clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mux_clk", 0, | 527 | clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0, |
529 | SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_GPT2_CLK_ENB, 0, | 528 | SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_GPT2_CLK_ENB, 0, |
530 | &_lock); | 529 | &_lock); |
531 | clk_register_clkdev(clk, NULL, "gpt2"); | 530 | clk_register_clkdev(clk, NULL, "gpt2"); |
532 | 531 | ||
533 | clk = clk_register_mux(NULL, "gpt3_mux_clk", gpt_parents, | 532 | clk = clk_register_mux(NULL, "gpt3_mclk", gpt_parents, |
534 | ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG, | 533 | ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG, |
535 | SPEAR1310_GPT3_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0, | 534 | SPEAR1310_GPT3_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0, |
536 | &_lock); | 535 | &_lock); |
537 | clk_register_clkdev(clk, "gpt3_mux_clk", NULL); | 536 | clk_register_clkdev(clk, "gpt3_mclk", NULL); |
538 | clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mux_clk", 0, | 537 | clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mclk", 0, |
539 | SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_GPT3_CLK_ENB, 0, | 538 | SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_GPT3_CLK_ENB, 0, |
540 | &_lock); | 539 | &_lock); |
541 | clk_register_clkdev(clk, NULL, "gpt3"); | 540 | clk_register_clkdev(clk, NULL, "gpt3"); |
542 | 541 | ||
543 | /* others */ | 542 | /* others */ |
544 | clk = clk_register_aux("uart_synth_clk", "uart_synth_gate_clk", | 543 | clk = clk_register_aux("uart_syn_clk", "uart_syn_gclk", "vco1div2_clk", |
545 | "vco1div2_clk", 0, SPEAR1310_UART_CLK_SYNT, NULL, | 544 | 0, SPEAR1310_UART_CLK_SYNT, NULL, aux_rtbl, |
546 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 545 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); |
547 | clk_register_clkdev(clk, "uart_synth_clk", NULL); | 546 | clk_register_clkdev(clk, "uart_syn_clk", NULL); |
548 | clk_register_clkdev(clk1, "uart_synth_gate_clk", NULL); | 547 | clk_register_clkdev(clk1, "uart_syn_gclk", NULL); |
549 | 548 | ||
550 | clk = clk_register_mux(NULL, "uart0_mux_clk", uart0_parents, | 549 | clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents, |
551 | ARRAY_SIZE(uart0_parents), 0, SPEAR1310_PERIP_CLK_CFG, | 550 | ARRAY_SIZE(uart0_parents), 0, SPEAR1310_PERIP_CLK_CFG, |
552 | SPEAR1310_UART_CLK_SHIFT, SPEAR1310_UART_CLK_MASK, 0, | 551 | SPEAR1310_UART_CLK_SHIFT, SPEAR1310_UART_CLK_MASK, 0, |
553 | &_lock); | 552 | &_lock); |
554 | clk_register_clkdev(clk, "uart0_mux_clk", NULL); | 553 | clk_register_clkdev(clk, "uart0_mclk", NULL); |
555 | 554 | ||
556 | clk = clk_register_gate(NULL, "uart0_clk", "uart0_mux_clk", 0, | 555 | clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", 0, |
557 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UART_CLK_ENB, 0, | 556 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UART_CLK_ENB, 0, |
558 | &_lock); | 557 | &_lock); |
559 | clk_register_clkdev(clk, NULL, "e0000000.serial"); | 558 | clk_register_clkdev(clk, NULL, "e0000000.serial"); |
560 | 559 | ||
561 | clk = clk_register_aux("sdhci_synth_clk", "sdhci_synth_gate_clk", | 560 | clk = clk_register_aux("sdhci_syn_clk", "sdhci_syn_gclk", |
562 | "vco1div2_clk", 0, SPEAR1310_SDHCI_CLK_SYNT, NULL, | 561 | "vco1div2_clk", 0, SPEAR1310_SDHCI_CLK_SYNT, NULL, |
563 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 562 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); |
564 | clk_register_clkdev(clk, "sdhci_synth_clk", NULL); | 563 | clk_register_clkdev(clk, "sdhci_syn_clk", NULL); |
565 | clk_register_clkdev(clk1, "sdhci_synth_gate_clk", NULL); | 564 | clk_register_clkdev(clk1, "sdhci_syn_gclk", NULL); |
566 | 565 | ||
567 | clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_synth_gate_clk", 0, | 566 | clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", 0, |
568 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_SDHCI_CLK_ENB, 0, | 567 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_SDHCI_CLK_ENB, 0, |
569 | &_lock); | 568 | &_lock); |
570 | clk_register_clkdev(clk, NULL, "b3000000.sdhci"); | 569 | clk_register_clkdev(clk, NULL, "b3000000.sdhci"); |
571 | 570 | ||
572 | clk = clk_register_aux("cfxd_synth_clk", "cfxd_synth_gate_clk", | 571 | clk = clk_register_aux("cfxd_syn_clk", "cfxd_syn_gclk", "vco1div2_clk", |
573 | "vco1div2_clk", 0, SPEAR1310_CFXD_CLK_SYNT, NULL, | 572 | 0, SPEAR1310_CFXD_CLK_SYNT, NULL, aux_rtbl, |
574 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 573 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); |
575 | clk_register_clkdev(clk, "cfxd_synth_clk", NULL); | 574 | clk_register_clkdev(clk, "cfxd_syn_clk", NULL); |
576 | clk_register_clkdev(clk1, "cfxd_synth_gate_clk", NULL); | 575 | clk_register_clkdev(clk1, "cfxd_syn_gclk", NULL); |
577 | 576 | ||
578 | clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_synth_gate_clk", 0, | 577 | clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", 0, |
579 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CFXD_CLK_ENB, 0, | 578 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CFXD_CLK_ENB, 0, |
580 | &_lock); | 579 | &_lock); |
581 | clk_register_clkdev(clk, NULL, "b2800000.cf"); | 580 | clk_register_clkdev(clk, NULL, "b2800000.cf"); |
582 | clk_register_clkdev(clk, NULL, "arasan_xd"); | 581 | clk_register_clkdev(clk, NULL, "arasan_xd"); |
583 | 582 | ||
584 | clk = clk_register_aux("c3_synth_clk", "c3_synth_gate_clk", | 583 | clk = clk_register_aux("c3_syn_clk", "c3_syn_gclk", "vco1div2_clk", |
585 | "vco1div2_clk", 0, SPEAR1310_C3_CLK_SYNT, NULL, | 584 | 0, SPEAR1310_C3_CLK_SYNT, NULL, aux_rtbl, |
586 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 585 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); |
587 | clk_register_clkdev(clk, "c3_synth_clk", NULL); | 586 | clk_register_clkdev(clk, "c3_syn_clk", NULL); |
588 | clk_register_clkdev(clk1, "c3_synth_gate_clk", NULL); | 587 | clk_register_clkdev(clk1, "c3_syn_gclk", NULL); |
589 | 588 | ||
590 | clk = clk_register_mux(NULL, "c3_mux_clk", c3_parents, | 589 | clk = clk_register_mux(NULL, "c3_mclk", c3_parents, |
591 | ARRAY_SIZE(c3_parents), 0, SPEAR1310_PERIP_CLK_CFG, | 590 | ARRAY_SIZE(c3_parents), 0, SPEAR1310_PERIP_CLK_CFG, |
592 | SPEAR1310_C3_CLK_SHIFT, SPEAR1310_C3_CLK_MASK, 0, | 591 | SPEAR1310_C3_CLK_SHIFT, SPEAR1310_C3_CLK_MASK, 0, |
593 | &_lock); | 592 | &_lock); |
594 | clk_register_clkdev(clk, "c3_mux_clk", NULL); | 593 | clk_register_clkdev(clk, "c3_mclk", NULL); |
595 | 594 | ||
596 | clk = clk_register_gate(NULL, "c3_clk", "c3_mux_clk", 0, | 595 | clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", 0, |
597 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_C3_CLK_ENB, 0, | 596 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_C3_CLK_ENB, 0, |
598 | &_lock); | 597 | &_lock); |
599 | clk_register_clkdev(clk, NULL, "c3"); | 598 | clk_register_clkdev(clk, NULL, "c3"); |
600 | 599 | ||
601 | /* gmac */ | 600 | /* gmac */ |
602 | clk = clk_register_mux(NULL, "gmac_phy_input_mux_clk", | 601 | clk = clk_register_mux(NULL, "phy_input_mclk", gmac_phy_input_parents, |
603 | gmac_phy_input_parents, | ||
604 | ARRAY_SIZE(gmac_phy_input_parents), 0, | 602 | ARRAY_SIZE(gmac_phy_input_parents), 0, |
605 | SPEAR1310_GMAC_CLK_CFG, | 603 | SPEAR1310_GMAC_CLK_CFG, |
606 | SPEAR1310_GMAC_PHY_INPUT_CLK_SHIFT, | 604 | SPEAR1310_GMAC_PHY_INPUT_CLK_SHIFT, |
607 | SPEAR1310_GMAC_PHY_INPUT_CLK_MASK, 0, &_lock); | 605 | SPEAR1310_GMAC_PHY_INPUT_CLK_MASK, 0, &_lock); |
608 | clk_register_clkdev(clk, "gmac_phy_input_mux_clk", NULL); | 606 | clk_register_clkdev(clk, "phy_input_mclk", NULL); |
609 | 607 | ||
610 | clk = clk_register_aux("gmac_phy_synth_clk", "gmac_phy_synth_gate_clk", | 608 | clk = clk_register_aux("phy_syn_clk", "phy_syn_gclk", "phy_input_mclk", |
611 | "gmac_phy_input_mux_clk", 0, SPEAR1310_GMAC_CLK_SYNT, | 609 | 0, SPEAR1310_GMAC_CLK_SYNT, NULL, gmac_rtbl, |
612 | NULL, gmac_rtbl, ARRAY_SIZE(gmac_rtbl), &_lock, &clk1); | 610 | ARRAY_SIZE(gmac_rtbl), &_lock, &clk1); |
613 | clk_register_clkdev(clk, "gmac_phy_synth_clk", NULL); | 611 | clk_register_clkdev(clk, "phy_syn_clk", NULL); |
614 | clk_register_clkdev(clk1, "gmac_phy_synth_gate_clk", NULL); | 612 | clk_register_clkdev(clk1, "phy_syn_gclk", NULL); |
615 | 613 | ||
616 | clk = clk_register_mux(NULL, "gmac_phy_mux_clk", gmac_phy_parents, | 614 | clk = clk_register_mux(NULL, "phy_mclk", gmac_phy_parents, |
617 | ARRAY_SIZE(gmac_phy_parents), 0, | 615 | ARRAY_SIZE(gmac_phy_parents), 0, |
618 | SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GMAC_PHY_CLK_SHIFT, | 616 | SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GMAC_PHY_CLK_SHIFT, |
619 | SPEAR1310_GMAC_PHY_CLK_MASK, 0, &_lock); | 617 | SPEAR1310_GMAC_PHY_CLK_MASK, 0, &_lock); |
620 | clk_register_clkdev(clk, NULL, "stmmacphy.0"); | 618 | clk_register_clkdev(clk, NULL, "stmmacphy.0"); |
621 | 619 | ||
622 | /* clcd */ | 620 | /* clcd */ |
623 | clk = clk_register_mux(NULL, "clcd_synth_mux_clk", clcd_synth_parents, | 621 | clk = clk_register_mux(NULL, "clcd_syn_mclk", clcd_synth_parents, |
624 | ARRAY_SIZE(clcd_synth_parents), 0, | 622 | ARRAY_SIZE(clcd_synth_parents), 0, |
625 | SPEAR1310_CLCD_CLK_SYNT, SPEAR1310_CLCD_SYNT_CLK_SHIFT, | 623 | SPEAR1310_CLCD_CLK_SYNT, SPEAR1310_CLCD_SYNT_CLK_SHIFT, |
626 | SPEAR1310_CLCD_SYNT_CLK_MASK, 0, &_lock); | 624 | SPEAR1310_CLCD_SYNT_CLK_MASK, 0, &_lock); |
627 | clk_register_clkdev(clk, "clcd_synth_mux_clk", NULL); | 625 | clk_register_clkdev(clk, "clcd_syn_mclk", NULL); |
628 | 626 | ||
629 | clk = clk_register_frac("clcd_synth_clk", "clcd_synth_mux_clk", 0, | 627 | clk = clk_register_frac("clcd_syn_clk", "clcd_syn_mclk", 0, |
630 | SPEAR1310_CLCD_CLK_SYNT, clcd_rtbl, | 628 | SPEAR1310_CLCD_CLK_SYNT, clcd_rtbl, |
631 | ARRAY_SIZE(clcd_rtbl), &_lock); | 629 | ARRAY_SIZE(clcd_rtbl), &_lock); |
632 | clk_register_clkdev(clk, "clcd_synth_clk", NULL); | 630 | clk_register_clkdev(clk, "clcd_syn_clk", NULL); |
633 | 631 | ||
634 | clk = clk_register_mux(NULL, "clcd_pixel_mux_clk", clcd_pixel_parents, | 632 | clk = clk_register_mux(NULL, "clcd_pixel_mclk", clcd_pixel_parents, |
635 | ARRAY_SIZE(clcd_pixel_parents), 0, | 633 | ARRAY_SIZE(clcd_pixel_parents), 0, |
636 | SPEAR1310_PERIP_CLK_CFG, SPEAR1310_CLCD_CLK_SHIFT, | 634 | SPEAR1310_PERIP_CLK_CFG, SPEAR1310_CLCD_CLK_SHIFT, |
637 | SPEAR1310_CLCD_CLK_MASK, 0, &_lock); | 635 | SPEAR1310_CLCD_CLK_MASK, 0, &_lock); |
638 | clk_register_clkdev(clk, "clcd_pixel_clk", NULL); | 636 | clk_register_clkdev(clk, "clcd_pixel_clk", NULL); |
639 | 637 | ||
640 | clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mux_clk", 0, | 638 | clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mclk", 0, |
641 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CLCD_CLK_ENB, 0, | 639 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CLCD_CLK_ENB, 0, |
642 | &_lock); | 640 | &_lock); |
643 | clk_register_clkdev(clk, "clcd_clk", NULL); | 641 | clk_register_clkdev(clk, "clcd_clk", NULL); |
644 | 642 | ||
645 | /* i2s */ | 643 | /* i2s */ |
646 | clk = clk_register_mux(NULL, "i2s_src_mux_clk", i2s_src_parents, | 644 | clk = clk_register_mux(NULL, "i2s_src_mclk", i2s_src_parents, |
647 | ARRAY_SIZE(i2s_src_parents), 0, SPEAR1310_I2S_CLK_CFG, | 645 | ARRAY_SIZE(i2s_src_parents), 0, SPEAR1310_I2S_CLK_CFG, |
648 | SPEAR1310_I2S_SRC_CLK_SHIFT, SPEAR1310_I2S_SRC_CLK_MASK, | 646 | SPEAR1310_I2S_SRC_CLK_SHIFT, SPEAR1310_I2S_SRC_CLK_MASK, |
649 | 0, &_lock); | 647 | 0, &_lock); |
650 | clk_register_clkdev(clk, "i2s_src_clk", NULL); | 648 | clk_register_clkdev(clk, "i2s_src_clk", NULL); |
651 | 649 | ||
652 | clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mux_clk", 0, | 650 | clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", 0, |
653 | SPEAR1310_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl, | 651 | SPEAR1310_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl, |
654 | ARRAY_SIZE(i2s_prs1_rtbl), &_lock, NULL); | 652 | ARRAY_SIZE(i2s_prs1_rtbl), &_lock, NULL); |
655 | clk_register_clkdev(clk, "i2s_prs1_clk", NULL); | 653 | clk_register_clkdev(clk, "i2s_prs1_clk", NULL); |
656 | 654 | ||
657 | clk = clk_register_mux(NULL, "i2s_ref_mux_clk", i2s_ref_parents, | 655 | clk = clk_register_mux(NULL, "i2s_ref_mclk", i2s_ref_parents, |
658 | ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1310_I2S_CLK_CFG, | 656 | ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1310_I2S_CLK_CFG, |
659 | SPEAR1310_I2S_REF_SHIFT, SPEAR1310_I2S_REF_SEL_MASK, 0, | 657 | SPEAR1310_I2S_REF_SHIFT, SPEAR1310_I2S_REF_SEL_MASK, 0, |
660 | &_lock); | 658 | &_lock); |
661 | clk_register_clkdev(clk, "i2s_ref_clk", NULL); | 659 | clk_register_clkdev(clk, "i2s_ref_clk", NULL); |
662 | 660 | ||
663 | clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mux_clk", 0, | 661 | clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mclk", 0, |
664 | SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_I2S_REF_PAD_CLK_ENB, | 662 | SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_I2S_REF_PAD_CLK_ENB, |
665 | 0, &_lock); | 663 | 0, &_lock); |
666 | clk_register_clkdev(clk, "i2s_ref_pad_clk", NULL); | 664 | clk_register_clkdev(clk, "i2s_ref_pad_clk", NULL); |
667 | 665 | ||
668 | clk = clk_register_aux("i2s_sclk_clk", "i2s_sclk_gate_clk", | 666 | clk = clk_register_aux("i2s_sclk_clk", "i2s_sclk_gclk", |
669 | "i2s_ref_pad_clk", 0, SPEAR1310_I2S_CLK_CFG, | 667 | "i2s_ref_pad_clk", 0, SPEAR1310_I2S_CLK_CFG, |
670 | &i2s_sclk_masks, i2s_sclk_rtbl, | 668 | &i2s_sclk_masks, i2s_sclk_rtbl, |
671 | ARRAY_SIZE(i2s_sclk_rtbl), &_lock, &clk1); | 669 | ARRAY_SIZE(i2s_sclk_rtbl), &_lock, &clk1); |
672 | clk_register_clkdev(clk, "i2s_sclk_clk", NULL); | 670 | clk_register_clkdev(clk, "i2s_sclk_clk", NULL); |
673 | clk_register_clkdev(clk1, "i2s_sclk_gate_clk", NULL); | 671 | clk_register_clkdev(clk1, "i2s_sclk_gclk", NULL); |
674 | 672 | ||
675 | /* clock derived from ahb clk */ | 673 | /* clock derived from ahb clk */ |
676 | clk = clk_register_gate(NULL, "i2c0_clk", "ahb_clk", 0, | 674 | clk = clk_register_gate(NULL, "i2c0_clk", "ahb_clk", 0, |
@@ -747,13 +745,13 @@ void __init spear1310_clk_init(void) | |||
747 | &_lock); | 745 | &_lock); |
748 | clk_register_clkdev(clk, "sysram1_clk", NULL); | 746 | clk_register_clkdev(clk, "sysram1_clk", NULL); |
749 | 747 | ||
750 | clk = clk_register_aux("adc_synth_clk", "adc_synth_gate_clk", "ahb_clk", | 748 | clk = clk_register_aux("adc_syn_clk", "adc_syn_gclk", "ahb_clk", |
751 | 0, SPEAR1310_ADC_CLK_SYNT, NULL, adc_rtbl, | 749 | 0, SPEAR1310_ADC_CLK_SYNT, NULL, adc_rtbl, |
752 | ARRAY_SIZE(adc_rtbl), &_lock, &clk1); | 750 | ARRAY_SIZE(adc_rtbl), &_lock, &clk1); |
753 | clk_register_clkdev(clk, "adc_synth_clk", NULL); | 751 | clk_register_clkdev(clk, "adc_syn_clk", NULL); |
754 | clk_register_clkdev(clk1, "adc_synth_gate_clk", NULL); | 752 | clk_register_clkdev(clk1, "adc_syn_gclk", NULL); |
755 | 753 | ||
756 | clk = clk_register_gate(NULL, "adc_clk", "adc_synth_gate_clk", 0, | 754 | clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", 0, |
757 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_ADC_CLK_ENB, 0, | 755 | SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_ADC_CLK_ENB, 0, |
758 | &_lock); | 756 | &_lock); |
759 | clk_register_clkdev(clk, NULL, "adc_clk"); | 757 | clk_register_clkdev(clk, NULL, "adc_clk"); |
@@ -790,37 +788,37 @@ void __init spear1310_clk_init(void) | |||
790 | clk_register_clkdev(clk, NULL, "e0300000.kbd"); | 788 | clk_register_clkdev(clk, NULL, "e0300000.kbd"); |
791 | 789 | ||
792 | /* RAS clks */ | 790 | /* RAS clks */ |
793 | clk = clk_register_mux(NULL, "gen_synth0_1_mux_clk", | 791 | clk = clk_register_mux(NULL, "gen_syn0_1_mclk", gen_synth0_1_parents, |
794 | gen_synth0_1_parents, ARRAY_SIZE(gen_synth0_1_parents), | 792 | ARRAY_SIZE(gen_synth0_1_parents), 0, SPEAR1310_PLL_CFG, |
795 | 0, SPEAR1310_PLL_CFG, SPEAR1310_RAS_SYNT0_1_CLK_SHIFT, | 793 | SPEAR1310_RAS_SYNT0_1_CLK_SHIFT, |
796 | SPEAR1310_RAS_SYNT_CLK_MASK, 0, &_lock); | 794 | SPEAR1310_RAS_SYNT_CLK_MASK, 0, &_lock); |
797 | clk_register_clkdev(clk, "gen_synth0_1_clk", NULL); | 795 | clk_register_clkdev(clk, "gen_syn0_1_clk", NULL); |
798 | 796 | ||
799 | clk = clk_register_mux(NULL, "gen_synth2_3_mux_clk", | 797 | clk = clk_register_mux(NULL, "gen_syn2_3_mclk", gen_synth2_3_parents, |
800 | gen_synth2_3_parents, ARRAY_SIZE(gen_synth2_3_parents), | 798 | ARRAY_SIZE(gen_synth2_3_parents), 0, SPEAR1310_PLL_CFG, |
801 | 0, SPEAR1310_PLL_CFG, SPEAR1310_RAS_SYNT2_3_CLK_SHIFT, | 799 | SPEAR1310_RAS_SYNT2_3_CLK_SHIFT, |
802 | SPEAR1310_RAS_SYNT_CLK_MASK, 0, &_lock); | 800 | SPEAR1310_RAS_SYNT_CLK_MASK, 0, &_lock); |
803 | clk_register_clkdev(clk, "gen_synth2_3_clk", NULL); | 801 | clk_register_clkdev(clk, "gen_syn2_3_clk", NULL); |
804 | 802 | ||
805 | clk = clk_register_frac("gen_synth0_clk", "gen_synth0_1_clk", 0, | 803 | clk = clk_register_frac("gen_syn0_clk", "gen_syn0_1_clk", 0, |
806 | SPEAR1310_RAS_CLK_SYNT0, gen_rtbl, ARRAY_SIZE(gen_rtbl), | 804 | SPEAR1310_RAS_CLK_SYNT0, gen_rtbl, ARRAY_SIZE(gen_rtbl), |
807 | &_lock); | 805 | &_lock); |
808 | clk_register_clkdev(clk, "gen_synth0_clk", NULL); | 806 | clk_register_clkdev(clk, "gen_syn0_clk", NULL); |
809 | 807 | ||
810 | clk = clk_register_frac("gen_synth1_clk", "gen_synth0_1_clk", 0, | 808 | clk = clk_register_frac("gen_syn1_clk", "gen_syn0_1_clk", 0, |
811 | SPEAR1310_RAS_CLK_SYNT1, gen_rtbl, ARRAY_SIZE(gen_rtbl), | 809 | SPEAR1310_RAS_CLK_SYNT1, gen_rtbl, ARRAY_SIZE(gen_rtbl), |
812 | &_lock); | 810 | &_lock); |
813 | clk_register_clkdev(clk, "gen_synth1_clk", NULL); | 811 | clk_register_clkdev(clk, "gen_syn1_clk", NULL); |
814 | 812 | ||
815 | clk = clk_register_frac("gen_synth2_clk", "gen_synth2_3_clk", 0, | 813 | clk = clk_register_frac("gen_syn2_clk", "gen_syn2_3_clk", 0, |
816 | SPEAR1310_RAS_CLK_SYNT2, gen_rtbl, ARRAY_SIZE(gen_rtbl), | 814 | SPEAR1310_RAS_CLK_SYNT2, gen_rtbl, ARRAY_SIZE(gen_rtbl), |
817 | &_lock); | 815 | &_lock); |
818 | clk_register_clkdev(clk, "gen_synth2_clk", NULL); | 816 | clk_register_clkdev(clk, "gen_syn2_clk", NULL); |
819 | 817 | ||
820 | clk = clk_register_frac("gen_synth3_clk", "gen_synth2_3_clk", 0, | 818 | clk = clk_register_frac("gen_syn3_clk", "gen_syn2_3_clk", 0, |
821 | SPEAR1310_RAS_CLK_SYNT3, gen_rtbl, ARRAY_SIZE(gen_rtbl), | 819 | SPEAR1310_RAS_CLK_SYNT3, gen_rtbl, ARRAY_SIZE(gen_rtbl), |
822 | &_lock); | 820 | &_lock); |
823 | clk_register_clkdev(clk, "gen_synth3_clk", NULL); | 821 | clk_register_clkdev(clk, "gen_syn3_clk", NULL); |
824 | 822 | ||
825 | clk = clk_register_gate(NULL, "ras_osc_24m_clk", "osc_24m_clk", 0, | 823 | clk = clk_register_gate(NULL, "ras_osc_24m_clk", "osc_24m_clk", 0, |
826 | SPEAR1310_RAS_CLK_ENB, SPEAR1310_OSC_24M_CLK_ENB, 0, | 824 | SPEAR1310_RAS_CLK_ENB, SPEAR1310_OSC_24M_CLK_ENB, 0, |
@@ -847,7 +845,7 @@ void __init spear1310_clk_init(void) | |||
847 | &_lock); | 845 | &_lock); |
848 | clk_register_clkdev(clk, "ras_pll3_clk", NULL); | 846 | clk_register_clkdev(clk, "ras_pll3_clk", NULL); |
849 | 847 | ||
850 | clk = clk_register_gate(NULL, "ras_tx125_clk", "gmii_125m_pad_clk", 0, | 848 | clk = clk_register_gate(NULL, "ras_tx125_clk", "gmii_pad_clk", 0, |
851 | SPEAR1310_RAS_CLK_ENB, SPEAR1310_C125M_PAD_CLK_ENB, 0, | 849 | SPEAR1310_RAS_CLK_ENB, SPEAR1310_C125M_PAD_CLK_ENB, 0, |
852 | &_lock); | 850 | &_lock); |
853 | clk_register_clkdev(clk, "ras_tx125_clk", NULL); | 851 | clk_register_clkdev(clk, "ras_tx125_clk", NULL); |
@@ -912,7 +910,7 @@ void __init spear1310_clk_init(void) | |||
912 | &_lock); | 910 | &_lock); |
913 | clk_register_clkdev(clk, NULL, "5c700000.eth"); | 911 | clk_register_clkdev(clk, NULL, "5c700000.eth"); |
914 | 912 | ||
915 | clk = clk_register_mux(NULL, "smii_rgmii_phy_mux_clk", | 913 | clk = clk_register_mux(NULL, "smii_rgmii_phy_mclk", |
916 | smii_rgmii_phy_parents, | 914 | smii_rgmii_phy_parents, |
917 | ARRAY_SIZE(smii_rgmii_phy_parents), 0, | 915 | ARRAY_SIZE(smii_rgmii_phy_parents), 0, |
918 | SPEAR1310_RAS_CTRL_REG1, | 916 | SPEAR1310_RAS_CTRL_REG1, |
@@ -922,184 +920,184 @@ void __init spear1310_clk_init(void) | |||
922 | clk_register_clkdev(clk, NULL, "stmmacphy.2"); | 920 | clk_register_clkdev(clk, NULL, "stmmacphy.2"); |
923 | clk_register_clkdev(clk, NULL, "stmmacphy.4"); | 921 | clk_register_clkdev(clk, NULL, "stmmacphy.4"); |
924 | 922 | ||
925 | clk = clk_register_mux(NULL, "rmii_phy_mux_clk", rmii_phy_parents, | 923 | clk = clk_register_mux(NULL, "rmii_phy_mclk", rmii_phy_parents, |
926 | ARRAY_SIZE(rmii_phy_parents), 0, | 924 | ARRAY_SIZE(rmii_phy_parents), 0, |
927 | SPEAR1310_RAS_CTRL_REG1, SPEAR1310_RMII_PHY_CLK_SHIFT, | 925 | SPEAR1310_RAS_CTRL_REG1, SPEAR1310_RMII_PHY_CLK_SHIFT, |
928 | SPEAR1310_PHY_CLK_MASK, 0, &_lock); | 926 | SPEAR1310_PHY_CLK_MASK, 0, &_lock); |
929 | clk_register_clkdev(clk, NULL, "stmmacphy.3"); | 927 | clk_register_clkdev(clk, NULL, "stmmacphy.3"); |
930 | 928 | ||
931 | clk = clk_register_mux(NULL, "uart1_mux_clk", uart_parents, | 929 | clk = clk_register_mux(NULL, "uart1_mclk", uart_parents, |
932 | ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 930 | ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
933 | SPEAR1310_UART1_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, | 931 | SPEAR1310_UART1_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, |
934 | 0, &_lock); | 932 | 0, &_lock); |
935 | clk_register_clkdev(clk, "uart1_mux_clk", NULL); | 933 | clk_register_clkdev(clk, "uart1_mclk", NULL); |
936 | 934 | ||
937 | clk = clk_register_gate(NULL, "uart1_clk", "uart1_mux_clk", 0, | 935 | clk = clk_register_gate(NULL, "uart1_clk", "uart1_mclk", 0, |
938 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART1_CLK_ENB, 0, | 936 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART1_CLK_ENB, 0, |
939 | &_lock); | 937 | &_lock); |
940 | clk_register_clkdev(clk, NULL, "5c800000.serial"); | 938 | clk_register_clkdev(clk, NULL, "5c800000.serial"); |
941 | 939 | ||
942 | clk = clk_register_mux(NULL, "uart2_mux_clk", uart_parents, | 940 | clk = clk_register_mux(NULL, "uart2_mclk", uart_parents, |
943 | ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 941 | ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
944 | SPEAR1310_UART2_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, | 942 | SPEAR1310_UART2_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, |
945 | 0, &_lock); | 943 | 0, &_lock); |
946 | clk_register_clkdev(clk, "uart2_mux_clk", NULL); | 944 | clk_register_clkdev(clk, "uart2_mclk", NULL); |
947 | 945 | ||
948 | clk = clk_register_gate(NULL, "uart2_clk", "uart2_mux_clk", 0, | 946 | clk = clk_register_gate(NULL, "uart2_clk", "uart2_mclk", 0, |
949 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART2_CLK_ENB, 0, | 947 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART2_CLK_ENB, 0, |
950 | &_lock); | 948 | &_lock); |
951 | clk_register_clkdev(clk, NULL, "5c900000.serial"); | 949 | clk_register_clkdev(clk, NULL, "5c900000.serial"); |
952 | 950 | ||
953 | clk = clk_register_mux(NULL, "uart3_mux_clk", uart_parents, | 951 | clk = clk_register_mux(NULL, "uart3_mclk", uart_parents, |
954 | ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 952 | ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
955 | SPEAR1310_UART3_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, | 953 | SPEAR1310_UART3_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, |
956 | 0, &_lock); | 954 | 0, &_lock); |
957 | clk_register_clkdev(clk, "uart3_mux_clk", NULL); | 955 | clk_register_clkdev(clk, "uart3_mclk", NULL); |
958 | 956 | ||
959 | clk = clk_register_gate(NULL, "uart3_clk", "uart3_mux_clk", 0, | 957 | clk = clk_register_gate(NULL, "uart3_clk", "uart3_mclk", 0, |
960 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART3_CLK_ENB, 0, | 958 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART3_CLK_ENB, 0, |
961 | &_lock); | 959 | &_lock); |
962 | clk_register_clkdev(clk, NULL, "5ca00000.serial"); | 960 | clk_register_clkdev(clk, NULL, "5ca00000.serial"); |
963 | 961 | ||
964 | clk = clk_register_mux(NULL, "uart4_mux_clk", uart_parents, | 962 | clk = clk_register_mux(NULL, "uart4_mclk", uart_parents, |
965 | ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 963 | ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
966 | SPEAR1310_UART4_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, | 964 | SPEAR1310_UART4_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, |
967 | 0, &_lock); | 965 | 0, &_lock); |
968 | clk_register_clkdev(clk, "uart4_mux_clk", NULL); | 966 | clk_register_clkdev(clk, "uart4_mclk", NULL); |
969 | 967 | ||
970 | clk = clk_register_gate(NULL, "uart4_clk", "uart4_mux_clk", 0, | 968 | clk = clk_register_gate(NULL, "uart4_clk", "uart4_mclk", 0, |
971 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART4_CLK_ENB, 0, | 969 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART4_CLK_ENB, 0, |
972 | &_lock); | 970 | &_lock); |
973 | clk_register_clkdev(clk, NULL, "5cb00000.serial"); | 971 | clk_register_clkdev(clk, NULL, "5cb00000.serial"); |
974 | 972 | ||
975 | clk = clk_register_mux(NULL, "uart5_mux_clk", uart_parents, | 973 | clk = clk_register_mux(NULL, "uart5_mclk", uart_parents, |
976 | ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 974 | ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
977 | SPEAR1310_UART5_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, | 975 | SPEAR1310_UART5_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK, |
978 | 0, &_lock); | 976 | 0, &_lock); |
979 | clk_register_clkdev(clk, "uart5_mux_clk", NULL); | 977 | clk_register_clkdev(clk, "uart5_mclk", NULL); |
980 | 978 | ||
981 | clk = clk_register_gate(NULL, "uart5_clk", "uart5_mux_clk", 0, | 979 | clk = clk_register_gate(NULL, "uart5_clk", "uart5_mclk", 0, |
982 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART5_CLK_ENB, 0, | 980 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_UART5_CLK_ENB, 0, |
983 | &_lock); | 981 | &_lock); |
984 | clk_register_clkdev(clk, NULL, "5cc00000.serial"); | 982 | clk_register_clkdev(clk, NULL, "5cc00000.serial"); |
985 | 983 | ||
986 | clk = clk_register_mux(NULL, "i2c1_mux_clk", i2c_parents, | 984 | clk = clk_register_mux(NULL, "i2c1_mclk", i2c_parents, |
987 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 985 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
988 | SPEAR1310_I2C1_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, | 986 | SPEAR1310_I2C1_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, |
989 | &_lock); | 987 | &_lock); |
990 | clk_register_clkdev(clk, "i2c1_mux_clk", NULL); | 988 | clk_register_clkdev(clk, "i2c1_mclk", NULL); |
991 | 989 | ||
992 | clk = clk_register_gate(NULL, "i2c1_clk", "i2c1_mux_clk", 0, | 990 | clk = clk_register_gate(NULL, "i2c1_clk", "i2c1_mclk", 0, |
993 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C1_CLK_ENB, 0, | 991 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C1_CLK_ENB, 0, |
994 | &_lock); | 992 | &_lock); |
995 | clk_register_clkdev(clk, NULL, "5cd00000.i2c"); | 993 | clk_register_clkdev(clk, NULL, "5cd00000.i2c"); |
996 | 994 | ||
997 | clk = clk_register_mux(NULL, "i2c2_mux_clk", i2c_parents, | 995 | clk = clk_register_mux(NULL, "i2c2_mclk", i2c_parents, |
998 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 996 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
999 | SPEAR1310_I2C2_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, | 997 | SPEAR1310_I2C2_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, |
1000 | &_lock); | 998 | &_lock); |
1001 | clk_register_clkdev(clk, "i2c2_mux_clk", NULL); | 999 | clk_register_clkdev(clk, "i2c2_mclk", NULL); |
1002 | 1000 | ||
1003 | clk = clk_register_gate(NULL, "i2c2_clk", "i2c2_mux_clk", 0, | 1001 | clk = clk_register_gate(NULL, "i2c2_clk", "i2c2_mclk", 0, |
1004 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C2_CLK_ENB, 0, | 1002 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C2_CLK_ENB, 0, |
1005 | &_lock); | 1003 | &_lock); |
1006 | clk_register_clkdev(clk, NULL, "5ce00000.i2c"); | 1004 | clk_register_clkdev(clk, NULL, "5ce00000.i2c"); |
1007 | 1005 | ||
1008 | clk = clk_register_mux(NULL, "i2c3_mux_clk", i2c_parents, | 1006 | clk = clk_register_mux(NULL, "i2c3_mclk", i2c_parents, |
1009 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 1007 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
1010 | SPEAR1310_I2C3_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, | 1008 | SPEAR1310_I2C3_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, |
1011 | &_lock); | 1009 | &_lock); |
1012 | clk_register_clkdev(clk, "i2c3_mux_clk", NULL); | 1010 | clk_register_clkdev(clk, "i2c3_mclk", NULL); |
1013 | 1011 | ||
1014 | clk = clk_register_gate(NULL, "i2c3_clk", "i2c3_mux_clk", 0, | 1012 | clk = clk_register_gate(NULL, "i2c3_clk", "i2c3_mclk", 0, |
1015 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C3_CLK_ENB, 0, | 1013 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C3_CLK_ENB, 0, |
1016 | &_lock); | 1014 | &_lock); |
1017 | clk_register_clkdev(clk, NULL, "5cf00000.i2c"); | 1015 | clk_register_clkdev(clk, NULL, "5cf00000.i2c"); |
1018 | 1016 | ||
1019 | clk = clk_register_mux(NULL, "i2c4_mux_clk", i2c_parents, | 1017 | clk = clk_register_mux(NULL, "i2c4_mclk", i2c_parents, |
1020 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 1018 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
1021 | SPEAR1310_I2C4_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, | 1019 | SPEAR1310_I2C4_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, |
1022 | &_lock); | 1020 | &_lock); |
1023 | clk_register_clkdev(clk, "i2c4_mux_clk", NULL); | 1021 | clk_register_clkdev(clk, "i2c4_mclk", NULL); |
1024 | 1022 | ||
1025 | clk = clk_register_gate(NULL, "i2c4_clk", "i2c4_mux_clk", 0, | 1023 | clk = clk_register_gate(NULL, "i2c4_clk", "i2c4_mclk", 0, |
1026 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C4_CLK_ENB, 0, | 1024 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C4_CLK_ENB, 0, |
1027 | &_lock); | 1025 | &_lock); |
1028 | clk_register_clkdev(clk, NULL, "5d000000.i2c"); | 1026 | clk_register_clkdev(clk, NULL, "5d000000.i2c"); |
1029 | 1027 | ||
1030 | clk = clk_register_mux(NULL, "i2c5_mux_clk", i2c_parents, | 1028 | clk = clk_register_mux(NULL, "i2c5_mclk", i2c_parents, |
1031 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 1029 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
1032 | SPEAR1310_I2C5_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, | 1030 | SPEAR1310_I2C5_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, |
1033 | &_lock); | 1031 | &_lock); |
1034 | clk_register_clkdev(clk, "i2c5_mux_clk", NULL); | 1032 | clk_register_clkdev(clk, "i2c5_mclk", NULL); |
1035 | 1033 | ||
1036 | clk = clk_register_gate(NULL, "i2c5_clk", "i2c5_mux_clk", 0, | 1034 | clk = clk_register_gate(NULL, "i2c5_clk", "i2c5_mclk", 0, |
1037 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C5_CLK_ENB, 0, | 1035 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C5_CLK_ENB, 0, |
1038 | &_lock); | 1036 | &_lock); |
1039 | clk_register_clkdev(clk, NULL, "5d100000.i2c"); | 1037 | clk_register_clkdev(clk, NULL, "5d100000.i2c"); |
1040 | 1038 | ||
1041 | clk = clk_register_mux(NULL, "i2c6_mux_clk", i2c_parents, | 1039 | clk = clk_register_mux(NULL, "i2c6_mclk", i2c_parents, |
1042 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 1040 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
1043 | SPEAR1310_I2C6_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, | 1041 | SPEAR1310_I2C6_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, |
1044 | &_lock); | 1042 | &_lock); |
1045 | clk_register_clkdev(clk, "i2c6_mux_clk", NULL); | 1043 | clk_register_clkdev(clk, "i2c6_mclk", NULL); |
1046 | 1044 | ||
1047 | clk = clk_register_gate(NULL, "i2c6_clk", "i2c6_mux_clk", 0, | 1045 | clk = clk_register_gate(NULL, "i2c6_clk", "i2c6_mclk", 0, |
1048 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C6_CLK_ENB, 0, | 1046 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C6_CLK_ENB, 0, |
1049 | &_lock); | 1047 | &_lock); |
1050 | clk_register_clkdev(clk, NULL, "5d200000.i2c"); | 1048 | clk_register_clkdev(clk, NULL, "5d200000.i2c"); |
1051 | 1049 | ||
1052 | clk = clk_register_mux(NULL, "i2c7_mux_clk", i2c_parents, | 1050 | clk = clk_register_mux(NULL, "i2c7_mclk", i2c_parents, |
1053 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 1051 | ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
1054 | SPEAR1310_I2C7_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, | 1052 | SPEAR1310_I2C7_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0, |
1055 | &_lock); | 1053 | &_lock); |
1056 | clk_register_clkdev(clk, "i2c7_mux_clk", NULL); | 1054 | clk_register_clkdev(clk, "i2c7_mclk", NULL); |
1057 | 1055 | ||
1058 | clk = clk_register_gate(NULL, "i2c7_clk", "i2c7_mux_clk", 0, | 1056 | clk = clk_register_gate(NULL, "i2c7_clk", "i2c7_mclk", 0, |
1059 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C7_CLK_ENB, 0, | 1057 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_I2C7_CLK_ENB, 0, |
1060 | &_lock); | 1058 | &_lock); |
1061 | clk_register_clkdev(clk, NULL, "5d300000.i2c"); | 1059 | clk_register_clkdev(clk, NULL, "5d300000.i2c"); |
1062 | 1060 | ||
1063 | clk = clk_register_mux(NULL, "ssp1_mux_clk", ssp1_parents, | 1061 | clk = clk_register_mux(NULL, "ssp1_mclk", ssp1_parents, |
1064 | ARRAY_SIZE(ssp1_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 1062 | ARRAY_SIZE(ssp1_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
1065 | SPEAR1310_SSP1_CLK_SHIFT, SPEAR1310_SSP1_CLK_MASK, 0, | 1063 | SPEAR1310_SSP1_CLK_SHIFT, SPEAR1310_SSP1_CLK_MASK, 0, |
1066 | &_lock); | 1064 | &_lock); |
1067 | clk_register_clkdev(clk, "ssp1_mux_clk", NULL); | 1065 | clk_register_clkdev(clk, "ssp1_mclk", NULL); |
1068 | 1066 | ||
1069 | clk = clk_register_gate(NULL, "ssp1_clk", "ssp1_mux_clk", 0, | 1067 | clk = clk_register_gate(NULL, "ssp1_clk", "ssp1_mclk", 0, |
1070 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_SSP1_CLK_ENB, 0, | 1068 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_SSP1_CLK_ENB, 0, |
1071 | &_lock); | 1069 | &_lock); |
1072 | clk_register_clkdev(clk, NULL, "5d400000.spi"); | 1070 | clk_register_clkdev(clk, NULL, "5d400000.spi"); |
1073 | 1071 | ||
1074 | clk = clk_register_mux(NULL, "pci_mux_clk", pci_parents, | 1072 | clk = clk_register_mux(NULL, "pci_mclk", pci_parents, |
1075 | ARRAY_SIZE(pci_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 1073 | ARRAY_SIZE(pci_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
1076 | SPEAR1310_PCI_CLK_SHIFT, SPEAR1310_PCI_CLK_MASK, 0, | 1074 | SPEAR1310_PCI_CLK_SHIFT, SPEAR1310_PCI_CLK_MASK, 0, |
1077 | &_lock); | 1075 | &_lock); |
1078 | clk_register_clkdev(clk, "pci_mux_clk", NULL); | 1076 | clk_register_clkdev(clk, "pci_mclk", NULL); |
1079 | 1077 | ||
1080 | clk = clk_register_gate(NULL, "pci_clk", "pci_mux_clk", 0, | 1078 | clk = clk_register_gate(NULL, "pci_clk", "pci_mclk", 0, |
1081 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_PCI_CLK_ENB, 0, | 1079 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_PCI_CLK_ENB, 0, |
1082 | &_lock); | 1080 | &_lock); |
1083 | clk_register_clkdev(clk, NULL, "pci"); | 1081 | clk_register_clkdev(clk, NULL, "pci"); |
1084 | 1082 | ||
1085 | clk = clk_register_mux(NULL, "tdm1_mux_clk", tdm_parents, | 1083 | clk = clk_register_mux(NULL, "tdm1_mclk", tdm_parents, |
1086 | ARRAY_SIZE(tdm_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 1084 | ARRAY_SIZE(tdm_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
1087 | SPEAR1310_TDM1_CLK_SHIFT, SPEAR1310_TDM_CLK_MASK, 0, | 1085 | SPEAR1310_TDM1_CLK_SHIFT, SPEAR1310_TDM_CLK_MASK, 0, |
1088 | &_lock); | 1086 | &_lock); |
1089 | clk_register_clkdev(clk, "tdm1_mux_clk", NULL); | 1087 | clk_register_clkdev(clk, "tdm1_mclk", NULL); |
1090 | 1088 | ||
1091 | clk = clk_register_gate(NULL, "tdm1_clk", "tdm1_mux_clk", 0, | 1089 | clk = clk_register_gate(NULL, "tdm1_clk", "tdm1_mclk", 0, |
1092 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_TDM1_CLK_ENB, 0, | 1090 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_TDM1_CLK_ENB, 0, |
1093 | &_lock); | 1091 | &_lock); |
1094 | clk_register_clkdev(clk, NULL, "tdm_hdlc.0"); | 1092 | clk_register_clkdev(clk, NULL, "tdm_hdlc.0"); |
1095 | 1093 | ||
1096 | clk = clk_register_mux(NULL, "tdm2_mux_clk", tdm_parents, | 1094 | clk = clk_register_mux(NULL, "tdm2_mclk", tdm_parents, |
1097 | ARRAY_SIZE(tdm_parents), 0, SPEAR1310_RAS_CTRL_REG0, | 1095 | ARRAY_SIZE(tdm_parents), 0, SPEAR1310_RAS_CTRL_REG0, |
1098 | SPEAR1310_TDM2_CLK_SHIFT, SPEAR1310_TDM_CLK_MASK, 0, | 1096 | SPEAR1310_TDM2_CLK_SHIFT, SPEAR1310_TDM_CLK_MASK, 0, |
1099 | &_lock); | 1097 | &_lock); |
1100 | clk_register_clkdev(clk, "tdm2_mux_clk", NULL); | 1098 | clk_register_clkdev(clk, "tdm2_mclk", NULL); |
1101 | 1099 | ||
1102 | clk = clk_register_gate(NULL, "tdm2_clk", "tdm2_mux_clk", 0, | 1100 | clk = clk_register_gate(NULL, "tdm2_clk", "tdm2_mclk", 0, |
1103 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_TDM2_CLK_ENB, 0, | 1101 | SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_TDM2_CLK_ENB, 0, |
1104 | &_lock); | 1102 | &_lock); |
1105 | clk_register_clkdev(clk, NULL, "tdm_hdlc.1"); | 1103 | clk_register_clkdev(clk, NULL, "tdm_hdlc.1"); |
diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index e3ea72162236..2352cee7f645 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c | |||
@@ -369,27 +369,25 @@ static struct frac_rate_tbl gen_rtbl[] = { | |||
369 | 369 | ||
370 | /* clock parents */ | 370 | /* clock parents */ |
371 | static const char *vco_parents[] = { "osc_24m_clk", "osc_25m_clk", }; | 371 | static const char *vco_parents[] = { "osc_24m_clk", "osc_25m_clk", }; |
372 | static const char *sys_parents[] = { "none", "pll1_clk", "none", "none", | 372 | static const char *sys_parents[] = { "pll1_clk", "pll1_clk", "pll1_clk", |
373 | "sys_synth_clk", "none", "pll2_clk", "pll3_clk", }; | 373 | "pll1_clk", "sys_synth_clk", "sys_synth_clk", "pll2_clk", "pll3_clk", }; |
374 | static const char *ahb_parents[] = { "cpu_div3_clk", "amba_synth_clk", }; | 374 | static const char *ahb_parents[] = { "cpu_div3_clk", "amba_syn_clk", }; |
375 | static const char *gpt_parents[] = { "osc_24m_clk", "apb_clk", }; | 375 | static const char *gpt_parents[] = { "osc_24m_clk", "apb_clk", }; |
376 | static const char *uart0_parents[] = { "pll5_clk", "osc_24m_clk", | 376 | static const char *uart0_parents[] = { "pll5_clk", "osc_24m_clk", |
377 | "uart0_synth_gate_clk", }; | 377 | "uart0_syn_gclk", }; |
378 | static const char *uart1_parents[] = { "pll5_clk", "osc_24m_clk", | 378 | static const char *uart1_parents[] = { "pll5_clk", "osc_24m_clk", |
379 | "uart1_synth_gate_clk", }; | 379 | "uart1_syn_gclk", }; |
380 | static const char *c3_parents[] = { "pll5_clk", "c3_synth_gate_clk", }; | 380 | static const char *c3_parents[] = { "pll5_clk", "c3_syn_gclk", }; |
381 | static const char *gmac_phy_input_parents[] = { "gmii_125m_pad_clk", "pll2_clk", | 381 | static const char *gmac_phy_input_parents[] = { "gmii_pad_clk", "pll2_clk", |
382 | "osc_25m_clk", }; | 382 | "osc_25m_clk", }; |
383 | static const char *gmac_phy_parents[] = { "gmac_phy_input_mux_clk", | 383 | static const char *gmac_phy_parents[] = { "phy_input_mclk", "phy_syn_gclk", }; |
384 | "gmac_phy_synth_gate_clk", }; | ||
385 | static const char *clcd_synth_parents[] = { "vco1div4_clk", "pll2_clk", }; | 384 | static const char *clcd_synth_parents[] = { "vco1div4_clk", "pll2_clk", }; |
386 | static const char *clcd_pixel_parents[] = { "pll5_clk", "clcd_synth_clk", }; | 385 | static const char *clcd_pixel_parents[] = { "pll5_clk", "clcd_syn_clk", }; |
387 | static const char *i2s_src_parents[] = { "vco1div2_clk", "pll2_clk", "pll3_clk", | 386 | static const char *i2s_src_parents[] = { "vco1div2_clk", "pll2_clk", "pll3_clk", |
388 | "i2s_src_pad_clk", }; | 387 | "i2s_src_pad_clk", }; |
389 | static const char *i2s_ref_parents[] = { "i2s_src_mux_clk", "i2s_prs1_clk", }; | 388 | static const char *i2s_ref_parents[] = { "i2s_src_mclk", "i2s_prs1_clk", }; |
390 | static const char *spdif_out_parents[] = { "i2s_src_pad_clk", "gen_synth2_clk", | 389 | static const char *spdif_out_parents[] = { "i2s_src_pad_clk", "gen_syn2_clk", }; |
391 | }; | 390 | static const char *spdif_in_parents[] = { "pll2_clk", "gen_syn3_clk", }; |
392 | static const char *spdif_in_parents[] = { "pll2_clk", "gen_synth3_clk", }; | ||
393 | 391 | ||
394 | static const char *gen_synth0_1_parents[] = { "vco1div4_clk", "vco3div2_clk", | 392 | static const char *gen_synth0_1_parents[] = { "vco1div4_clk", "vco3div2_clk", |
395 | "pll3_clk", }; | 393 | "pll3_clk", }; |
@@ -415,9 +413,9 @@ void __init spear1340_clk_init(void) | |||
415 | 25000000); | 413 | 25000000); |
416 | clk_register_clkdev(clk, "osc_25m_clk", NULL); | 414 | clk_register_clkdev(clk, "osc_25m_clk", NULL); |
417 | 415 | ||
418 | clk = clk_register_fixed_rate(NULL, "gmii_125m_pad_clk", NULL, | 416 | clk = clk_register_fixed_rate(NULL, "gmii_pad_clk", NULL, CLK_IS_ROOT, |
419 | CLK_IS_ROOT, 125000000); | 417 | 125000000); |
420 | clk_register_clkdev(clk, "gmii_125m_pad_clk", NULL); | 418 | clk_register_clkdev(clk, "gmii_pad_clk", NULL); |
421 | 419 | ||
422 | clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, | 420 | clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, |
423 | CLK_IS_ROOT, 12288000); | 421 | CLK_IS_ROOT, 12288000); |
@@ -431,35 +429,35 @@ void __init spear1340_clk_init(void) | |||
431 | 429 | ||
432 | /* clock derived from 24 or 25 MHz osc clk */ | 430 | /* clock derived from 24 or 25 MHz osc clk */ |
433 | /* vco-pll */ | 431 | /* vco-pll */ |
434 | clk = clk_register_mux(NULL, "vco1_mux_clk", vco_parents, | 432 | clk = clk_register_mux(NULL, "vco1_mclk", vco_parents, |
435 | ARRAY_SIZE(vco_parents), 0, SPEAR1340_PLL_CFG, | 433 | ARRAY_SIZE(vco_parents), 0, SPEAR1340_PLL_CFG, |
436 | SPEAR1340_PLL1_CLK_SHIFT, SPEAR1340_PLL_CLK_MASK, 0, | 434 | SPEAR1340_PLL1_CLK_SHIFT, SPEAR1340_PLL_CLK_MASK, 0, |
437 | &_lock); | 435 | &_lock); |
438 | clk_register_clkdev(clk, "vco1_mux_clk", NULL); | 436 | clk_register_clkdev(clk, "vco1_mclk", NULL); |
439 | clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "vco1_mux_clk", | 437 | clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "vco1_mclk", 0, |
440 | 0, SPEAR1340_PLL1_CTR, SPEAR1340_PLL1_FRQ, pll_rtbl, | 438 | SPEAR1340_PLL1_CTR, SPEAR1340_PLL1_FRQ, pll_rtbl, |
441 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); | 439 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); |
442 | clk_register_clkdev(clk, "vco1_clk", NULL); | 440 | clk_register_clkdev(clk, "vco1_clk", NULL); |
443 | clk_register_clkdev(clk1, "pll1_clk", NULL); | 441 | clk_register_clkdev(clk1, "pll1_clk", NULL); |
444 | 442 | ||
445 | clk = clk_register_mux(NULL, "vco2_mux_clk", vco_parents, | 443 | clk = clk_register_mux(NULL, "vco2_mclk", vco_parents, |
446 | ARRAY_SIZE(vco_parents), 0, SPEAR1340_PLL_CFG, | 444 | ARRAY_SIZE(vco_parents), 0, SPEAR1340_PLL_CFG, |
447 | SPEAR1340_PLL2_CLK_SHIFT, SPEAR1340_PLL_CLK_MASK, 0, | 445 | SPEAR1340_PLL2_CLK_SHIFT, SPEAR1340_PLL_CLK_MASK, 0, |
448 | &_lock); | 446 | &_lock); |
449 | clk_register_clkdev(clk, "vco2_mux_clk", NULL); | 447 | clk_register_clkdev(clk, "vco2_mclk", NULL); |
450 | clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "vco2_mux_clk", | 448 | clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "vco2_mclk", 0, |
451 | 0, SPEAR1340_PLL2_CTR, SPEAR1340_PLL2_FRQ, pll_rtbl, | 449 | SPEAR1340_PLL2_CTR, SPEAR1340_PLL2_FRQ, pll_rtbl, |
452 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); | 450 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); |
453 | clk_register_clkdev(clk, "vco2_clk", NULL); | 451 | clk_register_clkdev(clk, "vco2_clk", NULL); |
454 | clk_register_clkdev(clk1, "pll2_clk", NULL); | 452 | clk_register_clkdev(clk1, "pll2_clk", NULL); |
455 | 453 | ||
456 | clk = clk_register_mux(NULL, "vco3_mux_clk", vco_parents, | 454 | clk = clk_register_mux(NULL, "vco3_mclk", vco_parents, |
457 | ARRAY_SIZE(vco_parents), 0, SPEAR1340_PLL_CFG, | 455 | ARRAY_SIZE(vco_parents), 0, SPEAR1340_PLL_CFG, |
458 | SPEAR1340_PLL3_CLK_SHIFT, SPEAR1340_PLL_CLK_MASK, 0, | 456 | SPEAR1340_PLL3_CLK_SHIFT, SPEAR1340_PLL_CLK_MASK, 0, |
459 | &_lock); | 457 | &_lock); |
460 | clk_register_clkdev(clk, "vco3_mux_clk", NULL); | 458 | clk_register_clkdev(clk, "vco3_mclk", NULL); |
461 | clk = clk_register_vco_pll("vco3_clk", "pll3_clk", NULL, "vco3_mux_clk", | 459 | clk = clk_register_vco_pll("vco3_clk", "pll3_clk", NULL, "vco3_mclk", 0, |
462 | 0, SPEAR1340_PLL3_CTR, SPEAR1340_PLL3_FRQ, pll_rtbl, | 460 | SPEAR1340_PLL3_CTR, SPEAR1340_PLL3_FRQ, pll_rtbl, |
463 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); | 461 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); |
464 | clk_register_clkdev(clk, "vco3_clk", NULL); | 462 | clk_register_clkdev(clk, "vco3_clk", NULL); |
465 | clk_register_clkdev(clk1, "pll3_clk", NULL); | 463 | clk_register_clkdev(clk1, "pll3_clk", NULL); |
@@ -498,7 +496,7 @@ void __init spear1340_clk_init(void) | |||
498 | /* peripherals */ | 496 | /* peripherals */ |
499 | clk_register_fixed_factor(NULL, "thermal_clk", "osc_24m_clk", 0, 1, | 497 | clk_register_fixed_factor(NULL, "thermal_clk", "osc_24m_clk", 0, 1, |
500 | 128); | 498 | 128); |
501 | clk = clk_register_gate(NULL, "thermal_gate_clk", "thermal_clk", 0, | 499 | clk = clk_register_gate(NULL, "thermal_gclk", "thermal_clk", 0, |
502 | SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_THSENS_CLK_ENB, 0, | 500 | SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_THSENS_CLK_ENB, 0, |
503 | &_lock); | 501 | &_lock); |
504 | clk_register_clkdev(clk, NULL, "spear_thermal"); | 502 | clk_register_clkdev(clk, NULL, "spear_thermal"); |
@@ -509,23 +507,23 @@ void __init spear1340_clk_init(void) | |||
509 | clk_register_clkdev(clk, "ddr_clk", NULL); | 507 | clk_register_clkdev(clk, "ddr_clk", NULL); |
510 | 508 | ||
511 | /* clock derived from pll1 clk */ | 509 | /* clock derived from pll1 clk */ |
512 | clk = clk_register_frac("sys_synth_clk", "vco1div2_clk", 0, | 510 | clk = clk_register_frac("sys_syn_clk", "vco1div2_clk", 0, |
513 | SPEAR1340_SYS_CLK_SYNT, sys_synth_rtbl, | 511 | SPEAR1340_SYS_CLK_SYNT, sys_synth_rtbl, |
514 | ARRAY_SIZE(sys_synth_rtbl), &_lock); | 512 | ARRAY_SIZE(sys_synth_rtbl), &_lock); |
515 | clk_register_clkdev(clk, "sys_synth_clk", NULL); | 513 | clk_register_clkdev(clk, "sys_syn_clk", NULL); |
516 | 514 | ||
517 | clk = clk_register_frac("amba_synth_clk", "vco1div2_clk", 0, | 515 | clk = clk_register_frac("amba_syn_clk", "vco1div2_clk", 0, |
518 | SPEAR1340_AMBA_CLK_SYNT, amba_synth_rtbl, | 516 | SPEAR1340_AMBA_CLK_SYNT, amba_synth_rtbl, |
519 | ARRAY_SIZE(amba_synth_rtbl), &_lock); | 517 | ARRAY_SIZE(amba_synth_rtbl), &_lock); |
520 | clk_register_clkdev(clk, "amba_synth_clk", NULL); | 518 | clk_register_clkdev(clk, "amba_syn_clk", NULL); |
521 | 519 | ||
522 | clk = clk_register_mux(NULL, "sys_mux_clk", sys_parents, | 520 | clk = clk_register_mux(NULL, "sys_mclk", sys_parents, |
523 | ARRAY_SIZE(sys_parents), 0, SPEAR1340_SYS_CLK_CTRL, | 521 | ARRAY_SIZE(sys_parents), 0, SPEAR1340_SYS_CLK_CTRL, |
524 | SPEAR1340_SCLK_SRC_SEL_SHIFT, | 522 | SPEAR1340_SCLK_SRC_SEL_SHIFT, |
525 | SPEAR1340_SCLK_SRC_SEL_MASK, 0, &_lock); | 523 | SPEAR1340_SCLK_SRC_SEL_MASK, 0, &_lock); |
526 | clk_register_clkdev(clk, "sys_clk", NULL); | 524 | clk_register_clkdev(clk, "sys_clk", NULL); |
527 | 525 | ||
528 | clk = clk_register_fixed_factor(NULL, "cpu_clk", "sys_mux_clk", 0, 1, | 526 | clk = clk_register_fixed_factor(NULL, "cpu_clk", "sys_mclk", 0, 1, |
529 | 2); | 527 | 2); |
530 | clk_register_clkdev(clk, "cpu_clk", NULL); | 528 | clk_register_clkdev(clk, "cpu_clk", NULL); |
531 | 529 | ||
@@ -548,194 +546,193 @@ void __init spear1340_clk_init(void) | |||
548 | clk_register_clkdev(clk, "apb_clk", NULL); | 546 | clk_register_clkdev(clk, "apb_clk", NULL); |
549 | 547 | ||
550 | /* gpt clocks */ | 548 | /* gpt clocks */ |
551 | clk = clk_register_mux(NULL, "gpt0_mux_clk", gpt_parents, | 549 | clk = clk_register_mux(NULL, "gpt0_mclk", gpt_parents, |
552 | ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG, | 550 | ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG, |
553 | SPEAR1340_GPT0_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0, | 551 | SPEAR1340_GPT0_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0, |
554 | &_lock); | 552 | &_lock); |
555 | clk_register_clkdev(clk, "gpt0_mux_clk", NULL); | 553 | clk_register_clkdev(clk, "gpt0_mclk", NULL); |
556 | clk = clk_register_gate(NULL, "gpt0_clk", "gpt0_mux_clk", 0, | 554 | clk = clk_register_gate(NULL, "gpt0_clk", "gpt0_mclk", 0, |
557 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_GPT0_CLK_ENB, 0, | 555 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_GPT0_CLK_ENB, 0, |
558 | &_lock); | 556 | &_lock); |
559 | clk_register_clkdev(clk, NULL, "gpt0"); | 557 | clk_register_clkdev(clk, NULL, "gpt0"); |
560 | 558 | ||
561 | clk = clk_register_mux(NULL, "gpt1_mux_clk", gpt_parents, | 559 | clk = clk_register_mux(NULL, "gpt1_mclk", gpt_parents, |
562 | ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG, | 560 | ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG, |
563 | SPEAR1340_GPT1_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0, | 561 | SPEAR1340_GPT1_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0, |
564 | &_lock); | 562 | &_lock); |
565 | clk_register_clkdev(clk, "gpt1_mux_clk", NULL); | 563 | clk_register_clkdev(clk, "gpt1_mclk", NULL); |
566 | clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mux_clk", 0, | 564 | clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0, |
567 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_GPT1_CLK_ENB, 0, | 565 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_GPT1_CLK_ENB, 0, |
568 | &_lock); | 566 | &_lock); |
569 | clk_register_clkdev(clk, NULL, "gpt1"); | 567 | clk_register_clkdev(clk, NULL, "gpt1"); |
570 | 568 | ||
571 | clk = clk_register_mux(NULL, "gpt2_mux_clk", gpt_parents, | 569 | clk = clk_register_mux(NULL, "gpt2_mclk", gpt_parents, |
572 | ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG, | 570 | ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG, |
573 | SPEAR1340_GPT2_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0, | 571 | SPEAR1340_GPT2_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0, |
574 | &_lock); | 572 | &_lock); |
575 | clk_register_clkdev(clk, "gpt2_mux_clk", NULL); | 573 | clk_register_clkdev(clk, "gpt2_mclk", NULL); |
576 | clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mux_clk", 0, | 574 | clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0, |
577 | SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_GPT2_CLK_ENB, 0, | 575 | SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_GPT2_CLK_ENB, 0, |
578 | &_lock); | 576 | &_lock); |
579 | clk_register_clkdev(clk, NULL, "gpt2"); | 577 | clk_register_clkdev(clk, NULL, "gpt2"); |
580 | 578 | ||
581 | clk = clk_register_mux(NULL, "gpt3_mux_clk", gpt_parents, | 579 | clk = clk_register_mux(NULL, "gpt3_mclk", gpt_parents, |
582 | ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG, | 580 | ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG, |
583 | SPEAR1340_GPT3_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0, | 581 | SPEAR1340_GPT3_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0, |
584 | &_lock); | 582 | &_lock); |
585 | clk_register_clkdev(clk, "gpt3_mux_clk", NULL); | 583 | clk_register_clkdev(clk, "gpt3_mclk", NULL); |
586 | clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mux_clk", 0, | 584 | clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mclk", 0, |
587 | SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_GPT3_CLK_ENB, 0, | 585 | SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_GPT3_CLK_ENB, 0, |
588 | &_lock); | 586 | &_lock); |
589 | clk_register_clkdev(clk, NULL, "gpt3"); | 587 | clk_register_clkdev(clk, NULL, "gpt3"); |
590 | 588 | ||
591 | /* others */ | 589 | /* others */ |
592 | clk = clk_register_aux("uart0_synth_clk", "uart0_synth_gate_clk", | 590 | clk = clk_register_aux("uart0_syn_clk", "uart0_syn_gclk", |
593 | "vco1div2_clk", 0, SPEAR1340_UART0_CLK_SYNT, NULL, | 591 | "vco1div2_clk", 0, SPEAR1340_UART0_CLK_SYNT, NULL, |
594 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 592 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); |
595 | clk_register_clkdev(clk, "uart0_synth_clk", NULL); | 593 | clk_register_clkdev(clk, "uart0_syn_clk", NULL); |
596 | clk_register_clkdev(clk1, "uart0_synth_gate_clk", NULL); | 594 | clk_register_clkdev(clk1, "uart0_syn_gclk", NULL); |
597 | 595 | ||
598 | clk = clk_register_mux(NULL, "uart0_mux_clk", uart0_parents, | 596 | clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents, |
599 | ARRAY_SIZE(uart0_parents), 0, SPEAR1340_PERIP_CLK_CFG, | 597 | ARRAY_SIZE(uart0_parents), 0, SPEAR1340_PERIP_CLK_CFG, |
600 | SPEAR1340_UART0_CLK_SHIFT, SPEAR1340_UART_CLK_MASK, 0, | 598 | SPEAR1340_UART0_CLK_SHIFT, SPEAR1340_UART_CLK_MASK, 0, |
601 | &_lock); | 599 | &_lock); |
602 | clk_register_clkdev(clk, "uart0_mux_clk", NULL); | 600 | clk_register_clkdev(clk, "uart0_mclk", NULL); |
603 | 601 | ||
604 | clk = clk_register_gate(NULL, "uart0_clk", "uart0_mux_clk", 0, | 602 | clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", 0, |
605 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UART0_CLK_ENB, 0, | 603 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UART0_CLK_ENB, 0, |
606 | &_lock); | 604 | &_lock); |
607 | clk_register_clkdev(clk, NULL, "e0000000.serial"); | 605 | clk_register_clkdev(clk, NULL, "e0000000.serial"); |
608 | 606 | ||
609 | clk = clk_register_aux("uart1_synth_clk", "uart1_synth_gate_clk", | 607 | clk = clk_register_aux("uart1_syn_clk", "uart1_syn_gclk", |
610 | "vco1div2_clk", 0, SPEAR1340_UART1_CLK_SYNT, NULL, | 608 | "vco1div2_clk", 0, SPEAR1340_UART1_CLK_SYNT, NULL, |
611 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 609 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); |
612 | clk_register_clkdev(clk, "uart1_synth_clk", NULL); | 610 | clk_register_clkdev(clk, "uart1_syn_clk", NULL); |
613 | clk_register_clkdev(clk1, "uart1_synth_gate_clk", NULL); | 611 | clk_register_clkdev(clk1, "uart1_syn_gclk", NULL); |
614 | 612 | ||
615 | clk = clk_register_mux(NULL, "uart1_mux_clk", uart1_parents, | 613 | clk = clk_register_mux(NULL, "uart1_mclk", uart1_parents, |
616 | ARRAY_SIZE(uart1_parents), 0, SPEAR1340_PERIP_CLK_CFG, | 614 | ARRAY_SIZE(uart1_parents), 0, SPEAR1340_PERIP_CLK_CFG, |
617 | SPEAR1340_UART1_CLK_SHIFT, SPEAR1340_UART_CLK_MASK, 0, | 615 | SPEAR1340_UART1_CLK_SHIFT, SPEAR1340_UART_CLK_MASK, 0, |
618 | &_lock); | 616 | &_lock); |
619 | clk_register_clkdev(clk, "uart1_mux_clk", NULL); | 617 | clk_register_clkdev(clk, "uart1_mclk", NULL); |
620 | 618 | ||
621 | clk = clk_register_gate(NULL, "uart1_clk", "uart1_mux_clk", 0, | 619 | clk = clk_register_gate(NULL, "uart1_clk", "uart1_mclk", 0, |
622 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UART1_CLK_ENB, 0, | 620 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_UART1_CLK_ENB, 0, |
623 | &_lock); | 621 | &_lock); |
624 | clk_register_clkdev(clk, NULL, "b4100000.serial"); | 622 | clk_register_clkdev(clk, NULL, "b4100000.serial"); |
625 | 623 | ||
626 | clk = clk_register_aux("sdhci_synth_clk", "sdhci_synth_gate_clk", | 624 | clk = clk_register_aux("sdhci_syn_clk", "sdhci_syn_gclk", |
627 | "vco1div2_clk", 0, SPEAR1340_SDHCI_CLK_SYNT, NULL, | 625 | "vco1div2_clk", 0, SPEAR1340_SDHCI_CLK_SYNT, NULL, |
628 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 626 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); |
629 | clk_register_clkdev(clk, "sdhci_synth_clk", NULL); | 627 | clk_register_clkdev(clk, "sdhci_syn_clk", NULL); |
630 | clk_register_clkdev(clk1, "sdhci_synth_gate_clk", NULL); | 628 | clk_register_clkdev(clk1, "sdhci_syn_gclk", NULL); |
631 | 629 | ||
632 | clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_synth_gate_clk", 0, | 630 | clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", 0, |
633 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_SDHCI_CLK_ENB, 0, | 631 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_SDHCI_CLK_ENB, 0, |
634 | &_lock); | 632 | &_lock); |
635 | clk_register_clkdev(clk, NULL, "b3000000.sdhci"); | 633 | clk_register_clkdev(clk, NULL, "b3000000.sdhci"); |
636 | 634 | ||
637 | clk = clk_register_aux("cfxd_synth_clk", "cfxd_synth_gate_clk", | 635 | clk = clk_register_aux("cfxd_syn_clk", "cfxd_syn_gclk", "vco1div2_clk", |
638 | "vco1div2_clk", 0, SPEAR1340_CFXD_CLK_SYNT, NULL, | 636 | 0, SPEAR1340_CFXD_CLK_SYNT, NULL, aux_rtbl, |
639 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 637 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); |
640 | clk_register_clkdev(clk, "cfxd_synth_clk", NULL); | 638 | clk_register_clkdev(clk, "cfxd_syn_clk", NULL); |
641 | clk_register_clkdev(clk1, "cfxd_synth_gate_clk", NULL); | 639 | clk_register_clkdev(clk1, "cfxd_syn_gclk", NULL); |
642 | 640 | ||
643 | clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_synth_gate_clk", 0, | 641 | clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", 0, |
644 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CFXD_CLK_ENB, 0, | 642 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CFXD_CLK_ENB, 0, |
645 | &_lock); | 643 | &_lock); |
646 | clk_register_clkdev(clk, NULL, "b2800000.cf"); | 644 | clk_register_clkdev(clk, NULL, "b2800000.cf"); |
647 | clk_register_clkdev(clk, NULL, "arasan_xd"); | 645 | clk_register_clkdev(clk, NULL, "arasan_xd"); |
648 | 646 | ||
649 | clk = clk_register_aux("c3_synth_clk", "c3_synth_gate_clk", | 647 | clk = clk_register_aux("c3_syn_clk", "c3_syn_gclk", "vco1div2_clk", 0, |
650 | "vco1div2_clk", 0, SPEAR1340_C3_CLK_SYNT, NULL, | 648 | SPEAR1340_C3_CLK_SYNT, NULL, aux_rtbl, |
651 | aux_rtbl, ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 649 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); |
652 | clk_register_clkdev(clk, "c3_synth_clk", NULL); | 650 | clk_register_clkdev(clk, "c3_syn_clk", NULL); |
653 | clk_register_clkdev(clk1, "c3_synth_gate_clk", NULL); | 651 | clk_register_clkdev(clk1, "c3_syn_gclk", NULL); |
654 | 652 | ||
655 | clk = clk_register_mux(NULL, "c3_mux_clk", c3_parents, | 653 | clk = clk_register_mux(NULL, "c3_mclk", c3_parents, |
656 | ARRAY_SIZE(c3_parents), 0, SPEAR1340_PERIP_CLK_CFG, | 654 | ARRAY_SIZE(c3_parents), 0, SPEAR1340_PERIP_CLK_CFG, |
657 | SPEAR1340_C3_CLK_SHIFT, SPEAR1340_C3_CLK_MASK, 0, | 655 | SPEAR1340_C3_CLK_SHIFT, SPEAR1340_C3_CLK_MASK, 0, |
658 | &_lock); | 656 | &_lock); |
659 | clk_register_clkdev(clk, "c3_mux_clk", NULL); | 657 | clk_register_clkdev(clk, "c3_mclk", NULL); |
660 | 658 | ||
661 | clk = clk_register_gate(NULL, "c3_clk", "c3_mux_clk", 0, | 659 | clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", 0, |
662 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_C3_CLK_ENB, 0, | 660 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_C3_CLK_ENB, 0, |
663 | &_lock); | 661 | &_lock); |
664 | clk_register_clkdev(clk, NULL, "c3"); | 662 | clk_register_clkdev(clk, NULL, "c3"); |
665 | 663 | ||
666 | /* gmac */ | 664 | /* gmac */ |
667 | clk = clk_register_mux(NULL, "gmac_phy_input_mux_clk", | 665 | clk = clk_register_mux(NULL, "phy_input_mclk", gmac_phy_input_parents, |
668 | gmac_phy_input_parents, | ||
669 | ARRAY_SIZE(gmac_phy_input_parents), 0, | 666 | ARRAY_SIZE(gmac_phy_input_parents), 0, |
670 | SPEAR1340_GMAC_CLK_CFG, | 667 | SPEAR1340_GMAC_CLK_CFG, |
671 | SPEAR1340_GMAC_PHY_INPUT_CLK_SHIFT, | 668 | SPEAR1340_GMAC_PHY_INPUT_CLK_SHIFT, |
672 | SPEAR1340_GMAC_PHY_INPUT_CLK_MASK, 0, &_lock); | 669 | SPEAR1340_GMAC_PHY_INPUT_CLK_MASK, 0, &_lock); |
673 | clk_register_clkdev(clk, "gmac_phy_input_mux_clk", NULL); | 670 | clk_register_clkdev(clk, "phy_input_mclk", NULL); |
674 | 671 | ||
675 | clk = clk_register_aux("gmac_phy_synth_clk", "gmac_phy_synth_gate_clk", | 672 | clk = clk_register_aux("phy_syn_clk", "phy_syn_gclk", "phy_input_mclk", |
676 | "gmac_phy_input_mux_clk", 0, SPEAR1340_GMAC_CLK_SYNT, | 673 | 0, SPEAR1340_GMAC_CLK_SYNT, NULL, gmac_rtbl, |
677 | NULL, gmac_rtbl, ARRAY_SIZE(gmac_rtbl), &_lock, &clk1); | 674 | ARRAY_SIZE(gmac_rtbl), &_lock, &clk1); |
678 | clk_register_clkdev(clk, "gmac_phy_synth_clk", NULL); | 675 | clk_register_clkdev(clk, "phy_syn_clk", NULL); |
679 | clk_register_clkdev(clk1, "gmac_phy_synth_gate_clk", NULL); | 676 | clk_register_clkdev(clk1, "phy_syn_gclk", NULL); |
680 | 677 | ||
681 | clk = clk_register_mux(NULL, "gmac_phy_mux_clk", gmac_phy_parents, | 678 | clk = clk_register_mux(NULL, "phy_mclk", gmac_phy_parents, |
682 | ARRAY_SIZE(gmac_phy_parents), 0, | 679 | ARRAY_SIZE(gmac_phy_parents), 0, |
683 | SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GMAC_PHY_CLK_SHIFT, | 680 | SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GMAC_PHY_CLK_SHIFT, |
684 | SPEAR1340_GMAC_PHY_CLK_MASK, 0, &_lock); | 681 | SPEAR1340_GMAC_PHY_CLK_MASK, 0, &_lock); |
685 | clk_register_clkdev(clk, NULL, "stmmacphy.0"); | 682 | clk_register_clkdev(clk, NULL, "stmmacphy.0"); |
686 | 683 | ||
687 | /* clcd */ | 684 | /* clcd */ |
688 | clk = clk_register_mux(NULL, "clcd_synth_mux_clk", clcd_synth_parents, | 685 | clk = clk_register_mux(NULL, "clcd_syn_mclk", clcd_synth_parents, |
689 | ARRAY_SIZE(clcd_synth_parents), 0, | 686 | ARRAY_SIZE(clcd_synth_parents), 0, |
690 | SPEAR1340_CLCD_CLK_SYNT, SPEAR1340_CLCD_SYNT_CLK_SHIFT, | 687 | SPEAR1340_CLCD_CLK_SYNT, SPEAR1340_CLCD_SYNT_CLK_SHIFT, |
691 | SPEAR1340_CLCD_SYNT_CLK_MASK, 0, &_lock); | 688 | SPEAR1340_CLCD_SYNT_CLK_MASK, 0, &_lock); |
692 | clk_register_clkdev(clk, "clcd_synth_mux_clk", NULL); | 689 | clk_register_clkdev(clk, "clcd_syn_mclk", NULL); |
693 | 690 | ||
694 | clk = clk_register_frac("clcd_synth_clk", "clcd_synth_mux_clk", 0, | 691 | clk = clk_register_frac("clcd_syn_clk", "clcd_syn_mclk", 0, |
695 | SPEAR1340_CLCD_CLK_SYNT, clcd_rtbl, | 692 | SPEAR1340_CLCD_CLK_SYNT, clcd_rtbl, |
696 | ARRAY_SIZE(clcd_rtbl), &_lock); | 693 | ARRAY_SIZE(clcd_rtbl), &_lock); |
697 | clk_register_clkdev(clk, "clcd_synth_clk", NULL); | 694 | clk_register_clkdev(clk, "clcd_syn_clk", NULL); |
698 | 695 | ||
699 | clk = clk_register_mux(NULL, "clcd_pixel_mux_clk", clcd_pixel_parents, | 696 | clk = clk_register_mux(NULL, "clcd_pixel_mclk", clcd_pixel_parents, |
700 | ARRAY_SIZE(clcd_pixel_parents), 0, | 697 | ARRAY_SIZE(clcd_pixel_parents), 0, |
701 | SPEAR1340_PERIP_CLK_CFG, SPEAR1340_CLCD_CLK_SHIFT, | 698 | SPEAR1340_PERIP_CLK_CFG, SPEAR1340_CLCD_CLK_SHIFT, |
702 | SPEAR1340_CLCD_CLK_MASK, 0, &_lock); | 699 | SPEAR1340_CLCD_CLK_MASK, 0, &_lock); |
703 | clk_register_clkdev(clk, "clcd_pixel_clk", NULL); | 700 | clk_register_clkdev(clk, "clcd_pixel_clk", NULL); |
704 | 701 | ||
705 | clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mux_clk", 0, | 702 | clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mclk", 0, |
706 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CLCD_CLK_ENB, 0, | 703 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CLCD_CLK_ENB, 0, |
707 | &_lock); | 704 | &_lock); |
708 | clk_register_clkdev(clk, "clcd_clk", NULL); | 705 | clk_register_clkdev(clk, "clcd_clk", NULL); |
709 | 706 | ||
710 | /* i2s */ | 707 | /* i2s */ |
711 | clk = clk_register_mux(NULL, "i2s_src_mux_clk", i2s_src_parents, | 708 | clk = clk_register_mux(NULL, "i2s_src_mclk", i2s_src_parents, |
712 | ARRAY_SIZE(i2s_src_parents), 0, SPEAR1340_I2S_CLK_CFG, | 709 | ARRAY_SIZE(i2s_src_parents), 0, SPEAR1340_I2S_CLK_CFG, |
713 | SPEAR1340_I2S_SRC_CLK_SHIFT, SPEAR1340_I2S_SRC_CLK_MASK, | 710 | SPEAR1340_I2S_SRC_CLK_SHIFT, SPEAR1340_I2S_SRC_CLK_MASK, |
714 | 0, &_lock); | 711 | 0, &_lock); |
715 | clk_register_clkdev(clk, "i2s_src_clk", NULL); | 712 | clk_register_clkdev(clk, "i2s_src_clk", NULL); |
716 | 713 | ||
717 | clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mux_clk", 0, | 714 | clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", 0, |
718 | SPEAR1340_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl, | 715 | SPEAR1340_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl, |
719 | ARRAY_SIZE(i2s_prs1_rtbl), &_lock, NULL); | 716 | ARRAY_SIZE(i2s_prs1_rtbl), &_lock, NULL); |
720 | clk_register_clkdev(clk, "i2s_prs1_clk", NULL); | 717 | clk_register_clkdev(clk, "i2s_prs1_clk", NULL); |
721 | 718 | ||
722 | clk = clk_register_mux(NULL, "i2s_ref_mux_clk", i2s_ref_parents, | 719 | clk = clk_register_mux(NULL, "i2s_ref_mclk", i2s_ref_parents, |
723 | ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1340_I2S_CLK_CFG, | 720 | ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1340_I2S_CLK_CFG, |
724 | SPEAR1340_I2S_REF_SHIFT, SPEAR1340_I2S_REF_SEL_MASK, 0, | 721 | SPEAR1340_I2S_REF_SHIFT, SPEAR1340_I2S_REF_SEL_MASK, 0, |
725 | &_lock); | 722 | &_lock); |
726 | clk_register_clkdev(clk, "i2s_ref_clk", NULL); | 723 | clk_register_clkdev(clk, "i2s_ref_clk", NULL); |
727 | 724 | ||
728 | clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mux_clk", 0, | 725 | clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mclk", 0, |
729 | SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_I2S_REF_PAD_CLK_ENB, | 726 | SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_I2S_REF_PAD_CLK_ENB, |
730 | 0, &_lock); | 727 | 0, &_lock); |
731 | clk_register_clkdev(clk, "i2s_ref_pad_clk", NULL); | 728 | clk_register_clkdev(clk, "i2s_ref_pad_clk", NULL); |
732 | 729 | ||
733 | clk = clk_register_aux("i2s_sclk_clk", "i2s_sclk_gate_clk", | 730 | clk = clk_register_aux("i2s_sclk_clk", "i2s_sclk_gclk", "i2s_ref_mclk", |
734 | "i2s_ref_mux_clk", 0, SPEAR1340_I2S_CLK_CFG, | 731 | 0, SPEAR1340_I2S_CLK_CFG, &i2s_sclk_masks, |
735 | &i2s_sclk_masks, i2s_sclk_rtbl, | 732 | i2s_sclk_rtbl, ARRAY_SIZE(i2s_sclk_rtbl), &_lock, |
736 | ARRAY_SIZE(i2s_sclk_rtbl), &_lock, &clk1); | 733 | &clk1); |
737 | clk_register_clkdev(clk, "i2s_sclk_clk", NULL); | 734 | clk_register_clkdev(clk, "i2s_sclk_clk", NULL); |
738 | clk_register_clkdev(clk1, "i2s_sclk_gate_clk", NULL); | 735 | clk_register_clkdev(clk1, "i2s_sclk_gclk", NULL); |
739 | 736 | ||
740 | /* clock derived from ahb clk */ | 737 | /* clock derived from ahb clk */ |
741 | clk = clk_register_gate(NULL, "i2c0_clk", "ahb_clk", 0, | 738 | clk = clk_register_gate(NULL, "i2c0_clk", "ahb_clk", 0, |
@@ -744,7 +741,7 @@ void __init spear1340_clk_init(void) | |||
744 | clk_register_clkdev(clk, NULL, "e0280000.i2c"); | 741 | clk_register_clkdev(clk, NULL, "e0280000.i2c"); |
745 | 742 | ||
746 | clk = clk_register_gate(NULL, "i2c1_clk", "ahb_clk", 0, | 743 | clk = clk_register_gate(NULL, "i2c1_clk", "ahb_clk", 0, |
747 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_I2C1_CLK_ENB, 0, | 744 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_I2C1_CLK_ENB, 0, |
748 | &_lock); | 745 | &_lock); |
749 | clk_register_clkdev(clk, NULL, "b4000000.i2c"); | 746 | clk_register_clkdev(clk, NULL, "b4000000.i2c"); |
750 | 747 | ||
@@ -800,13 +797,13 @@ void __init spear1340_clk_init(void) | |||
800 | &_lock); | 797 | &_lock); |
801 | clk_register_clkdev(clk, "sysram1_clk", NULL); | 798 | clk_register_clkdev(clk, "sysram1_clk", NULL); |
802 | 799 | ||
803 | clk = clk_register_aux("adc_synth_clk", "adc_synth_gate_clk", "ahb_clk", | 800 | clk = clk_register_aux("adc_syn_clk", "adc_syn_gclk", "ahb_clk", |
804 | 0, SPEAR1340_ADC_CLK_SYNT, NULL, adc_rtbl, | 801 | 0, SPEAR1340_ADC_CLK_SYNT, NULL, adc_rtbl, |
805 | ARRAY_SIZE(adc_rtbl), &_lock, &clk1); | 802 | ARRAY_SIZE(adc_rtbl), &_lock, &clk1); |
806 | clk_register_clkdev(clk, "adc_synth_clk", NULL); | 803 | clk_register_clkdev(clk, "adc_syn_clk", NULL); |
807 | clk_register_clkdev(clk1, "adc_synth_gate_clk", NULL); | 804 | clk_register_clkdev(clk1, "adc_syn_gclk", NULL); |
808 | 805 | ||
809 | clk = clk_register_gate(NULL, "adc_clk", "adc_synth_gate_clk", 0, | 806 | clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", 0, |
810 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_ADC_CLK_ENB, 0, | 807 | SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_ADC_CLK_ENB, 0, |
811 | &_lock); | 808 | &_lock); |
812 | clk_register_clkdev(clk, NULL, "adc_clk"); | 809 | clk_register_clkdev(clk, NULL, "adc_clk"); |
@@ -843,39 +840,39 @@ void __init spear1340_clk_init(void) | |||
843 | clk_register_clkdev(clk, NULL, "e0300000.kbd"); | 840 | clk_register_clkdev(clk, NULL, "e0300000.kbd"); |
844 | 841 | ||
845 | /* RAS clks */ | 842 | /* RAS clks */ |
846 | clk = clk_register_mux(NULL, "gen_synth0_1_mux_clk", | 843 | clk = clk_register_mux(NULL, "gen_syn0_1_mclk", gen_synth0_1_parents, |
847 | gen_synth0_1_parents, ARRAY_SIZE(gen_synth0_1_parents), | 844 | ARRAY_SIZE(gen_synth0_1_parents), 0, SPEAR1340_PLL_CFG, |
848 | 0, SPEAR1340_PLL_CFG, SPEAR1340_GEN_SYNT0_1_CLK_SHIFT, | 845 | SPEAR1340_GEN_SYNT0_1_CLK_SHIFT, |
849 | SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock); | 846 | SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock); |
850 | clk_register_clkdev(clk, "gen_synth0_1_clk", NULL); | 847 | clk_register_clkdev(clk, "gen_syn0_1_clk", NULL); |
851 | 848 | ||
852 | clk = clk_register_mux(NULL, "gen_synth2_3_mux_clk", | 849 | clk = clk_register_mux(NULL, "gen_syn2_3_mclk", gen_synth2_3_parents, |
853 | gen_synth2_3_parents, ARRAY_SIZE(gen_synth2_3_parents), | 850 | ARRAY_SIZE(gen_synth2_3_parents), 0, SPEAR1340_PLL_CFG, |
854 | 0, SPEAR1340_PLL_CFG, SPEAR1340_GEN_SYNT2_3_CLK_SHIFT, | 851 | SPEAR1340_GEN_SYNT2_3_CLK_SHIFT, |
855 | SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock); | 852 | SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock); |
856 | clk_register_clkdev(clk, "gen_synth2_3_clk", NULL); | 853 | clk_register_clkdev(clk, "gen_syn2_3_clk", NULL); |
857 | 854 | ||
858 | clk = clk_register_frac("gen_synth0_clk", "gen_synth0_1_clk", 0, | 855 | clk = clk_register_frac("gen_syn0_clk", "gen_syn0_1_clk", 0, |
859 | SPEAR1340_GEN_CLK_SYNT0, gen_rtbl, ARRAY_SIZE(gen_rtbl), | 856 | SPEAR1340_GEN_CLK_SYNT0, gen_rtbl, ARRAY_SIZE(gen_rtbl), |
860 | &_lock); | 857 | &_lock); |
861 | clk_register_clkdev(clk, "gen_synth0_clk", NULL); | 858 | clk_register_clkdev(clk, "gen_syn0_clk", NULL); |
862 | 859 | ||
863 | clk = clk_register_frac("gen_synth1_clk", "gen_synth0_1_clk", 0, | 860 | clk = clk_register_frac("gen_syn1_clk", "gen_syn0_1_clk", 0, |
864 | SPEAR1340_GEN_CLK_SYNT1, gen_rtbl, ARRAY_SIZE(gen_rtbl), | 861 | SPEAR1340_GEN_CLK_SYNT1, gen_rtbl, ARRAY_SIZE(gen_rtbl), |
865 | &_lock); | 862 | &_lock); |
866 | clk_register_clkdev(clk, "gen_synth1_clk", NULL); | 863 | clk_register_clkdev(clk, "gen_syn1_clk", NULL); |
867 | 864 | ||
868 | clk = clk_register_frac("gen_synth2_clk", "gen_synth2_3_clk", 0, | 865 | clk = clk_register_frac("gen_syn2_clk", "gen_syn2_3_clk", 0, |
869 | SPEAR1340_GEN_CLK_SYNT2, gen_rtbl, ARRAY_SIZE(gen_rtbl), | 866 | SPEAR1340_GEN_CLK_SYNT2, gen_rtbl, ARRAY_SIZE(gen_rtbl), |
870 | &_lock); | 867 | &_lock); |
871 | clk_register_clkdev(clk, "gen_synth2_clk", NULL); | 868 | clk_register_clkdev(clk, "gen_syn2_clk", NULL); |
872 | 869 | ||
873 | clk = clk_register_frac("gen_synth3_clk", "gen_synth2_3_clk", 0, | 870 | clk = clk_register_frac("gen_syn3_clk", "gen_syn2_3_clk", 0, |
874 | SPEAR1340_GEN_CLK_SYNT3, gen_rtbl, ARRAY_SIZE(gen_rtbl), | 871 | SPEAR1340_GEN_CLK_SYNT3, gen_rtbl, ARRAY_SIZE(gen_rtbl), |
875 | &_lock); | 872 | &_lock); |
876 | clk_register_clkdev(clk, "gen_synth3_clk", NULL); | 873 | clk_register_clkdev(clk, "gen_syn3_clk", NULL); |
877 | 874 | ||
878 | clk = clk_register_gate(NULL, "mali_clk", "gen_synth3_clk", 0, | 875 | clk = clk_register_gate(NULL, "mali_clk", "gen_syn3_clk", 0, |
879 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_MALI_CLK_ENB, 0, | 876 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_MALI_CLK_ENB, 0, |
880 | &_lock); | 877 | &_lock); |
881 | clk_register_clkdev(clk, NULL, "mali"); | 878 | clk_register_clkdev(clk, NULL, "mali"); |
@@ -890,74 +887,74 @@ void __init spear1340_clk_init(void) | |||
890 | &_lock); | 887 | &_lock); |
891 | clk_register_clkdev(clk, NULL, "spear_cec.1"); | 888 | clk_register_clkdev(clk, NULL, "spear_cec.1"); |
892 | 889 | ||
893 | clk = clk_register_mux(NULL, "spdif_out_mux_clk", spdif_out_parents, | 890 | clk = clk_register_mux(NULL, "spdif_out_mclk", spdif_out_parents, |
894 | ARRAY_SIZE(spdif_out_parents), 0, | 891 | ARRAY_SIZE(spdif_out_parents), 0, |
895 | SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_OUT_CLK_SHIFT, | 892 | SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_OUT_CLK_SHIFT, |
896 | SPEAR1340_SPDIF_CLK_MASK, 0, &_lock); | 893 | SPEAR1340_SPDIF_CLK_MASK, 0, &_lock); |
897 | clk_register_clkdev(clk, "spdif_out_mux_clk", NULL); | 894 | clk_register_clkdev(clk, "spdif_out_mclk", NULL); |
898 | 895 | ||
899 | clk = clk_register_gate(NULL, "spdif_out_clk", "spdif_out_mux_clk", 0, | 896 | clk = clk_register_gate(NULL, "spdif_out_clk", "spdif_out_mclk", 0, |
900 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_OUT_CLK_ENB, | 897 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_OUT_CLK_ENB, |
901 | 0, &_lock); | 898 | 0, &_lock); |
902 | clk_register_clkdev(clk, NULL, "spdif-out"); | 899 | clk_register_clkdev(clk, NULL, "spdif-out"); |
903 | 900 | ||
904 | clk = clk_register_mux(NULL, "spdif_in_mux_clk", spdif_in_parents, | 901 | clk = clk_register_mux(NULL, "spdif_in_mclk", spdif_in_parents, |
905 | ARRAY_SIZE(spdif_in_parents), 0, | 902 | ARRAY_SIZE(spdif_in_parents), 0, |
906 | SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_IN_CLK_SHIFT, | 903 | SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_IN_CLK_SHIFT, |
907 | SPEAR1340_SPDIF_CLK_MASK, 0, &_lock); | 904 | SPEAR1340_SPDIF_CLK_MASK, 0, &_lock); |
908 | clk_register_clkdev(clk, "spdif_in_mux_clk", NULL); | 905 | clk_register_clkdev(clk, "spdif_in_mclk", NULL); |
909 | 906 | ||
910 | clk = clk_register_gate(NULL, "spdif_in_clk", "spdif_in_mux_clk", 0, | 907 | clk = clk_register_gate(NULL, "spdif_in_clk", "spdif_in_mclk", 0, |
911 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_IN_CLK_ENB, 0, | 908 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_IN_CLK_ENB, 0, |
912 | &_lock); | 909 | &_lock); |
913 | clk_register_clkdev(clk, NULL, "spdif-in"); | 910 | clk_register_clkdev(clk, NULL, "spdif-in"); |
914 | 911 | ||
915 | clk = clk_register_gate(NULL, "acp_clk", "acp_mux_clk", 0, | 912 | clk = clk_register_gate(NULL, "acp_clk", "acp_mclk", 0, |
916 | SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_ACP_CLK_ENB, 0, | 913 | SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_ACP_CLK_ENB, 0, |
917 | &_lock); | 914 | &_lock); |
918 | clk_register_clkdev(clk, NULL, "acp_clk"); | 915 | clk_register_clkdev(clk, NULL, "acp_clk"); |
919 | 916 | ||
920 | clk = clk_register_gate(NULL, "plgpio_clk", "plgpio_mux_clk", 0, | 917 | clk = clk_register_gate(NULL, "plgpio_clk", "plgpio_mclk", 0, |
921 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PLGPIO_CLK_ENB, 0, | 918 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PLGPIO_CLK_ENB, 0, |
922 | &_lock); | 919 | &_lock); |
923 | clk_register_clkdev(clk, NULL, "plgpio"); | 920 | clk_register_clkdev(clk, NULL, "plgpio"); |
924 | 921 | ||
925 | clk = clk_register_gate(NULL, "video_dec_clk", "video_dec_mux_clk", 0, | 922 | clk = clk_register_gate(NULL, "video_dec_clk", "video_dec_mclk", 0, |
926 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_DEC_CLK_ENB, | 923 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_DEC_CLK_ENB, |
927 | 0, &_lock); | 924 | 0, &_lock); |
928 | clk_register_clkdev(clk, NULL, "video_dec"); | 925 | clk_register_clkdev(clk, NULL, "video_dec"); |
929 | 926 | ||
930 | clk = clk_register_gate(NULL, "video_enc_clk", "video_enc_mux_clk", 0, | 927 | clk = clk_register_gate(NULL, "video_enc_clk", "video_enc_mclk", 0, |
931 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_ENC_CLK_ENB, | 928 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_ENC_CLK_ENB, |
932 | 0, &_lock); | 929 | 0, &_lock); |
933 | clk_register_clkdev(clk, NULL, "video_enc"); | 930 | clk_register_clkdev(clk, NULL, "video_enc"); |
934 | 931 | ||
935 | clk = clk_register_gate(NULL, "video_in_clk", "video_in_mux_clk", 0, | 932 | clk = clk_register_gate(NULL, "video_in_clk", "video_in_mclk", 0, |
936 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_IN_CLK_ENB, 0, | 933 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_IN_CLK_ENB, 0, |
937 | &_lock); | 934 | &_lock); |
938 | clk_register_clkdev(clk, NULL, "spear_vip"); | 935 | clk_register_clkdev(clk, NULL, "spear_vip"); |
939 | 936 | ||
940 | clk = clk_register_gate(NULL, "cam0_clk", "cam0_mux_clk", 0, | 937 | clk = clk_register_gate(NULL, "cam0_clk", "cam0_mclk", 0, |
941 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM0_CLK_ENB, 0, | 938 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM0_CLK_ENB, 0, |
942 | &_lock); | 939 | &_lock); |
943 | clk_register_clkdev(clk, NULL, "spear_camif.0"); | 940 | clk_register_clkdev(clk, NULL, "spear_camif.0"); |
944 | 941 | ||
945 | clk = clk_register_gate(NULL, "cam1_clk", "cam1_mux_clk", 0, | 942 | clk = clk_register_gate(NULL, "cam1_clk", "cam1_mclk", 0, |
946 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM1_CLK_ENB, 0, | 943 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM1_CLK_ENB, 0, |
947 | &_lock); | 944 | &_lock); |
948 | clk_register_clkdev(clk, NULL, "spear_camif.1"); | 945 | clk_register_clkdev(clk, NULL, "spear_camif.1"); |
949 | 946 | ||
950 | clk = clk_register_gate(NULL, "cam2_clk", "cam2_mux_clk", 0, | 947 | clk = clk_register_gate(NULL, "cam2_clk", "cam2_mclk", 0, |
951 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM2_CLK_ENB, 0, | 948 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM2_CLK_ENB, 0, |
952 | &_lock); | 949 | &_lock); |
953 | clk_register_clkdev(clk, NULL, "spear_camif.2"); | 950 | clk_register_clkdev(clk, NULL, "spear_camif.2"); |
954 | 951 | ||
955 | clk = clk_register_gate(NULL, "cam3_clk", "cam3_mux_clk", 0, | 952 | clk = clk_register_gate(NULL, "cam3_clk", "cam3_mclk", 0, |
956 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM3_CLK_ENB, 0, | 953 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM3_CLK_ENB, 0, |
957 | &_lock); | 954 | &_lock); |
958 | clk_register_clkdev(clk, NULL, "spear_camif.3"); | 955 | clk_register_clkdev(clk, NULL, "spear_camif.3"); |
959 | 956 | ||
960 | clk = clk_register_gate(NULL, "pwm_clk", "pwm_mux_clk", 0, | 957 | clk = clk_register_gate(NULL, "pwm_clk", "pwm_mclk", 0, |
961 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PWM_CLK_ENB, 0, | 958 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PWM_CLK_ENB, 0, |
962 | &_lock); | 959 | &_lock); |
963 | clk_register_clkdev(clk, NULL, "pwm"); | 960 | clk_register_clkdev(clk, NULL, "pwm"); |
diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index 01dd6daff2a1..c3157454bb3f 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c | |||
@@ -122,12 +122,12 @@ static struct gpt_rate_tbl gpt_rtbl[] = { | |||
122 | }; | 122 | }; |
123 | 123 | ||
124 | /* clock parents */ | 124 | /* clock parents */ |
125 | static const char *uart0_parents[] = { "pll3_48m_clk", "uart_synth_gate_clk", }; | 125 | static const char *uart0_parents[] = { "pll3_clk", "uart_syn_gclk", }; |
126 | static const char *firda_parents[] = { "pll3_48m_clk", "firda_synth_gate_clk", | 126 | static const char *firda_parents[] = { "pll3_clk", "firda_syn_gclk", |
127 | }; | 127 | }; |
128 | static const char *gpt0_parents[] = { "pll3_48m_clk", "gpt0_synth_clk", }; | 128 | static const char *gpt0_parents[] = { "pll3_clk", "gpt0_syn_clk", }; |
129 | static const char *gpt1_parents[] = { "pll3_48m_clk", "gpt1_synth_clk", }; | 129 | static const char *gpt1_parents[] = { "pll3_clk", "gpt1_syn_clk", }; |
130 | static const char *gpt2_parents[] = { "pll3_48m_clk", "gpt2_synth_clk", }; | 130 | static const char *gpt2_parents[] = { "pll3_clk", "gpt2_syn_clk", }; |
131 | static const char *gen2_3_parents[] = { "pll1_clk", "pll2_clk", }; | 131 | static const char *gen2_3_parents[] = { "pll1_clk", "pll2_clk", }; |
132 | static const char *ddr_parents[] = { "ahb_clk", "ahbmult2_clk", "none", | 132 | static const char *ddr_parents[] = { "ahb_clk", "ahbmult2_clk", "none", |
133 | "pll2_clk", }; | 133 | "pll2_clk", }; |
@@ -137,7 +137,7 @@ static void __init spear300_clk_init(void) | |||
137 | { | 137 | { |
138 | struct clk *clk; | 138 | struct clk *clk; |
139 | 139 | ||
140 | clk = clk_register_fixed_factor(NULL, "clcd_clk", "ras_pll3_48m_clk", 0, | 140 | clk = clk_register_fixed_factor(NULL, "clcd_clk", "ras_pll3_clk", 0, |
141 | 1, 1); | 141 | 1, 1); |
142 | clk_register_clkdev(clk, NULL, "60000000.clcd"); | 142 | clk_register_clkdev(clk, NULL, "60000000.clcd"); |
143 | 143 | ||
@@ -219,15 +219,11 @@ static void __init spear310_clk_init(void) | |||
219 | #define SPEAR320_UARTX_PCLK_VAL_SYNTH1 0x0 | 219 | #define SPEAR320_UARTX_PCLK_VAL_SYNTH1 0x0 |
220 | #define SPEAR320_UARTX_PCLK_VAL_APB 0x1 | 220 | #define SPEAR320_UARTX_PCLK_VAL_APB 0x1 |
221 | 221 | ||
222 | static const char *i2s_ref_parents[] = { "ras_pll2_clk", | 222 | static const char *i2s_ref_parents[] = { "ras_pll2_clk", "ras_syn2_gclk", }; |
223 | "ras_gen2_synth_gate_clk", }; | 223 | static const char *sdhci_parents[] = { "ras_pll3_clk", "ras_syn3_gclk", }; |
224 | static const char *sdhci_parents[] = { "ras_pll3_48m_clk", | ||
225 | "ras_gen3_synth_gate_clk", | ||
226 | }; | ||
227 | static const char *smii0_parents[] = { "smii_125m_pad", "ras_pll2_clk", | 224 | static const char *smii0_parents[] = { "smii_125m_pad", "ras_pll2_clk", |
228 | "ras_gen0_synth_gate_clk", }; | 225 | "ras_syn0_gclk", }; |
229 | static const char *uartx_parents[] = { "ras_gen1_synth_gate_clk", "ras_apb_clk", | 226 | static const char *uartx_parents[] = { "ras_syn1_gclk", "ras_apb_clk", }; |
230 | }; | ||
231 | 227 | ||
232 | static void __init spear320_clk_init(void) | 228 | static void __init spear320_clk_init(void) |
233 | { | 229 | { |
@@ -237,7 +233,7 @@ static void __init spear320_clk_init(void) | |||
237 | CLK_IS_ROOT, 125000000); | 233 | CLK_IS_ROOT, 125000000); |
238 | clk_register_clkdev(clk, "smii_125m_pad", NULL); | 234 | clk_register_clkdev(clk, "smii_125m_pad", NULL); |
239 | 235 | ||
240 | clk = clk_register_fixed_factor(NULL, "clcd_clk", "ras_pll3_48m_clk", 0, | 236 | clk = clk_register_fixed_factor(NULL, "clcd_clk", "ras_pll3_clk", 0, |
241 | 1, 1); | 237 | 1, 1); |
242 | clk_register_clkdev(clk, NULL, "90000000.clcd"); | 238 | clk_register_clkdev(clk, NULL, "90000000.clcd"); |
243 | 239 | ||
@@ -363,9 +359,9 @@ void __init spear3xx_clk_init(void) | |||
363 | clk_register_clkdev(clk, NULL, "fc900000.rtc"); | 359 | clk_register_clkdev(clk, NULL, "fc900000.rtc"); |
364 | 360 | ||
365 | /* clock derived from 24 MHz osc clk */ | 361 | /* clock derived from 24 MHz osc clk */ |
366 | clk = clk_register_fixed_rate(NULL, "pll3_48m_clk", "osc_24m_clk", 0, | 362 | clk = clk_register_fixed_rate(NULL, "pll3_clk", "osc_24m_clk", 0, |
367 | 48000000); | 363 | 48000000); |
368 | clk_register_clkdev(clk, "pll3_48m_clk", NULL); | 364 | clk_register_clkdev(clk, "pll3_clk", NULL); |
369 | 365 | ||
370 | clk = clk_register_fixed_factor(NULL, "wdt_clk", "osc_24m_clk", 0, 1, | 366 | clk = clk_register_fixed_factor(NULL, "wdt_clk", "osc_24m_clk", 0, 1, |
371 | 1); | 367 | 1); |
@@ -392,98 +388,98 @@ void __init spear3xx_clk_init(void) | |||
392 | HCLK_RATIO_MASK, 0, &_lock); | 388 | HCLK_RATIO_MASK, 0, &_lock); |
393 | clk_register_clkdev(clk, "ahb_clk", NULL); | 389 | clk_register_clkdev(clk, "ahb_clk", NULL); |
394 | 390 | ||
395 | clk = clk_register_aux("uart_synth_clk", "uart_synth_gate_clk", | 391 | clk = clk_register_aux("uart_syn_clk", "uart_syn_gclk", "pll1_clk", 0, |
396 | "pll1_clk", 0, UART_CLK_SYNT, NULL, aux_rtbl, | 392 | UART_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), |
397 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 393 | &_lock, &clk1); |
398 | clk_register_clkdev(clk, "uart_synth_clk", NULL); | 394 | clk_register_clkdev(clk, "uart_syn_clk", NULL); |
399 | clk_register_clkdev(clk1, "uart_synth_gate_clk", NULL); | 395 | clk_register_clkdev(clk1, "uart_syn_gclk", NULL); |
400 | 396 | ||
401 | clk = clk_register_mux(NULL, "uart0_mux_clk", uart0_parents, | 397 | clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents, |
402 | ARRAY_SIZE(uart0_parents), 0, PERIP_CLK_CFG, | 398 | ARRAY_SIZE(uart0_parents), 0, PERIP_CLK_CFG, |
403 | UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock); | 399 | UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock); |
404 | clk_register_clkdev(clk, "uart0_mux_clk", NULL); | 400 | clk_register_clkdev(clk, "uart0_mclk", NULL); |
405 | 401 | ||
406 | clk = clk_register_gate(NULL, "uart0", "uart0_mux_clk", 0, | 402 | clk = clk_register_gate(NULL, "uart0", "uart0_mclk", 0, PERIP1_CLK_ENB, |
407 | PERIP1_CLK_ENB, UART_CLK_ENB, 0, &_lock); | 403 | UART_CLK_ENB, 0, &_lock); |
408 | clk_register_clkdev(clk, NULL, "d0000000.serial"); | 404 | clk_register_clkdev(clk, NULL, "d0000000.serial"); |
409 | 405 | ||
410 | clk = clk_register_aux("firda_synth_clk", "firda_synth_gate_clk", | 406 | clk = clk_register_aux("firda_syn_clk", "firda_syn_gclk", "pll1_clk", 0, |
411 | "pll1_clk", 0, FIRDA_CLK_SYNT, NULL, aux_rtbl, | 407 | FIRDA_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), |
412 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 408 | &_lock, &clk1); |
413 | clk_register_clkdev(clk, "firda_synth_clk", NULL); | 409 | clk_register_clkdev(clk, "firda_syn_clk", NULL); |
414 | clk_register_clkdev(clk1, "firda_synth_gate_clk", NULL); | 410 | clk_register_clkdev(clk1, "firda_syn_gclk", NULL); |
415 | 411 | ||
416 | clk = clk_register_mux(NULL, "firda_mux_clk", firda_parents, | 412 | clk = clk_register_mux(NULL, "firda_mclk", firda_parents, |
417 | ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG, | 413 | ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG, |
418 | FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock); | 414 | FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock); |
419 | clk_register_clkdev(clk, "firda_mux_clk", NULL); | 415 | clk_register_clkdev(clk, "firda_mclk", NULL); |
420 | 416 | ||
421 | clk = clk_register_gate(NULL, "firda_clk", "firda_mux_clk", 0, | 417 | clk = clk_register_gate(NULL, "firda_clk", "firda_mclk", 0, |
422 | PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, &_lock); | 418 | PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, &_lock); |
423 | clk_register_clkdev(clk, NULL, "firda"); | 419 | clk_register_clkdev(clk, NULL, "firda"); |
424 | 420 | ||
425 | /* gpt clocks */ | 421 | /* gpt clocks */ |
426 | clk_register_gpt("gpt0_synth_clk", "pll1_clk", 0, PRSC0_CLK_CFG, | 422 | clk_register_gpt("gpt0_syn_clk", "pll1_clk", 0, PRSC0_CLK_CFG, gpt_rtbl, |
427 | gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); | 423 | ARRAY_SIZE(gpt_rtbl), &_lock); |
428 | clk = clk_register_mux(NULL, "gpt0_clk", gpt0_parents, | 424 | clk = clk_register_mux(NULL, "gpt0_clk", gpt0_parents, |
429 | ARRAY_SIZE(gpt0_parents), 0, PERIP_CLK_CFG, | 425 | ARRAY_SIZE(gpt0_parents), 0, PERIP_CLK_CFG, |
430 | GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); | 426 | GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); |
431 | clk_register_clkdev(clk, NULL, "gpt0"); | 427 | clk_register_clkdev(clk, NULL, "gpt0"); |
432 | 428 | ||
433 | clk_register_gpt("gpt1_synth_clk", "pll1_clk", 0, PRSC1_CLK_CFG, | 429 | clk_register_gpt("gpt1_syn_clk", "pll1_clk", 0, PRSC1_CLK_CFG, gpt_rtbl, |
434 | gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); | 430 | ARRAY_SIZE(gpt_rtbl), &_lock); |
435 | clk = clk_register_mux(NULL, "gpt1_mux_clk", gpt1_parents, | 431 | clk = clk_register_mux(NULL, "gpt1_mclk", gpt1_parents, |
436 | ARRAY_SIZE(gpt1_parents), 0, PERIP_CLK_CFG, | 432 | ARRAY_SIZE(gpt1_parents), 0, PERIP_CLK_CFG, |
437 | GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); | 433 | GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); |
438 | clk_register_clkdev(clk, "gpt1_mux_clk", NULL); | 434 | clk_register_clkdev(clk, "gpt1_mclk", NULL); |
439 | clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mux_clk", 0, | 435 | clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0, |
440 | PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, &_lock); | 436 | PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, &_lock); |
441 | clk_register_clkdev(clk, NULL, "gpt1"); | 437 | clk_register_clkdev(clk, NULL, "gpt1"); |
442 | 438 | ||
443 | clk_register_gpt("gpt2_synth_clk", "pll1_clk", 0, PRSC2_CLK_CFG, | 439 | clk_register_gpt("gpt2_syn_clk", "pll1_clk", 0, PRSC2_CLK_CFG, gpt_rtbl, |
444 | gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); | 440 | ARRAY_SIZE(gpt_rtbl), &_lock); |
445 | clk = clk_register_mux(NULL, "gpt2_mux_clk", gpt2_parents, | 441 | clk = clk_register_mux(NULL, "gpt2_mclk", gpt2_parents, |
446 | ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG, | 442 | ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG, |
447 | GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); | 443 | GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); |
448 | clk_register_clkdev(clk, "gpt2_mux_clk", NULL); | 444 | clk_register_clkdev(clk, "gpt2_mclk", NULL); |
449 | clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mux_clk", 0, | 445 | clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0, |
450 | PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, &_lock); | 446 | PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, &_lock); |
451 | clk_register_clkdev(clk, NULL, "gpt2"); | 447 | clk_register_clkdev(clk, NULL, "gpt2"); |
452 | 448 | ||
453 | /* general synths clocks */ | 449 | /* general synths clocks */ |
454 | clk = clk_register_aux("gen0_synth_clk", "gen0_synth_gate_clk", | 450 | clk = clk_register_aux("gen0_syn_clk", "gen0_syn_gclk", "pll1_clk", |
455 | "pll1_clk", 0, GEN0_CLK_SYNT, NULL, aux_rtbl, | 451 | 0, GEN0_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), |
456 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 452 | &_lock, &clk1); |
457 | clk_register_clkdev(clk, "gen0_synth_clk", NULL); | 453 | clk_register_clkdev(clk, "gen0_syn_clk", NULL); |
458 | clk_register_clkdev(clk1, "gen0_synth_gate_clk", NULL); | 454 | clk_register_clkdev(clk1, "gen0_syn_gclk", NULL); |
459 | 455 | ||
460 | clk = clk_register_aux("gen1_synth_clk", "gen1_synth_gate_clk", | 456 | clk = clk_register_aux("gen1_syn_clk", "gen1_syn_gclk", "pll1_clk", |
461 | "pll1_clk", 0, GEN1_CLK_SYNT, NULL, aux_rtbl, | 457 | 0, GEN1_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), |
462 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 458 | &_lock, &clk1); |
463 | clk_register_clkdev(clk, "gen1_synth_clk", NULL); | 459 | clk_register_clkdev(clk, "gen1_syn_clk", NULL); |
464 | clk_register_clkdev(clk1, "gen1_synth_gate_clk", NULL); | 460 | clk_register_clkdev(clk1, "gen1_syn_gclk", NULL); |
465 | 461 | ||
466 | clk = clk_register_mux(NULL, "gen2_3_parent_clk", gen2_3_parents, | 462 | clk = clk_register_mux(NULL, "gen2_3_par_clk", gen2_3_parents, |
467 | ARRAY_SIZE(gen2_3_parents), 0, CORE_CLK_CFG, | 463 | ARRAY_SIZE(gen2_3_parents), 0, CORE_CLK_CFG, |
468 | GEN_SYNTH2_3_CLK_SHIFT, GEN_SYNTH2_3_CLK_MASK, 0, | 464 | GEN_SYNTH2_3_CLK_SHIFT, GEN_SYNTH2_3_CLK_MASK, 0, |
469 | &_lock); | 465 | &_lock); |
470 | clk_register_clkdev(clk, "gen2_3_parent_clk", NULL); | 466 | clk_register_clkdev(clk, "gen2_3_par_clk", NULL); |
471 | 467 | ||
472 | clk = clk_register_aux("gen2_synth_clk", "gen2_synth_gate_clk", | 468 | clk = clk_register_aux("gen2_syn_clk", "gen2_syn_gclk", |
473 | "gen2_3_parent_clk", 0, GEN2_CLK_SYNT, NULL, aux_rtbl, | 469 | "gen2_3_par_clk", 0, GEN2_CLK_SYNT, NULL, aux_rtbl, |
474 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 470 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); |
475 | clk_register_clkdev(clk, "gen2_synth_clk", NULL); | 471 | clk_register_clkdev(clk, "gen2_syn_clk", NULL); |
476 | clk_register_clkdev(clk1, "gen2_synth_gate_clk", NULL); | 472 | clk_register_clkdev(clk1, "gen2_syn_gclk", NULL); |
477 | 473 | ||
478 | clk = clk_register_aux("gen3_synth_clk", "gen3_synth_gate_clk", | 474 | clk = clk_register_aux("gen3_syn_clk", "gen3_syn_gclk", |
479 | "gen2_3_parent_clk", 0, GEN3_CLK_SYNT, NULL, aux_rtbl, | 475 | "gen2_3_par_clk", 0, GEN3_CLK_SYNT, NULL, aux_rtbl, |
480 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 476 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); |
481 | clk_register_clkdev(clk, "gen3_synth_clk", NULL); | 477 | clk_register_clkdev(clk, "gen3_syn_clk", NULL); |
482 | clk_register_clkdev(clk1, "gen3_synth_gate_clk", NULL); | 478 | clk_register_clkdev(clk1, "gen3_syn_gclk", NULL); |
483 | 479 | ||
484 | /* clock derived from pll3 clk */ | 480 | /* clock derived from pll3 clk */ |
485 | clk = clk_register_gate(NULL, "usbh_clk", "pll3_48m_clk", 0, | 481 | clk = clk_register_gate(NULL, "usbh_clk", "pll3_clk", 0, PERIP1_CLK_ENB, |
486 | PERIP1_CLK_ENB, USBH_CLK_ENB, 0, &_lock); | 482 | USBH_CLK_ENB, 0, &_lock); |
487 | clk_register_clkdev(clk, "usbh_clk", NULL); | 483 | clk_register_clkdev(clk, "usbh_clk", NULL); |
488 | 484 | ||
489 | clk = clk_register_fixed_factor(NULL, "usbh.0_clk", "usbh_clk", 0, 1, | 485 | clk = clk_register_fixed_factor(NULL, "usbh.0_clk", "usbh_clk", 0, 1, |
@@ -494,8 +490,8 @@ void __init spear3xx_clk_init(void) | |||
494 | 1); | 490 | 1); |
495 | clk_register_clkdev(clk, "usbh.1_clk", NULL); | 491 | clk_register_clkdev(clk, "usbh.1_clk", NULL); |
496 | 492 | ||
497 | clk = clk_register_gate(NULL, "usbd_clk", "pll3_48m_clk", 0, | 493 | clk = clk_register_gate(NULL, "usbd_clk", "pll3_clk", 0, PERIP1_CLK_ENB, |
498 | PERIP1_CLK_ENB, USBD_CLK_ENB, 0, &_lock); | 494 | USBD_CLK_ENB, 0, &_lock); |
499 | clk_register_clkdev(clk, NULL, "designware_udc"); | 495 | clk_register_clkdev(clk, NULL, "designware_udc"); |
500 | 496 | ||
501 | /* clock derived from ahb clk */ | 497 | /* clock derived from ahb clk */ |
@@ -579,29 +575,25 @@ void __init spear3xx_clk_init(void) | |||
579 | RAS_CLK_ENB, RAS_PLL2_CLK_ENB, 0, &_lock); | 575 | RAS_CLK_ENB, RAS_PLL2_CLK_ENB, 0, &_lock); |
580 | clk_register_clkdev(clk, "ras_pll2_clk", NULL); | 576 | clk_register_clkdev(clk, "ras_pll2_clk", NULL); |
581 | 577 | ||
582 | clk = clk_register_gate(NULL, "ras_pll3_48m_clk", "pll3_48m_clk", 0, | 578 | clk = clk_register_gate(NULL, "ras_pll3_clk", "pll3_clk", 0, |
583 | RAS_CLK_ENB, RAS_48M_CLK_ENB, 0, &_lock); | 579 | RAS_CLK_ENB, RAS_48M_CLK_ENB, 0, &_lock); |
584 | clk_register_clkdev(clk, "ras_pll3_48m_clk", NULL); | 580 | clk_register_clkdev(clk, "ras_pll3_clk", NULL); |
585 | 581 | ||
586 | clk = clk_register_gate(NULL, "ras_gen0_synth_gate_clk", | 582 | clk = clk_register_gate(NULL, "ras_syn0_gclk", "gen0_syn_gclk", 0, |
587 | "gen0_synth_gate_clk", 0, RAS_CLK_ENB, | 583 | RAS_CLK_ENB, RAS_SYNT0_CLK_ENB, 0, &_lock); |
588 | RAS_SYNT0_CLK_ENB, 0, &_lock); | 584 | clk_register_clkdev(clk, "ras_syn0_gclk", NULL); |
589 | clk_register_clkdev(clk, "ras_gen0_synth_gate_clk", NULL); | 585 | |
590 | 586 | clk = clk_register_gate(NULL, "ras_syn1_gclk", "gen1_syn_gclk", 0, | |
591 | clk = clk_register_gate(NULL, "ras_gen1_synth_gate_clk", | 587 | RAS_CLK_ENB, RAS_SYNT1_CLK_ENB, 0, &_lock); |
592 | "gen1_synth_gate_clk", 0, RAS_CLK_ENB, | 588 | clk_register_clkdev(clk, "ras_syn1_gclk", NULL); |
593 | RAS_SYNT1_CLK_ENB, 0, &_lock); | 589 | |
594 | clk_register_clkdev(clk, "ras_gen1_synth_gate_clk", NULL); | 590 | clk = clk_register_gate(NULL, "ras_syn2_gclk", "gen2_syn_gclk", 0, |
595 | 591 | RAS_CLK_ENB, RAS_SYNT2_CLK_ENB, 0, &_lock); | |
596 | clk = clk_register_gate(NULL, "ras_gen2_synth_gate_clk", | 592 | clk_register_clkdev(clk, "ras_syn2_gclk", NULL); |
597 | "gen2_synth_gate_clk", 0, RAS_CLK_ENB, | 593 | |
598 | RAS_SYNT2_CLK_ENB, 0, &_lock); | 594 | clk = clk_register_gate(NULL, "ras_syn3_gclk", "gen3_syn_gclk", 0, |
599 | clk_register_clkdev(clk, "ras_gen2_synth_gate_clk", NULL); | 595 | RAS_CLK_ENB, RAS_SYNT3_CLK_ENB, 0, &_lock); |
600 | 596 | clk_register_clkdev(clk, "ras_syn3_gclk", NULL); | |
601 | clk = clk_register_gate(NULL, "ras_gen3_synth_gate_clk", | ||
602 | "gen3_synth_gate_clk", 0, RAS_CLK_ENB, | ||
603 | RAS_SYNT3_CLK_ENB, 0, &_lock); | ||
604 | clk_register_clkdev(clk, "ras_gen3_synth_gate_clk", NULL); | ||
605 | 597 | ||
606 | if (of_machine_is_compatible("st,spear300")) | 598 | if (of_machine_is_compatible("st,spear300")) |
607 | spear300_clk_init(); | 599 | spear300_clk_init(); |
diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index 61026ae564ab..a98d0866f541 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c | |||
@@ -97,13 +97,12 @@ static struct aux_rate_tbl aux_rtbl[] = { | |||
97 | {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */ | 97 | {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */ |
98 | }; | 98 | }; |
99 | 99 | ||
100 | static const char *clcd_parents[] = { "pll3_48m_clk", "clcd_synth_gate_clk", }; | 100 | static const char *clcd_parents[] = { "pll3_clk", "clcd_syn_gclk", }; |
101 | static const char *firda_parents[] = { "pll3_48m_clk", "firda_synth_gate_clk", | 101 | static const char *firda_parents[] = { "pll3_clk", "firda_syn_gclk", }; |
102 | }; | 102 | static const char *uart_parents[] = { "pll3_clk", "uart_syn_gclk", }; |
103 | static const char *uart_parents[] = { "pll3_48m_clk", "uart_synth_gate_clk", }; | 103 | static const char *gpt0_1_parents[] = { "pll3_clk", "gpt0_1_syn_clk", }; |
104 | static const char *gpt0_1_parents[] = { "pll3_48m_clk", "gpt0_1_synth_clk", }; | 104 | static const char *gpt2_parents[] = { "pll3_clk", "gpt2_syn_clk", }; |
105 | static const char *gpt2_parents[] = { "pll3_48m_clk", "gpt2_synth_clk", }; | 105 | static const char *gpt3_parents[] = { "pll3_clk", "gpt3_syn_clk", }; |
106 | static const char *gpt3_parents[] = { "pll3_48m_clk", "gpt3_synth_clk", }; | ||
107 | static const char *ddr_parents[] = { "ahb_clk", "ahbmult2_clk", "none", | 106 | static const char *ddr_parents[] = { "ahb_clk", "ahbmult2_clk", "none", |
108 | "pll2_clk", }; | 107 | "pll2_clk", }; |
109 | 108 | ||
@@ -136,9 +135,9 @@ void __init spear6xx_clk_init(void) | |||
136 | clk_register_clkdev(clk, NULL, "rtc-spear"); | 135 | clk_register_clkdev(clk, NULL, "rtc-spear"); |
137 | 136 | ||
138 | /* clock derived from 30 MHz osc clk */ | 137 | /* clock derived from 30 MHz osc clk */ |
139 | clk = clk_register_fixed_rate(NULL, "pll3_48m_clk", "osc_24m_clk", 0, | 138 | clk = clk_register_fixed_rate(NULL, "pll3_clk", "osc_24m_clk", 0, |
140 | 48000000); | 139 | 48000000); |
141 | clk_register_clkdev(clk, "pll3_48m_clk", NULL); | 140 | clk_register_clkdev(clk, "pll3_clk", NULL); |
142 | 141 | ||
143 | clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "osc_30m_clk", | 142 | clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "osc_30m_clk", |
144 | 0, PLL1_CTR, PLL1_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl), | 143 | 0, PLL1_CTR, PLL1_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl), |
@@ -146,9 +145,9 @@ void __init spear6xx_clk_init(void) | |||
146 | clk_register_clkdev(clk, "vco1_clk", NULL); | 145 | clk_register_clkdev(clk, "vco1_clk", NULL); |
147 | clk_register_clkdev(clk1, "pll1_clk", NULL); | 146 | clk_register_clkdev(clk1, "pll1_clk", NULL); |
148 | 147 | ||
149 | clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, | 148 | clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "osc_30m_clk", |
150 | "osc_30m_clk", 0, PLL2_CTR, PLL2_FRQ, pll_rtbl, | 149 | 0, PLL2_CTR, PLL2_FRQ, pll_rtbl, ARRAY_SIZE(pll_rtbl), |
151 | ARRAY_SIZE(pll_rtbl), &_lock, &clk1, NULL); | 150 | &_lock, &clk1, NULL); |
152 | clk_register_clkdev(clk, "vco2_clk", NULL); | 151 | clk_register_clkdev(clk, "vco2_clk", NULL); |
153 | clk_register_clkdev(clk1, "pll2_clk", NULL); | 152 | clk_register_clkdev(clk1, "pll2_clk", NULL); |
154 | 153 | ||
@@ -165,111 +164,111 @@ void __init spear6xx_clk_init(void) | |||
165 | HCLK_RATIO_MASK, 0, &_lock); | 164 | HCLK_RATIO_MASK, 0, &_lock); |
166 | clk_register_clkdev(clk, "ahb_clk", NULL); | 165 | clk_register_clkdev(clk, "ahb_clk", NULL); |
167 | 166 | ||
168 | clk = clk_register_aux("uart_synth_clk", "uart_synth_gate_clk", | 167 | clk = clk_register_aux("uart_syn_clk", "uart_syn_gclk", "pll1_clk", 0, |
169 | "pll1_clk", 0, UART_CLK_SYNT, NULL, aux_rtbl, | 168 | UART_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), |
170 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 169 | &_lock, &clk1); |
171 | clk_register_clkdev(clk, "uart_synth_clk", NULL); | 170 | clk_register_clkdev(clk, "uart_syn_clk", NULL); |
172 | clk_register_clkdev(clk1, "uart_synth_gate_clk", NULL); | 171 | clk_register_clkdev(clk1, "uart_syn_gclk", NULL); |
173 | 172 | ||
174 | clk = clk_register_mux(NULL, "uart_mux_clk", uart_parents, | 173 | clk = clk_register_mux(NULL, "uart_mclk", uart_parents, |
175 | ARRAY_SIZE(uart_parents), 0, PERIP_CLK_CFG, | 174 | ARRAY_SIZE(uart_parents), 0, PERIP_CLK_CFG, |
176 | UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock); | 175 | UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock); |
177 | clk_register_clkdev(clk, "uart_mux_clk", NULL); | 176 | clk_register_clkdev(clk, "uart_mclk", NULL); |
178 | 177 | ||
179 | clk = clk_register_gate(NULL, "uart0", "uart_mux_clk", 0, | 178 | clk = clk_register_gate(NULL, "uart0", "uart_mclk", 0, PERIP1_CLK_ENB, |
180 | PERIP1_CLK_ENB, UART0_CLK_ENB, 0, &_lock); | 179 | UART0_CLK_ENB, 0, &_lock); |
181 | clk_register_clkdev(clk, NULL, "d0000000.serial"); | 180 | clk_register_clkdev(clk, NULL, "d0000000.serial"); |
182 | 181 | ||
183 | clk = clk_register_gate(NULL, "uart1", "uart_mux_clk", 0, | 182 | clk = clk_register_gate(NULL, "uart1", "uart_mclk", 0, PERIP1_CLK_ENB, |
184 | PERIP1_CLK_ENB, UART1_CLK_ENB, 0, &_lock); | 183 | UART1_CLK_ENB, 0, &_lock); |
185 | clk_register_clkdev(clk, NULL, "d0080000.serial"); | 184 | clk_register_clkdev(clk, NULL, "d0080000.serial"); |
186 | 185 | ||
187 | clk = clk_register_aux("firda_synth_clk", "firda_synth_gate_clk", | 186 | clk = clk_register_aux("firda_syn_clk", "firda_syn_gclk", "pll1_clk", |
188 | "pll1_clk", 0, FIRDA_CLK_SYNT, NULL, aux_rtbl, | 187 | 0, FIRDA_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), |
189 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 188 | &_lock, &clk1); |
190 | clk_register_clkdev(clk, "firda_synth_clk", NULL); | 189 | clk_register_clkdev(clk, "firda_syn_clk", NULL); |
191 | clk_register_clkdev(clk1, "firda_synth_gate_clk", NULL); | 190 | clk_register_clkdev(clk1, "firda_syn_gclk", NULL); |
192 | 191 | ||
193 | clk = clk_register_mux(NULL, "firda_mux_clk", firda_parents, | 192 | clk = clk_register_mux(NULL, "firda_mclk", firda_parents, |
194 | ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG, | 193 | ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG, |
195 | FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock); | 194 | FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock); |
196 | clk_register_clkdev(clk, "firda_mux_clk", NULL); | 195 | clk_register_clkdev(clk, "firda_mclk", NULL); |
197 | 196 | ||
198 | clk = clk_register_gate(NULL, "firda_clk", "firda_mux_clk", 0, | 197 | clk = clk_register_gate(NULL, "firda_clk", "firda_mclk", 0, |
199 | PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, &_lock); | 198 | PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, &_lock); |
200 | clk_register_clkdev(clk, NULL, "firda"); | 199 | clk_register_clkdev(clk, NULL, "firda"); |
201 | 200 | ||
202 | clk = clk_register_aux("clcd_synth_clk", "clcd_synth_gate_clk", | 201 | clk = clk_register_aux("clcd_syn_clk", "clcd_syn_gclk", "pll1_clk", |
203 | "pll1_clk", 0, CLCD_CLK_SYNT, NULL, aux_rtbl, | 202 | 0, CLCD_CLK_SYNT, NULL, aux_rtbl, ARRAY_SIZE(aux_rtbl), |
204 | ARRAY_SIZE(aux_rtbl), &_lock, &clk1); | 203 | &_lock, &clk1); |
205 | clk_register_clkdev(clk, "clcd_synth_clk", NULL); | 204 | clk_register_clkdev(clk, "clcd_syn_clk", NULL); |
206 | clk_register_clkdev(clk1, "clcd_synth_gate_clk", NULL); | 205 | clk_register_clkdev(clk1, "clcd_syn_gclk", NULL); |
207 | 206 | ||
208 | clk = clk_register_mux(NULL, "clcd_mux_clk", clcd_parents, | 207 | clk = clk_register_mux(NULL, "clcd_mclk", clcd_parents, |
209 | ARRAY_SIZE(clcd_parents), 0, PERIP_CLK_CFG, | 208 | ARRAY_SIZE(clcd_parents), 0, PERIP_CLK_CFG, |
210 | CLCD_CLK_SHIFT, CLCD_CLK_MASK, 0, &_lock); | 209 | CLCD_CLK_SHIFT, CLCD_CLK_MASK, 0, &_lock); |
211 | clk_register_clkdev(clk, "clcd_mux_clk", NULL); | 210 | clk_register_clkdev(clk, "clcd_mclk", NULL); |
212 | 211 | ||
213 | clk = clk_register_gate(NULL, "clcd_clk", "clcd_mux_clk", 0, | 212 | clk = clk_register_gate(NULL, "clcd_clk", "clcd_mclk", 0, |
214 | PERIP1_CLK_ENB, CLCD_CLK_ENB, 0, &_lock); | 213 | PERIP1_CLK_ENB, CLCD_CLK_ENB, 0, &_lock); |
215 | clk_register_clkdev(clk, NULL, "clcd"); | 214 | clk_register_clkdev(clk, NULL, "clcd"); |
216 | 215 | ||
217 | /* gpt clocks */ | 216 | /* gpt clocks */ |
218 | clk = clk_register_gpt("gpt0_1_synth_clk", "pll1_clk", 0, PRSC0_CLK_CFG, | 217 | clk = clk_register_gpt("gpt0_1_syn_clk", "pll1_clk", 0, PRSC0_CLK_CFG, |
219 | gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); | 218 | gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); |
220 | clk_register_clkdev(clk, "gpt0_1_synth_clk", NULL); | 219 | clk_register_clkdev(clk, "gpt0_1_syn_clk", NULL); |
221 | 220 | ||
222 | clk = clk_register_mux(NULL, "gpt0_mux_clk", gpt0_1_parents, | 221 | clk = clk_register_mux(NULL, "gpt0_mclk", gpt0_1_parents, |
223 | ARRAY_SIZE(gpt0_1_parents), 0, PERIP_CLK_CFG, | 222 | ARRAY_SIZE(gpt0_1_parents), 0, PERIP_CLK_CFG, |
224 | GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); | 223 | GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); |
225 | clk_register_clkdev(clk, NULL, "gpt0"); | 224 | clk_register_clkdev(clk, NULL, "gpt0"); |
226 | 225 | ||
227 | clk = clk_register_mux(NULL, "gpt1_mux_clk", gpt0_1_parents, | 226 | clk = clk_register_mux(NULL, "gpt1_mclk", gpt0_1_parents, |
228 | ARRAY_SIZE(gpt0_1_parents), 0, PERIP_CLK_CFG, | 227 | ARRAY_SIZE(gpt0_1_parents), 0, PERIP_CLK_CFG, |
229 | GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); | 228 | GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); |
230 | clk_register_clkdev(clk, "gpt1_mux_clk", NULL); | 229 | clk_register_clkdev(clk, "gpt1_mclk", NULL); |
231 | 230 | ||
232 | clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mux_clk", 0, | 231 | clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0, |
233 | PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, &_lock); | 232 | PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, &_lock); |
234 | clk_register_clkdev(clk, NULL, "gpt1"); | 233 | clk_register_clkdev(clk, NULL, "gpt1"); |
235 | 234 | ||
236 | clk = clk_register_gpt("gpt2_synth_clk", "pll1_clk", 0, PRSC1_CLK_CFG, | 235 | clk = clk_register_gpt("gpt2_syn_clk", "pll1_clk", 0, PRSC1_CLK_CFG, |
237 | gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); | 236 | gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); |
238 | clk_register_clkdev(clk, "gpt2_synth_clk", NULL); | 237 | clk_register_clkdev(clk, "gpt2_syn_clk", NULL); |
239 | 238 | ||
240 | clk = clk_register_mux(NULL, "gpt2_mux_clk", gpt2_parents, | 239 | clk = clk_register_mux(NULL, "gpt2_mclk", gpt2_parents, |
241 | ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG, | 240 | ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG, |
242 | GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); | 241 | GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); |
243 | clk_register_clkdev(clk, "gpt2_mux_clk", NULL); | 242 | clk_register_clkdev(clk, "gpt2_mclk", NULL); |
244 | 243 | ||
245 | clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mux_clk", 0, | 244 | clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0, |
246 | PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, &_lock); | 245 | PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, &_lock); |
247 | clk_register_clkdev(clk, NULL, "gpt2"); | 246 | clk_register_clkdev(clk, NULL, "gpt2"); |
248 | 247 | ||
249 | clk = clk_register_gpt("gpt3_synth_clk", "pll1_clk", 0, PRSC2_CLK_CFG, | 248 | clk = clk_register_gpt("gpt3_syn_clk", "pll1_clk", 0, PRSC2_CLK_CFG, |
250 | gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); | 249 | gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); |
251 | clk_register_clkdev(clk, "gpt3_synth_clk", NULL); | 250 | clk_register_clkdev(clk, "gpt3_syn_clk", NULL); |
252 | 251 | ||
253 | clk = clk_register_mux(NULL, "gpt3_mux_clk", gpt3_parents, | 252 | clk = clk_register_mux(NULL, "gpt3_mclk", gpt3_parents, |
254 | ARRAY_SIZE(gpt3_parents), 0, PERIP_CLK_CFG, | 253 | ARRAY_SIZE(gpt3_parents), 0, PERIP_CLK_CFG, |
255 | GPT3_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); | 254 | GPT3_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); |
256 | clk_register_clkdev(clk, "gpt3_mux_clk", NULL); | 255 | clk_register_clkdev(clk, "gpt3_mclk", NULL); |
257 | 256 | ||
258 | clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mux_clk", 0, | 257 | clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mclk", 0, |
259 | PERIP1_CLK_ENB, GPT3_CLK_ENB, 0, &_lock); | 258 | PERIP1_CLK_ENB, GPT3_CLK_ENB, 0, &_lock); |
260 | clk_register_clkdev(clk, NULL, "gpt3"); | 259 | clk_register_clkdev(clk, NULL, "gpt3"); |
261 | 260 | ||
262 | /* clock derived from pll3 clk */ | 261 | /* clock derived from pll3 clk */ |
263 | clk = clk_register_gate(NULL, "usbh0_clk", "pll3_48m_clk", 0, | 262 | clk = clk_register_gate(NULL, "usbh0_clk", "pll3_clk", 0, |
264 | PERIP1_CLK_ENB, USBH0_CLK_ENB, 0, &_lock); | 263 | PERIP1_CLK_ENB, USBH0_CLK_ENB, 0, &_lock); |
265 | clk_register_clkdev(clk, NULL, "usbh.0_clk"); | 264 | clk_register_clkdev(clk, NULL, "usbh.0_clk"); |
266 | 265 | ||
267 | clk = clk_register_gate(NULL, "usbh1_clk", "pll3_48m_clk", 0, | 266 | clk = clk_register_gate(NULL, "usbh1_clk", "pll3_clk", 0, |
268 | PERIP1_CLK_ENB, USBH1_CLK_ENB, 0, &_lock); | 267 | PERIP1_CLK_ENB, USBH1_CLK_ENB, 0, &_lock); |
269 | clk_register_clkdev(clk, NULL, "usbh.1_clk"); | 268 | clk_register_clkdev(clk, NULL, "usbh.1_clk"); |
270 | 269 | ||
271 | clk = clk_register_gate(NULL, "usbd_clk", "pll3_48m_clk", 0, | 270 | clk = clk_register_gate(NULL, "usbd_clk", "pll3_clk", 0, PERIP1_CLK_ENB, |
272 | PERIP1_CLK_ENB, USBD_CLK_ENB, 0, &_lock); | 271 | USBD_CLK_ENB, 0, &_lock); |
273 | clk_register_clkdev(clk, NULL, "designware_udc"); | 272 | clk_register_clkdev(clk, NULL, "designware_udc"); |
274 | 273 | ||
275 | /* clock derived from ahb clk */ | 274 | /* clock derived from ahb clk */ |
@@ -278,9 +277,8 @@ void __init spear6xx_clk_init(void) | |||
278 | clk_register_clkdev(clk, "ahbmult2_clk", NULL); | 277 | clk_register_clkdev(clk, "ahbmult2_clk", NULL); |
279 | 278 | ||
280 | clk = clk_register_mux(NULL, "ddr_clk", ddr_parents, | 279 | clk = clk_register_mux(NULL, "ddr_clk", ddr_parents, |
281 | ARRAY_SIZE(ddr_parents), | 280 | ARRAY_SIZE(ddr_parents), 0, PLL_CLK_CFG, MCTR_CLK_SHIFT, |
282 | 0, PLL_CLK_CFG, MCTR_CLK_SHIFT, MCTR_CLK_MASK, 0, | 281 | MCTR_CLK_MASK, 0, &_lock); |
283 | &_lock); | ||
284 | clk_register_clkdev(clk, "ddr_clk", NULL); | 282 | clk_register_clkdev(clk, "ddr_clk", NULL); |
285 | 283 | ||
286 | clk = clk_register_divider(NULL, "apb_clk", "ahb_clk", | 284 | clk = clk_register_divider(NULL, "apb_clk", "ahb_clk", |
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c index 9764045428ce..b7e7b49d8f62 100644 --- a/drivers/gpu/drm/gma500/cdv_device.c +++ b/drivers/gpu/drm/gma500/cdv_device.c | |||
@@ -78,21 +78,6 @@ static int cdv_backlight_combination_mode(struct drm_device *dev) | |||
78 | return REG_READ(BLC_PWM_CTL2) & PWM_LEGACY_MODE; | 78 | return REG_READ(BLC_PWM_CTL2) & PWM_LEGACY_MODE; |
79 | } | 79 | } |
80 | 80 | ||
81 | static int cdv_get_brightness(struct backlight_device *bd) | ||
82 | { | ||
83 | struct drm_device *dev = bl_get_data(bd); | ||
84 | u32 val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; | ||
85 | |||
86 | if (cdv_backlight_combination_mode(dev)) { | ||
87 | u8 lbpc; | ||
88 | |||
89 | val &= ~1; | ||
90 | pci_read_config_byte(dev->pdev, 0xF4, &lbpc); | ||
91 | val *= lbpc; | ||
92 | } | ||
93 | return val; | ||
94 | } | ||
95 | |||
96 | static u32 cdv_get_max_backlight(struct drm_device *dev) | 81 | static u32 cdv_get_max_backlight(struct drm_device *dev) |
97 | { | 82 | { |
98 | u32 max = REG_READ(BLC_PWM_CTL); | 83 | u32 max = REG_READ(BLC_PWM_CTL); |
@@ -110,6 +95,22 @@ static u32 cdv_get_max_backlight(struct drm_device *dev) | |||
110 | return max; | 95 | return max; |
111 | } | 96 | } |
112 | 97 | ||
98 | static int cdv_get_brightness(struct backlight_device *bd) | ||
99 | { | ||
100 | struct drm_device *dev = bl_get_data(bd); | ||
101 | u32 val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; | ||
102 | |||
103 | if (cdv_backlight_combination_mode(dev)) { | ||
104 | u8 lbpc; | ||
105 | |||
106 | val &= ~1; | ||
107 | pci_read_config_byte(dev->pdev, 0xF4, &lbpc); | ||
108 | val *= lbpc; | ||
109 | } | ||
110 | return (val * 100)/cdv_get_max_backlight(dev); | ||
111 | |||
112 | } | ||
113 | |||
113 | static int cdv_set_brightness(struct backlight_device *bd) | 114 | static int cdv_set_brightness(struct backlight_device *bd) |
114 | { | 115 | { |
115 | struct drm_device *dev = bl_get_data(bd); | 116 | struct drm_device *dev = bl_get_data(bd); |
@@ -120,6 +121,9 @@ static int cdv_set_brightness(struct backlight_device *bd) | |||
120 | if (level < 1) | 121 | if (level < 1) |
121 | level = 1; | 122 | level = 1; |
122 | 123 | ||
124 | level *= cdv_get_max_backlight(dev); | ||
125 | level /= 100; | ||
126 | |||
123 | if (cdv_backlight_combination_mode(dev)) { | 127 | if (cdv_backlight_combination_mode(dev)) { |
124 | u32 max = cdv_get_max_backlight(dev); | 128 | u32 max = cdv_get_max_backlight(dev); |
125 | u8 lbpc; | 129 | u8 lbpc; |
@@ -157,7 +161,6 @@ static int cdv_backlight_init(struct drm_device *dev) | |||
157 | 161 | ||
158 | cdv_backlight_device->props.brightness = | 162 | cdv_backlight_device->props.brightness = |
159 | cdv_get_brightness(cdv_backlight_device); | 163 | cdv_get_brightness(cdv_backlight_device); |
160 | cdv_backlight_device->props.max_brightness = cdv_get_max_backlight(dev); | ||
161 | backlight_update_status(cdv_backlight_device); | 164 | backlight_update_status(cdv_backlight_device); |
162 | dev_priv->backlight_device = cdv_backlight_device; | 165 | dev_priv->backlight_device = cdv_backlight_device; |
163 | return 0; | 166 | return 0; |
diff --git a/drivers/gpu/drm/gma500/opregion.c b/drivers/gpu/drm/gma500/opregion.c index 4f186eca3a30..c430bd424681 100644 --- a/drivers/gpu/drm/gma500/opregion.c +++ b/drivers/gpu/drm/gma500/opregion.c | |||
@@ -144,6 +144,8 @@ struct opregion_asle { | |||
144 | 144 | ||
145 | #define ASLE_CBLV_VALID (1<<31) | 145 | #define ASLE_CBLV_VALID (1<<31) |
146 | 146 | ||
147 | static struct psb_intel_opregion *system_opregion; | ||
148 | |||
147 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | 149 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) |
148 | { | 150 | { |
149 | struct drm_psb_private *dev_priv = dev->dev_private; | 151 | struct drm_psb_private *dev_priv = dev->dev_private; |
@@ -205,7 +207,7 @@ void psb_intel_opregion_enable_asle(struct drm_device *dev) | |||
205 | struct drm_psb_private *dev_priv = dev->dev_private; | 207 | struct drm_psb_private *dev_priv = dev->dev_private; |
206 | struct opregion_asle *asle = dev_priv->opregion.asle; | 208 | struct opregion_asle *asle = dev_priv->opregion.asle; |
207 | 209 | ||
208 | if (asle) { | 210 | if (asle && system_opregion ) { |
209 | /* Don't do this on Medfield or other non PC like devices, they | 211 | /* Don't do this on Medfield or other non PC like devices, they |
210 | use the bit for something different altogether */ | 212 | use the bit for something different altogether */ |
211 | psb_enable_pipestat(dev_priv, 0, PIPE_LEGACY_BLC_EVENT_ENABLE); | 213 | psb_enable_pipestat(dev_priv, 0, PIPE_LEGACY_BLC_EVENT_ENABLE); |
@@ -221,7 +223,6 @@ void psb_intel_opregion_enable_asle(struct drm_device *dev) | |||
221 | #define ACPI_EV_LID (1<<1) | 223 | #define ACPI_EV_LID (1<<1) |
222 | #define ACPI_EV_DOCK (1<<2) | 224 | #define ACPI_EV_DOCK (1<<2) |
223 | 225 | ||
224 | static struct psb_intel_opregion *system_opregion; | ||
225 | 226 | ||
226 | static int psb_intel_opregion_video_event(struct notifier_block *nb, | 227 | static int psb_intel_opregion_video_event(struct notifier_block *nb, |
227 | unsigned long val, void *data) | 228 | unsigned long val, void *data) |
@@ -266,9 +267,6 @@ void psb_intel_opregion_init(struct drm_device *dev) | |||
266 | system_opregion = opregion; | 267 | system_opregion = opregion; |
267 | register_acpi_notifier(&psb_intel_opregion_notifier); | 268 | register_acpi_notifier(&psb_intel_opregion_notifier); |
268 | } | 269 | } |
269 | |||
270 | if (opregion->asle) | ||
271 | psb_intel_opregion_enable_asle(dev); | ||
272 | } | 270 | } |
273 | 271 | ||
274 | void psb_intel_opregion_fini(struct drm_device *dev) | 272 | void psb_intel_opregion_fini(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/gma500/opregion.h b/drivers/gpu/drm/gma500/opregion.h index 72dc6b921265..4a90f8b0e16c 100644 --- a/drivers/gpu/drm/gma500/opregion.h +++ b/drivers/gpu/drm/gma500/opregion.h | |||
@@ -27,6 +27,7 @@ extern void psb_intel_opregion_asle_intr(struct drm_device *dev); | |||
27 | extern void psb_intel_opregion_init(struct drm_device *dev); | 27 | extern void psb_intel_opregion_init(struct drm_device *dev); |
28 | extern void psb_intel_opregion_fini(struct drm_device *dev); | 28 | extern void psb_intel_opregion_fini(struct drm_device *dev); |
29 | extern int psb_intel_opregion_setup(struct drm_device *dev); | 29 | extern int psb_intel_opregion_setup(struct drm_device *dev); |
30 | extern void psb_intel_opregion_enable_asle(struct drm_device *dev); | ||
30 | 31 | ||
31 | #else | 32 | #else |
32 | 33 | ||
@@ -46,4 +47,8 @@ extern inline int psb_intel_opregion_setup(struct drm_device *dev) | |||
46 | { | 47 | { |
47 | return 0; | 48 | return 0; |
48 | } | 49 | } |
50 | |||
51 | extern inline void psb_intel_opregion_enable_asle(struct drm_device *dev) | ||
52 | { | ||
53 | } | ||
49 | #endif | 54 | #endif |
diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c index eff039bf92d4..5971bc82b765 100644 --- a/drivers/gpu/drm/gma500/psb_device.c +++ b/drivers/gpu/drm/gma500/psb_device.c | |||
@@ -144,6 +144,10 @@ static int psb_backlight_init(struct drm_device *dev) | |||
144 | psb_backlight_device->props.max_brightness = 100; | 144 | psb_backlight_device->props.max_brightness = 100; |
145 | backlight_update_status(psb_backlight_device); | 145 | backlight_update_status(psb_backlight_device); |
146 | dev_priv->backlight_device = psb_backlight_device; | 146 | dev_priv->backlight_device = psb_backlight_device; |
147 | |||
148 | /* This must occur after the backlight is properly initialised */ | ||
149 | psb_lid_timer_init(dev_priv); | ||
150 | |||
147 | return 0; | 151 | return 0; |
148 | } | 152 | } |
149 | 153 | ||
@@ -354,13 +358,6 @@ static int psb_chip_setup(struct drm_device *dev) | |||
354 | return 0; | 358 | return 0; |
355 | } | 359 | } |
356 | 360 | ||
357 | /* Not exactly an erratum more an irritation */ | ||
358 | static void psb_chip_errata(struct drm_device *dev) | ||
359 | { | ||
360 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
361 | psb_lid_timer_init(dev_priv); | ||
362 | } | ||
363 | |||
364 | static void psb_chip_teardown(struct drm_device *dev) | 361 | static void psb_chip_teardown(struct drm_device *dev) |
365 | { | 362 | { |
366 | struct drm_psb_private *dev_priv = dev->dev_private; | 363 | struct drm_psb_private *dev_priv = dev->dev_private; |
@@ -379,7 +376,6 @@ const struct psb_ops psb_chip_ops = { | |||
379 | .sgx_offset = PSB_SGX_OFFSET, | 376 | .sgx_offset = PSB_SGX_OFFSET, |
380 | .chip_setup = psb_chip_setup, | 377 | .chip_setup = psb_chip_setup, |
381 | .chip_teardown = psb_chip_teardown, | 378 | .chip_teardown = psb_chip_teardown, |
382 | .errata = psb_chip_errata, | ||
383 | 379 | ||
384 | .crtc_helper = &psb_intel_helper_funcs, | 380 | .crtc_helper = &psb_intel_helper_funcs, |
385 | .crtc_funcs = &psb_intel_crtc_funcs, | 381 | .crtc_funcs = &psb_intel_crtc_funcs, |
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index caba6e08693c..a8858a907f47 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c | |||
@@ -374,6 +374,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) | |||
374 | 374 | ||
375 | if (ret) | 375 | if (ret) |
376 | return ret; | 376 | return ret; |
377 | psb_intel_opregion_enable_asle(dev); | ||
377 | #if 0 | 378 | #if 0 |
378 | /*enable runtime pm at last*/ | 379 | /*enable runtime pm at last*/ |
379 | pm_runtime_enable(&dev->pdev->dev); | 380 | pm_runtime_enable(&dev->pdev->dev); |
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index bef04c192768..3fda8c87f02c 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -386,6 +386,7 @@ config HID_MULTITOUCH | |||
386 | - Unitec Panels | 386 | - Unitec Panels |
387 | - XAT optical touch panels | 387 | - XAT optical touch panels |
388 | - Xiroku optical touch panels | 388 | - Xiroku optical touch panels |
389 | - Zytronic touch panels | ||
389 | 390 | ||
390 | If unsure, say N. | 391 | If unsure, say N. |
391 | 392 | ||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 875ff451842b..32039235cfee 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -659,6 +659,9 @@ | |||
659 | #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 | 659 | #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 |
660 | #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 | 660 | #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 |
661 | 661 | ||
662 | #define USB_VENDOR_ID_SENNHEISER 0x1395 | ||
663 | #define USB_DEVICE_ID_SENNHEISER_BTD500USB 0x002c | ||
664 | |||
662 | #define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f | 665 | #define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f |
663 | #define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002 | 666 | #define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002 |
664 | 667 | ||
@@ -808,6 +811,9 @@ | |||
808 | #define USB_VENDOR_ID_ZYDACRON 0x13EC | 811 | #define USB_VENDOR_ID_ZYDACRON 0x13EC |
809 | #define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 | 812 | #define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 |
810 | 813 | ||
814 | #define USB_VENDOR_ID_ZYTRONIC 0x14c8 | ||
815 | #define USB_DEVICE_ID_ZYTRONIC_ZXY100 0x0005 | ||
816 | |||
811 | #define USB_VENDOR_ID_PRIMAX 0x0461 | 817 | #define USB_VENDOR_ID_PRIMAX 0x0461 |
812 | #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 | 818 | #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 |
813 | 819 | ||
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 132b0019365e..5301006f6c15 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -301,6 +301,9 @@ static const struct hid_device_id hid_battery_quirks[] = { | |||
301 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | 301 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
302 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), | 302 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), |
303 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | 303 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, |
304 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
305 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), | ||
306 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | ||
304 | {} | 307 | {} |
305 | }; | 308 | }; |
306 | 309 | ||
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 6e3332a99976..76479246d4ee 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -1048,6 +1048,11 @@ static const struct hid_device_id mt_devices[] = { | |||
1048 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, | 1048 | MT_USB_DEVICE(USB_VENDOR_ID_XIROKU, |
1049 | USB_DEVICE_ID_XIROKU_CSR2) }, | 1049 | USB_DEVICE_ID_XIROKU_CSR2) }, |
1050 | 1050 | ||
1051 | /* Zytronic panels */ | ||
1052 | { .driver_data = MT_CLS_SERIAL, | ||
1053 | MT_USB_DEVICE(USB_VENDOR_ID_ZYTRONIC, | ||
1054 | USB_DEVICE_ID_ZYTRONIC_ZXY100) }, | ||
1055 | |||
1051 | /* Generic MT device */ | 1056 | /* Generic MT device */ |
1052 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) }, | 1057 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) }, |
1053 | { } | 1058 | { } |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 0597ee604f6e..903eef3d3e10 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -76,6 +76,7 @@ static const struct hid_blacklist { | |||
76 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, | 76 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, |
77 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, | 77 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, |
78 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, | 78 | { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, |
79 | { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET }, | ||
79 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, | 80 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, |
80 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, | 81 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, |
81 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, | 82 | { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 5c1bc995e560..f10221f40803 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -123,7 +123,7 @@ static void ipoib_ud_skb_put_frags(struct ipoib_dev_priv *priv, | |||
123 | 123 | ||
124 | skb_frag_size_set(frag, size); | 124 | skb_frag_size_set(frag, size); |
125 | skb->data_len += size; | 125 | skb->data_len += size; |
126 | skb->truesize += size; | 126 | skb->truesize += PAGE_SIZE; |
127 | } else | 127 | } else |
128 | skb_put(skb, length); | 128 | skb_put(skb, length); |
129 | 129 | ||
@@ -156,14 +156,18 @@ static struct sk_buff *ipoib_alloc_rx_skb(struct net_device *dev, int id) | |||
156 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 156 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
157 | struct sk_buff *skb; | 157 | struct sk_buff *skb; |
158 | int buf_size; | 158 | int buf_size; |
159 | int tailroom; | ||
159 | u64 *mapping; | 160 | u64 *mapping; |
160 | 161 | ||
161 | if (ipoib_ud_need_sg(priv->max_ib_mtu)) | 162 | if (ipoib_ud_need_sg(priv->max_ib_mtu)) { |
162 | buf_size = IPOIB_UD_HEAD_SIZE; | 163 | buf_size = IPOIB_UD_HEAD_SIZE; |
163 | else | 164 | tailroom = 128; /* reserve some tailroom for IP/TCP headers */ |
165 | } else { | ||
164 | buf_size = IPOIB_UD_BUF_SIZE(priv->max_ib_mtu); | 166 | buf_size = IPOIB_UD_BUF_SIZE(priv->max_ib_mtu); |
167 | tailroom = 0; | ||
168 | } | ||
165 | 169 | ||
166 | skb = dev_alloc_skb(buf_size + 4); | 170 | skb = dev_alloc_skb(buf_size + tailroom + 4); |
167 | if (unlikely(!skb)) | 171 | if (unlikely(!skb)) |
168 | return NULL; | 172 | return NULL; |
169 | 173 | ||
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 3a74e4410fc0..86e2f4a62b9a 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c | |||
@@ -26,6 +26,8 @@ | |||
26 | * These routines are used by both DMA-remapping and Interrupt-remapping | 26 | * These routines are used by both DMA-remapping and Interrupt-remapping |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* has to precede printk.h */ | ||
30 | |||
29 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
30 | #include <linux/dmar.h> | 32 | #include <linux/dmar.h> |
31 | #include <linux/iova.h> | 33 | #include <linux/iova.h> |
@@ -39,8 +41,6 @@ | |||
39 | #include <asm/irq_remapping.h> | 41 | #include <asm/irq_remapping.h> |
40 | #include <asm/iommu_table.h> | 42 | #include <asm/iommu_table.h> |
41 | 43 | ||
42 | #define PREFIX "DMAR: " | ||
43 | |||
44 | /* No locks are needed as DMA remapping hardware unit | 44 | /* No locks are needed as DMA remapping hardware unit |
45 | * list is constructed at boot time and hotplug of | 45 | * list is constructed at boot time and hotplug of |
46 | * these units are not supported by the architecture. | 46 | * these units are not supported by the architecture. |
@@ -83,16 +83,12 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, | |||
83 | * ignore it | 83 | * ignore it |
84 | */ | 84 | */ |
85 | if (!bus) { | 85 | if (!bus) { |
86 | printk(KERN_WARNING | 86 | pr_warn("Device scope bus [%d] not found\n", scope->bus); |
87 | PREFIX "Device scope bus [%d] not found\n", | ||
88 | scope->bus); | ||
89 | break; | 87 | break; |
90 | } | 88 | } |
91 | pdev = pci_get_slot(bus, PCI_DEVFN(path->dev, path->fn)); | 89 | pdev = pci_get_slot(bus, PCI_DEVFN(path->dev, path->fn)); |
92 | if (!pdev) { | 90 | if (!pdev) { |
93 | printk(KERN_WARNING PREFIX | 91 | /* warning will be printed below */ |
94 | "Device scope device [%04x:%02x:%02x.%02x] not found\n", | ||
95 | segment, bus->number, path->dev, path->fn); | ||
96 | break; | 92 | break; |
97 | } | 93 | } |
98 | path ++; | 94 | path ++; |
@@ -100,9 +96,8 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, | |||
100 | bus = pdev->subordinate; | 96 | bus = pdev->subordinate; |
101 | } | 97 | } |
102 | if (!pdev) { | 98 | if (!pdev) { |
103 | printk(KERN_WARNING PREFIX | 99 | pr_warn("Device scope device [%04x:%02x:%02x.%02x] not found\n", |
104 | "Device scope device [%04x:%02x:%02x.%02x] not found\n", | 100 | segment, scope->bus, path->dev, path->fn); |
105 | segment, scope->bus, path->dev, path->fn); | ||
106 | *dev = NULL; | 101 | *dev = NULL; |
107 | return 0; | 102 | return 0; |
108 | } | 103 | } |
@@ -110,9 +105,8 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, | |||
110 | pdev->subordinate) || (scope->entry_type == \ | 105 | pdev->subordinate) || (scope->entry_type == \ |
111 | ACPI_DMAR_SCOPE_TYPE_BRIDGE && !pdev->subordinate)) { | 106 | ACPI_DMAR_SCOPE_TYPE_BRIDGE && !pdev->subordinate)) { |
112 | pci_dev_put(pdev); | 107 | pci_dev_put(pdev); |
113 | printk(KERN_WARNING PREFIX | 108 | pr_warn("Device scope type does not match for %s\n", |
114 | "Device scope type does not match for %s\n", | 109 | pci_name(pdev)); |
115 | pci_name(pdev)); | ||
116 | return -EINVAL; | 110 | return -EINVAL; |
117 | } | 111 | } |
118 | *dev = pdev; | 112 | *dev = pdev; |
@@ -134,8 +128,7 @@ int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, | |||
134 | scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) | 128 | scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) |
135 | (*cnt)++; | 129 | (*cnt)++; |
136 | else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC) { | 130 | else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC) { |
137 | printk(KERN_WARNING PREFIX | 131 | pr_warn("Unsupported device scope\n"); |
138 | "Unsupported device scope\n"); | ||
139 | } | 132 | } |
140 | start += scope->length; | 133 | start += scope->length; |
141 | } | 134 | } |
@@ -261,25 +254,23 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header) | |||
261 | case ACPI_DMAR_TYPE_HARDWARE_UNIT: | 254 | case ACPI_DMAR_TYPE_HARDWARE_UNIT: |
262 | drhd = container_of(header, struct acpi_dmar_hardware_unit, | 255 | drhd = container_of(header, struct acpi_dmar_hardware_unit, |
263 | header); | 256 | header); |
264 | printk (KERN_INFO PREFIX | 257 | pr_info("DRHD base: %#016Lx flags: %#x\n", |
265 | "DRHD base: %#016Lx flags: %#x\n", | ||
266 | (unsigned long long)drhd->address, drhd->flags); | 258 | (unsigned long long)drhd->address, drhd->flags); |
267 | break; | 259 | break; |
268 | case ACPI_DMAR_TYPE_RESERVED_MEMORY: | 260 | case ACPI_DMAR_TYPE_RESERVED_MEMORY: |
269 | rmrr = container_of(header, struct acpi_dmar_reserved_memory, | 261 | rmrr = container_of(header, struct acpi_dmar_reserved_memory, |
270 | header); | 262 | header); |
271 | printk (KERN_INFO PREFIX | 263 | pr_info("RMRR base: %#016Lx end: %#016Lx\n", |
272 | "RMRR base: %#016Lx end: %#016Lx\n", | ||
273 | (unsigned long long)rmrr->base_address, | 264 | (unsigned long long)rmrr->base_address, |
274 | (unsigned long long)rmrr->end_address); | 265 | (unsigned long long)rmrr->end_address); |
275 | break; | 266 | break; |
276 | case ACPI_DMAR_TYPE_ATSR: | 267 | case ACPI_DMAR_TYPE_ATSR: |
277 | atsr = container_of(header, struct acpi_dmar_atsr, header); | 268 | atsr = container_of(header, struct acpi_dmar_atsr, header); |
278 | printk(KERN_INFO PREFIX "ATSR flags: %#x\n", atsr->flags); | 269 | pr_info("ATSR flags: %#x\n", atsr->flags); |
279 | break; | 270 | break; |
280 | case ACPI_DMAR_HARDWARE_AFFINITY: | 271 | case ACPI_DMAR_HARDWARE_AFFINITY: |
281 | rhsa = container_of(header, struct acpi_dmar_rhsa, header); | 272 | rhsa = container_of(header, struct acpi_dmar_rhsa, header); |
282 | printk(KERN_INFO PREFIX "RHSA base: %#016Lx proximity domain: %#x\n", | 273 | pr_info("RHSA base: %#016Lx proximity domain: %#x\n", |
283 | (unsigned long long)rhsa->base_address, | 274 | (unsigned long long)rhsa->base_address, |
284 | rhsa->proximity_domain); | 275 | rhsa->proximity_domain); |
285 | break; | 276 | break; |
@@ -299,7 +290,7 @@ static int __init dmar_table_detect(void) | |||
299 | &dmar_tbl_size); | 290 | &dmar_tbl_size); |
300 | 291 | ||
301 | if (ACPI_SUCCESS(status) && !dmar_tbl) { | 292 | if (ACPI_SUCCESS(status) && !dmar_tbl) { |
302 | printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); | 293 | pr_warn("Unable to map DMAR\n"); |
303 | status = AE_NOT_FOUND; | 294 | status = AE_NOT_FOUND; |
304 | } | 295 | } |
305 | 296 | ||
@@ -333,20 +324,18 @@ parse_dmar_table(void) | |||
333 | return -ENODEV; | 324 | return -ENODEV; |
334 | 325 | ||
335 | if (dmar->width < PAGE_SHIFT - 1) { | 326 | if (dmar->width < PAGE_SHIFT - 1) { |
336 | printk(KERN_WARNING PREFIX "Invalid DMAR haw\n"); | 327 | pr_warn("Invalid DMAR haw\n"); |
337 | return -EINVAL; | 328 | return -EINVAL; |
338 | } | 329 | } |
339 | 330 | ||
340 | printk (KERN_INFO PREFIX "Host address width %d\n", | 331 | pr_info("Host address width %d\n", dmar->width + 1); |
341 | dmar->width + 1); | ||
342 | 332 | ||
343 | entry_header = (struct acpi_dmar_header *)(dmar + 1); | 333 | entry_header = (struct acpi_dmar_header *)(dmar + 1); |
344 | while (((unsigned long)entry_header) < | 334 | while (((unsigned long)entry_header) < |
345 | (((unsigned long)dmar) + dmar_tbl->length)) { | 335 | (((unsigned long)dmar) + dmar_tbl->length)) { |
346 | /* Avoid looping forever on bad ACPI tables */ | 336 | /* Avoid looping forever on bad ACPI tables */ |
347 | if (entry_header->length == 0) { | 337 | if (entry_header->length == 0) { |
348 | printk(KERN_WARNING PREFIX | 338 | pr_warn("Invalid 0-length structure\n"); |
349 | "Invalid 0-length structure\n"); | ||
350 | ret = -EINVAL; | 339 | ret = -EINVAL; |
351 | break; | 340 | break; |
352 | } | 341 | } |
@@ -369,8 +358,7 @@ parse_dmar_table(void) | |||
369 | #endif | 358 | #endif |
370 | break; | 359 | break; |
371 | default: | 360 | default: |
372 | printk(KERN_WARNING PREFIX | 361 | pr_warn("Unknown DMAR structure type %d\n", |
373 | "Unknown DMAR structure type %d\n", | ||
374 | entry_header->type); | 362 | entry_header->type); |
375 | ret = 0; /* for forward compatibility */ | 363 | ret = 0; /* for forward compatibility */ |
376 | break; | 364 | break; |
@@ -469,12 +457,12 @@ int __init dmar_table_init(void) | |||
469 | ret = parse_dmar_table(); | 457 | ret = parse_dmar_table(); |
470 | if (ret) { | 458 | if (ret) { |
471 | if (ret != -ENODEV) | 459 | if (ret != -ENODEV) |
472 | printk(KERN_INFO PREFIX "parse DMAR table failure.\n"); | 460 | pr_info("parse DMAR table failure.\n"); |
473 | return ret; | 461 | return ret; |
474 | } | 462 | } |
475 | 463 | ||
476 | if (list_empty(&dmar_drhd_units)) { | 464 | if (list_empty(&dmar_drhd_units)) { |
477 | printk(KERN_INFO PREFIX "No DMAR devices found\n"); | 465 | pr_info("No DMAR devices found\n"); |
478 | return -ENODEV; | 466 | return -ENODEV; |
479 | } | 467 | } |
480 | 468 | ||
@@ -506,8 +494,7 @@ int __init check_zero_address(void) | |||
506 | (((unsigned long)dmar) + dmar_tbl->length)) { | 494 | (((unsigned long)dmar) + dmar_tbl->length)) { |
507 | /* Avoid looping forever on bad ACPI tables */ | 495 | /* Avoid looping forever on bad ACPI tables */ |
508 | if (entry_header->length == 0) { | 496 | if (entry_header->length == 0) { |
509 | printk(KERN_WARNING PREFIX | 497 | pr_warn("Invalid 0-length structure\n"); |
510 | "Invalid 0-length structure\n"); | ||
511 | return 0; | 498 | return 0; |
512 | } | 499 | } |
513 | 500 | ||
@@ -558,8 +545,7 @@ int __init detect_intel_iommu(void) | |||
558 | 545 | ||
559 | if (ret && irq_remapping_enabled && cpu_has_x2apic && | 546 | if (ret && irq_remapping_enabled && cpu_has_x2apic && |
560 | dmar->flags & 0x1) | 547 | dmar->flags & 0x1) |
561 | printk(KERN_INFO | 548 | pr_info("Queued invalidation will be enabled to support x2apic and Intr-remapping.\n"); |
562 | "Queued invalidation will be enabled to support x2apic and Intr-remapping.\n"); | ||
563 | 549 | ||
564 | if (ret && !no_iommu && !iommu_detected && !dmar_disabled) { | 550 | if (ret && !no_iommu && !iommu_detected && !dmar_disabled) { |
565 | iommu_detected = 1; | 551 | iommu_detected = 1; |
@@ -579,14 +565,89 @@ int __init detect_intel_iommu(void) | |||
579 | } | 565 | } |
580 | 566 | ||
581 | 567 | ||
568 | static void unmap_iommu(struct intel_iommu *iommu) | ||
569 | { | ||
570 | iounmap(iommu->reg); | ||
571 | release_mem_region(iommu->reg_phys, iommu->reg_size); | ||
572 | } | ||
573 | |||
574 | /** | ||
575 | * map_iommu: map the iommu's registers | ||
576 | * @iommu: the iommu to map | ||
577 | * @phys_addr: the physical address of the base resgister | ||
578 | * | ||
579 | * Memory map the iommu's registers. Start w/ a single page, and | ||
580 | * possibly expand if that turns out to be insufficent. | ||
581 | */ | ||
582 | static int map_iommu(struct intel_iommu *iommu, u64 phys_addr) | ||
583 | { | ||
584 | int map_size, err=0; | ||
585 | |||
586 | iommu->reg_phys = phys_addr; | ||
587 | iommu->reg_size = VTD_PAGE_SIZE; | ||
588 | |||
589 | if (!request_mem_region(iommu->reg_phys, iommu->reg_size, iommu->name)) { | ||
590 | pr_err("IOMMU: can't reserve memory\n"); | ||
591 | err = -EBUSY; | ||
592 | goto out; | ||
593 | } | ||
594 | |||
595 | iommu->reg = ioremap(iommu->reg_phys, iommu->reg_size); | ||
596 | if (!iommu->reg) { | ||
597 | pr_err("IOMMU: can't map the region\n"); | ||
598 | err = -ENOMEM; | ||
599 | goto release; | ||
600 | } | ||
601 | |||
602 | iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); | ||
603 | iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); | ||
604 | |||
605 | if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { | ||
606 | err = -EINVAL; | ||
607 | warn_invalid_dmar(phys_addr, " returns all ones"); | ||
608 | goto unmap; | ||
609 | } | ||
610 | |||
611 | /* the registers might be more than one page */ | ||
612 | map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), | ||
613 | cap_max_fault_reg_offset(iommu->cap)); | ||
614 | map_size = VTD_PAGE_ALIGN(map_size); | ||
615 | if (map_size > iommu->reg_size) { | ||
616 | iounmap(iommu->reg); | ||
617 | release_mem_region(iommu->reg_phys, iommu->reg_size); | ||
618 | iommu->reg_size = map_size; | ||
619 | if (!request_mem_region(iommu->reg_phys, iommu->reg_size, | ||
620 | iommu->name)) { | ||
621 | pr_err("IOMMU: can't reserve memory\n"); | ||
622 | err = -EBUSY; | ||
623 | goto out; | ||
624 | } | ||
625 | iommu->reg = ioremap(iommu->reg_phys, iommu->reg_size); | ||
626 | if (!iommu->reg) { | ||
627 | pr_err("IOMMU: can't map the region\n"); | ||
628 | err = -ENOMEM; | ||
629 | goto release; | ||
630 | } | ||
631 | } | ||
632 | err = 0; | ||
633 | goto out; | ||
634 | |||
635 | unmap: | ||
636 | iounmap(iommu->reg); | ||
637 | release: | ||
638 | release_mem_region(iommu->reg_phys, iommu->reg_size); | ||
639 | out: | ||
640 | return err; | ||
641 | } | ||
642 | |||
582 | int alloc_iommu(struct dmar_drhd_unit *drhd) | 643 | int alloc_iommu(struct dmar_drhd_unit *drhd) |
583 | { | 644 | { |
584 | struct intel_iommu *iommu; | 645 | struct intel_iommu *iommu; |
585 | int map_size; | ||
586 | u32 ver; | 646 | u32 ver; |
587 | static int iommu_allocated = 0; | 647 | static int iommu_allocated = 0; |
588 | int agaw = 0; | 648 | int agaw = 0; |
589 | int msagaw = 0; | 649 | int msagaw = 0; |
650 | int err; | ||
590 | 651 | ||
591 | if (!drhd->reg_base_addr) { | 652 | if (!drhd->reg_base_addr) { |
592 | warn_invalid_dmar(0, ""); | 653 | warn_invalid_dmar(0, ""); |
@@ -600,30 +661,22 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
600 | iommu->seq_id = iommu_allocated++; | 661 | iommu->seq_id = iommu_allocated++; |
601 | sprintf (iommu->name, "dmar%d", iommu->seq_id); | 662 | sprintf (iommu->name, "dmar%d", iommu->seq_id); |
602 | 663 | ||
603 | iommu->reg = ioremap(drhd->reg_base_addr, VTD_PAGE_SIZE); | 664 | err = map_iommu(iommu, drhd->reg_base_addr); |
604 | if (!iommu->reg) { | 665 | if (err) { |
605 | printk(KERN_ERR "IOMMU: can't map the region\n"); | 666 | pr_err("IOMMU: failed to map %s\n", iommu->name); |
606 | goto error; | 667 | goto error; |
607 | } | 668 | } |
608 | iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); | ||
609 | iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); | ||
610 | |||
611 | if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { | ||
612 | warn_invalid_dmar(drhd->reg_base_addr, " returns all ones"); | ||
613 | goto err_unmap; | ||
614 | } | ||
615 | 669 | ||
670 | err = -EINVAL; | ||
616 | agaw = iommu_calculate_agaw(iommu); | 671 | agaw = iommu_calculate_agaw(iommu); |
617 | if (agaw < 0) { | 672 | if (agaw < 0) { |
618 | printk(KERN_ERR | 673 | pr_err("Cannot get a valid agaw for iommu (seq_id = %d)\n", |
619 | "Cannot get a valid agaw for iommu (seq_id = %d)\n", | 674 | iommu->seq_id); |
620 | iommu->seq_id); | ||
621 | goto err_unmap; | 675 | goto err_unmap; |
622 | } | 676 | } |
623 | msagaw = iommu_calculate_max_sagaw(iommu); | 677 | msagaw = iommu_calculate_max_sagaw(iommu); |
624 | if (msagaw < 0) { | 678 | if (msagaw < 0) { |
625 | printk(KERN_ERR | 679 | pr_err("Cannot get a valid max agaw for iommu (seq_id = %d)\n", |
626 | "Cannot get a valid max agaw for iommu (seq_id = %d)\n", | ||
627 | iommu->seq_id); | 680 | iommu->seq_id); |
628 | goto err_unmap; | 681 | goto err_unmap; |
629 | } | 682 | } |
@@ -632,19 +685,6 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
632 | 685 | ||
633 | iommu->node = -1; | 686 | iommu->node = -1; |
634 | 687 | ||
635 | /* the registers might be more than one page */ | ||
636 | map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap), | ||
637 | cap_max_fault_reg_offset(iommu->cap)); | ||
638 | map_size = VTD_PAGE_ALIGN(map_size); | ||
639 | if (map_size > VTD_PAGE_SIZE) { | ||
640 | iounmap(iommu->reg); | ||
641 | iommu->reg = ioremap(drhd->reg_base_addr, map_size); | ||
642 | if (!iommu->reg) { | ||
643 | printk(KERN_ERR "IOMMU: can't map the region\n"); | ||
644 | goto error; | ||
645 | } | ||
646 | } | ||
647 | |||
648 | ver = readl(iommu->reg + DMAR_VER_REG); | 688 | ver = readl(iommu->reg + DMAR_VER_REG); |
649 | pr_info("IOMMU %d: reg_base_addr %llx ver %d:%d cap %llx ecap %llx\n", | 689 | pr_info("IOMMU %d: reg_base_addr %llx ver %d:%d cap %llx ecap %llx\n", |
650 | iommu->seq_id, | 690 | iommu->seq_id, |
@@ -659,10 +699,10 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
659 | return 0; | 699 | return 0; |
660 | 700 | ||
661 | err_unmap: | 701 | err_unmap: |
662 | iounmap(iommu->reg); | 702 | unmap_iommu(iommu); |
663 | error: | 703 | error: |
664 | kfree(iommu); | 704 | kfree(iommu); |
665 | return -1; | 705 | return err; |
666 | } | 706 | } |
667 | 707 | ||
668 | void free_iommu(struct intel_iommu *iommu) | 708 | void free_iommu(struct intel_iommu *iommu) |
@@ -673,7 +713,8 @@ void free_iommu(struct intel_iommu *iommu) | |||
673 | free_dmar_iommu(iommu); | 713 | free_dmar_iommu(iommu); |
674 | 714 | ||
675 | if (iommu->reg) | 715 | if (iommu->reg) |
676 | iounmap(iommu->reg); | 716 | unmap_iommu(iommu); |
717 | |||
677 | kfree(iommu); | 718 | kfree(iommu); |
678 | } | 719 | } |
679 | 720 | ||
@@ -710,7 +751,7 @@ static int qi_check_fault(struct intel_iommu *iommu, int index) | |||
710 | if (fault & DMA_FSTS_IQE) { | 751 | if (fault & DMA_FSTS_IQE) { |
711 | head = readl(iommu->reg + DMAR_IQH_REG); | 752 | head = readl(iommu->reg + DMAR_IQH_REG); |
712 | if ((head >> DMAR_IQ_SHIFT) == index) { | 753 | if ((head >> DMAR_IQ_SHIFT) == index) { |
713 | printk(KERN_ERR "VT-d detected invalid descriptor: " | 754 | pr_err("VT-d detected invalid descriptor: " |
714 | "low=%llx, high=%llx\n", | 755 | "low=%llx, high=%llx\n", |
715 | (unsigned long long)qi->desc[index].low, | 756 | (unsigned long long)qi->desc[index].low, |
716 | (unsigned long long)qi->desc[index].high); | 757 | (unsigned long long)qi->desc[index].high); |
@@ -1129,15 +1170,14 @@ static int dmar_fault_do_one(struct intel_iommu *iommu, int type, | |||
1129 | reason = dmar_get_fault_reason(fault_reason, &fault_type); | 1170 | reason = dmar_get_fault_reason(fault_reason, &fault_type); |
1130 | 1171 | ||
1131 | if (fault_type == INTR_REMAP) | 1172 | if (fault_type == INTR_REMAP) |
1132 | printk(KERN_ERR "INTR-REMAP: Request device [[%02x:%02x.%d] " | 1173 | pr_err("INTR-REMAP: Request device [[%02x:%02x.%d] " |
1133 | "fault index %llx\n" | 1174 | "fault index %llx\n" |
1134 | "INTR-REMAP:[fault reason %02d] %s\n", | 1175 | "INTR-REMAP:[fault reason %02d] %s\n", |
1135 | (source_id >> 8), PCI_SLOT(source_id & 0xFF), | 1176 | (source_id >> 8), PCI_SLOT(source_id & 0xFF), |
1136 | PCI_FUNC(source_id & 0xFF), addr >> 48, | 1177 | PCI_FUNC(source_id & 0xFF), addr >> 48, |
1137 | fault_reason, reason); | 1178 | fault_reason, reason); |
1138 | else | 1179 | else |
1139 | printk(KERN_ERR | 1180 | pr_err("DMAR:[%s] Request device [%02x:%02x.%d] " |
1140 | "DMAR:[%s] Request device [%02x:%02x.%d] " | ||
1141 | "fault addr %llx \n" | 1181 | "fault addr %llx \n" |
1142 | "DMAR:[fault reason %02d] %s\n", | 1182 | "DMAR:[fault reason %02d] %s\n", |
1143 | (type ? "DMA Read" : "DMA Write"), | 1183 | (type ? "DMA Read" : "DMA Write"), |
@@ -1157,8 +1197,7 @@ irqreturn_t dmar_fault(int irq, void *dev_id) | |||
1157 | raw_spin_lock_irqsave(&iommu->register_lock, flag); | 1197 | raw_spin_lock_irqsave(&iommu->register_lock, flag); |
1158 | fault_status = readl(iommu->reg + DMAR_FSTS_REG); | 1198 | fault_status = readl(iommu->reg + DMAR_FSTS_REG); |
1159 | if (fault_status) | 1199 | if (fault_status) |
1160 | printk(KERN_ERR "DRHD: handling fault status reg %x\n", | 1200 | pr_err("DRHD: handling fault status reg %x\n", fault_status); |
1161 | fault_status); | ||
1162 | 1201 | ||
1163 | /* TBD: ignore advanced fault log currently */ | 1202 | /* TBD: ignore advanced fault log currently */ |
1164 | if (!(fault_status & DMA_FSTS_PPF)) | 1203 | if (!(fault_status & DMA_FSTS_PPF)) |
@@ -1224,7 +1263,7 @@ int dmar_set_interrupt(struct intel_iommu *iommu) | |||
1224 | 1263 | ||
1225 | irq = create_irq(); | 1264 | irq = create_irq(); |
1226 | if (!irq) { | 1265 | if (!irq) { |
1227 | printk(KERN_ERR "IOMMU: no free vectors\n"); | 1266 | pr_err("IOMMU: no free vectors\n"); |
1228 | return -EINVAL; | 1267 | return -EINVAL; |
1229 | } | 1268 | } |
1230 | 1269 | ||
@@ -1241,7 +1280,7 @@ int dmar_set_interrupt(struct intel_iommu *iommu) | |||
1241 | 1280 | ||
1242 | ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu); | 1281 | ret = request_irq(irq, dmar_fault, IRQF_NO_THREAD, iommu->name, iommu); |
1243 | if (ret) | 1282 | if (ret) |
1244 | printk(KERN_ERR "IOMMU: can't request irq\n"); | 1283 | pr_err("IOMMU: can't request irq\n"); |
1245 | return ret; | 1284 | return ret; |
1246 | } | 1285 | } |
1247 | 1286 | ||
@@ -1258,8 +1297,7 @@ int __init enable_drhd_fault_handling(void) | |||
1258 | ret = dmar_set_interrupt(iommu); | 1297 | ret = dmar_set_interrupt(iommu); |
1259 | 1298 | ||
1260 | if (ret) { | 1299 | if (ret) { |
1261 | printk(KERN_ERR "DRHD %Lx: failed to enable fault, " | 1300 | pr_err("DRHD %Lx: failed to enable fault, interrupt, ret %d\n", |
1262 | " interrupt, ret %d\n", | ||
1263 | (unsigned long long)drhd->reg_base_addr, ret); | 1301 | (unsigned long long)drhd->reg_base_addr, ret); |
1264 | return -1; | 1302 | return -1; |
1265 | } | 1303 | } |
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 6d347064b8b0..e0b18f3ae9a8 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c | |||
@@ -902,7 +902,6 @@ static int intel_setup_ioapic_entry(int irq, | |||
902 | return 0; | 902 | return 0; |
903 | } | 903 | } |
904 | 904 | ||
905 | #ifdef CONFIG_SMP | ||
906 | /* | 905 | /* |
907 | * Migrate the IO-APIC irq in the presence of intr-remapping. | 906 | * Migrate the IO-APIC irq in the presence of intr-remapping. |
908 | * | 907 | * |
@@ -924,6 +923,10 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | |||
924 | struct irq_cfg *cfg = data->chip_data; | 923 | struct irq_cfg *cfg = data->chip_data; |
925 | unsigned int dest, irq = data->irq; | 924 | unsigned int dest, irq = data->irq; |
926 | struct irte irte; | 925 | struct irte irte; |
926 | int err; | ||
927 | |||
928 | if (!config_enabled(CONFIG_SMP)) | ||
929 | return -EINVAL; | ||
927 | 930 | ||
928 | if (!cpumask_intersects(mask, cpu_online_mask)) | 931 | if (!cpumask_intersects(mask, cpu_online_mask)) |
929 | return -EINVAL; | 932 | return -EINVAL; |
@@ -931,10 +934,16 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | |||
931 | if (get_irte(irq, &irte)) | 934 | if (get_irte(irq, &irte)) |
932 | return -EBUSY; | 935 | return -EBUSY; |
933 | 936 | ||
934 | if (assign_irq_vector(irq, cfg, mask)) | 937 | err = assign_irq_vector(irq, cfg, mask); |
935 | return -EBUSY; | 938 | if (err) |
939 | return err; | ||
936 | 940 | ||
937 | dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask); | 941 | err = apic->cpu_mask_to_apicid_and(cfg->domain, mask, &dest); |
942 | if (err) { | ||
943 | if (assign_irq_vector(irq, cfg, data->affinity)) | ||
944 | pr_err("Failed to recover vector for irq %d\n", irq); | ||
945 | return err; | ||
946 | } | ||
938 | 947 | ||
939 | irte.vector = cfg->vector; | 948 | irte.vector = cfg->vector; |
940 | irte.dest_id = IRTE_DEST(dest); | 949 | irte.dest_id = IRTE_DEST(dest); |
@@ -956,7 +965,6 @@ intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, | |||
956 | cpumask_copy(data->affinity, mask); | 965 | cpumask_copy(data->affinity, mask); |
957 | return 0; | 966 | return 0; |
958 | } | 967 | } |
959 | #endif | ||
960 | 968 | ||
961 | static void intel_compose_msi_msg(struct pci_dev *pdev, | 969 | static void intel_compose_msi_msg(struct pci_dev *pdev, |
962 | unsigned int irq, unsigned int dest, | 970 | unsigned int irq, unsigned int dest, |
@@ -1058,9 +1066,7 @@ struct irq_remap_ops intel_irq_remap_ops = { | |||
1058 | .reenable = reenable_irq_remapping, | 1066 | .reenable = reenable_irq_remapping, |
1059 | .enable_faulting = enable_drhd_fault_handling, | 1067 | .enable_faulting = enable_drhd_fault_handling, |
1060 | .setup_ioapic_entry = intel_setup_ioapic_entry, | 1068 | .setup_ioapic_entry = intel_setup_ioapic_entry, |
1061 | #ifdef CONFIG_SMP | ||
1062 | .set_affinity = intel_ioapic_set_affinity, | 1069 | .set_affinity = intel_ioapic_set_affinity, |
1063 | #endif | ||
1064 | .free_irq = free_irte, | 1070 | .free_irq = free_irte, |
1065 | .compose_msi_msg = intel_compose_msi_msg, | 1071 | .compose_msi_msg = intel_compose_msi_msg, |
1066 | .msi_alloc_irq = intel_msi_alloc_irq, | 1072 | .msi_alloc_irq = intel_msi_alloc_irq, |
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c index 40cda8e98d87..1d29b1c66e72 100644 --- a/drivers/iommu/irq_remapping.c +++ b/drivers/iommu/irq_remapping.c | |||
@@ -111,16 +111,15 @@ int setup_ioapic_remapped_entry(int irq, | |||
111 | vector, attr); | 111 | vector, attr); |
112 | } | 112 | } |
113 | 113 | ||
114 | #ifdef CONFIG_SMP | ||
115 | int set_remapped_irq_affinity(struct irq_data *data, const struct cpumask *mask, | 114 | int set_remapped_irq_affinity(struct irq_data *data, const struct cpumask *mask, |
116 | bool force) | 115 | bool force) |
117 | { | 116 | { |
118 | if (!remap_ops || !remap_ops->set_affinity) | 117 | if (!config_enabled(CONFIG_SMP) || !remap_ops || |
118 | !remap_ops->set_affinity) | ||
119 | return 0; | 119 | return 0; |
120 | 120 | ||
121 | return remap_ops->set_affinity(data, mask, force); | 121 | return remap_ops->set_affinity(data, mask, force); |
122 | } | 122 | } |
123 | #endif | ||
124 | 123 | ||
125 | void free_remapped_irq(int irq) | 124 | void free_remapped_irq(int irq) |
126 | { | 125 | { |
diff --git a/drivers/iommu/irq_remapping.h b/drivers/iommu/irq_remapping.h index be9d72950c51..b12974cc1dfe 100644 --- a/drivers/iommu/irq_remapping.h +++ b/drivers/iommu/irq_remapping.h | |||
@@ -59,11 +59,9 @@ struct irq_remap_ops { | |||
59 | unsigned int, int, | 59 | unsigned int, int, |
60 | struct io_apic_irq_attr *); | 60 | struct io_apic_irq_attr *); |
61 | 61 | ||
62 | #ifdef CONFIG_SMP | ||
63 | /* Set the CPU affinity of a remapped interrupt */ | 62 | /* Set the CPU affinity of a remapped interrupt */ |
64 | int (*set_affinity)(struct irq_data *data, const struct cpumask *mask, | 63 | int (*set_affinity)(struct irq_data *data, const struct cpumask *mask, |
65 | bool force); | 64 | bool force); |
66 | #endif | ||
67 | 65 | ||
68 | /* Free an IRQ */ | 66 | /* Free an IRQ */ |
69 | int (*free_irq)(int); | 67 | int (*free_irq)(int); |
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c index 1a0ae4445ff2..5f21f629b7ae 100644 --- a/drivers/isdn/mISDN/stack.c +++ b/drivers/isdn/mISDN/stack.c | |||
@@ -135,8 +135,8 @@ send_layer2(struct mISDNstack *st, struct sk_buff *skb) | |||
135 | skb = NULL; | 135 | skb = NULL; |
136 | else if (*debug & DEBUG_SEND_ERR) | 136 | else if (*debug & DEBUG_SEND_ERR) |
137 | printk(KERN_DEBUG | 137 | printk(KERN_DEBUG |
138 | "%s ch%d mgr prim(%x) addr(%x) err %d\n", | 138 | "%s mgr prim(%x) err %d\n", |
139 | __func__, ch->nr, hh->prim, ch->addr, ret); | 139 | __func__, hh->prim, ret); |
140 | } | 140 | } |
141 | out: | 141 | out: |
142 | mutex_unlock(&st->lmutex); | 142 | mutex_unlock(&st->lmutex); |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index d039de8322f0..b58b7a33914a 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -1084,6 +1084,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1084 | ti->split_io = dm_rh_get_region_size(ms->rh); | 1084 | ti->split_io = dm_rh_get_region_size(ms->rh); |
1085 | ti->num_flush_requests = 1; | 1085 | ti->num_flush_requests = 1; |
1086 | ti->num_discard_requests = 1; | 1086 | ti->num_discard_requests = 1; |
1087 | ti->discard_zeroes_data_unsupported = 1; | ||
1087 | 1088 | ||
1088 | ms->kmirrord_wq = alloc_workqueue("kmirrord", | 1089 | ms->kmirrord_wq = alloc_workqueue("kmirrord", |
1089 | WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); | 1090 | WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0); |
@@ -1214,7 +1215,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, | |||
1214 | * We need to dec pending if this was a write. | 1215 | * We need to dec pending if this was a write. |
1215 | */ | 1216 | */ |
1216 | if (rw == WRITE) { | 1217 | if (rw == WRITE) { |
1217 | if (!(bio->bi_rw & REQ_FLUSH)) | 1218 | if (!(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) |
1218 | dm_rh_dec(ms->rh, map_context->ll); | 1219 | dm_rh_dec(ms->rh, map_context->ll); |
1219 | return error; | 1220 | return error; |
1220 | } | 1221 | } |
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index 7771ed212182..69732e03eb34 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c | |||
@@ -404,6 +404,9 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio) | |||
404 | return; | 404 | return; |
405 | } | 405 | } |
406 | 406 | ||
407 | if (bio->bi_rw & REQ_DISCARD) | ||
408 | return; | ||
409 | |||
407 | /* We must inform the log that the sync count has changed. */ | 410 | /* We must inform the log that the sync count has changed. */ |
408 | log->type->set_region_sync(log, region, 0); | 411 | log->type->set_region_sync(log, region, 0); |
409 | 412 | ||
@@ -524,7 +527,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios) | |||
524 | struct bio *bio; | 527 | struct bio *bio; |
525 | 528 | ||
526 | for (bio = bios->head; bio; bio = bio->bi_next) { | 529 | for (bio = bios->head; bio; bio = bio->bi_next) { |
527 | if (bio->bi_rw & REQ_FLUSH) | 530 | if (bio->bi_rw & (REQ_FLUSH | REQ_DISCARD)) |
528 | continue; | 531 | continue; |
529 | rh_inc(rh, dm_rh_bio_to_region(rh, bio)); | 532 | rh_inc(rh, dm_rh_bio_to_region(rh, bio)); |
530 | } | 533 | } |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index ce59824fb414..68694da0d21d 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
@@ -1245,7 +1245,10 @@ static void process_discard(struct thin_c *tc, struct bio *bio) | |||
1245 | 1245 | ||
1246 | cell_release_singleton(cell, bio); | 1246 | cell_release_singleton(cell, bio); |
1247 | cell_release_singleton(cell2, bio); | 1247 | cell_release_singleton(cell2, bio); |
1248 | remap_and_issue(tc, bio, lookup_result.block); | 1248 | if ((!lookup_result.shared) && pool->pf.discard_passdown) |
1249 | remap_and_issue(tc, bio, lookup_result.block); | ||
1250 | else | ||
1251 | bio_endio(bio, 0); | ||
1249 | } | 1252 | } |
1250 | break; | 1253 | break; |
1251 | 1254 | ||
@@ -2628,6 +2631,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2628 | if (tc->pool->pf.discard_enabled) { | 2631 | if (tc->pool->pf.discard_enabled) { |
2629 | ti->discards_supported = 1; | 2632 | ti->discards_supported = 1; |
2630 | ti->num_discard_requests = 1; | 2633 | ti->num_discard_requests = 1; |
2634 | ti->discard_zeroes_data_unsupported = 1; | ||
2631 | } | 2635 | } |
2632 | 2636 | ||
2633 | dm_put(pool_md); | 2637 | dm_put(pool_md); |
diff --git a/drivers/md/md.c b/drivers/md/md.c index a4c219e3c859..d5ab4493c8be 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2931,6 +2931,7 @@ offset_store(struct md_rdev *rdev, const char *buf, size_t len) | |||
2931 | * can be sane */ | 2931 | * can be sane */ |
2932 | return -EBUSY; | 2932 | return -EBUSY; |
2933 | rdev->data_offset = offset; | 2933 | rdev->data_offset = offset; |
2934 | rdev->new_data_offset = offset; | ||
2934 | return len; | 2935 | return len; |
2935 | } | 2936 | } |
2936 | 2937 | ||
@@ -3926,8 +3927,8 @@ array_state_show(struct mddev *mddev, char *page) | |||
3926 | return sprintf(page, "%s\n", array_states[st]); | 3927 | return sprintf(page, "%s\n", array_states[st]); |
3927 | } | 3928 | } |
3928 | 3929 | ||
3929 | static int do_md_stop(struct mddev * mddev, int ro, int is_open); | 3930 | static int do_md_stop(struct mddev * mddev, int ro, struct block_device *bdev); |
3930 | static int md_set_readonly(struct mddev * mddev, int is_open); | 3931 | static int md_set_readonly(struct mddev * mddev, struct block_device *bdev); |
3931 | static int do_md_run(struct mddev * mddev); | 3932 | static int do_md_run(struct mddev * mddev); |
3932 | static int restart_array(struct mddev *mddev); | 3933 | static int restart_array(struct mddev *mddev); |
3933 | 3934 | ||
@@ -3943,14 +3944,14 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) | |||
3943 | /* stopping an active array */ | 3944 | /* stopping an active array */ |
3944 | if (atomic_read(&mddev->openers) > 0) | 3945 | if (atomic_read(&mddev->openers) > 0) |
3945 | return -EBUSY; | 3946 | return -EBUSY; |
3946 | err = do_md_stop(mddev, 0, 0); | 3947 | err = do_md_stop(mddev, 0, NULL); |
3947 | break; | 3948 | break; |
3948 | case inactive: | 3949 | case inactive: |
3949 | /* stopping an active array */ | 3950 | /* stopping an active array */ |
3950 | if (mddev->pers) { | 3951 | if (mddev->pers) { |
3951 | if (atomic_read(&mddev->openers) > 0) | 3952 | if (atomic_read(&mddev->openers) > 0) |
3952 | return -EBUSY; | 3953 | return -EBUSY; |
3953 | err = do_md_stop(mddev, 2, 0); | 3954 | err = do_md_stop(mddev, 2, NULL); |
3954 | } else | 3955 | } else |
3955 | err = 0; /* already inactive */ | 3956 | err = 0; /* already inactive */ |
3956 | break; | 3957 | break; |
@@ -3958,7 +3959,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) | |||
3958 | break; /* not supported yet */ | 3959 | break; /* not supported yet */ |
3959 | case readonly: | 3960 | case readonly: |
3960 | if (mddev->pers) | 3961 | if (mddev->pers) |
3961 | err = md_set_readonly(mddev, 0); | 3962 | err = md_set_readonly(mddev, NULL); |
3962 | else { | 3963 | else { |
3963 | mddev->ro = 1; | 3964 | mddev->ro = 1; |
3964 | set_disk_ro(mddev->gendisk, 1); | 3965 | set_disk_ro(mddev->gendisk, 1); |
@@ -3968,7 +3969,7 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) | |||
3968 | case read_auto: | 3969 | case read_auto: |
3969 | if (mddev->pers) { | 3970 | if (mddev->pers) { |
3970 | if (mddev->ro == 0) | 3971 | if (mddev->ro == 0) |
3971 | err = md_set_readonly(mddev, 0); | 3972 | err = md_set_readonly(mddev, NULL); |
3972 | else if (mddev->ro == 1) | 3973 | else if (mddev->ro == 1) |
3973 | err = restart_array(mddev); | 3974 | err = restart_array(mddev); |
3974 | if (err == 0) { | 3975 | if (err == 0) { |
@@ -5351,15 +5352,17 @@ void md_stop(struct mddev *mddev) | |||
5351 | } | 5352 | } |
5352 | EXPORT_SYMBOL_GPL(md_stop); | 5353 | EXPORT_SYMBOL_GPL(md_stop); |
5353 | 5354 | ||
5354 | static int md_set_readonly(struct mddev *mddev, int is_open) | 5355 | static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) |
5355 | { | 5356 | { |
5356 | int err = 0; | 5357 | int err = 0; |
5357 | mutex_lock(&mddev->open_mutex); | 5358 | mutex_lock(&mddev->open_mutex); |
5358 | if (atomic_read(&mddev->openers) > is_open) { | 5359 | if (atomic_read(&mddev->openers) > !!bdev) { |
5359 | printk("md: %s still in use.\n",mdname(mddev)); | 5360 | printk("md: %s still in use.\n",mdname(mddev)); |
5360 | err = -EBUSY; | 5361 | err = -EBUSY; |
5361 | goto out; | 5362 | goto out; |
5362 | } | 5363 | } |
5364 | if (bdev) | ||
5365 | sync_blockdev(bdev); | ||
5363 | if (mddev->pers) { | 5366 | if (mddev->pers) { |
5364 | __md_stop_writes(mddev); | 5367 | __md_stop_writes(mddev); |
5365 | 5368 | ||
@@ -5381,18 +5384,26 @@ out: | |||
5381 | * 0 - completely stop and dis-assemble array | 5384 | * 0 - completely stop and dis-assemble array |
5382 | * 2 - stop but do not disassemble array | 5385 | * 2 - stop but do not disassemble array |
5383 | */ | 5386 | */ |
5384 | static int do_md_stop(struct mddev * mddev, int mode, int is_open) | 5387 | static int do_md_stop(struct mddev * mddev, int mode, |
5388 | struct block_device *bdev) | ||
5385 | { | 5389 | { |
5386 | struct gendisk *disk = mddev->gendisk; | 5390 | struct gendisk *disk = mddev->gendisk; |
5387 | struct md_rdev *rdev; | 5391 | struct md_rdev *rdev; |
5388 | 5392 | ||
5389 | mutex_lock(&mddev->open_mutex); | 5393 | mutex_lock(&mddev->open_mutex); |
5390 | if (atomic_read(&mddev->openers) > is_open || | 5394 | if (atomic_read(&mddev->openers) > !!bdev || |
5391 | mddev->sysfs_active) { | 5395 | mddev->sysfs_active) { |
5392 | printk("md: %s still in use.\n",mdname(mddev)); | 5396 | printk("md: %s still in use.\n",mdname(mddev)); |
5393 | mutex_unlock(&mddev->open_mutex); | 5397 | mutex_unlock(&mddev->open_mutex); |
5394 | return -EBUSY; | 5398 | return -EBUSY; |
5395 | } | 5399 | } |
5400 | if (bdev) | ||
5401 | /* It is possible IO was issued on some other | ||
5402 | * open file which was closed before we took ->open_mutex. | ||
5403 | * As that was not the last close __blkdev_put will not | ||
5404 | * have called sync_blockdev, so we must. | ||
5405 | */ | ||
5406 | sync_blockdev(bdev); | ||
5396 | 5407 | ||
5397 | if (mddev->pers) { | 5408 | if (mddev->pers) { |
5398 | if (mddev->ro) | 5409 | if (mddev->ro) |
@@ -5466,7 +5477,7 @@ static void autorun_array(struct mddev *mddev) | |||
5466 | err = do_md_run(mddev); | 5477 | err = do_md_run(mddev); |
5467 | if (err) { | 5478 | if (err) { |
5468 | printk(KERN_WARNING "md: do_md_run() returned %d\n", err); | 5479 | printk(KERN_WARNING "md: do_md_run() returned %d\n", err); |
5469 | do_md_stop(mddev, 0, 0); | 5480 | do_md_stop(mddev, 0, NULL); |
5470 | } | 5481 | } |
5471 | } | 5482 | } |
5472 | 5483 | ||
@@ -6481,11 +6492,11 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, | |||
6481 | goto done_unlock; | 6492 | goto done_unlock; |
6482 | 6493 | ||
6483 | case STOP_ARRAY: | 6494 | case STOP_ARRAY: |
6484 | err = do_md_stop(mddev, 0, 1); | 6495 | err = do_md_stop(mddev, 0, bdev); |
6485 | goto done_unlock; | 6496 | goto done_unlock; |
6486 | 6497 | ||
6487 | case STOP_ARRAY_RO: | 6498 | case STOP_ARRAY_RO: |
6488 | err = md_set_readonly(mddev, 1); | 6499 | err = md_set_readonly(mddev, bdev); |
6489 | goto done_unlock; | 6500 | goto done_unlock; |
6490 | 6501 | ||
6491 | case BLKROSET: | 6502 | case BLKROSET: |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 240ff3125040..cacd008d6864 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1818,8 +1818,14 @@ static void sync_request_write(struct mddev *mddev, struct r1bio *r1_bio) | |||
1818 | 1818 | ||
1819 | if (atomic_dec_and_test(&r1_bio->remaining)) { | 1819 | if (atomic_dec_and_test(&r1_bio->remaining)) { |
1820 | /* if we're here, all write(s) have completed, so clean up */ | 1820 | /* if we're here, all write(s) have completed, so clean up */ |
1821 | md_done_sync(mddev, r1_bio->sectors, 1); | 1821 | int s = r1_bio->sectors; |
1822 | put_buf(r1_bio); | 1822 | if (test_bit(R1BIO_MadeGood, &r1_bio->state) || |
1823 | test_bit(R1BIO_WriteError, &r1_bio->state)) | ||
1824 | reschedule_retry(r1_bio); | ||
1825 | else { | ||
1826 | put_buf(r1_bio); | ||
1827 | md_done_sync(mddev, s, 1); | ||
1828 | } | ||
1823 | } | 1829 | } |
1824 | } | 1830 | } |
1825 | 1831 | ||
diff --git a/drivers/media/video/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c index 83c1aa6b2e6c..f11f6f07e915 100644 --- a/drivers/media/video/cx25821/cx25821-core.c +++ b/drivers/media/video/cx25821/cx25821-core.c | |||
@@ -904,9 +904,6 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) | |||
904 | list_add_tail(&dev->devlist, &cx25821_devlist); | 904 | list_add_tail(&dev->devlist, &cx25821_devlist); |
905 | mutex_unlock(&cx25821_devlist_mutex); | 905 | mutex_unlock(&cx25821_devlist_mutex); |
906 | 906 | ||
907 | strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown"); | ||
908 | strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821"); | ||
909 | |||
910 | if (dev->pci->device != 0x8210) { | 907 | if (dev->pci->device != 0x8210) { |
911 | pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n", | 908 | pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n", |
912 | __func__, dev->pci->device); | 909 | __func__, dev->pci->device); |
diff --git a/drivers/media/video/cx25821/cx25821.h b/drivers/media/video/cx25821/cx25821.h index b9aa801b00a7..029f2934a6d8 100644 --- a/drivers/media/video/cx25821/cx25821.h +++ b/drivers/media/video/cx25821/cx25821.h | |||
@@ -187,7 +187,7 @@ enum port { | |||
187 | }; | 187 | }; |
188 | 188 | ||
189 | struct cx25821_board { | 189 | struct cx25821_board { |
190 | char *name; | 190 | const char *name; |
191 | enum port porta; | 191 | enum port porta; |
192 | enum port portb; | 192 | enum port portb; |
193 | enum port portc; | 193 | enum port portc; |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 83dbb2ddff10..0cbada18f6f5 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -681,6 +681,7 @@ static void determine_valid_ioctls(struct video_device *vdev) | |||
681 | SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings); | 681 | SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings); |
682 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings); | 682 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings); |
683 | SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings); | 683 | SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings); |
684 | SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap); | ||
684 | /* yes, really vidioc_subscribe_event */ | 685 | /* yes, really vidioc_subscribe_event */ |
685 | SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event); | 686 | SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event); |
686 | SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event); | 687 | SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event); |
diff --git a/drivers/net/bonding/bond_debugfs.c b/drivers/net/bonding/bond_debugfs.c index 3680aa251dea..2cf084eb9d52 100644 --- a/drivers/net/bonding/bond_debugfs.c +++ b/drivers/net/bonding/bond_debugfs.c | |||
@@ -6,7 +6,7 @@ | |||
6 | #include "bonding.h" | 6 | #include "bonding.h" |
7 | #include "bond_alb.h" | 7 | #include "bond_alb.h" |
8 | 8 | ||
9 | #ifdef CONFIG_DEBUG_FS | 9 | #if defined(CONFIG_DEBUG_FS) && !defined(CONFIG_NET_NS) |
10 | 10 | ||
11 | #include <linux/debugfs.h> | 11 | #include <linux/debugfs.h> |
12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b9c2ae62166d..2ee76993f052 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -3227,6 +3227,12 @@ static int bond_master_netdev_event(unsigned long event, | |||
3227 | switch (event) { | 3227 | switch (event) { |
3228 | case NETDEV_CHANGENAME: | 3228 | case NETDEV_CHANGENAME: |
3229 | return bond_event_changename(event_bond); | 3229 | return bond_event_changename(event_bond); |
3230 | case NETDEV_UNREGISTER: | ||
3231 | bond_remove_proc_entry(event_bond); | ||
3232 | break; | ||
3233 | case NETDEV_REGISTER: | ||
3234 | bond_create_proc_entry(event_bond); | ||
3235 | break; | ||
3230 | default: | 3236 | default: |
3231 | break; | 3237 | break; |
3232 | } | 3238 | } |
@@ -4411,8 +4417,6 @@ static void bond_uninit(struct net_device *bond_dev) | |||
4411 | 4417 | ||
4412 | bond_work_cancel_all(bond); | 4418 | bond_work_cancel_all(bond); |
4413 | 4419 | ||
4414 | bond_remove_proc_entry(bond); | ||
4415 | |||
4416 | bond_debug_unregister(bond); | 4420 | bond_debug_unregister(bond); |
4417 | 4421 | ||
4418 | __hw_addr_flush(&bond->mc_list); | 4422 | __hw_addr_flush(&bond->mc_list); |
@@ -4814,7 +4818,6 @@ static int bond_init(struct net_device *bond_dev) | |||
4814 | 4818 | ||
4815 | bond_set_lockdep_class(bond_dev); | 4819 | bond_set_lockdep_class(bond_dev); |
4816 | 4820 | ||
4817 | bond_create_proc_entry(bond); | ||
4818 | list_add_tail(&bond->bond_list, &bn->dev_list); | 4821 | list_add_tail(&bond->bond_list, &bn->dev_list); |
4819 | 4822 | ||
4820 | bond_prepare_sysfs_group(bond); | 4823 | bond_prepare_sysfs_group(bond); |
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 9cc15701101b..1f78b63d5efe 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c | |||
@@ -261,7 +261,6 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) | |||
261 | if ((phy_data & BMSR_LSTATUS) == 0) { | 261 | if ((phy_data & BMSR_LSTATUS) == 0) { |
262 | /* link down */ | 262 | /* link down */ |
263 | netif_carrier_off(netdev); | 263 | netif_carrier_off(netdev); |
264 | netif_stop_queue(netdev); | ||
265 | hw->hibernate = true; | 264 | hw->hibernate = true; |
266 | if (atl1c_reset_mac(hw) != 0) | 265 | if (atl1c_reset_mac(hw) != 0) |
267 | if (netif_msg_hw(adapter)) | 266 | if (netif_msg_hw(adapter)) |
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 46b8b7d81633..d09c6b583d17 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c | |||
@@ -656,7 +656,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) | |||
656 | dma_unmap_single(bp->sdev->dma_dev, mapping, | 656 | dma_unmap_single(bp->sdev->dma_dev, mapping, |
657 | RX_PKT_BUF_SZ, DMA_FROM_DEVICE); | 657 | RX_PKT_BUF_SZ, DMA_FROM_DEVICE); |
658 | dev_kfree_skb_any(skb); | 658 | dev_kfree_skb_any(skb); |
659 | skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA); | 659 | skb = alloc_skb(RX_PKT_BUF_SZ, GFP_ATOMIC | GFP_DMA); |
660 | if (skb == NULL) | 660 | if (skb == NULL) |
661 | return -ENOMEM; | 661 | return -ENOMEM; |
662 | mapping = dma_map_single(bp->sdev->dma_dev, skb->data, | 662 | mapping = dma_map_single(bp->sdev->dma_dev, skb->data, |
@@ -967,7 +967,7 @@ static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
967 | dma_unmap_single(bp->sdev->dma_dev, mapping, len, | 967 | dma_unmap_single(bp->sdev->dma_dev, mapping, len, |
968 | DMA_TO_DEVICE); | 968 | DMA_TO_DEVICE); |
969 | 969 | ||
970 | bounce_skb = __netdev_alloc_skb(dev, len, GFP_ATOMIC | GFP_DMA); | 970 | bounce_skb = alloc_skb(len, GFP_ATOMIC | GFP_DMA); |
971 | if (!bounce_skb) | 971 | if (!bounce_skb) |
972 | goto err_out; | 972 | goto err_out; |
973 | 973 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index ac7b74488531..1fa4927a45b1 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c | |||
@@ -5372,7 +5372,7 @@ bnx2_free_tx_skbs(struct bnx2 *bp) | |||
5372 | int k, last; | 5372 | int k, last; |
5373 | 5373 | ||
5374 | if (skb == NULL) { | 5374 | if (skb == NULL) { |
5375 | j++; | 5375 | j = NEXT_TX_BD(j); |
5376 | continue; | 5376 | continue; |
5377 | } | 5377 | } |
5378 | 5378 | ||
@@ -5384,8 +5384,8 @@ bnx2_free_tx_skbs(struct bnx2 *bp) | |||
5384 | tx_buf->skb = NULL; | 5384 | tx_buf->skb = NULL; |
5385 | 5385 | ||
5386 | last = tx_buf->nr_frags; | 5386 | last = tx_buf->nr_frags; |
5387 | j++; | 5387 | j = NEXT_TX_BD(j); |
5388 | for (k = 0; k < last; k++, j++) { | 5388 | for (k = 0; k < last; k++, j = NEXT_TX_BD(j)) { |
5389 | tx_buf = &txr->tx_buf_ring[TX_RING_IDX(j)]; | 5389 | tx_buf = &txr->tx_buf_ring[TX_RING_IDX(j)]; |
5390 | dma_unmap_page(&bp->pdev->dev, | 5390 | dma_unmap_page(&bp->pdev->dev, |
5391 | dma_unmap_addr(tx_buf, mapping), | 5391 | dma_unmap_addr(tx_buf, mapping), |
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index c95e7b5e2b85..2c89d17cbb29 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c | |||
@@ -534,7 +534,8 @@ int cnic_unregister_driver(int ulp_type) | |||
534 | } | 534 | } |
535 | 535 | ||
536 | if (atomic_read(&ulp_ops->ref_count) != 0) | 536 | if (atomic_read(&ulp_ops->ref_count) != 0) |
537 | netdev_warn(dev->netdev, "Failed waiting for ref count to go to zero\n"); | 537 | pr_warn("%s: Failed waiting for ref count to go to zero\n", |
538 | __func__); | ||
538 | return 0; | 539 | return 0; |
539 | 540 | ||
540 | out_unlock: | 541 | out_unlock: |
@@ -1053,12 +1054,13 @@ static int cnic_init_uio(struct cnic_dev *dev) | |||
1053 | 1054 | ||
1054 | uinfo = &udev->cnic_uinfo; | 1055 | uinfo = &udev->cnic_uinfo; |
1055 | 1056 | ||
1056 | uinfo->mem[0].addr = dev->netdev->base_addr; | 1057 | uinfo->mem[0].addr = pci_resource_start(dev->pcidev, 0); |
1057 | uinfo->mem[0].internal_addr = dev->regview; | 1058 | uinfo->mem[0].internal_addr = dev->regview; |
1058 | uinfo->mem[0].size = dev->netdev->mem_end - dev->netdev->mem_start; | ||
1059 | uinfo->mem[0].memtype = UIO_MEM_PHYS; | 1059 | uinfo->mem[0].memtype = UIO_MEM_PHYS; |
1060 | 1060 | ||
1061 | if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { | 1061 | if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { |
1062 | uinfo->mem[0].size = MB_GET_CID_ADDR(TX_TSS_CID + | ||
1063 | TX_MAX_TSS_RINGS + 1); | ||
1062 | uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen & | 1064 | uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen & |
1063 | PAGE_MASK; | 1065 | PAGE_MASK; |
1064 | if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) | 1066 | if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) |
@@ -1068,6 +1070,8 @@ static int cnic_init_uio(struct cnic_dev *dev) | |||
1068 | 1070 | ||
1069 | uinfo->name = "bnx2_cnic"; | 1071 | uinfo->name = "bnx2_cnic"; |
1070 | } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { | 1072 | } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { |
1073 | uinfo->mem[0].size = pci_resource_len(dev->pcidev, 0); | ||
1074 | |||
1071 | uinfo->mem[1].addr = (unsigned long) cp->bnx2x_def_status_blk & | 1075 | uinfo->mem[1].addr = (unsigned long) cp->bnx2x_def_status_blk & |
1072 | PAGE_MASK; | 1076 | PAGE_MASK; |
1073 | uinfo->mem[1].size = sizeof(*cp->bnx2x_def_status_blk); | 1077 | uinfo->mem[1].size = sizeof(*cp->bnx2x_def_status_blk); |
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index f2db8fca46a1..ab1d80ff0791 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -2063,10 +2063,9 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2063 | return NETDEV_TX_OK; | 2063 | return NETDEV_TX_OK; |
2064 | } | 2064 | } |
2065 | 2065 | ||
2066 | /* Steal sock reference for processing TX time stamps */ | 2066 | if (skb->sk) |
2067 | swap(skb_new->sk, skb->sk); | 2067 | skb_set_owner_w(skb_new, skb->sk); |
2068 | swap(skb_new->destructor, skb->destructor); | 2068 | consume_skb(skb); |
2069 | kfree_skb(skb); | ||
2070 | skb = skb_new; | 2069 | skb = skb_new; |
2071 | } | 2070 | } |
2072 | 2071 | ||
diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 36db4df09aed..1f063dcd8f85 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c | |||
@@ -1572,6 +1572,9 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) | |||
1572 | ctrl = er32(CTRL); | 1572 | ctrl = er32(CTRL); |
1573 | status = er32(STATUS); | 1573 | status = er32(STATUS); |
1574 | rxcw = er32(RXCW); | 1574 | rxcw = er32(RXCW); |
1575 | /* SYNCH bit and IV bit are sticky */ | ||
1576 | udelay(10); | ||
1577 | rxcw = er32(RXCW); | ||
1575 | 1578 | ||
1576 | if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) { | 1579 | if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) { |
1577 | 1580 | ||
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 238ab2f8a5e7..e3a7b07df629 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c | |||
@@ -325,24 +325,46 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) | |||
325 | **/ | 325 | **/ |
326 | static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw) | 326 | static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw) |
327 | { | 327 | { |
328 | u16 phy_reg; | 328 | u16 phy_reg = 0; |
329 | u32 phy_id; | 329 | u32 phy_id = 0; |
330 | s32 ret_val; | ||
331 | u16 retry_count; | ||
332 | |||
333 | for (retry_count = 0; retry_count < 2; retry_count++) { | ||
334 | ret_val = e1e_rphy_locked(hw, PHY_ID1, &phy_reg); | ||
335 | if (ret_val || (phy_reg == 0xFFFF)) | ||
336 | continue; | ||
337 | phy_id = (u32)(phy_reg << 16); | ||
330 | 338 | ||
331 | e1e_rphy_locked(hw, PHY_ID1, &phy_reg); | 339 | ret_val = e1e_rphy_locked(hw, PHY_ID2, &phy_reg); |
332 | phy_id = (u32)(phy_reg << 16); | 340 | if (ret_val || (phy_reg == 0xFFFF)) { |
333 | e1e_rphy_locked(hw, PHY_ID2, &phy_reg); | 341 | phy_id = 0; |
334 | phy_id |= (u32)(phy_reg & PHY_REVISION_MASK); | 342 | continue; |
343 | } | ||
344 | phy_id |= (u32)(phy_reg & PHY_REVISION_MASK); | ||
345 | break; | ||
346 | } | ||
335 | 347 | ||
336 | if (hw->phy.id) { | 348 | if (hw->phy.id) { |
337 | if (hw->phy.id == phy_id) | 349 | if (hw->phy.id == phy_id) |
338 | return true; | 350 | return true; |
339 | } else { | 351 | } else if (phy_id) { |
340 | if ((phy_id != 0) && (phy_id != PHY_REVISION_MASK)) | 352 | hw->phy.id = phy_id; |
341 | hw->phy.id = phy_id; | 353 | hw->phy.revision = (u32)(phy_reg & ~PHY_REVISION_MASK); |
342 | return true; | 354 | return true; |
343 | } | 355 | } |
344 | 356 | ||
345 | return false; | 357 | /* |
358 | * In case the PHY needs to be in mdio slow mode, | ||
359 | * set slow mode and try to get the PHY id again. | ||
360 | */ | ||
361 | hw->phy.ops.release(hw); | ||
362 | ret_val = e1000_set_mdio_slow_mode_hv(hw); | ||
363 | if (!ret_val) | ||
364 | ret_val = e1000e_get_phy_id(hw); | ||
365 | hw->phy.ops.acquire(hw); | ||
366 | |||
367 | return !ret_val; | ||
346 | } | 368 | } |
347 | 369 | ||
348 | /** | 370 | /** |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 18ca3bcadf0c..e242104ab471 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -6647,6 +6647,11 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) | |||
6647 | return -EINVAL; | 6647 | return -EINVAL; |
6648 | } | 6648 | } |
6649 | 6649 | ||
6650 | if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { | ||
6651 | e_err(drv, "Enable failed, SR-IOV enabled\n"); | ||
6652 | return -EINVAL; | ||
6653 | } | ||
6654 | |||
6650 | /* Hardware supports up to 8 traffic classes */ | 6655 | /* Hardware supports up to 8 traffic classes */ |
6651 | if (tc > adapter->dcb_cfg.num_tcs.pg_tcs || | 6656 | if (tc > adapter->dcb_cfg.num_tcs.pg_tcs || |
6652 | (hw->mac.type == ixgbe_mac_82598EB && | 6657 | (hw->mac.type == ixgbe_mac_82598EB && |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index f69ec4288b10..41e32257a4e8 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
@@ -201,6 +201,9 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter, | |||
201 | unsigned int i, eop, count = 0; | 201 | unsigned int i, eop, count = 0; |
202 | unsigned int total_bytes = 0, total_packets = 0; | 202 | unsigned int total_bytes = 0, total_packets = 0; |
203 | 203 | ||
204 | if (test_bit(__IXGBEVF_DOWN, &adapter->state)) | ||
205 | return true; | ||
206 | |||
204 | i = tx_ring->next_to_clean; | 207 | i = tx_ring->next_to_clean; |
205 | eop = tx_ring->tx_buffer_info[i].next_to_watch; | 208 | eop = tx_ring->tx_buffer_info[i].next_to_watch; |
206 | eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); | 209 | eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); |
@@ -969,8 +972,6 @@ static irqreturn_t ixgbevf_msix_clean_tx(int irq, void *data) | |||
969 | r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); | 972 | r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); |
970 | for (i = 0; i < q_vector->txr_count; i++) { | 973 | for (i = 0; i < q_vector->txr_count; i++) { |
971 | tx_ring = &(adapter->tx_ring[r_idx]); | 974 | tx_ring = &(adapter->tx_ring[r_idx]); |
972 | tx_ring->total_bytes = 0; | ||
973 | tx_ring->total_packets = 0; | ||
974 | ixgbevf_clean_tx_irq(adapter, tx_ring); | 975 | ixgbevf_clean_tx_irq(adapter, tx_ring); |
975 | r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, | 976 | r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, |
976 | r_idx + 1); | 977 | r_idx + 1); |
@@ -994,16 +995,6 @@ static irqreturn_t ixgbevf_msix_clean_rx(int irq, void *data) | |||
994 | struct ixgbe_hw *hw = &adapter->hw; | 995 | struct ixgbe_hw *hw = &adapter->hw; |
995 | struct ixgbevf_ring *rx_ring; | 996 | struct ixgbevf_ring *rx_ring; |
996 | int r_idx; | 997 | int r_idx; |
997 | int i; | ||
998 | |||
999 | r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); | ||
1000 | for (i = 0; i < q_vector->rxr_count; i++) { | ||
1001 | rx_ring = &(adapter->rx_ring[r_idx]); | ||
1002 | rx_ring->total_bytes = 0; | ||
1003 | rx_ring->total_packets = 0; | ||
1004 | r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, | ||
1005 | r_idx + 1); | ||
1006 | } | ||
1007 | 998 | ||
1008 | if (!q_vector->rxr_count) | 999 | if (!q_vector->rxr_count) |
1009 | return IRQ_HANDLED; | 1000 | return IRQ_HANDLED; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c index fb8377da1687..4b785e10f2ed 100644 --- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c | |||
@@ -51,7 +51,7 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) | |||
51 | desc->des3 = desc->des2 + BUF_SIZE_4KiB; | 51 | desc->des3 = desc->des2 + BUF_SIZE_4KiB; |
52 | priv->hw->desc->prepare_tx_desc(desc, 1, bmax, | 52 | priv->hw->desc->prepare_tx_desc(desc, 1, bmax, |
53 | csum); | 53 | csum); |
54 | 54 | wmb(); | |
55 | entry = (++priv->cur_tx) % txsize; | 55 | entry = (++priv->cur_tx) % txsize; |
56 | desc = priv->dma_tx + entry; | 56 | desc = priv->dma_tx + entry; |
57 | 57 | ||
@@ -59,6 +59,7 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) | |||
59 | len, DMA_TO_DEVICE); | 59 | len, DMA_TO_DEVICE); |
60 | desc->des3 = desc->des2 + BUF_SIZE_4KiB; | 60 | desc->des3 = desc->des2 + BUF_SIZE_4KiB; |
61 | priv->hw->desc->prepare_tx_desc(desc, 0, len, csum); | 61 | priv->hw->desc->prepare_tx_desc(desc, 0, len, csum); |
62 | wmb(); | ||
62 | priv->hw->desc->set_tx_owner(desc); | 63 | priv->hw->desc->set_tx_owner(desc); |
63 | priv->tx_skbuff[entry] = NULL; | 64 | priv->tx_skbuff[entry] = NULL; |
64 | } else { | 65 | } else { |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 51b3b68528ee..ea3003edde18 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -1212,6 +1212,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1212 | priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion); | 1212 | priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion); |
1213 | wmb(); | 1213 | wmb(); |
1214 | priv->hw->desc->set_tx_owner(desc); | 1214 | priv->hw->desc->set_tx_owner(desc); |
1215 | wmb(); | ||
1215 | } | 1216 | } |
1216 | 1217 | ||
1217 | /* Interrupt on completition only for the latest segment */ | 1218 | /* Interrupt on completition only for the latest segment */ |
@@ -1227,6 +1228,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1227 | 1228 | ||
1228 | /* To avoid raise condition */ | 1229 | /* To avoid raise condition */ |
1229 | priv->hw->desc->set_tx_owner(first); | 1230 | priv->hw->desc->set_tx_owner(first); |
1231 | wmb(); | ||
1230 | 1232 | ||
1231 | priv->cur_tx++; | 1233 | priv->cur_tx++; |
1232 | 1234 | ||
@@ -1290,6 +1292,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) | |||
1290 | } | 1292 | } |
1291 | wmb(); | 1293 | wmb(); |
1292 | priv->hw->desc->set_rx_owner(p + entry); | 1294 | priv->hw->desc->set_rx_owner(p + entry); |
1295 | wmb(); | ||
1293 | } | 1296 | } |
1294 | } | 1297 | } |
1295 | 1298 | ||
diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c index 39ea0674dcde..5c120189ec86 100644 --- a/drivers/net/phy/mdio-mux.c +++ b/drivers/net/phy/mdio-mux.c | |||
@@ -46,7 +46,13 @@ static int mdio_mux_read(struct mii_bus *bus, int phy_id, int regnum) | |||
46 | struct mdio_mux_parent_bus *pb = cb->parent; | 46 | struct mdio_mux_parent_bus *pb = cb->parent; |
47 | int r; | 47 | int r; |
48 | 48 | ||
49 | mutex_lock(&pb->mii_bus->mdio_lock); | 49 | /* In theory multiple mdio_mux could be stacked, thus creating |
50 | * more than a single level of nesting. But in practice, | ||
51 | * SINGLE_DEPTH_NESTING will cover the vast majority of use | ||
52 | * cases. We use it, instead of trying to handle the general | ||
53 | * case. | ||
54 | */ | ||
55 | mutex_lock_nested(&pb->mii_bus->mdio_lock, SINGLE_DEPTH_NESTING); | ||
50 | r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); | 56 | r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); |
51 | if (r) | 57 | if (r) |
52 | goto out; | 58 | goto out; |
@@ -71,7 +77,7 @@ static int mdio_mux_write(struct mii_bus *bus, int phy_id, | |||
71 | 77 | ||
72 | int r; | 78 | int r; |
73 | 79 | ||
74 | mutex_lock(&pb->mii_bus->mdio_lock); | 80 | mutex_lock_nested(&pb->mii_bus->mdio_lock, SINGLE_DEPTH_NESTING); |
75 | r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); | 81 | r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); |
76 | if (r) | 82 | if (r) |
77 | goto out; | 83 | goto out; |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index b01960fcfbc9..a051cedd64bd 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -346,6 +346,15 @@ static const struct driver_info qmi_wwan_force_int1 = { | |||
346 | .data = BIT(1), /* interface whitelist bitmap */ | 346 | .data = BIT(1), /* interface whitelist bitmap */ |
347 | }; | 347 | }; |
348 | 348 | ||
349 | static const struct driver_info qmi_wwan_force_int2 = { | ||
350 | .description = "Qualcomm WWAN/QMI device", | ||
351 | .flags = FLAG_WWAN, | ||
352 | .bind = qmi_wwan_bind_shared, | ||
353 | .unbind = qmi_wwan_unbind_shared, | ||
354 | .manage_power = qmi_wwan_manage_power, | ||
355 | .data = BIT(2), /* interface whitelist bitmap */ | ||
356 | }; | ||
357 | |||
349 | static const struct driver_info qmi_wwan_force_int3 = { | 358 | static const struct driver_info qmi_wwan_force_int3 = { |
350 | .description = "Qualcomm WWAN/QMI device", | 359 | .description = "Qualcomm WWAN/QMI device", |
351 | .flags = FLAG_WWAN, | 360 | .flags = FLAG_WWAN, |
@@ -498,6 +507,15 @@ static const struct usb_device_id products[] = { | |||
498 | .bInterfaceProtocol = 0xff, | 507 | .bInterfaceProtocol = 0xff, |
499 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | 508 | .driver_info = (unsigned long)&qmi_wwan_force_int4, |
500 | }, | 509 | }, |
510 | { /* ZTE MF60 */ | ||
511 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
512 | .idVendor = 0x19d2, | ||
513 | .idProduct = 0x1402, | ||
514 | .bInterfaceClass = 0xff, | ||
515 | .bInterfaceSubClass = 0xff, | ||
516 | .bInterfaceProtocol = 0xff, | ||
517 | .driver_info = (unsigned long)&qmi_wwan_force_int2, | ||
518 | }, | ||
501 | { /* Sierra Wireless MC77xx in QMI mode */ | 519 | { /* Sierra Wireless MC77xx in QMI mode */ |
502 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | 520 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, |
503 | .idVendor = 0x1199, | 521 | .idVendor = 0x1199, |
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index f1f8bd09bd87..c8baf020c20f 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
@@ -1072,7 +1072,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, | |||
1072 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | 1072 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); |
1073 | /* create a bounce buffer in zone_dma on mapping failure. */ | 1073 | /* create a bounce buffer in zone_dma on mapping failure. */ |
1074 | if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { | 1074 | if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { |
1075 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); | 1075 | bounce_skb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); |
1076 | if (!bounce_skb) { | 1076 | if (!bounce_skb) { |
1077 | ring->current_slot = old_top_slot; | 1077 | ring->current_slot = old_top_slot; |
1078 | ring->used_slots = old_used_slots; | 1078 | ring->used_slots = old_used_slots; |
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 509301a5e7e2..ff5d689e13f3 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c | |||
@@ -3405,7 +3405,7 @@ il4965_remove_dynamic_key(struct il_priv *il, | |||
3405 | return 0; | 3405 | return 0; |
3406 | } | 3406 | } |
3407 | 3407 | ||
3408 | if (il->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { | 3408 | if (il->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_INVALID) { |
3409 | IL_WARN("Removing wrong key %d 0x%x\n", keyconf->keyidx, | 3409 | IL_WARN("Removing wrong key %d 0x%x\n", keyconf->keyidx, |
3410 | key_flags); | 3410 | key_flags); |
3411 | spin_unlock_irqrestore(&il->sta_lock, flags); | 3411 | spin_unlock_irqrestore(&il->sta_lock, flags); |
@@ -3420,7 +3420,7 @@ il4965_remove_dynamic_key(struct il_priv *il, | |||
3420 | memset(&il->stations[sta_id].sta.key, 0, sizeof(struct il4965_keyinfo)); | 3420 | memset(&il->stations[sta_id].sta.key, 0, sizeof(struct il4965_keyinfo)); |
3421 | il->stations[sta_id].sta.key.key_flags = | 3421 | il->stations[sta_id].sta.key.key_flags = |
3422 | STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; | 3422 | STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; |
3423 | il->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET; | 3423 | il->stations[sta_id].sta.key.key_offset = keyconf->hw_key_idx; |
3424 | il->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 3424 | il->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
3425 | il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 3425 | il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
3426 | 3426 | ||
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index cbf2dc18341f..5d4807c2b56d 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c | |||
@@ -4767,14 +4767,12 @@ il_bg_watchdog(unsigned long data) | |||
4767 | return; | 4767 | return; |
4768 | 4768 | ||
4769 | /* monitor and check for other stuck queues */ | 4769 | /* monitor and check for other stuck queues */ |
4770 | if (il_is_any_associated(il)) { | 4770 | for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) { |
4771 | for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) { | 4771 | /* skip as we already checked the command queue */ |
4772 | /* skip as we already checked the command queue */ | 4772 | if (cnt == il->cmd_queue) |
4773 | if (cnt == il->cmd_queue) | 4773 | continue; |
4774 | continue; | 4774 | if (il_check_stuck_queue(il, cnt)) |
4775 | if (il_check_stuck_queue(il, cnt)) | 4775 | return; |
4776 | return; | ||
4777 | } | ||
4778 | } | 4776 | } |
4779 | 4777 | ||
4780 | mod_timer(&il->watchdog, | 4778 | mod_timer(&il->watchdog, |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index ce61b6fae1c9..5c7fd185373c 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -958,6 +958,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, | |||
958 | case NL80211_HIDDEN_SSID_ZERO_CONTENTS: | 958 | case NL80211_HIDDEN_SSID_ZERO_CONTENTS: |
959 | /* firmware doesn't support this type of hidden SSID */ | 959 | /* firmware doesn't support this type of hidden SSID */ |
960 | default: | 960 | default: |
961 | kfree(bss_cfg); | ||
961 | return -EINVAL; | 962 | return -EINVAL; |
962 | } | 963 | } |
963 | 964 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index d357d1ed92f6..74ecc33fdd90 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -436,8 +436,8 @@ void rt2x00usb_kick_queue(struct data_queue *queue) | |||
436 | case QID_RX: | 436 | case QID_RX: |
437 | if (!rt2x00queue_full(queue)) | 437 | if (!rt2x00queue_full(queue)) |
438 | rt2x00queue_for_each_entry(queue, | 438 | rt2x00queue_for_each_entry(queue, |
439 | Q_INDEX_DONE, | ||
440 | Q_INDEX, | 439 | Q_INDEX, |
440 | Q_INDEX_DONE, | ||
441 | NULL, | 441 | NULL, |
442 | rt2x00usb_kick_rx_entry); | 442 | rt2x00usb_kick_rx_entry); |
443 | break; | 443 | break; |
diff --git a/drivers/oprofile/oprofile_perf.c b/drivers/oprofile/oprofile_perf.c index efc4b7f308cf..f3cfa0b9adfa 100644 --- a/drivers/oprofile/oprofile_perf.c +++ b/drivers/oprofile/oprofile_perf.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2010 ARM Ltd. | 2 | * Copyright 2010 ARM Ltd. |
3 | * Copyright 2012 Advanced Micro Devices, Inc., Robert Richter | ||
3 | * | 4 | * |
4 | * Perf-events backend for OProfile. | 5 | * Perf-events backend for OProfile. |
5 | */ | 6 | */ |
@@ -25,7 +26,7 @@ static int oprofile_perf_enabled; | |||
25 | static DEFINE_MUTEX(oprofile_perf_mutex); | 26 | static DEFINE_MUTEX(oprofile_perf_mutex); |
26 | 27 | ||
27 | static struct op_counter_config *counter_config; | 28 | static struct op_counter_config *counter_config; |
28 | static struct perf_event **perf_events[NR_CPUS]; | 29 | static DEFINE_PER_CPU(struct perf_event **, perf_events); |
29 | static int num_counters; | 30 | static int num_counters; |
30 | 31 | ||
31 | /* | 32 | /* |
@@ -38,7 +39,7 @@ static void op_overflow_handler(struct perf_event *event, | |||
38 | u32 cpu = smp_processor_id(); | 39 | u32 cpu = smp_processor_id(); |
39 | 40 | ||
40 | for (id = 0; id < num_counters; ++id) | 41 | for (id = 0; id < num_counters; ++id) |
41 | if (perf_events[cpu][id] == event) | 42 | if (per_cpu(perf_events, cpu)[id] == event) |
42 | break; | 43 | break; |
43 | 44 | ||
44 | if (id != num_counters) | 45 | if (id != num_counters) |
@@ -74,7 +75,7 @@ static int op_create_counter(int cpu, int event) | |||
74 | { | 75 | { |
75 | struct perf_event *pevent; | 76 | struct perf_event *pevent; |
76 | 77 | ||
77 | if (!counter_config[event].enabled || perf_events[cpu][event]) | 78 | if (!counter_config[event].enabled || per_cpu(perf_events, cpu)[event]) |
78 | return 0; | 79 | return 0; |
79 | 80 | ||
80 | pevent = perf_event_create_kernel_counter(&counter_config[event].attr, | 81 | pevent = perf_event_create_kernel_counter(&counter_config[event].attr, |
@@ -91,18 +92,18 @@ static int op_create_counter(int cpu, int event) | |||
91 | return -EBUSY; | 92 | return -EBUSY; |
92 | } | 93 | } |
93 | 94 | ||
94 | perf_events[cpu][event] = pevent; | 95 | per_cpu(perf_events, cpu)[event] = pevent; |
95 | 96 | ||
96 | return 0; | 97 | return 0; |
97 | } | 98 | } |
98 | 99 | ||
99 | static void op_destroy_counter(int cpu, int event) | 100 | static void op_destroy_counter(int cpu, int event) |
100 | { | 101 | { |
101 | struct perf_event *pevent = perf_events[cpu][event]; | 102 | struct perf_event *pevent = per_cpu(perf_events, cpu)[event]; |
102 | 103 | ||
103 | if (pevent) { | 104 | if (pevent) { |
104 | perf_event_release_kernel(pevent); | 105 | perf_event_release_kernel(pevent); |
105 | perf_events[cpu][event] = NULL; | 106 | per_cpu(perf_events, cpu)[event] = NULL; |
106 | } | 107 | } |
107 | } | 108 | } |
108 | 109 | ||
@@ -257,12 +258,12 @@ void oprofile_perf_exit(void) | |||
257 | 258 | ||
258 | for_each_possible_cpu(cpu) { | 259 | for_each_possible_cpu(cpu) { |
259 | for (id = 0; id < num_counters; ++id) { | 260 | for (id = 0; id < num_counters; ++id) { |
260 | event = perf_events[cpu][id]; | 261 | event = per_cpu(perf_events, cpu)[id]; |
261 | if (event) | 262 | if (event) |
262 | perf_event_release_kernel(event); | 263 | perf_event_release_kernel(event); |
263 | } | 264 | } |
264 | 265 | ||
265 | kfree(perf_events[cpu]); | 266 | kfree(per_cpu(perf_events, cpu)); |
266 | } | 267 | } |
267 | 268 | ||
268 | kfree(counter_config); | 269 | kfree(counter_config); |
@@ -277,8 +278,6 @@ int __init oprofile_perf_init(struct oprofile_operations *ops) | |||
277 | if (ret) | 278 | if (ret) |
278 | return ret; | 279 | return ret; |
279 | 280 | ||
280 | memset(&perf_events, 0, sizeof(perf_events)); | ||
281 | |||
282 | num_counters = perf_num_counters(); | 281 | num_counters = perf_num_counters(); |
283 | if (num_counters <= 0) { | 282 | if (num_counters <= 0) { |
284 | pr_info("oprofile: no performance counters\n"); | 283 | pr_info("oprofile: no performance counters\n"); |
@@ -298,9 +297,9 @@ int __init oprofile_perf_init(struct oprofile_operations *ops) | |||
298 | } | 297 | } |
299 | 298 | ||
300 | for_each_possible_cpu(cpu) { | 299 | for_each_possible_cpu(cpu) { |
301 | perf_events[cpu] = kcalloc(num_counters, | 300 | per_cpu(perf_events, cpu) = kcalloc(num_counters, |
302 | sizeof(struct perf_event *), GFP_KERNEL); | 301 | sizeof(struct perf_event *), GFP_KERNEL); |
303 | if (!perf_events[cpu]) { | 302 | if (!per_cpu(perf_events, cpu)) { |
304 | pr_info("oprofile: failed to allocate %d perf events " | 303 | pr_info("oprofile: failed to allocate %d perf events " |
305 | "for cpu %d\n", num_counters, cpu); | 304 | "for cpu %d\n", num_counters, cpu); |
306 | ret = -ENOMEM; | 305 | ret = -ENOMEM; |
diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c index dd6d93aa5334..90c837f469a6 100644 --- a/drivers/pinctrl/pinctrl-imx.c +++ b/drivers/pinctrl/pinctrl-imx.c | |||
@@ -474,7 +474,9 @@ static int __devinit imx_pinctrl_parse_groups(struct device_node *np, | |||
474 | grp->configs[j] = config & ~IMX_PAD_SION; | 474 | grp->configs[j] = config & ~IMX_PAD_SION; |
475 | } | 475 | } |
476 | 476 | ||
477 | #ifdef DEBUG | ||
477 | IMX_PMX_DUMP(info, grp->pins, grp->mux_mode, grp->configs, grp->npins); | 478 | IMX_PMX_DUMP(info, grp->pins, grp->mux_mode, grp->configs, grp->npins); |
479 | #endif | ||
478 | 480 | ||
479 | return 0; | 481 | return 0; |
480 | } | 482 | } |
diff --git a/drivers/pinctrl/pinctrl-imx6q.c b/drivers/pinctrl/pinctrl-imx6q.c index 7737d4d71a3c..e9bf71fbedca 100644 --- a/drivers/pinctrl/pinctrl-imx6q.c +++ b/drivers/pinctrl/pinctrl-imx6q.c | |||
@@ -1950,6 +1950,8 @@ static struct imx_pin_reg imx6q_pin_regs[] = { | |||
1950 | IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 5, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__GPIO_1_12 */ | 1950 | IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 5, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__GPIO_1_12 */ |
1951 | IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 6, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__SJC_DONE */ | 1951 | IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 6, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__SJC_DONE */ |
1952 | IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 7, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__ANATOP_TESTO_3 */ | 1952 | IMX_PIN_REG(MX6Q_PAD_SD2_DAT3, 0x0744, 0x035C, 7, 0x0000, 0), /* MX6Q_PAD_SD2_DAT3__ANATOP_TESTO_3 */ |
1953 | IMX_PIN_REG(MX6Q_PAD_ENET_RX_ER, 0x04EC, 0x01D8, 0, 0x0000, 0), /* MX6Q_PAD_ENET_RX_ER__ANATOP_USBOTG_ID */ | ||
1954 | IMX_PIN_REG(MX6Q_PAD_GPIO_1, 0x05F4, 0x0224, 3, 0x0000, 0), /* MX6Q_PAD_GPIO_1__ANATOP_USBOTG_ID */ | ||
1953 | }; | 1955 | }; |
1954 | 1956 | ||
1955 | /* Pad names for the pinmux subsystem */ | 1957 | /* Pad names for the pinmux subsystem */ |
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 4f20f8dd3d7c..17f6dfd8dbfb 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
@@ -694,10 +694,10 @@ MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); | |||
694 | static int __devinit ideapad_acpi_add(struct acpi_device *adevice) | 694 | static int __devinit ideapad_acpi_add(struct acpi_device *adevice) |
695 | { | 695 | { |
696 | int ret, i; | 696 | int ret, i; |
697 | unsigned long cfg; | 697 | int cfg; |
698 | struct ideapad_private *priv; | 698 | struct ideapad_private *priv; |
699 | 699 | ||
700 | if (read_method_int(adevice->handle, "_CFG", (int *)&cfg)) | 700 | if (read_method_int(adevice->handle, "_CFG", &cfg)) |
701 | return -ENODEV; | 701 | return -ENODEV; |
702 | 702 | ||
703 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 703 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
@@ -721,7 +721,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice) | |||
721 | goto input_failed; | 721 | goto input_failed; |
722 | 722 | ||
723 | for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { | 723 | for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { |
724 | if (test_bit(ideapad_rfk_data[i].cfgbit, &cfg)) | 724 | if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) |
725 | ideapad_register_rfkill(adevice, i); | 725 | ideapad_register_rfkill(adevice, i); |
726 | else | 726 | else |
727 | priv->rfk[i] = NULL; | 727 | priv->rfk[i] = NULL; |
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index 0ffdb3cde2bb..9af4257d4901 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c | |||
@@ -72,6 +72,7 @@ | |||
72 | #include <linux/string.h> | 72 | #include <linux/string.h> |
73 | #include <linux/tick.h> | 73 | #include <linux/tick.h> |
74 | #include <linux/timer.h> | 74 | #include <linux/timer.h> |
75 | #include <linux/dmi.h> | ||
75 | #include <drm/i915_drm.h> | 76 | #include <drm/i915_drm.h> |
76 | #include <asm/msr.h> | 77 | #include <asm/msr.h> |
77 | #include <asm/processor.h> | 78 | #include <asm/processor.h> |
@@ -1485,6 +1486,24 @@ static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = { | |||
1485 | 1486 | ||
1486 | MODULE_DEVICE_TABLE(pci, ips_id_table); | 1487 | MODULE_DEVICE_TABLE(pci, ips_id_table); |
1487 | 1488 | ||
1489 | static int ips_blacklist_callback(const struct dmi_system_id *id) | ||
1490 | { | ||
1491 | pr_info("Blacklisted intel_ips for %s\n", id->ident); | ||
1492 | return 1; | ||
1493 | } | ||
1494 | |||
1495 | static const struct dmi_system_id ips_blacklist[] = { | ||
1496 | { | ||
1497 | .callback = ips_blacklist_callback, | ||
1498 | .ident = "HP ProBook", | ||
1499 | .matches = { | ||
1500 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
1501 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook"), | ||
1502 | }, | ||
1503 | }, | ||
1504 | { } /* terminating entry */ | ||
1505 | }; | ||
1506 | |||
1488 | static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) | 1507 | static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) |
1489 | { | 1508 | { |
1490 | u64 platform_info; | 1509 | u64 platform_info; |
@@ -1494,6 +1513,9 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1494 | u16 htshi, trc, trc_required_mask; | 1513 | u16 htshi, trc, trc_required_mask; |
1495 | u8 tse; | 1514 | u8 tse; |
1496 | 1515 | ||
1516 | if (dmi_check_system(ips_blacklist)) | ||
1517 | return -ENODEV; | ||
1518 | |||
1497 | ips = kzalloc(sizeof(struct ips_driver), GFP_KERNEL); | 1519 | ips = kzalloc(sizeof(struct ips_driver), GFP_KERNEL); |
1498 | if (!ips) | 1520 | if (!ips) |
1499 | return -ENOMEM; | 1521 | return -ENOMEM; |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 210d4ae547c2..d456ff0c73b7 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -973,7 +973,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, | |||
973 | struct device_attribute *attr, | 973 | struct device_attribute *attr, |
974 | const char *buffer, size_t count) | 974 | const char *buffer, size_t count) |
975 | { | 975 | { |
976 | unsigned long value = 0; | 976 | int value; |
977 | int ret = 0; | 977 | int ret = 0; |
978 | struct sony_nc_value *item = | 978 | struct sony_nc_value *item = |
979 | container_of(attr, struct sony_nc_value, devattr); | 979 | container_of(attr, struct sony_nc_value, devattr); |
@@ -984,7 +984,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, | |||
984 | if (count > 31) | 984 | if (count > 31) |
985 | return -EINVAL; | 985 | return -EINVAL; |
986 | 986 | ||
987 | if (kstrtoul(buffer, 10, &value)) | 987 | if (kstrtoint(buffer, 10, &value)) |
988 | return -EINVAL; | 988 | return -EINVAL; |
989 | 989 | ||
990 | if (item->validate) | 990 | if (item->validate) |
@@ -994,7 +994,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, | |||
994 | return value; | 994 | return value; |
995 | 995 | ||
996 | ret = sony_nc_int_call(sony_nc_acpi_handle, *item->acpiset, | 996 | ret = sony_nc_int_call(sony_nc_acpi_handle, *item->acpiset, |
997 | (int *)&value, NULL); | 997 | &value, NULL); |
998 | if (ret < 0) | 998 | if (ret < 0) |
999 | return -EIO; | 999 | return -EIO; |
1000 | 1000 | ||
@@ -1010,6 +1010,7 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, | |||
1010 | struct sony_backlight_props { | 1010 | struct sony_backlight_props { |
1011 | struct backlight_device *dev; | 1011 | struct backlight_device *dev; |
1012 | int handle; | 1012 | int handle; |
1013 | int cmd_base; | ||
1013 | u8 offset; | 1014 | u8 offset; |
1014 | u8 maxlvl; | 1015 | u8 maxlvl; |
1015 | }; | 1016 | }; |
@@ -1037,7 +1038,7 @@ static int sony_nc_get_brightness_ng(struct backlight_device *bd) | |||
1037 | struct sony_backlight_props *sdev = | 1038 | struct sony_backlight_props *sdev = |
1038 | (struct sony_backlight_props *)bl_get_data(bd); | 1039 | (struct sony_backlight_props *)bl_get_data(bd); |
1039 | 1040 | ||
1040 | sony_call_snc_handle(sdev->handle, 0x0200, &result); | 1041 | sony_call_snc_handle(sdev->handle, sdev->cmd_base + 0x100, &result); |
1041 | 1042 | ||
1042 | return (result & 0xff) - sdev->offset; | 1043 | return (result & 0xff) - sdev->offset; |
1043 | } | 1044 | } |
@@ -1049,7 +1050,8 @@ static int sony_nc_update_status_ng(struct backlight_device *bd) | |||
1049 | (struct sony_backlight_props *)bl_get_data(bd); | 1050 | (struct sony_backlight_props *)bl_get_data(bd); |
1050 | 1051 | ||
1051 | value = bd->props.brightness + sdev->offset; | 1052 | value = bd->props.brightness + sdev->offset; |
1052 | if (sony_call_snc_handle(sdev->handle, 0x0100 | (value << 16), &result)) | 1053 | if (sony_call_snc_handle(sdev->handle, sdev->cmd_base | (value << 0x10), |
1054 | &result)) | ||
1053 | return -EIO; | 1055 | return -EIO; |
1054 | 1056 | ||
1055 | return value; | 1057 | return value; |
@@ -1172,6 +1174,11 @@ static int sony_nc_hotkeys_decode(u32 event, unsigned int handle) | |||
1172 | /* | 1174 | /* |
1173 | * ACPI callbacks | 1175 | * ACPI callbacks |
1174 | */ | 1176 | */ |
1177 | enum event_types { | ||
1178 | HOTKEY = 1, | ||
1179 | KILLSWITCH, | ||
1180 | GFX_SWITCH | ||
1181 | }; | ||
1175 | static void sony_nc_notify(struct acpi_device *device, u32 event) | 1182 | static void sony_nc_notify(struct acpi_device *device, u32 event) |
1176 | { | 1183 | { |
1177 | u32 real_ev = event; | 1184 | u32 real_ev = event; |
@@ -1196,7 +1203,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) | |||
1196 | /* hotkey event */ | 1203 | /* hotkey event */ |
1197 | case 0x0100: | 1204 | case 0x0100: |
1198 | case 0x0127: | 1205 | case 0x0127: |
1199 | ev_type = 1; | 1206 | ev_type = HOTKEY; |
1200 | real_ev = sony_nc_hotkeys_decode(event, handle); | 1207 | real_ev = sony_nc_hotkeys_decode(event, handle); |
1201 | 1208 | ||
1202 | if (real_ev > 0) | 1209 | if (real_ev > 0) |
@@ -1216,7 +1223,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) | |||
1216 | * update the rfkill device status when the | 1223 | * update the rfkill device status when the |
1217 | * switch is moved. | 1224 | * switch is moved. |
1218 | */ | 1225 | */ |
1219 | ev_type = 2; | 1226 | ev_type = KILLSWITCH; |
1220 | sony_call_snc_handle(handle, 0x0100, &result); | 1227 | sony_call_snc_handle(handle, 0x0100, &result); |
1221 | real_ev = result & 0x03; | 1228 | real_ev = result & 0x03; |
1222 | 1229 | ||
@@ -1226,6 +1233,24 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) | |||
1226 | 1233 | ||
1227 | break; | 1234 | break; |
1228 | 1235 | ||
1236 | case 0x0128: | ||
1237 | case 0x0146: | ||
1238 | /* Hybrid GFX switching */ | ||
1239 | sony_call_snc_handle(handle, 0x0000, &result); | ||
1240 | dprintk("GFX switch event received (reason: %s)\n", | ||
1241 | (result & 0x01) ? | ||
1242 | "switch change" : "unknown"); | ||
1243 | |||
1244 | /* verify the switch state | ||
1245 | * 1: discrete GFX | ||
1246 | * 0: integrated GFX | ||
1247 | */ | ||
1248 | sony_call_snc_handle(handle, 0x0100, &result); | ||
1249 | |||
1250 | ev_type = GFX_SWITCH; | ||
1251 | real_ev = result & 0xff; | ||
1252 | break; | ||
1253 | |||
1229 | default: | 1254 | default: |
1230 | dprintk("Unknown event 0x%x for handle 0x%x\n", | 1255 | dprintk("Unknown event 0x%x for handle 0x%x\n", |
1231 | event, handle); | 1256 | event, handle); |
@@ -1238,7 +1263,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event) | |||
1238 | 1263 | ||
1239 | } else { | 1264 | } else { |
1240 | /* old style event */ | 1265 | /* old style event */ |
1241 | ev_type = 1; | 1266 | ev_type = HOTKEY; |
1242 | sony_laptop_report_input_event(real_ev); | 1267 | sony_laptop_report_input_event(real_ev); |
1243 | } | 1268 | } |
1244 | 1269 | ||
@@ -1893,32 +1918,33 @@ static ssize_t sony_nc_battery_care_limit_store(struct device *dev, | |||
1893 | * bits 4,5: store the limit into the EC | 1918 | * bits 4,5: store the limit into the EC |
1894 | * bits 6,7: store the limit into the battery | 1919 | * bits 6,7: store the limit into the battery |
1895 | */ | 1920 | */ |
1921 | cmd = 0; | ||
1896 | 1922 | ||
1897 | /* | 1923 | if (value > 0) { |
1898 | * handle 0x0115 should allow storing on battery too; | 1924 | if (value <= 50) |
1899 | * handle 0x0136 same as 0x0115 + health status; | 1925 | cmd = 0x20; |
1900 | * handle 0x013f, same as 0x0136 but no storing on the battery | ||
1901 | * | ||
1902 | * Store only inside the EC for now, regardless the handle number | ||
1903 | */ | ||
1904 | if (value == 0) | ||
1905 | /* disable limits */ | ||
1906 | cmd = 0x0; | ||
1907 | 1926 | ||
1908 | else if (value <= 50) | 1927 | else if (value <= 80) |
1909 | cmd = 0x21; | 1928 | cmd = 0x10; |
1910 | 1929 | ||
1911 | else if (value <= 80) | 1930 | else if (value <= 100) |
1912 | cmd = 0x11; | 1931 | cmd = 0x30; |
1913 | 1932 | ||
1914 | else if (value <= 100) | 1933 | else |
1915 | cmd = 0x31; | 1934 | return -EINVAL; |
1916 | 1935 | ||
1917 | else | 1936 | /* |
1918 | return -EINVAL; | 1937 | * handle 0x0115 should allow storing on battery too; |
1938 | * handle 0x0136 same as 0x0115 + health status; | ||
1939 | * handle 0x013f, same as 0x0136 but no storing on the battery | ||
1940 | */ | ||
1941 | if (bcare_ctl->handle != 0x013f) | ||
1942 | cmd = cmd | (cmd << 2); | ||
1919 | 1943 | ||
1920 | if (sony_call_snc_handle(bcare_ctl->handle, (cmd << 0x10) | 0x0100, | 1944 | cmd = (cmd | 0x1) << 0x10; |
1921 | &result)) | 1945 | } |
1946 | |||
1947 | if (sony_call_snc_handle(bcare_ctl->handle, cmd | 0x0100, &result)) | ||
1922 | return -EIO; | 1948 | return -EIO; |
1923 | 1949 | ||
1924 | return count; | 1950 | return count; |
@@ -2113,7 +2139,7 @@ static ssize_t sony_nc_thermal_mode_show(struct device *dev, | |||
2113 | struct device_attribute *attr, char *buffer) | 2139 | struct device_attribute *attr, char *buffer) |
2114 | { | 2140 | { |
2115 | ssize_t count = 0; | 2141 | ssize_t count = 0; |
2116 | unsigned int mode = sony_nc_thermal_mode_get(); | 2142 | int mode = sony_nc_thermal_mode_get(); |
2117 | 2143 | ||
2118 | if (mode < 0) | 2144 | if (mode < 0) |
2119 | return mode; | 2145 | return mode; |
@@ -2472,6 +2498,7 @@ static void sony_nc_backlight_ng_read_limits(int handle, | |||
2472 | { | 2498 | { |
2473 | u64 offset; | 2499 | u64 offset; |
2474 | int i; | 2500 | int i; |
2501 | int lvl_table_len = 0; | ||
2475 | u8 min = 0xff, max = 0x00; | 2502 | u8 min = 0xff, max = 0x00; |
2476 | unsigned char buffer[32] = { 0 }; | 2503 | unsigned char buffer[32] = { 0 }; |
2477 | 2504 | ||
@@ -2480,8 +2507,6 @@ static void sony_nc_backlight_ng_read_limits(int handle, | |||
2480 | props->maxlvl = 0xff; | 2507 | props->maxlvl = 0xff; |
2481 | 2508 | ||
2482 | offset = sony_find_snc_handle(handle); | 2509 | offset = sony_find_snc_handle(handle); |
2483 | if (offset < 0) | ||
2484 | return; | ||
2485 | 2510 | ||
2486 | /* try to read the boundaries from ACPI tables, if we fail the above | 2511 | /* try to read the boundaries from ACPI tables, if we fail the above |
2487 | * defaults should be reasonable | 2512 | * defaults should be reasonable |
@@ -2491,11 +2516,21 @@ static void sony_nc_backlight_ng_read_limits(int handle, | |||
2491 | if (i < 0) | 2516 | if (i < 0) |
2492 | return; | 2517 | return; |
2493 | 2518 | ||
2519 | switch (handle) { | ||
2520 | case 0x012f: | ||
2521 | case 0x0137: | ||
2522 | lvl_table_len = 9; | ||
2523 | break; | ||
2524 | case 0x143: | ||
2525 | lvl_table_len = 16; | ||
2526 | break; | ||
2527 | } | ||
2528 | |||
2494 | /* the buffer lists brightness levels available, brightness levels are | 2529 | /* the buffer lists brightness levels available, brightness levels are |
2495 | * from position 0 to 8 in the array, other values are used by ALS | 2530 | * from position 0 to 8 in the array, other values are used by ALS |
2496 | * control. | 2531 | * control. |
2497 | */ | 2532 | */ |
2498 | for (i = 0; i < 9 && i < ARRAY_SIZE(buffer); i++) { | 2533 | for (i = 0; i < lvl_table_len && i < ARRAY_SIZE(buffer); i++) { |
2499 | 2534 | ||
2500 | dprintk("Brightness level: %d\n", buffer[i]); | 2535 | dprintk("Brightness level: %d\n", buffer[i]); |
2501 | 2536 | ||
@@ -2520,16 +2555,24 @@ static void sony_nc_backlight_setup(void) | |||
2520 | const struct backlight_ops *ops = NULL; | 2555 | const struct backlight_ops *ops = NULL; |
2521 | struct backlight_properties props; | 2556 | struct backlight_properties props; |
2522 | 2557 | ||
2523 | if (sony_find_snc_handle(0x12f) != -1) { | 2558 | if (sony_find_snc_handle(0x12f) >= 0) { |
2524 | ops = &sony_backlight_ng_ops; | 2559 | ops = &sony_backlight_ng_ops; |
2560 | sony_bl_props.cmd_base = 0x0100; | ||
2525 | sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props); | 2561 | sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props); |
2526 | max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; | 2562 | max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; |
2527 | 2563 | ||
2528 | } else if (sony_find_snc_handle(0x137) != -1) { | 2564 | } else if (sony_find_snc_handle(0x137) >= 0) { |
2529 | ops = &sony_backlight_ng_ops; | 2565 | ops = &sony_backlight_ng_ops; |
2566 | sony_bl_props.cmd_base = 0x0100; | ||
2530 | sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props); | 2567 | sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props); |
2531 | max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; | 2568 | max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; |
2532 | 2569 | ||
2570 | } else if (sony_find_snc_handle(0x143) >= 0) { | ||
2571 | ops = &sony_backlight_ng_ops; | ||
2572 | sony_bl_props.cmd_base = 0x3000; | ||
2573 | sony_nc_backlight_ng_read_limits(0x143, &sony_bl_props); | ||
2574 | max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; | ||
2575 | |||
2533 | } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", | 2576 | } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", |
2534 | &unused))) { | 2577 | &unused))) { |
2535 | ops = &sony_backlight_ops; | 2578 | ops = &sony_backlight_ops; |
@@ -2597,6 +2640,12 @@ static int sony_nc_add(struct acpi_device *device) | |||
2597 | } | 2640 | } |
2598 | } | 2641 | } |
2599 | 2642 | ||
2643 | result = sony_laptop_setup_input(device); | ||
2644 | if (result) { | ||
2645 | pr_err("Unable to create input devices\n"); | ||
2646 | goto outplatform; | ||
2647 | } | ||
2648 | |||
2600 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", | 2649 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", |
2601 | &handle))) { | 2650 | &handle))) { |
2602 | int arg = 1; | 2651 | int arg = 1; |
@@ -2614,12 +2663,6 @@ static int sony_nc_add(struct acpi_device *device) | |||
2614 | } | 2663 | } |
2615 | 2664 | ||
2616 | /* setup input devices and helper fifo */ | 2665 | /* setup input devices and helper fifo */ |
2617 | result = sony_laptop_setup_input(device); | ||
2618 | if (result) { | ||
2619 | pr_err("Unable to create input devices\n"); | ||
2620 | goto outsnc; | ||
2621 | } | ||
2622 | |||
2623 | if (acpi_video_backlight_support()) { | 2666 | if (acpi_video_backlight_support()) { |
2624 | pr_info("brightness ignored, must be controlled by ACPI video driver\n"); | 2667 | pr_info("brightness ignored, must be controlled by ACPI video driver\n"); |
2625 | } else { | 2668 | } else { |
@@ -2667,22 +2710,21 @@ static int sony_nc_add(struct acpi_device *device) | |||
2667 | 2710 | ||
2668 | return 0; | 2711 | return 0; |
2669 | 2712 | ||
2670 | out_sysfs: | 2713 | out_sysfs: |
2671 | for (item = sony_nc_values; item->name; ++item) { | 2714 | for (item = sony_nc_values; item->name; ++item) { |
2672 | device_remove_file(&sony_pf_device->dev, &item->devattr); | 2715 | device_remove_file(&sony_pf_device->dev, &item->devattr); |
2673 | } | 2716 | } |
2674 | sony_nc_backlight_cleanup(); | 2717 | sony_nc_backlight_cleanup(); |
2675 | |||
2676 | sony_laptop_remove_input(); | ||
2677 | |||
2678 | outsnc: | ||
2679 | sony_nc_function_cleanup(sony_pf_device); | 2718 | sony_nc_function_cleanup(sony_pf_device); |
2680 | sony_nc_handles_cleanup(sony_pf_device); | 2719 | sony_nc_handles_cleanup(sony_pf_device); |
2681 | 2720 | ||
2682 | outpresent: | 2721 | outplatform: |
2722 | sony_laptop_remove_input(); | ||
2723 | |||
2724 | outpresent: | ||
2683 | sony_pf_remove(); | 2725 | sony_pf_remove(); |
2684 | 2726 | ||
2685 | outwalk: | 2727 | outwalk: |
2686 | sony_nc_rfkill_cleanup(); | 2728 | sony_nc_rfkill_cleanup(); |
2687 | return result; | 2729 | return result; |
2688 | } | 2730 | } |
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 39d3aa41adda..f56c8ba3a861 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c | |||
@@ -1085,7 +1085,7 @@ static int __init rpmsg_init(void) | |||
1085 | 1085 | ||
1086 | return ret; | 1086 | return ret; |
1087 | } | 1087 | } |
1088 | module_init(rpmsg_init); | 1088 | subsys_initcall(rpmsg_init); |
1089 | 1089 | ||
1090 | static void __exit rpmsg_fini(void) | 1090 | static void __exit rpmsg_fini(void) |
1091 | { | 1091 | { |
diff --git a/drivers/scsi/scsi_wait_scan.c b/drivers/scsi/scsi_wait_scan.c index ae7814874618..072734538876 100644 --- a/drivers/scsi/scsi_wait_scan.c +++ b/drivers/scsi/scsi_wait_scan.c | |||
@@ -22,11 +22,6 @@ static int __init wait_scan_init(void) | |||
22 | * and might not yet have reached the scsi async scanning | 22 | * and might not yet have reached the scsi async scanning |
23 | */ | 23 | */ |
24 | wait_for_device_probe(); | 24 | wait_for_device_probe(); |
25 | /* | ||
26 | * and then we wait for the actual asynchronous scsi scan | ||
27 | * to finish. | ||
28 | */ | ||
29 | scsi_complete_async_scans(); | ||
30 | return 0; | 25 | return 0; |
31 | } | 26 | } |
32 | 27 | ||
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 9888693a18fe..664f6e775d0e 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c | |||
@@ -1095,7 +1095,7 @@ int target_emulate_write_same(struct se_cmd *cmd) | |||
1095 | if (num_blocks != 0) | 1095 | if (num_blocks != 0) |
1096 | range = num_blocks; | 1096 | range = num_blocks; |
1097 | else | 1097 | else |
1098 | range = (dev->transport->get_blocks(dev) - lba); | 1098 | range = (dev->transport->get_blocks(dev) - lba) + 1; |
1099 | 1099 | ||
1100 | pr_debug("WRITE_SAME UNMAP: LBA: %llu Range: %llu\n", | 1100 | pr_debug("WRITE_SAME UNMAP: LBA: %llu Range: %llu\n", |
1101 | (unsigned long long)lba, (unsigned long long)range); | 1101 | (unsigned long long)lba, (unsigned long long)range); |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 85564998500a..a1bcd927a9e6 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -2031,7 +2031,7 @@ static int __core_scsi3_write_aptpl_to_file( | |||
2031 | if (IS_ERR(file) || !file || !file->f_dentry) { | 2031 | if (IS_ERR(file) || !file || !file->f_dentry) { |
2032 | pr_err("filp_open(%s) for APTPL metadata" | 2032 | pr_err("filp_open(%s) for APTPL metadata" |
2033 | " failed\n", path); | 2033 | " failed\n", path); |
2034 | return (PTR_ERR(file) < 0 ? PTR_ERR(file) : -ENOENT); | 2034 | return IS_ERR(file) ? PTR_ERR(file) : -ENOENT; |
2035 | } | 2035 | } |
2036 | 2036 | ||
2037 | iov[0].iov_base = &buf[0]; | 2037 | iov[0].iov_base = &buf[0]; |
@@ -3818,7 +3818,7 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3818 | " SPC-2 reservation is held, returning" | 3818 | " SPC-2 reservation is held, returning" |
3819 | " RESERVATION_CONFLICT\n"); | 3819 | " RESERVATION_CONFLICT\n"); |
3820 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 3820 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3821 | ret = EINVAL; | 3821 | ret = -EINVAL; |
3822 | goto out; | 3822 | goto out; |
3823 | } | 3823 | } |
3824 | 3824 | ||
@@ -3828,7 +3828,8 @@ int target_scsi3_emulate_pr_out(struct se_cmd *cmd) | |||
3828 | */ | 3828 | */ |
3829 | if (!cmd->se_sess) { | 3829 | if (!cmd->se_sess) { |
3830 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 3830 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3831 | return -EINVAL; | 3831 | ret = -EINVAL; |
3832 | goto out; | ||
3832 | } | 3833 | } |
3833 | 3834 | ||
3834 | if (cmd->data_length < 24) { | 3835 | if (cmd->data_length < 24) { |
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index f03fb9730f5b..5b65f33939a8 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c | |||
@@ -230,6 +230,8 @@ u32 ft_get_task_tag(struct se_cmd *se_cmd) | |||
230 | { | 230 | { |
231 | struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd); | 231 | struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd); |
232 | 232 | ||
233 | if (cmd->aborted) | ||
234 | return ~0; | ||
233 | return fc_seq_exch(cmd->seq)->rxid; | 235 | return fc_seq_exch(cmd->seq)->rxid; |
234 | } | 236 | } |
235 | 237 | ||
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 5b400730c213..4ee522b3f66f 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -86,7 +86,31 @@ static struct { | |||
86 | #endif /* CONFIG_CIFS_WEAK_PW_HASH */ | 86 | #endif /* CONFIG_CIFS_WEAK_PW_HASH */ |
87 | #endif /* CIFS_POSIX */ | 87 | #endif /* CIFS_POSIX */ |
88 | 88 | ||
89 | /* Forward declarations */ | 89 | #ifdef CONFIG_HIGHMEM |
90 | /* | ||
91 | * On arches that have high memory, kmap address space is limited. By | ||
92 | * serializing the kmap operations on those arches, we ensure that we don't | ||
93 | * end up with a bunch of threads in writeback with partially mapped page | ||
94 | * arrays, stuck waiting for kmap to come back. That situation prevents | ||
95 | * progress and can deadlock. | ||
96 | */ | ||
97 | static DEFINE_MUTEX(cifs_kmap_mutex); | ||
98 | |||
99 | static inline void | ||
100 | cifs_kmap_lock(void) | ||
101 | { | ||
102 | mutex_lock(&cifs_kmap_mutex); | ||
103 | } | ||
104 | |||
105 | static inline void | ||
106 | cifs_kmap_unlock(void) | ||
107 | { | ||
108 | mutex_unlock(&cifs_kmap_mutex); | ||
109 | } | ||
110 | #else /* !CONFIG_HIGHMEM */ | ||
111 | #define cifs_kmap_lock() do { ; } while(0) | ||
112 | #define cifs_kmap_unlock() do { ; } while(0) | ||
113 | #endif /* CONFIG_HIGHMEM */ | ||
90 | 114 | ||
91 | /* Mark as invalid, all open files on tree connections since they | 115 | /* Mark as invalid, all open files on tree connections since they |
92 | were closed when session to server was lost */ | 116 | were closed when session to server was lost */ |
@@ -1503,7 +1527,9 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) | |||
1503 | } | 1527 | } |
1504 | 1528 | ||
1505 | /* marshal up the page array */ | 1529 | /* marshal up the page array */ |
1530 | cifs_kmap_lock(); | ||
1506 | len = rdata->marshal_iov(rdata, data_len); | 1531 | len = rdata->marshal_iov(rdata, data_len); |
1532 | cifs_kmap_unlock(); | ||
1507 | data_len -= len; | 1533 | data_len -= len; |
1508 | 1534 | ||
1509 | /* issue the read if we have any iovecs left to fill */ | 1535 | /* issue the read if we have any iovecs left to fill */ |
@@ -2069,7 +2095,9 @@ cifs_async_writev(struct cifs_writedata *wdata) | |||
2069 | * and set the iov_len properly for each one. It may also set | 2095 | * and set the iov_len properly for each one. It may also set |
2070 | * wdata->bytes too. | 2096 | * wdata->bytes too. |
2071 | */ | 2097 | */ |
2098 | cifs_kmap_lock(); | ||
2072 | wdata->marshal_iov(iov, wdata); | 2099 | wdata->marshal_iov(iov, wdata); |
2100 | cifs_kmap_unlock(); | ||
2073 | 2101 | ||
2074 | cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes); | 2102 | cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes); |
2075 | 2103 | ||
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 0ae86ddf2213..94b7788c3189 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -3445,6 +3445,18 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | |||
3445 | #define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024) | 3445 | #define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024) |
3446 | #define CIFS_DEFAULT_NON_POSIX_WSIZE (65536) | 3446 | #define CIFS_DEFAULT_NON_POSIX_WSIZE (65536) |
3447 | 3447 | ||
3448 | /* | ||
3449 | * On hosts with high memory, we can't currently support wsize/rsize that are | ||
3450 | * larger than we can kmap at once. Cap the rsize/wsize at | ||
3451 | * LAST_PKMAP * PAGE_SIZE. We'll never be able to fill a read or write request | ||
3452 | * larger than that anyway. | ||
3453 | */ | ||
3454 | #ifdef CONFIG_HIGHMEM | ||
3455 | #define CIFS_KMAP_SIZE_LIMIT (LAST_PKMAP * PAGE_CACHE_SIZE) | ||
3456 | #else /* CONFIG_HIGHMEM */ | ||
3457 | #define CIFS_KMAP_SIZE_LIMIT (1<<24) | ||
3458 | #endif /* CONFIG_HIGHMEM */ | ||
3459 | |||
3448 | static unsigned int | 3460 | static unsigned int |
3449 | cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | 3461 | cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) |
3450 | { | 3462 | { |
@@ -3475,6 +3487,9 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | |||
3475 | wsize = min_t(unsigned int, wsize, | 3487 | wsize = min_t(unsigned int, wsize, |
3476 | server->maxBuf - sizeof(WRITE_REQ) + 4); | 3488 | server->maxBuf - sizeof(WRITE_REQ) + 4); |
3477 | 3489 | ||
3490 | /* limit to the amount that we can kmap at once */ | ||
3491 | wsize = min_t(unsigned int, wsize, CIFS_KMAP_SIZE_LIMIT); | ||
3492 | |||
3478 | /* hard limit of CIFS_MAX_WSIZE */ | 3493 | /* hard limit of CIFS_MAX_WSIZE */ |
3479 | wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); | 3494 | wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); |
3480 | 3495 | ||
@@ -3516,6 +3531,9 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | |||
3516 | if (!(server->capabilities & CAP_LARGE_READ_X)) | 3531 | if (!(server->capabilities & CAP_LARGE_READ_X)) |
3517 | rsize = min_t(unsigned int, CIFSMaxBufSize, rsize); | 3532 | rsize = min_t(unsigned int, CIFSMaxBufSize, rsize); |
3518 | 3533 | ||
3534 | /* limit to the amount that we can kmap at once */ | ||
3535 | rsize = min_t(unsigned int, rsize, CIFS_KMAP_SIZE_LIMIT); | ||
3536 | |||
3519 | /* hard limit of CIFS_MAX_RSIZE */ | 3537 | /* hard limit of CIFS_MAX_RSIZE */ |
3520 | rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE); | 3538 | rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE); |
3521 | 3539 | ||
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 0a8224d1c4c5..a4217f02fab2 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -86,9 +86,12 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, | |||
86 | 86 | ||
87 | dentry = d_lookup(parent, name); | 87 | dentry = d_lookup(parent, name); |
88 | if (dentry) { | 88 | if (dentry) { |
89 | /* FIXME: check for inode number changes? */ | 89 | inode = dentry->d_inode; |
90 | if (dentry->d_inode != NULL) | 90 | /* update inode in place if i_ino didn't change */ |
91 | if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { | ||
92 | cifs_fattr_to_inode(inode, fattr); | ||
91 | return dentry; | 93 | return dentry; |
94 | } | ||
92 | d_drop(dentry); | 95 | d_drop(dentry); |
93 | dput(dentry); | 96 | dput(dentry); |
94 | } | 97 | } |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 3097ee58fd7d..f25d4ea14be4 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -365,16 +365,14 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct kvec *iov, | |||
365 | if (mid == NULL) | 365 | if (mid == NULL) |
366 | return -ENOMEM; | 366 | return -ENOMEM; |
367 | 367 | ||
368 | /* put it on the pending_mid_q */ | ||
369 | spin_lock(&GlobalMid_Lock); | ||
370 | list_add_tail(&mid->qhead, &server->pending_mid_q); | ||
371 | spin_unlock(&GlobalMid_Lock); | ||
372 | |||
373 | rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number); | 368 | rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number); |
374 | if (rc) | 369 | if (rc) { |
375 | delete_mid(mid); | 370 | DeleteMidQEntry(mid); |
371 | return rc; | ||
372 | } | ||
373 | |||
376 | *ret_mid = mid; | 374 | *ret_mid = mid; |
377 | return rc; | 375 | return 0; |
378 | } | 376 | } |
379 | 377 | ||
380 | /* | 378 | /* |
@@ -407,17 +405,21 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, | |||
407 | mid->callback_data = cbdata; | 405 | mid->callback_data = cbdata; |
408 | mid->mid_state = MID_REQUEST_SUBMITTED; | 406 | mid->mid_state = MID_REQUEST_SUBMITTED; |
409 | 407 | ||
408 | /* put it on the pending_mid_q */ | ||
409 | spin_lock(&GlobalMid_Lock); | ||
410 | list_add_tail(&mid->qhead, &server->pending_mid_q); | ||
411 | spin_unlock(&GlobalMid_Lock); | ||
412 | |||
413 | |||
410 | cifs_in_send_inc(server); | 414 | cifs_in_send_inc(server); |
411 | rc = smb_sendv(server, iov, nvec); | 415 | rc = smb_sendv(server, iov, nvec); |
412 | cifs_in_send_dec(server); | 416 | cifs_in_send_dec(server); |
413 | cifs_save_when_sent(mid); | 417 | cifs_save_when_sent(mid); |
414 | mutex_unlock(&server->srv_mutex); | 418 | mutex_unlock(&server->srv_mutex); |
415 | 419 | ||
416 | if (rc) | 420 | if (rc == 0) |
417 | goto out_err; | 421 | return 0; |
418 | 422 | ||
419 | return rc; | ||
420 | out_err: | ||
421 | delete_mid(mid); | 423 | delete_mid(mid); |
422 | add_credits(server, 1); | 424 | add_credits(server, 1); |
423 | wake_up(&server->request_q); | 425 | wake_up(&server->request_q); |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 74598f67efeb..1c8b55670804 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -1710,7 +1710,7 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, | |||
1710 | goto error_tgt_fput; | 1710 | goto error_tgt_fput; |
1711 | 1711 | ||
1712 | /* Check if EPOLLWAKEUP is allowed */ | 1712 | /* Check if EPOLLWAKEUP is allowed */ |
1713 | if ((epds.events & EPOLLWAKEUP) && !capable(CAP_EPOLLWAKEUP)) | 1713 | if ((epds.events & EPOLLWAKEUP) && !capable(CAP_BLOCK_SUSPEND)) |
1714 | epds.events &= ~EPOLLWAKEUP; | 1714 | epds.events &= ~EPOLLWAKEUP; |
1715 | 1715 | ||
1716 | /* | 1716 | /* |
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c index 49cf230554a2..24a49d47e935 100644 --- a/fs/exofs/ore.c +++ b/fs/exofs/ore.c | |||
@@ -735,13 +735,7 @@ static int _prepare_for_striping(struct ore_io_state *ios) | |||
735 | out: | 735 | out: |
736 | ios->numdevs = devs_in_group; | 736 | ios->numdevs = devs_in_group; |
737 | ios->pages_consumed = cur_pg; | 737 | ios->pages_consumed = cur_pg; |
738 | if (unlikely(ret)) { | 738 | return ret; |
739 | if (length == ios->length) | ||
740 | return ret; | ||
741 | else | ||
742 | ios->length -= length; | ||
743 | } | ||
744 | return 0; | ||
745 | } | 739 | } |
746 | 740 | ||
747 | int ore_create(struct ore_io_state *ios) | 741 | int ore_create(struct ore_io_state *ios) |
diff --git a/fs/exofs/ore_raid.c b/fs/exofs/ore_raid.c index d222c77cfa1b..5f376d14fdcc 100644 --- a/fs/exofs/ore_raid.c +++ b/fs/exofs/ore_raid.c | |||
@@ -144,26 +144,26 @@ static void _sp2d_reset(struct __stripe_pages_2d *sp2d, | |||
144 | { | 144 | { |
145 | unsigned data_devs = sp2d->data_devs; | 145 | unsigned data_devs = sp2d->data_devs; |
146 | unsigned group_width = data_devs + sp2d->parity; | 146 | unsigned group_width = data_devs + sp2d->parity; |
147 | unsigned p; | 147 | int p, c; |
148 | 148 | ||
149 | if (!sp2d->needed) | 149 | if (!sp2d->needed) |
150 | return; | 150 | return; |
151 | 151 | ||
152 | for (p = 0; p < sp2d->pages_in_unit; p++) { | 152 | for (c = data_devs - 1; c >= 0; --c) |
153 | struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p]; | 153 | for (p = sp2d->pages_in_unit - 1; p >= 0; --p) { |
154 | 154 | struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p]; | |
155 | if (_1ps->write_count < group_width) { | ||
156 | unsigned c; | ||
157 | 155 | ||
158 | for (c = 0; c < data_devs; c++) | 156 | if (_1ps->page_is_read[c]) { |
159 | if (_1ps->page_is_read[c]) { | 157 | struct page *page = _1ps->pages[c]; |
160 | struct page *page = _1ps->pages[c]; | ||
161 | 158 | ||
162 | r4w->put_page(priv, page); | 159 | r4w->put_page(priv, page); |
163 | _1ps->page_is_read[c] = false; | 160 | _1ps->page_is_read[c] = false; |
164 | } | 161 | } |
165 | } | 162 | } |
166 | 163 | ||
164 | for (p = 0; p < sp2d->pages_in_unit; p++) { | ||
165 | struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p]; | ||
166 | |||
167 | memset(_1ps->pages, 0, group_width * sizeof(*_1ps->pages)); | 167 | memset(_1ps->pages, 0, group_width * sizeof(*_1ps->pages)); |
168 | _1ps->write_count = 0; | 168 | _1ps->write_count = 0; |
169 | _1ps->tx = NULL; | 169 | _1ps->tx = NULL; |
@@ -461,16 +461,12 @@ static void _mark_read4write_pages_uptodate(struct ore_io_state *ios, int ret) | |||
461 | * ios->sp2d[p][*], xor is calculated the same way. These pages are | 461 | * ios->sp2d[p][*], xor is calculated the same way. These pages are |
462 | * allocated/freed and don't go through cache | 462 | * allocated/freed and don't go through cache |
463 | */ | 463 | */ |
464 | static int _read_4_write(struct ore_io_state *ios) | 464 | static int _read_4_write_first_stripe(struct ore_io_state *ios) |
465 | { | 465 | { |
466 | struct ore_io_state *ios_read; | ||
467 | struct ore_striping_info read_si; | 466 | struct ore_striping_info read_si; |
468 | struct __stripe_pages_2d *sp2d = ios->sp2d; | 467 | struct __stripe_pages_2d *sp2d = ios->sp2d; |
469 | u64 offset = ios->si.first_stripe_start; | 468 | u64 offset = ios->si.first_stripe_start; |
470 | u64 last_stripe_end; | 469 | unsigned c, p, min_p = sp2d->pages_in_unit, max_p = -1; |
471 | unsigned bytes_in_stripe = ios->si.bytes_in_stripe; | ||
472 | unsigned i, c, p, min_p = sp2d->pages_in_unit, max_p = -1; | ||
473 | int ret; | ||
474 | 470 | ||
475 | if (offset == ios->offset) /* Go to start collect $200 */ | 471 | if (offset == ios->offset) /* Go to start collect $200 */ |
476 | goto read_last_stripe; | 472 | goto read_last_stripe; |
@@ -478,6 +474,9 @@ static int _read_4_write(struct ore_io_state *ios) | |||
478 | min_p = _sp2d_min_pg(sp2d); | 474 | min_p = _sp2d_min_pg(sp2d); |
479 | max_p = _sp2d_max_pg(sp2d); | 475 | max_p = _sp2d_max_pg(sp2d); |
480 | 476 | ||
477 | ORE_DBGMSG("stripe_start=0x%llx ios->offset=0x%llx min_p=%d max_p=%d\n", | ||
478 | offset, ios->offset, min_p, max_p); | ||
479 | |||
481 | for (c = 0; ; c++) { | 480 | for (c = 0; ; c++) { |
482 | ore_calc_stripe_info(ios->layout, offset, 0, &read_si); | 481 | ore_calc_stripe_info(ios->layout, offset, 0, &read_si); |
483 | read_si.obj_offset += min_p * PAGE_SIZE; | 482 | read_si.obj_offset += min_p * PAGE_SIZE; |
@@ -512,6 +511,18 @@ static int _read_4_write(struct ore_io_state *ios) | |||
512 | } | 511 | } |
513 | 512 | ||
514 | read_last_stripe: | 513 | read_last_stripe: |
514 | return 0; | ||
515 | } | ||
516 | |||
517 | static int _read_4_write_last_stripe(struct ore_io_state *ios) | ||
518 | { | ||
519 | struct ore_striping_info read_si; | ||
520 | struct __stripe_pages_2d *sp2d = ios->sp2d; | ||
521 | u64 offset; | ||
522 | u64 last_stripe_end; | ||
523 | unsigned bytes_in_stripe = ios->si.bytes_in_stripe; | ||
524 | unsigned c, p, min_p = sp2d->pages_in_unit, max_p = -1; | ||
525 | |||
515 | offset = ios->offset + ios->length; | 526 | offset = ios->offset + ios->length; |
516 | if (offset % PAGE_SIZE) | 527 | if (offset % PAGE_SIZE) |
517 | _add_to_r4w_last_page(ios, &offset); | 528 | _add_to_r4w_last_page(ios, &offset); |
@@ -527,15 +538,15 @@ read_last_stripe: | |||
527 | c = _dev_order(ios->layout->group_width * ios->layout->mirrors_p1, | 538 | c = _dev_order(ios->layout->group_width * ios->layout->mirrors_p1, |
528 | ios->layout->mirrors_p1, read_si.par_dev, read_si.dev); | 539 | ios->layout->mirrors_p1, read_si.par_dev, read_si.dev); |
529 | 540 | ||
530 | BUG_ON(ios->si.first_stripe_start + bytes_in_stripe != last_stripe_end); | ||
531 | /* unaligned IO must be within a single stripe */ | ||
532 | |||
533 | if (min_p == sp2d->pages_in_unit) { | 541 | if (min_p == sp2d->pages_in_unit) { |
534 | /* Didn't do it yet */ | 542 | /* Didn't do it yet */ |
535 | min_p = _sp2d_min_pg(sp2d); | 543 | min_p = _sp2d_min_pg(sp2d); |
536 | max_p = _sp2d_max_pg(sp2d); | 544 | max_p = _sp2d_max_pg(sp2d); |
537 | } | 545 | } |
538 | 546 | ||
547 | ORE_DBGMSG("offset=0x%llx stripe_end=0x%llx min_p=%d max_p=%d\n", | ||
548 | offset, last_stripe_end, min_p, max_p); | ||
549 | |||
539 | while (offset < last_stripe_end) { | 550 | while (offset < last_stripe_end) { |
540 | struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p]; | 551 | struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p]; |
541 | 552 | ||
@@ -568,6 +579,15 @@ read_last_stripe: | |||
568 | } | 579 | } |
569 | 580 | ||
570 | read_it: | 581 | read_it: |
582 | return 0; | ||
583 | } | ||
584 | |||
585 | static int _read_4_write_execute(struct ore_io_state *ios) | ||
586 | { | ||
587 | struct ore_io_state *ios_read; | ||
588 | unsigned i; | ||
589 | int ret; | ||
590 | |||
571 | ios_read = ios->ios_read_4_write; | 591 | ios_read = ios->ios_read_4_write; |
572 | if (!ios_read) | 592 | if (!ios_read) |
573 | return 0; | 593 | return 0; |
@@ -591,6 +611,8 @@ read_it: | |||
591 | } | 611 | } |
592 | 612 | ||
593 | _mark_read4write_pages_uptodate(ios_read, ret); | 613 | _mark_read4write_pages_uptodate(ios_read, ret); |
614 | ore_put_io_state(ios_read); | ||
615 | ios->ios_read_4_write = NULL; /* Might need a reuse at last stripe */ | ||
594 | return 0; | 616 | return 0; |
595 | } | 617 | } |
596 | 618 | ||
@@ -626,8 +648,11 @@ int _ore_add_parity_unit(struct ore_io_state *ios, | |||
626 | /* If first stripe, Read in all read4write pages | 648 | /* If first stripe, Read in all read4write pages |
627 | * (if needed) before we calculate the first parity. | 649 | * (if needed) before we calculate the first parity. |
628 | */ | 650 | */ |
629 | _read_4_write(ios); | 651 | _read_4_write_first_stripe(ios); |
630 | } | 652 | } |
653 | if (!cur_len) /* If last stripe r4w pages of last stripe */ | ||
654 | _read_4_write_last_stripe(ios); | ||
655 | _read_4_write_execute(ios); | ||
631 | 656 | ||
632 | for (i = 0; i < num_pages; i++) { | 657 | for (i = 0; i < num_pages; i++) { |
633 | pages[i] = _raid_page_alloc(); | 658 | pages[i] = _raid_page_alloc(); |
@@ -654,34 +679,14 @@ int _ore_add_parity_unit(struct ore_io_state *ios, | |||
654 | 679 | ||
655 | int _ore_post_alloc_raid_stuff(struct ore_io_state *ios) | 680 | int _ore_post_alloc_raid_stuff(struct ore_io_state *ios) |
656 | { | 681 | { |
657 | struct ore_layout *layout = ios->layout; | ||
658 | |||
659 | if (ios->parity_pages) { | 682 | if (ios->parity_pages) { |
683 | struct ore_layout *layout = ios->layout; | ||
660 | unsigned pages_in_unit = layout->stripe_unit / PAGE_SIZE; | 684 | unsigned pages_in_unit = layout->stripe_unit / PAGE_SIZE; |
661 | unsigned stripe_size = ios->si.bytes_in_stripe; | ||
662 | u64 last_stripe, first_stripe; | ||
663 | 685 | ||
664 | if (_sp2d_alloc(pages_in_unit, layout->group_width, | 686 | if (_sp2d_alloc(pages_in_unit, layout->group_width, |
665 | layout->parity, &ios->sp2d)) { | 687 | layout->parity, &ios->sp2d)) { |
666 | return -ENOMEM; | 688 | return -ENOMEM; |
667 | } | 689 | } |
668 | |||
669 | /* Round io down to last full strip */ | ||
670 | first_stripe = div_u64(ios->offset, stripe_size); | ||
671 | last_stripe = div_u64(ios->offset + ios->length, stripe_size); | ||
672 | |||
673 | /* If an IO spans more then a single stripe it must end at | ||
674 | * a stripe boundary. The reminder at the end is pushed into the | ||
675 | * next IO. | ||
676 | */ | ||
677 | if (last_stripe != first_stripe) { | ||
678 | ios->length = last_stripe * stripe_size - ios->offset; | ||
679 | |||
680 | BUG_ON(!ios->length); | ||
681 | ios->nr_pages = (ios->length + PAGE_SIZE - 1) / | ||
682 | PAGE_SIZE; | ||
683 | ios->si.length = ios->length; /*make it consistent */ | ||
684 | } | ||
685 | } | 690 | } |
686 | return 0; | 691 | return 0; |
687 | } | 692 | } |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index e34deac3f366..6ec6f9ee2fec 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -268,7 +268,6 @@ group_extend_out: | |||
268 | err = ext4_move_extents(filp, donor_filp, me.orig_start, | 268 | err = ext4_move_extents(filp, donor_filp, me.orig_start, |
269 | me.donor_start, me.len, &me.moved_len); | 269 | me.donor_start, me.len, &me.moved_len); |
270 | mnt_drop_write_file(filp); | 270 | mnt_drop_write_file(filp); |
271 | mnt_drop_write(filp->f_path.mnt); | ||
272 | 271 | ||
273 | if (copy_to_user((struct move_extent __user *)arg, | 272 | if (copy_to_user((struct move_extent __user *)arg, |
274 | &me, sizeof(me))) | 273 | &me, sizeof(me))) |
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
15 | #include <linux/pipe_fs_i.h> | 15 | #include <linux/pipe_fs_i.h> |
16 | 16 | ||
17 | static void wait_for_partner(struct inode* inode, unsigned int *cnt) | 17 | static int wait_for_partner(struct inode* inode, unsigned int *cnt) |
18 | { | 18 | { |
19 | int cur = *cnt; | 19 | int cur = *cnt; |
20 | 20 | ||
@@ -23,6 +23,7 @@ static void wait_for_partner(struct inode* inode, unsigned int *cnt) | |||
23 | if (signal_pending(current)) | 23 | if (signal_pending(current)) |
24 | break; | 24 | break; |
25 | } | 25 | } |
26 | return cur == *cnt ? -ERESTARTSYS : 0; | ||
26 | } | 27 | } |
27 | 28 | ||
28 | static void wake_up_partner(struct inode* inode) | 29 | static void wake_up_partner(struct inode* inode) |
@@ -67,8 +68,7 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
67 | * seen a writer */ | 68 | * seen a writer */ |
68 | filp->f_version = pipe->w_counter; | 69 | filp->f_version = pipe->w_counter; |
69 | } else { | 70 | } else { |
70 | wait_for_partner(inode, &pipe->w_counter); | 71 | if (wait_for_partner(inode, &pipe->w_counter)) |
71 | if(signal_pending(current)) | ||
72 | goto err_rd; | 72 | goto err_rd; |
73 | } | 73 | } |
74 | } | 74 | } |
@@ -90,8 +90,7 @@ static int fifo_open(struct inode *inode, struct file *filp) | |||
90 | wake_up_partner(inode); | 90 | wake_up_partner(inode); |
91 | 91 | ||
92 | if (!pipe->readers) { | 92 | if (!pipe->readers) { |
93 | wait_for_partner(inode, &pipe->r_counter); | 93 | if (wait_for_partner(inode, &pipe->r_counter)) |
94 | if (signal_pending(current)) | ||
95 | goto err_wr; | 94 | goto err_wr; |
96 | } | 95 | } |
97 | break; | 96 | break; |
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c index b47277baebab..f50d3e8d6f22 100644 --- a/fs/nfs/objlayout/objio_osd.c +++ b/fs/nfs/objlayout/objio_osd.c | |||
@@ -454,7 +454,10 @@ int objio_read_pagelist(struct nfs_read_data *rdata) | |||
454 | objios->ios->done = _read_done; | 454 | objios->ios->done = _read_done; |
455 | dprintk("%s: offset=0x%llx length=0x%x\n", __func__, | 455 | dprintk("%s: offset=0x%llx length=0x%x\n", __func__, |
456 | rdata->args.offset, rdata->args.count); | 456 | rdata->args.offset, rdata->args.count); |
457 | return ore_read(objios->ios); | 457 | ret = ore_read(objios->ios); |
458 | if (unlikely(ret)) | ||
459 | objio_free_result(&objios->oir); | ||
460 | return ret; | ||
458 | } | 461 | } |
459 | 462 | ||
460 | /* | 463 | /* |
@@ -486,8 +489,16 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) | |||
486 | struct nfs_write_data *wdata = objios->oir.rpcdata; | 489 | struct nfs_write_data *wdata = objios->oir.rpcdata; |
487 | struct address_space *mapping = wdata->header->inode->i_mapping; | 490 | struct address_space *mapping = wdata->header->inode->i_mapping; |
488 | pgoff_t index = offset / PAGE_SIZE; | 491 | pgoff_t index = offset / PAGE_SIZE; |
489 | struct page *page = find_get_page(mapping, index); | 492 | struct page *page; |
493 | loff_t i_size = i_size_read(wdata->header->inode); | ||
494 | |||
495 | if (offset >= i_size) { | ||
496 | *uptodate = true; | ||
497 | dprintk("%s: g_zero_page index=0x%lx\n", __func__, index); | ||
498 | return ZERO_PAGE(0); | ||
499 | } | ||
490 | 500 | ||
501 | page = find_get_page(mapping, index); | ||
491 | if (!page) { | 502 | if (!page) { |
492 | page = find_or_create_page(mapping, index, GFP_NOFS); | 503 | page = find_or_create_page(mapping, index, GFP_NOFS); |
493 | if (unlikely(!page)) { | 504 | if (unlikely(!page)) { |
@@ -507,8 +518,10 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) | |||
507 | 518 | ||
508 | static void __r4w_put_page(void *priv, struct page *page) | 519 | static void __r4w_put_page(void *priv, struct page *page) |
509 | { | 520 | { |
510 | dprintk("%s: index=0x%lx\n", __func__, page->index); | 521 | dprintk("%s: index=0x%lx\n", __func__, |
511 | page_cache_release(page); | 522 | (page == ZERO_PAGE(0)) ? -1UL : page->index); |
523 | if (ZERO_PAGE(0) != page) | ||
524 | page_cache_release(page); | ||
512 | return; | 525 | return; |
513 | } | 526 | } |
514 | 527 | ||
@@ -539,8 +552,10 @@ int objio_write_pagelist(struct nfs_write_data *wdata, int how) | |||
539 | dprintk("%s: offset=0x%llx length=0x%x\n", __func__, | 552 | dprintk("%s: offset=0x%llx length=0x%x\n", __func__, |
540 | wdata->args.offset, wdata->args.count); | 553 | wdata->args.offset, wdata->args.count); |
541 | ret = ore_write(objios->ios); | 554 | ret = ore_write(objios->ios); |
542 | if (unlikely(ret)) | 555 | if (unlikely(ret)) { |
556 | objio_free_result(&objios->oir); | ||
543 | return ret; | 557 | return ret; |
558 | } | ||
544 | 559 | ||
545 | if (objios->sync) | 560 | if (objios->sync) |
546 | _write_done(objios->ios, objios); | 561 | _write_done(objios->ios, objios); |
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c index ef3d1ba6d992..15e2fc5aa60b 100644 --- a/fs/ubifs/sb.c +++ b/fs/ubifs/sb.c | |||
@@ -718,8 +718,12 @@ static int fixup_free_space(struct ubifs_info *c) | |||
718 | lnum = ubifs_next_log_lnum(c, lnum); | 718 | lnum = ubifs_next_log_lnum(c, lnum); |
719 | } | 719 | } |
720 | 720 | ||
721 | /* Fixup the current log head */ | 721 | /* |
722 | err = fixup_leb(c, c->lhead_lnum, c->lhead_offs); | 722 | * Fixup the log head which contains the only a CS node at the |
723 | * beginning. | ||
724 | */ | ||
725 | err = fixup_leb(c, c->lhead_lnum, | ||
726 | ALIGN(UBIFS_CS_NODE_SZ, c->min_io_size)); | ||
723 | if (err) | 727 | if (err) |
724 | goto out; | 728 | goto out; |
725 | 729 | ||
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 9d1aeb7e2734..4f33c32affe3 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -1074,13 +1074,13 @@ restart: | |||
1074 | * If we couldn't get anything, give up. | 1074 | * If we couldn't get anything, give up. |
1075 | */ | 1075 | */ |
1076 | if (bno_cur_lt == NULL && bno_cur_gt == NULL) { | 1076 | if (bno_cur_lt == NULL && bno_cur_gt == NULL) { |
1077 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); | ||
1078 | |||
1077 | if (!forced++) { | 1079 | if (!forced++) { |
1078 | trace_xfs_alloc_near_busy(args); | 1080 | trace_xfs_alloc_near_busy(args); |
1079 | xfs_log_force(args->mp, XFS_LOG_SYNC); | 1081 | xfs_log_force(args->mp, XFS_LOG_SYNC); |
1080 | goto restart; | 1082 | goto restart; |
1081 | } | 1083 | } |
1082 | |||
1083 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); | ||
1084 | trace_xfs_alloc_size_neither(args); | 1084 | trace_xfs_alloc_size_neither(args); |
1085 | args->agbno = NULLAGBLOCK; | 1085 | args->agbno = NULLAGBLOCK; |
1086 | return 0; | 1086 | return 0; |
@@ -2434,13 +2434,22 @@ xfs_alloc_vextent_worker( | |||
2434 | current_restore_flags_nested(&pflags, PF_FSTRANS); | 2434 | current_restore_flags_nested(&pflags, PF_FSTRANS); |
2435 | } | 2435 | } |
2436 | 2436 | ||
2437 | 2437 | /* | |
2438 | int /* error */ | 2438 | * Data allocation requests often come in with little stack to work on. Push |
2439 | * them off to a worker thread so there is lots of stack to use. Metadata | ||
2440 | * requests, OTOH, are generally from low stack usage paths, so avoid the | ||
2441 | * context switch overhead here. | ||
2442 | */ | ||
2443 | int | ||
2439 | xfs_alloc_vextent( | 2444 | xfs_alloc_vextent( |
2440 | xfs_alloc_arg_t *args) /* allocation argument structure */ | 2445 | struct xfs_alloc_arg *args) |
2441 | { | 2446 | { |
2442 | DECLARE_COMPLETION_ONSTACK(done); | 2447 | DECLARE_COMPLETION_ONSTACK(done); |
2443 | 2448 | ||
2449 | if (!args->userdata) | ||
2450 | return __xfs_alloc_vextent(args); | ||
2451 | |||
2452 | |||
2444 | args->done = &done; | 2453 | args->done = &done; |
2445 | INIT_WORK_ONSTACK(&args->work, xfs_alloc_vextent_worker); | 2454 | INIT_WORK_ONSTACK(&args->work, xfs_alloc_vextent_worker); |
2446 | queue_work(xfs_alloc_wq, &args->work); | 2455 | queue_work(xfs_alloc_wq, &args->work); |
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index a4beb421018a..269b35c084da 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
@@ -989,27 +989,6 @@ xfs_buf_ioerror_alert( | |||
989 | (__uint64_t)XFS_BUF_ADDR(bp), func, bp->b_error, bp->b_length); | 989 | (__uint64_t)XFS_BUF_ADDR(bp), func, bp->b_error, bp->b_length); |
990 | } | 990 | } |
991 | 991 | ||
992 | int | ||
993 | xfs_bwrite( | ||
994 | struct xfs_buf *bp) | ||
995 | { | ||
996 | int error; | ||
997 | |||
998 | ASSERT(xfs_buf_islocked(bp)); | ||
999 | |||
1000 | bp->b_flags |= XBF_WRITE; | ||
1001 | bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q); | ||
1002 | |||
1003 | xfs_bdstrat_cb(bp); | ||
1004 | |||
1005 | error = xfs_buf_iowait(bp); | ||
1006 | if (error) { | ||
1007 | xfs_force_shutdown(bp->b_target->bt_mount, | ||
1008 | SHUTDOWN_META_IO_ERROR); | ||
1009 | } | ||
1010 | return error; | ||
1011 | } | ||
1012 | |||
1013 | /* | 992 | /* |
1014 | * Called when we want to stop a buffer from getting written or read. | 993 | * Called when we want to stop a buffer from getting written or read. |
1015 | * We attach the EIO error, muck with its flags, and call xfs_buf_ioend | 994 | * We attach the EIO error, muck with its flags, and call xfs_buf_ioend |
@@ -1079,14 +1058,7 @@ xfs_bioerror_relse( | |||
1079 | return EIO; | 1058 | return EIO; |
1080 | } | 1059 | } |
1081 | 1060 | ||
1082 | 1061 | STATIC int | |
1083 | /* | ||
1084 | * All xfs metadata buffers except log state machine buffers | ||
1085 | * get this attached as their b_bdstrat callback function. | ||
1086 | * This is so that we can catch a buffer | ||
1087 | * after prematurely unpinning it to forcibly shutdown the filesystem. | ||
1088 | */ | ||
1089 | int | ||
1090 | xfs_bdstrat_cb( | 1062 | xfs_bdstrat_cb( |
1091 | struct xfs_buf *bp) | 1063 | struct xfs_buf *bp) |
1092 | { | 1064 | { |
@@ -1107,6 +1079,27 @@ xfs_bdstrat_cb( | |||
1107 | return 0; | 1079 | return 0; |
1108 | } | 1080 | } |
1109 | 1081 | ||
1082 | int | ||
1083 | xfs_bwrite( | ||
1084 | struct xfs_buf *bp) | ||
1085 | { | ||
1086 | int error; | ||
1087 | |||
1088 | ASSERT(xfs_buf_islocked(bp)); | ||
1089 | |||
1090 | bp->b_flags |= XBF_WRITE; | ||
1091 | bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q); | ||
1092 | |||
1093 | xfs_bdstrat_cb(bp); | ||
1094 | |||
1095 | error = xfs_buf_iowait(bp); | ||
1096 | if (error) { | ||
1097 | xfs_force_shutdown(bp->b_target->bt_mount, | ||
1098 | SHUTDOWN_META_IO_ERROR); | ||
1099 | } | ||
1100 | return error; | ||
1101 | } | ||
1102 | |||
1110 | /* | 1103 | /* |
1111 | * Wrapper around bdstrat so that we can stop data from going to disk in case | 1104 | * Wrapper around bdstrat so that we can stop data from going to disk in case |
1112 | * we are shutting down the filesystem. Typically user data goes thru this | 1105 | * we are shutting down the filesystem. Typically user data goes thru this |
@@ -1243,7 +1236,7 @@ xfs_buf_iorequest( | |||
1243 | */ | 1236 | */ |
1244 | atomic_set(&bp->b_io_remaining, 1); | 1237 | atomic_set(&bp->b_io_remaining, 1); |
1245 | _xfs_buf_ioapply(bp); | 1238 | _xfs_buf_ioapply(bp); |
1246 | _xfs_buf_ioend(bp, 0); | 1239 | _xfs_buf_ioend(bp, 1); |
1247 | 1240 | ||
1248 | xfs_buf_rele(bp); | 1241 | xfs_buf_rele(bp); |
1249 | } | 1242 | } |
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 7f1d1392ce37..79344c48008e 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h | |||
@@ -180,7 +180,6 @@ extern void xfs_buf_unlock(xfs_buf_t *); | |||
180 | extern int xfs_bwrite(struct xfs_buf *bp); | 180 | extern int xfs_bwrite(struct xfs_buf *bp); |
181 | 181 | ||
182 | extern void xfsbdstrat(struct xfs_mount *, struct xfs_buf *); | 182 | extern void xfsbdstrat(struct xfs_mount *, struct xfs_buf *); |
183 | extern int xfs_bdstrat_cb(struct xfs_buf *); | ||
184 | 183 | ||
185 | extern void xfs_buf_ioend(xfs_buf_t *, int); | 184 | extern void xfs_buf_ioend(xfs_buf_t *, int); |
186 | extern void xfs_buf_ioerror(xfs_buf_t *, int); | 185 | extern void xfs_buf_ioerror(xfs_buf_t *, int); |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 45df2b857d48..d9e451115f98 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -954,7 +954,7 @@ xfs_buf_iodone_callbacks( | |||
954 | 954 | ||
955 | if (!XFS_BUF_ISSTALE(bp)) { | 955 | if (!XFS_BUF_ISSTALE(bp)) { |
956 | bp->b_flags |= XBF_WRITE | XBF_ASYNC | XBF_DONE; | 956 | bp->b_flags |= XBF_WRITE | XBF_ASYNC | XBF_DONE; |
957 | xfs_bdstrat_cb(bp); | 957 | xfs_buf_iorequest(bp); |
958 | } else { | 958 | } else { |
959 | xfs_buf_relse(bp); | 959 | xfs_buf_relse(bp); |
960 | } | 960 | } |
diff --git a/include/asm-generic/dma-contiguous.h b/include/asm-generic/dma-contiguous.h index c544356b374b..294b1e755ab2 100644 --- a/include/asm-generic/dma-contiguous.h +++ b/include/asm-generic/dma-contiguous.h | |||
@@ -18,7 +18,7 @@ static inline void dev_set_cma_area(struct device *dev, struct cma *cma) | |||
18 | { | 18 | { |
19 | if (dev) | 19 | if (dev) |
20 | dev->cma_area = cma; | 20 | dev->cma_area = cma; |
21 | if (!dev || !dma_contiguous_default_area) | 21 | if (!dev && !dma_contiguous_default_area) |
22 | dma_contiguous_default_area = cma; | 22 | dma_contiguous_default_area = cma; |
23 | } | 23 | } |
24 | 24 | ||
diff --git a/include/linux/capability.h b/include/linux/capability.h index 68d56effc328..d10b7ed595b1 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h | |||
@@ -360,11 +360,11 @@ struct cpu_vfs_cap_data { | |||
360 | 360 | ||
361 | #define CAP_WAKE_ALARM 35 | 361 | #define CAP_WAKE_ALARM 35 |
362 | 362 | ||
363 | /* Allow preventing system suspends while epoll events are pending */ | 363 | /* Allow preventing system suspends */ |
364 | 364 | ||
365 | #define CAP_EPOLLWAKEUP 36 | 365 | #define CAP_BLOCK_SUSPEND 36 |
366 | 366 | ||
367 | #define CAP_LAST_CAP CAP_EPOLLWAKEUP | 367 | #define CAP_LAST_CAP CAP_BLOCK_SUSPEND |
368 | 368 | ||
369 | #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) | 369 | #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) |
370 | 370 | ||
diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h index 2521a95fa6d9..44c87e731e9d 100644 --- a/include/linux/ceph/messenger.h +++ b/include/linux/ceph/messenger.h | |||
@@ -163,16 +163,8 @@ struct ceph_connection { | |||
163 | 163 | ||
164 | /* connection negotiation temps */ | 164 | /* connection negotiation temps */ |
165 | char in_banner[CEPH_BANNER_MAX_LEN]; | 165 | char in_banner[CEPH_BANNER_MAX_LEN]; |
166 | union { | 166 | struct ceph_msg_connect out_connect; |
167 | struct { /* outgoing connection */ | 167 | struct ceph_msg_connect_reply in_reply; |
168 | struct ceph_msg_connect out_connect; | ||
169 | struct ceph_msg_connect_reply in_reply; | ||
170 | }; | ||
171 | struct { /* incoming */ | ||
172 | struct ceph_msg_connect in_connect; | ||
173 | struct ceph_msg_connect_reply out_reply; | ||
174 | }; | ||
175 | }; | ||
176 | struct ceph_entity_addr actual_peer_addr; | 168 | struct ceph_entity_addr actual_peer_addr; |
177 | 169 | ||
178 | /* message out temps */ | 170 | /* message out temps */ |
diff --git a/include/linux/device.h b/include/linux/device.h index 161d96241b1b..6de94151ff6f 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -865,8 +865,6 @@ extern int (*platform_notify_remove)(struct device *dev); | |||
865 | extern struct device *get_device(struct device *dev); | 865 | extern struct device *get_device(struct device *dev); |
866 | extern void put_device(struct device *dev); | 866 | extern void put_device(struct device *dev); |
867 | 867 | ||
868 | extern void wait_for_device_probe(void); | ||
869 | |||
870 | #ifdef CONFIG_DEVTMPFS | 868 | #ifdef CONFIG_DEVTMPFS |
871 | extern int devtmpfs_create_node(struct device *dev); | 869 | extern int devtmpfs_create_node(struct device *dev); |
872 | extern int devtmpfs_delete_node(struct device *dev); | 870 | extern int devtmpfs_delete_node(struct device *dev); |
diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h index 6f8be328770a..f4bb378ccf6a 100644 --- a/include/linux/eventpoll.h +++ b/include/linux/eventpoll.h | |||
@@ -34,7 +34,7 @@ | |||
34 | * re-allowed until epoll_wait is called again after consuming the wakeup | 34 | * re-allowed until epoll_wait is called again after consuming the wakeup |
35 | * event(s). | 35 | * event(s). |
36 | * | 36 | * |
37 | * Requires CAP_EPOLLWAKEUP | 37 | * Requires CAP_BLOCK_SUSPEND |
38 | */ | 38 | */ |
39 | #define EPOLLWAKEUP (1 << 29) | 39 | #define EPOLLWAKEUP (1 << 29) |
40 | 40 | ||
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 176a939d1547..af961d6f7ab1 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -65,7 +65,7 @@ struct trace_iterator { | |||
65 | void *private; | 65 | void *private; |
66 | int cpu_file; | 66 | int cpu_file; |
67 | struct mutex mutex; | 67 | struct mutex mutex; |
68 | struct ring_buffer_iter *buffer_iter[NR_CPUS]; | 68 | struct ring_buffer_iter **buffer_iter; |
69 | unsigned long iter_flags; | 69 | unsigned long iter_flags; |
70 | 70 | ||
71 | /* trace_seq for __print_flags() and __print_symbolic() etc. */ | 71 | /* trace_seq for __print_flags() and __print_symbolic() etc. */ |
@@ -207,6 +207,9 @@ struct ftrace_event_call { | |||
207 | * bit 1: enabled | 207 | * bit 1: enabled |
208 | * bit 2: filter_active | 208 | * bit 2: filter_active |
209 | * bit 3: enabled cmd record | 209 | * bit 3: enabled cmd record |
210 | * bit 4: allow trace by non root (cap any) | ||
211 | * bit 5: failed to apply filter | ||
212 | * bit 6: ftrace internal event (do not enable) | ||
210 | * | 213 | * |
211 | * Changes to flags must hold the event_mutex. | 214 | * Changes to flags must hold the event_mutex. |
212 | * | 215 | * |
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 9e65eff6af3b..8a7476186990 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
@@ -168,8 +168,8 @@ extern struct cred init_cred; | |||
168 | .children = LIST_HEAD_INIT(tsk.children), \ | 168 | .children = LIST_HEAD_INIT(tsk.children), \ |
169 | .sibling = LIST_HEAD_INIT(tsk.sibling), \ | 169 | .sibling = LIST_HEAD_INIT(tsk.sibling), \ |
170 | .group_leader = &tsk, \ | 170 | .group_leader = &tsk, \ |
171 | RCU_INIT_POINTER(.real_cred, &init_cred), \ | 171 | RCU_POINTER_INITIALIZER(real_cred, &init_cred), \ |
172 | RCU_INIT_POINTER(.cred, &init_cred), \ | 172 | RCU_POINTER_INITIALIZER(cred, &init_cred), \ |
173 | .comm = INIT_TASK_COMM, \ | 173 | .comm = INIT_TASK_COMM, \ |
174 | .thread = INIT_THREAD, \ | 174 | .thread = INIT_THREAD, \ |
175 | .fs = &init_fs, \ | 175 | .fs = &init_fs, \ |
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index e6ca56de9936..78e2ada50cd5 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h | |||
@@ -308,6 +308,8 @@ enum { | |||
308 | 308 | ||
309 | struct intel_iommu { | 309 | struct intel_iommu { |
310 | void __iomem *reg; /* Pointer to hardware regs, virtual addr */ | 310 | void __iomem *reg; /* Pointer to hardware regs, virtual addr */ |
311 | u64 reg_phys; /* physical address of hw register set */ | ||
312 | u64 reg_size; /* size of hw register set */ | ||
311 | u64 cap; | 313 | u64 cap; |
312 | u64 ecap; | 314 | u64 ecap; |
313 | u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */ | 315 | u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */ |
diff --git a/include/linux/irq.h b/include/linux/irq.h index a5261e3d2e3c..553fb66da130 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -150,9 +150,7 @@ struct irq_data { | |||
150 | void *handler_data; | 150 | void *handler_data; |
151 | void *chip_data; | 151 | void *chip_data; |
152 | struct msi_desc *msi_desc; | 152 | struct msi_desc *msi_desc; |
153 | #ifdef CONFIG_SMP | ||
154 | cpumask_var_t affinity; | 153 | cpumask_var_t affinity; |
155 | #endif | ||
156 | }; | 154 | }; |
157 | 155 | ||
158 | /* | 156 | /* |
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index c513a40510f5..0976fc46d1e0 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h | |||
@@ -42,8 +42,7 @@ | |||
42 | * allowed. | 42 | * allowed. |
43 | * | 43 | * |
44 | * Not initializing the key (static data is initialized to 0s anyway) is the | 44 | * Not initializing the key (static data is initialized to 0s anyway) is the |
45 | * same as using STATIC_KEY_INIT_FALSE and static_key_false() is | 45 | * same as using STATIC_KEY_INIT_FALSE. |
46 | * equivalent with static_branch(). | ||
47 | * | 46 | * |
48 | */ | 47 | */ |
49 | 48 | ||
@@ -107,12 +106,6 @@ static __always_inline bool static_key_true(struct static_key *key) | |||
107 | return !static_key_false(key); | 106 | return !static_key_false(key); |
108 | } | 107 | } |
109 | 108 | ||
110 | /* Deprecated. Please use 'static_key_false() instead. */ | ||
111 | static __always_inline bool static_branch(struct static_key *key) | ||
112 | { | ||
113 | return arch_static_branch(key); | ||
114 | } | ||
115 | |||
116 | extern struct jump_entry __start___jump_table[]; | 109 | extern struct jump_entry __start___jump_table[]; |
117 | extern struct jump_entry __stop___jump_table[]; | 110 | extern struct jump_entry __stop___jump_table[]; |
118 | 111 | ||
@@ -166,14 +159,6 @@ static __always_inline bool static_key_true(struct static_key *key) | |||
166 | return false; | 159 | return false; |
167 | } | 160 | } |
168 | 161 | ||
169 | /* Deprecated. Please use 'static_key_false() instead. */ | ||
170 | static __always_inline bool static_branch(struct static_key *key) | ||
171 | { | ||
172 | if (unlikely(atomic_read(&key->enabled)) > 0) | ||
173 | return true; | ||
174 | return false; | ||
175 | } | ||
176 | |||
177 | static inline void static_key_slow_inc(struct static_key *key) | 162 | static inline void static_key_slow_inc(struct static_key *key) |
178 | { | 163 | { |
179 | atomic_inc(&key->enabled); | 164 | atomic_inc(&key->enabled); |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index e07f5e0c5df4..604382143bcf 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -377,7 +377,6 @@ extern enum system_states { | |||
377 | SYSTEM_HALT, | 377 | SYSTEM_HALT, |
378 | SYSTEM_POWER_OFF, | 378 | SYSTEM_POWER_OFF, |
379 | SYSTEM_RESTART, | 379 | SYSTEM_RESTART, |
380 | SYSTEM_SUSPEND_DISK, | ||
381 | } system_state; | 380 | } system_state; |
382 | 381 | ||
383 | #define TAINT_PROPRIETARY_MODULE 0 | 382 | #define TAINT_PROPRIETARY_MODULE 0 |
diff --git a/include/linux/key.h b/include/linux/key.h index 4cd22ed627ef..cef3b315ba7c 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -303,7 +303,9 @@ static inline bool key_is_instantiated(const struct key *key) | |||
303 | rwsem_is_locked(&((struct key *)(KEY))->sem))) | 303 | rwsem_is_locked(&((struct key *)(KEY))->sem))) |
304 | 304 | ||
305 | #define rcu_assign_keypointer(KEY, PAYLOAD) \ | 305 | #define rcu_assign_keypointer(KEY, PAYLOAD) \ |
306 | (rcu_assign_pointer((KEY)->payload.rcudata, PAYLOAD)) | 306 | do { \ |
307 | rcu_assign_pointer((KEY)->payload.rcudata, (PAYLOAD)); \ | ||
308 | } while (0) | ||
307 | 309 | ||
308 | #ifdef CONFIG_SYSCTL | 310 | #ifdef CONFIG_SYSCTL |
309 | extern ctl_table key_sysctls[]; | 311 | extern ctl_table key_sysctls[]; |
diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h index d6bd50110ec2..2e7a1e032c71 100644 --- a/include/linux/kmsg_dump.h +++ b/include/linux/kmsg_dump.h | |||
@@ -55,12 +55,17 @@ struct kmsg_dumper { | |||
55 | #ifdef CONFIG_PRINTK | 55 | #ifdef CONFIG_PRINTK |
56 | void kmsg_dump(enum kmsg_dump_reason reason); | 56 | void kmsg_dump(enum kmsg_dump_reason reason); |
57 | 57 | ||
58 | bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog, | ||
59 | char *line, size_t size, size_t *len); | ||
60 | |||
58 | bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, | 61 | bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, |
59 | char *line, size_t size, size_t *len); | 62 | char *line, size_t size, size_t *len); |
60 | 63 | ||
61 | bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, | 64 | bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, |
62 | char *buf, size_t size, size_t *len); | 65 | char *buf, size_t size, size_t *len); |
63 | 66 | ||
67 | void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper); | ||
68 | |||
64 | void kmsg_dump_rewind(struct kmsg_dumper *dumper); | 69 | void kmsg_dump_rewind(struct kmsg_dumper *dumper); |
65 | 70 | ||
66 | int kmsg_dump_register(struct kmsg_dumper *dumper); | 71 | int kmsg_dump_register(struct kmsg_dumper *dumper); |
@@ -71,6 +76,13 @@ static inline void kmsg_dump(enum kmsg_dump_reason reason) | |||
71 | { | 76 | { |
72 | } | 77 | } |
73 | 78 | ||
79 | static inline bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, | ||
80 | bool syslog, const char *line, | ||
81 | size_t size, size_t *len) | ||
82 | { | ||
83 | return false; | ||
84 | } | ||
85 | |||
74 | static inline bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, | 86 | static inline bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, |
75 | const char *line, size_t size, size_t *len) | 87 | const char *line, size_t size, size_t *len) |
76 | { | 88 | { |
@@ -83,6 +95,10 @@ static inline bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, | |||
83 | return false; | 95 | return false; |
84 | } | 96 | } |
85 | 97 | ||
98 | static inline void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper) | ||
99 | { | ||
100 | } | ||
101 | |||
86 | static inline void kmsg_dump_rewind(struct kmsg_dumper *dumper) | 102 | static inline void kmsg_dump_rewind(struct kmsg_dumper *dumper) |
87 | { | 103 | { |
88 | } | 104 | } |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab741b0d0074..5f187026b812 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2755,6 +2755,17 @@ | |||
2755 | #define PCI_DEVICE_ID_INTEL_IOAT_SNB7 0x3c27 | 2755 | #define PCI_DEVICE_ID_INTEL_IOAT_SNB7 0x3c27 |
2756 | #define PCI_DEVICE_ID_INTEL_IOAT_SNB8 0x3c2e | 2756 | #define PCI_DEVICE_ID_INTEL_IOAT_SNB8 0x3c2e |
2757 | #define PCI_DEVICE_ID_INTEL_IOAT_SNB9 0x3c2f | 2757 | #define PCI_DEVICE_ID_INTEL_IOAT_SNB9 0x3c2f |
2758 | #define PCI_DEVICE_ID_INTEL_UNC_HA 0x3c46 | ||
2759 | #define PCI_DEVICE_ID_INTEL_UNC_IMC0 0x3cb0 | ||
2760 | #define PCI_DEVICE_ID_INTEL_UNC_IMC1 0x3cb1 | ||
2761 | #define PCI_DEVICE_ID_INTEL_UNC_IMC2 0x3cb4 | ||
2762 | #define PCI_DEVICE_ID_INTEL_UNC_IMC3 0x3cb5 | ||
2763 | #define PCI_DEVICE_ID_INTEL_UNC_QPI0 0x3c41 | ||
2764 | #define PCI_DEVICE_ID_INTEL_UNC_QPI1 0x3c42 | ||
2765 | #define PCI_DEVICE_ID_INTEL_UNC_R2PCIE 0x3c43 | ||
2766 | #define PCI_DEVICE_ID_INTEL_UNC_R3QPI0 0x3c44 | ||
2767 | #define PCI_DEVICE_ID_INTEL_UNC_R3QPI1 0x3c45 | ||
2768 | #define PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX 0x3ce0 | ||
2758 | #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f | 2769 | #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f |
2759 | #define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 | 2770 | #define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 |
2760 | #define PCI_DEVICE_ID_INTEL_5100_21 0x65f5 | 2771 | #define PCI_DEVICE_ID_INTEL_5100_21 0x65f5 |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 45db49f64bb4..76c5c8b724a7 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -677,6 +677,7 @@ struct hw_perf_event { | |||
677 | u64 last_tag; | 677 | u64 last_tag; |
678 | unsigned long config_base; | 678 | unsigned long config_base; |
679 | unsigned long event_base; | 679 | unsigned long event_base; |
680 | int event_base_rdpmc; | ||
680 | int idx; | 681 | int idx; |
681 | int last_cpu; | 682 | int last_cpu; |
682 | 683 | ||
@@ -1106,6 +1107,8 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, | |||
1106 | struct task_struct *task, | 1107 | struct task_struct *task, |
1107 | perf_overflow_handler_t callback, | 1108 | perf_overflow_handler_t callback, |
1108 | void *context); | 1109 | void *context); |
1110 | extern void perf_pmu_migrate_context(struct pmu *pmu, | ||
1111 | int src_cpu, int dst_cpu); | ||
1109 | extern u64 perf_event_read_value(struct perf_event *event, | 1112 | extern u64 perf_event_read_value(struct perf_event *event, |
1110 | u64 *enabled, u64 *running); | 1113 | u64 *enabled, u64 *running); |
1111 | 1114 | ||
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 9cac722b169c..115ead2b5155 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -147,6 +147,7 @@ extern void synchronize_sched(void); | |||
147 | 147 | ||
148 | extern void __rcu_read_lock(void); | 148 | extern void __rcu_read_lock(void); |
149 | extern void __rcu_read_unlock(void); | 149 | extern void __rcu_read_unlock(void); |
150 | extern void rcu_read_unlock_special(struct task_struct *t); | ||
150 | void synchronize_rcu(void); | 151 | void synchronize_rcu(void); |
151 | 152 | ||
152 | /* | 153 | /* |
@@ -255,6 +256,10 @@ static inline void destroy_rcu_head_on_stack(struct rcu_head *head) | |||
255 | } | 256 | } |
256 | #endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ | 257 | #endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ |
257 | 258 | ||
259 | #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SMP) | ||
260 | extern int rcu_is_cpu_idle(void); | ||
261 | #endif /* #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_SMP) */ | ||
262 | |||
258 | #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) | 263 | #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) |
259 | bool rcu_lockdep_current_cpu_online(void); | 264 | bool rcu_lockdep_current_cpu_online(void); |
260 | #else /* #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) */ | 265 | #else /* #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) */ |
@@ -266,15 +271,6 @@ static inline bool rcu_lockdep_current_cpu_online(void) | |||
266 | 271 | ||
267 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 272 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
268 | 273 | ||
269 | #ifdef CONFIG_PROVE_RCU | ||
270 | extern int rcu_is_cpu_idle(void); | ||
271 | #else /* !CONFIG_PROVE_RCU */ | ||
272 | static inline int rcu_is_cpu_idle(void) | ||
273 | { | ||
274 | return 0; | ||
275 | } | ||
276 | #endif /* else !CONFIG_PROVE_RCU */ | ||
277 | |||
278 | static inline void rcu_lock_acquire(struct lockdep_map *map) | 274 | static inline void rcu_lock_acquire(struct lockdep_map *map) |
279 | { | 275 | { |
280 | lock_acquire(map, 0, 0, 2, 1, NULL, _THIS_IP_); | 276 | lock_acquire(map, 0, 0, 2, 1, NULL, _THIS_IP_); |
@@ -431,8 +427,7 @@ extern int rcu_my_thread_group_empty(void); | |||
431 | static inline void rcu_preempt_sleep_check(void) | 427 | static inline void rcu_preempt_sleep_check(void) |
432 | { | 428 | { |
433 | rcu_lockdep_assert(!lock_is_held(&rcu_lock_map), | 429 | rcu_lockdep_assert(!lock_is_held(&rcu_lock_map), |
434 | "Illegal context switch in RCU read-side " | 430 | "Illegal context switch in RCU read-side critical section"); |
435 | "critical section"); | ||
436 | } | 431 | } |
437 | #else /* #ifdef CONFIG_PROVE_RCU */ | 432 | #else /* #ifdef CONFIG_PROVE_RCU */ |
438 | static inline void rcu_preempt_sleep_check(void) | 433 | static inline void rcu_preempt_sleep_check(void) |
@@ -513,10 +508,10 @@ static inline void rcu_preempt_sleep_check(void) | |||
513 | (_________p1); \ | 508 | (_________p1); \ |
514 | }) | 509 | }) |
515 | #define __rcu_assign_pointer(p, v, space) \ | 510 | #define __rcu_assign_pointer(p, v, space) \ |
516 | ({ \ | 511 | do { \ |
517 | smp_wmb(); \ | 512 | smp_wmb(); \ |
518 | (p) = (typeof(*v) __force space *)(v); \ | 513 | (p) = (typeof(*v) __force space *)(v); \ |
519 | }) | 514 | } while (0) |
520 | 515 | ||
521 | 516 | ||
522 | /** | 517 | /** |
@@ -851,7 +846,7 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
851 | * | 846 | * |
852 | * Assigns the specified value to the specified RCU-protected | 847 | * Assigns the specified value to the specified RCU-protected |
853 | * pointer, ensuring that any concurrent RCU readers will see | 848 | * pointer, ensuring that any concurrent RCU readers will see |
854 | * any prior initialization. Returns the value assigned. | 849 | * any prior initialization. |
855 | * | 850 | * |
856 | * Inserts memory barriers on architectures that require them | 851 | * Inserts memory barriers on architectures that require them |
857 | * (which is most of them), and also prevents the compiler from | 852 | * (which is most of them), and also prevents the compiler from |
@@ -903,25 +898,17 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
903 | * the reader-accessible portions of the linked structure. | 898 | * the reader-accessible portions of the linked structure. |
904 | */ | 899 | */ |
905 | #define RCU_INIT_POINTER(p, v) \ | 900 | #define RCU_INIT_POINTER(p, v) \ |
906 | p = (typeof(*v) __force __rcu *)(v) | 901 | do { \ |
907 | 902 | p = (typeof(*v) __force __rcu *)(v); \ | |
908 | static __always_inline bool __is_kfree_rcu_offset(unsigned long offset) | 903 | } while (0) |
909 | { | ||
910 | return offset < 4096; | ||
911 | } | ||
912 | |||
913 | static __always_inline | ||
914 | void __kfree_rcu(struct rcu_head *head, unsigned long offset) | ||
915 | { | ||
916 | typedef void (*rcu_callback)(struct rcu_head *); | ||
917 | |||
918 | BUILD_BUG_ON(!__builtin_constant_p(offset)); | ||
919 | |||
920 | /* See the kfree_rcu() header comment. */ | ||
921 | BUILD_BUG_ON(!__is_kfree_rcu_offset(offset)); | ||
922 | 904 | ||
923 | kfree_call_rcu(head, (rcu_callback)offset); | 905 | /** |
924 | } | 906 | * RCU_POINTER_INITIALIZER() - statically initialize an RCU protected pointer |
907 | * | ||
908 | * GCC-style initialization for an RCU-protected pointer in a structure field. | ||
909 | */ | ||
910 | #define RCU_POINTER_INITIALIZER(p, v) \ | ||
911 | .p = (typeof(*v) __force __rcu *)(v) | ||
925 | 912 | ||
926 | /* | 913 | /* |
927 | * Does the specified offset indicate that the corresponding rcu_head | 914 | * Does the specified offset indicate that the corresponding rcu_head |
@@ -935,7 +922,7 @@ void __kfree_rcu(struct rcu_head *head, unsigned long offset) | |||
935 | #define __kfree_rcu(head, offset) \ | 922 | #define __kfree_rcu(head, offset) \ |
936 | do { \ | 923 | do { \ |
937 | BUILD_BUG_ON(!__is_kfree_rcu_offset(offset)); \ | 924 | BUILD_BUG_ON(!__is_kfree_rcu_offset(offset)); \ |
938 | call_rcu(head, (void (*)(struct rcu_head *))(unsigned long)(offset)); \ | 925 | kfree_call_rcu(head, (void (*)(struct rcu_head *))(unsigned long)(offset)); \ |
939 | } while (0) | 926 | } while (0) |
940 | 927 | ||
941 | /** | 928 | /** |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 4a1f493e0fef..64d9df5c3a49 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1581,7 +1581,6 @@ struct task_struct { | |||
1581 | #endif | 1581 | #endif |
1582 | #ifdef CONFIG_UPROBES | 1582 | #ifdef CONFIG_UPROBES |
1583 | struct uprobe_task *utask; | 1583 | struct uprobe_task *utask; |
1584 | int uprobe_srcu_id; | ||
1585 | #endif | 1584 | #endif |
1586 | }; | 1585 | }; |
1587 | 1586 | ||
diff --git a/include/linux/smp.h b/include/linux/smp.h index 717fb746c9a8..dd6f06be3c9f 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h | |||
@@ -90,10 +90,6 @@ void kick_all_cpus_sync(void); | |||
90 | void __init call_function_init(void); | 90 | void __init call_function_init(void); |
91 | void generic_smp_call_function_single_interrupt(void); | 91 | void generic_smp_call_function_single_interrupt(void); |
92 | void generic_smp_call_function_interrupt(void); | 92 | void generic_smp_call_function_interrupt(void); |
93 | void ipi_call_lock(void); | ||
94 | void ipi_call_unlock(void); | ||
95 | void ipi_call_lock_irq(void); | ||
96 | void ipi_call_unlock_irq(void); | ||
97 | #else | 93 | #else |
98 | static inline void call_function_init(void) { } | 94 | static inline void call_function_init(void) { } |
99 | #endif | 95 | #endif |
@@ -181,7 +177,6 @@ static inline int up_smp_call_function(smp_call_func_t func, void *info) | |||
181 | } while (0) | 177 | } while (0) |
182 | 178 | ||
183 | static inline void smp_send_reschedule(int cpu) { } | 179 | static inline void smp_send_reschedule(int cpu) { } |
184 | #define num_booting_cpus() 1 | ||
185 | #define smp_prepare_boot_cpu() do {} while (0) | 180 | #define smp_prepare_boot_cpu() do {} while (0) |
186 | #define smp_call_function_many(mask, func, info, wait) \ | 181 | #define smp_call_function_many(mask, func, info, wait) \ |
187 | (up_smp_call_function(func, info)) | 182 | (up_smp_call_function(func, info)) |
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index bd96ecd0e05c..802de56c41e8 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
@@ -153,7 +153,7 @@ static inline void tracepoint_synchronize_unregister(void) | |||
153 | } \ | 153 | } \ |
154 | static inline void trace_##name##_rcuidle(proto) \ | 154 | static inline void trace_##name##_rcuidle(proto) \ |
155 | { \ | 155 | { \ |
156 | if (static_branch(&__tracepoint_##name.key)) \ | 156 | if (static_key_false(&__tracepoint_##name.key)) \ |
157 | __DO_TRACE(&__tracepoint_##name, \ | 157 | __DO_TRACE(&__tracepoint_##name, \ |
158 | TP_PROTO(data_proto), \ | 158 | TP_PROTO(data_proto), \ |
159 | TP_ARGS(data_args), \ | 159 | TP_ARGS(data_args), \ |
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index d6146b4811c2..95374d1696a1 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -1425,7 +1425,7 @@ static inline void ip_vs_notrack(struct sk_buff *skb) | |||
1425 | struct nf_conn *ct = nf_ct_get(skb, &ctinfo); | 1425 | struct nf_conn *ct = nf_ct_get(skb, &ctinfo); |
1426 | 1426 | ||
1427 | if (!ct || !nf_ct_is_untracked(ct)) { | 1427 | if (!ct || !nf_ct_is_untracked(ct)) { |
1428 | nf_reset(skb); | 1428 | nf_conntrack_put(skb->nfct); |
1429 | skb->nfct = &nf_ct_untracked_get()->ct_general; | 1429 | skb->nfct = &nf_ct_untracked_get()->ct_general; |
1430 | skb->nfctinfo = IP_CT_NEW; | 1430 | skb->nfctinfo = IP_CT_NEW; |
1431 | nf_conntrack_get(skb->nfct); | 1431 | nf_conntrack_get(skb->nfct); |
diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h index a88fb6939387..e1ce1048fe5f 100644 --- a/include/net/netfilter/nf_conntrack_ecache.h +++ b/include/net/netfilter/nf_conntrack_ecache.h | |||
@@ -78,7 +78,7 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) | |||
78 | struct net *net = nf_ct_net(ct); | 78 | struct net *net = nf_ct_net(ct); |
79 | struct nf_conntrack_ecache *e; | 79 | struct nf_conntrack_ecache *e; |
80 | 80 | ||
81 | if (net->ct.nf_conntrack_event_cb == NULL) | 81 | if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) |
82 | return; | 82 | return; |
83 | 83 | ||
84 | e = nf_ct_ecache_find(ct); | 84 | e = nf_ct_ecache_find(ct); |
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h index d274734b2aa4..5bde94d8585b 100644 --- a/include/trace/events/rcu.h +++ b/include/trace/events/rcu.h | |||
@@ -541,6 +541,50 @@ TRACE_EVENT(rcu_torture_read, | |||
541 | __entry->rcutorturename, __entry->rhp) | 541 | __entry->rcutorturename, __entry->rhp) |
542 | ); | 542 | ); |
543 | 543 | ||
544 | /* | ||
545 | * Tracepoint for _rcu_barrier() execution. The string "s" describes | ||
546 | * the _rcu_barrier phase: | ||
547 | * "Begin": rcu_barrier_callback() started. | ||
548 | * "Check": rcu_barrier_callback() checking for piggybacking. | ||
549 | * "EarlyExit": rcu_barrier_callback() piggybacked, thus early exit. | ||
550 | * "Inc1": rcu_barrier_callback() piggyback check counter incremented. | ||
551 | * "Offline": rcu_barrier_callback() found offline CPU | ||
552 | * "OnlineQ": rcu_barrier_callback() found online CPU with callbacks. | ||
553 | * "OnlineNQ": rcu_barrier_callback() found online CPU, no callbacks. | ||
554 | * "IRQ": An rcu_barrier_callback() callback posted on remote CPU. | ||
555 | * "CB": An rcu_barrier_callback() invoked a callback, not the last. | ||
556 | * "LastCB": An rcu_barrier_callback() invoked the last callback. | ||
557 | * "Inc2": rcu_barrier_callback() piggyback check counter incremented. | ||
558 | * The "cpu" argument is the CPU or -1 if meaningless, the "cnt" argument | ||
559 | * is the count of remaining callbacks, and "done" is the piggybacking count. | ||
560 | */ | ||
561 | TRACE_EVENT(rcu_barrier, | ||
562 | |||
563 | TP_PROTO(char *rcuname, char *s, int cpu, int cnt, unsigned long done), | ||
564 | |||
565 | TP_ARGS(rcuname, s, cpu, cnt, done), | ||
566 | |||
567 | TP_STRUCT__entry( | ||
568 | __field(char *, rcuname) | ||
569 | __field(char *, s) | ||
570 | __field(int, cpu) | ||
571 | __field(int, cnt) | ||
572 | __field(unsigned long, done) | ||
573 | ), | ||
574 | |||
575 | TP_fast_assign( | ||
576 | __entry->rcuname = rcuname; | ||
577 | __entry->s = s; | ||
578 | __entry->cpu = cpu; | ||
579 | __entry->cnt = cnt; | ||
580 | __entry->done = done; | ||
581 | ), | ||
582 | |||
583 | TP_printk("%s %s cpu %d remaining %d # %lu", | ||
584 | __entry->rcuname, __entry->s, __entry->cpu, __entry->cnt, | ||
585 | __entry->done) | ||
586 | ); | ||
587 | |||
544 | #else /* #ifdef CONFIG_RCU_TRACE */ | 588 | #else /* #ifdef CONFIG_RCU_TRACE */ |
545 | 589 | ||
546 | #define trace_rcu_grace_period(rcuname, gpnum, gpevent) do { } while (0) | 590 | #define trace_rcu_grace_period(rcuname, gpnum, gpevent) do { } while (0) |
@@ -564,6 +608,7 @@ TRACE_EVENT(rcu_torture_read, | |||
564 | #define trace_rcu_batch_end(rcuname, callbacks_invoked, cb, nr, iit, risk) \ | 608 | #define trace_rcu_batch_end(rcuname, callbacks_invoked, cb, nr, iit, risk) \ |
565 | do { } while (0) | 609 | do { } while (0) |
566 | #define trace_rcu_torture_read(rcutorturename, rhp) do { } while (0) | 610 | #define trace_rcu_torture_read(rcutorturename, rhp) do { } while (0) |
611 | #define trace_rcu_barrier(name, s, cpu, cnt, done) do { } while (0) | ||
567 | 612 | ||
568 | #endif /* #else #ifdef CONFIG_RCU_TRACE */ | 613 | #endif /* #else #ifdef CONFIG_RCU_TRACE */ |
569 | 614 | ||
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 769724944fc6..c6bc2faaf261 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
@@ -571,6 +571,7 @@ static inline void ftrace_test_probe_##call(void) \ | |||
571 | 571 | ||
572 | #undef __print_flags | 572 | #undef __print_flags |
573 | #undef __print_symbolic | 573 | #undef __print_symbolic |
574 | #undef __print_hex | ||
574 | #undef __get_dynamic_array | 575 | #undef __get_dynamic_array |
575 | #undef __get_str | 576 | #undef __get_str |
576 | 577 | ||
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 67b847dfa2bb..1f91413edb87 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/ctype.h> | 14 | #include <linux/ctype.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/kmsg_dump.h> | ||
17 | #include <linux/reboot.h> | 18 | #include <linux/reboot.h> |
18 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
19 | #include <linux/sysrq.h> | 20 | #include <linux/sysrq.h> |
@@ -2040,8 +2041,15 @@ static int kdb_env(int argc, const char **argv) | |||
2040 | */ | 2041 | */ |
2041 | static int kdb_dmesg(int argc, const char **argv) | 2042 | static int kdb_dmesg(int argc, const char **argv) |
2042 | { | 2043 | { |
2043 | char *syslog_data[4], *start, *end, c = '\0', *p; | 2044 | int diag; |
2044 | int diag, logging, logsize, lines = 0, adjust = 0, n; | 2045 | int logging; |
2046 | int lines = 0; | ||
2047 | int adjust = 0; | ||
2048 | int n = 0; | ||
2049 | int skip = 0; | ||
2050 | struct kmsg_dumper dumper = { .active = 1 }; | ||
2051 | size_t len; | ||
2052 | char buf[201]; | ||
2045 | 2053 | ||
2046 | if (argc > 2) | 2054 | if (argc > 2) |
2047 | return KDB_ARGCOUNT; | 2055 | return KDB_ARGCOUNT; |
@@ -2064,22 +2072,10 @@ static int kdb_dmesg(int argc, const char **argv) | |||
2064 | kdb_set(2, setargs); | 2072 | kdb_set(2, setargs); |
2065 | } | 2073 | } |
2066 | 2074 | ||
2067 | /* syslog_data[0,1] physical start, end+1. syslog_data[2,3] | 2075 | kmsg_dump_rewind_nolock(&dumper); |
2068 | * logical start, end+1. */ | 2076 | while (kmsg_dump_get_line_nolock(&dumper, 1, NULL, 0, NULL)) |
2069 | kdb_syslog_data(syslog_data); | 2077 | n++; |
2070 | if (syslog_data[2] == syslog_data[3]) | 2078 | |
2071 | return 0; | ||
2072 | logsize = syslog_data[1] - syslog_data[0]; | ||
2073 | start = syslog_data[2]; | ||
2074 | end = syslog_data[3]; | ||
2075 | #define KDB_WRAP(p) (((p - syslog_data[0]) % logsize) + syslog_data[0]) | ||
2076 | for (n = 0, p = start; p < end; ++p) { | ||
2077 | c = *KDB_WRAP(p); | ||
2078 | if (c == '\n') | ||
2079 | ++n; | ||
2080 | } | ||
2081 | if (c != '\n') | ||
2082 | ++n; | ||
2083 | if (lines < 0) { | 2079 | if (lines < 0) { |
2084 | if (adjust >= n) | 2080 | if (adjust >= n) |
2085 | kdb_printf("buffer only contains %d lines, nothing " | 2081 | kdb_printf("buffer only contains %d lines, nothing " |
@@ -2087,21 +2083,11 @@ static int kdb_dmesg(int argc, const char **argv) | |||
2087 | else if (adjust - lines >= n) | 2083 | else if (adjust - lines >= n) |
2088 | kdb_printf("buffer only contains %d lines, last %d " | 2084 | kdb_printf("buffer only contains %d lines, last %d " |
2089 | "lines printed\n", n, n - adjust); | 2085 | "lines printed\n", n, n - adjust); |
2090 | if (adjust) { | 2086 | skip = adjust; |
2091 | for (; start < end && adjust; ++start) { | 2087 | lines = abs(lines); |
2092 | if (*KDB_WRAP(start) == '\n') | ||
2093 | --adjust; | ||
2094 | } | ||
2095 | if (start < end) | ||
2096 | ++start; | ||
2097 | } | ||
2098 | for (p = start; p < end && lines; ++p) { | ||
2099 | if (*KDB_WRAP(p) == '\n') | ||
2100 | ++lines; | ||
2101 | } | ||
2102 | end = p; | ||
2103 | } else if (lines > 0) { | 2088 | } else if (lines > 0) { |
2104 | int skip = n - (adjust + lines); | 2089 | skip = n - lines - adjust; |
2090 | lines = abs(lines); | ||
2105 | if (adjust >= n) { | 2091 | if (adjust >= n) { |
2106 | kdb_printf("buffer only contains %d lines, " | 2092 | kdb_printf("buffer only contains %d lines, " |
2107 | "nothing printed\n", n); | 2093 | "nothing printed\n", n); |
@@ -2112,35 +2098,24 @@ static int kdb_dmesg(int argc, const char **argv) | |||
2112 | kdb_printf("buffer only contains %d lines, first " | 2098 | kdb_printf("buffer only contains %d lines, first " |
2113 | "%d lines printed\n", n, lines); | 2099 | "%d lines printed\n", n, lines); |
2114 | } | 2100 | } |
2115 | for (; start < end && skip; ++start) { | 2101 | } else { |
2116 | if (*KDB_WRAP(start) == '\n') | 2102 | lines = n; |
2117 | --skip; | ||
2118 | } | ||
2119 | for (p = start; p < end && lines; ++p) { | ||
2120 | if (*KDB_WRAP(p) == '\n') | ||
2121 | --lines; | ||
2122 | } | ||
2123 | end = p; | ||
2124 | } | 2103 | } |
2125 | /* Do a line at a time (max 200 chars) to reduce protocol overhead */ | 2104 | |
2126 | c = '\n'; | 2105 | if (skip >= n || skip < 0) |
2127 | while (start != end) { | 2106 | return 0; |
2128 | char buf[201]; | 2107 | |
2129 | p = buf; | 2108 | kmsg_dump_rewind_nolock(&dumper); |
2130 | if (KDB_FLAG(CMD_INTERRUPT)) | 2109 | while (kmsg_dump_get_line_nolock(&dumper, 1, buf, sizeof(buf), &len)) { |
2131 | return 0; | 2110 | if (skip) { |
2132 | while (start < end && (c = *KDB_WRAP(start)) && | 2111 | skip--; |
2133 | (p - buf) < sizeof(buf)-1) { | 2112 | continue; |
2134 | ++start; | ||
2135 | *p++ = c; | ||
2136 | if (c == '\n') | ||
2137 | break; | ||
2138 | } | 2113 | } |
2139 | *p = '\0'; | 2114 | if (!lines--) |
2140 | kdb_printf("%s", buf); | 2115 | break; |
2116 | |||
2117 | kdb_printf("%.*s\n", (int)len - 1, buf); | ||
2141 | } | 2118 | } |
2142 | if (c != '\n') | ||
2143 | kdb_printf("\n"); | ||
2144 | 2119 | ||
2145 | return 0; | 2120 | return 0; |
2146 | } | 2121 | } |
diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 47c4e56e513b..392ec6a25844 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h | |||
@@ -205,7 +205,6 @@ extern char kdb_grep_string[]; | |||
205 | extern int kdb_grep_leading; | 205 | extern int kdb_grep_leading; |
206 | extern int kdb_grep_trailing; | 206 | extern int kdb_grep_trailing; |
207 | extern char *kdb_cmds[]; | 207 | extern char *kdb_cmds[]; |
208 | extern void kdb_syslog_data(char *syslog_data[]); | ||
209 | extern unsigned long kdb_task_state_string(const char *); | 208 | extern unsigned long kdb_task_state_string(const char *); |
210 | extern char kdb_task_state_char (const struct task_struct *); | 209 | extern char kdb_task_state_char (const struct task_struct *); |
211 | extern unsigned long kdb_task_state(const struct task_struct *p, | 210 | extern unsigned long kdb_task_state(const struct task_struct *p, |
diff --git a/kernel/events/core.c b/kernel/events/core.c index d7d71d6ec972..f1cf0edeb39a 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -1645,6 +1645,8 @@ perf_install_in_context(struct perf_event_context *ctx, | |||
1645 | lockdep_assert_held(&ctx->mutex); | 1645 | lockdep_assert_held(&ctx->mutex); |
1646 | 1646 | ||
1647 | event->ctx = ctx; | 1647 | event->ctx = ctx; |
1648 | if (event->cpu != -1) | ||
1649 | event->cpu = cpu; | ||
1648 | 1650 | ||
1649 | if (!task) { | 1651 | if (!task) { |
1650 | /* | 1652 | /* |
@@ -6252,6 +6254,8 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6252 | } | 6254 | } |
6253 | } | 6255 | } |
6254 | 6256 | ||
6257 | get_online_cpus(); | ||
6258 | |||
6255 | event = perf_event_alloc(&attr, cpu, task, group_leader, NULL, | 6259 | event = perf_event_alloc(&attr, cpu, task, group_leader, NULL, |
6256 | NULL, NULL); | 6260 | NULL, NULL); |
6257 | if (IS_ERR(event)) { | 6261 | if (IS_ERR(event)) { |
@@ -6304,7 +6308,7 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6304 | /* | 6308 | /* |
6305 | * Get the target context (task or percpu): | 6309 | * Get the target context (task or percpu): |
6306 | */ | 6310 | */ |
6307 | ctx = find_get_context(pmu, task, cpu); | 6311 | ctx = find_get_context(pmu, task, event->cpu); |
6308 | if (IS_ERR(ctx)) { | 6312 | if (IS_ERR(ctx)) { |
6309 | err = PTR_ERR(ctx); | 6313 | err = PTR_ERR(ctx); |
6310 | goto err_alloc; | 6314 | goto err_alloc; |
@@ -6377,20 +6381,23 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6377 | mutex_lock(&ctx->mutex); | 6381 | mutex_lock(&ctx->mutex); |
6378 | 6382 | ||
6379 | if (move_group) { | 6383 | if (move_group) { |
6380 | perf_install_in_context(ctx, group_leader, cpu); | 6384 | synchronize_rcu(); |
6385 | perf_install_in_context(ctx, group_leader, event->cpu); | ||
6381 | get_ctx(ctx); | 6386 | get_ctx(ctx); |
6382 | list_for_each_entry(sibling, &group_leader->sibling_list, | 6387 | list_for_each_entry(sibling, &group_leader->sibling_list, |
6383 | group_entry) { | 6388 | group_entry) { |
6384 | perf_install_in_context(ctx, sibling, cpu); | 6389 | perf_install_in_context(ctx, sibling, event->cpu); |
6385 | get_ctx(ctx); | 6390 | get_ctx(ctx); |
6386 | } | 6391 | } |
6387 | } | 6392 | } |
6388 | 6393 | ||
6389 | perf_install_in_context(ctx, event, cpu); | 6394 | perf_install_in_context(ctx, event, event->cpu); |
6390 | ++ctx->generation; | 6395 | ++ctx->generation; |
6391 | perf_unpin_context(ctx); | 6396 | perf_unpin_context(ctx); |
6392 | mutex_unlock(&ctx->mutex); | 6397 | mutex_unlock(&ctx->mutex); |
6393 | 6398 | ||
6399 | put_online_cpus(); | ||
6400 | |||
6394 | event->owner = current; | 6401 | event->owner = current; |
6395 | 6402 | ||
6396 | mutex_lock(¤t->perf_event_mutex); | 6403 | mutex_lock(¤t->perf_event_mutex); |
@@ -6419,6 +6426,7 @@ err_context: | |||
6419 | err_alloc: | 6426 | err_alloc: |
6420 | free_event(event); | 6427 | free_event(event); |
6421 | err_task: | 6428 | err_task: |
6429 | put_online_cpus(); | ||
6422 | if (task) | 6430 | if (task) |
6423 | put_task_struct(task); | 6431 | put_task_struct(task); |
6424 | err_group_fd: | 6432 | err_group_fd: |
@@ -6479,6 +6487,39 @@ err: | |||
6479 | } | 6487 | } |
6480 | EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter); | 6488 | EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter); |
6481 | 6489 | ||
6490 | void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu) | ||
6491 | { | ||
6492 | struct perf_event_context *src_ctx; | ||
6493 | struct perf_event_context *dst_ctx; | ||
6494 | struct perf_event *event, *tmp; | ||
6495 | LIST_HEAD(events); | ||
6496 | |||
6497 | src_ctx = &per_cpu_ptr(pmu->pmu_cpu_context, src_cpu)->ctx; | ||
6498 | dst_ctx = &per_cpu_ptr(pmu->pmu_cpu_context, dst_cpu)->ctx; | ||
6499 | |||
6500 | mutex_lock(&src_ctx->mutex); | ||
6501 | list_for_each_entry_safe(event, tmp, &src_ctx->event_list, | ||
6502 | event_entry) { | ||
6503 | perf_remove_from_context(event); | ||
6504 | put_ctx(src_ctx); | ||
6505 | list_add(&event->event_entry, &events); | ||
6506 | } | ||
6507 | mutex_unlock(&src_ctx->mutex); | ||
6508 | |||
6509 | synchronize_rcu(); | ||
6510 | |||
6511 | mutex_lock(&dst_ctx->mutex); | ||
6512 | list_for_each_entry_safe(event, tmp, &events, event_entry) { | ||
6513 | list_del(&event->event_entry); | ||
6514 | if (event->state >= PERF_EVENT_STATE_OFF) | ||
6515 | event->state = PERF_EVENT_STATE_INACTIVE; | ||
6516 | perf_install_in_context(dst_ctx, event, dst_cpu); | ||
6517 | get_ctx(dst_ctx); | ||
6518 | } | ||
6519 | mutex_unlock(&dst_ctx->mutex); | ||
6520 | } | ||
6521 | EXPORT_SYMBOL_GPL(perf_pmu_migrate_context); | ||
6522 | |||
6482 | static void sync_child_event(struct perf_event *child_event, | 6523 | static void sync_child_event(struct perf_event *child_event, |
6483 | struct task_struct *child) | 6524 | struct task_struct *child) |
6484 | { | 6525 | { |
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 985be4d80fe8..f93532748bca 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -38,13 +38,29 @@ | |||
38 | #define UINSNS_PER_PAGE (PAGE_SIZE/UPROBE_XOL_SLOT_BYTES) | 38 | #define UINSNS_PER_PAGE (PAGE_SIZE/UPROBE_XOL_SLOT_BYTES) |
39 | #define MAX_UPROBE_XOL_SLOTS UINSNS_PER_PAGE | 39 | #define MAX_UPROBE_XOL_SLOTS UINSNS_PER_PAGE |
40 | 40 | ||
41 | static struct srcu_struct uprobes_srcu; | ||
42 | static struct rb_root uprobes_tree = RB_ROOT; | 41 | static struct rb_root uprobes_tree = RB_ROOT; |
43 | 42 | ||
44 | static DEFINE_SPINLOCK(uprobes_treelock); /* serialize rbtree access */ | 43 | static DEFINE_SPINLOCK(uprobes_treelock); /* serialize rbtree access */ |
45 | 44 | ||
46 | #define UPROBES_HASH_SZ 13 | 45 | #define UPROBES_HASH_SZ 13 |
47 | 46 | ||
47 | /* | ||
48 | * We need separate register/unregister and mmap/munmap lock hashes because | ||
49 | * of mmap_sem nesting. | ||
50 | * | ||
51 | * uprobe_register() needs to install probes on (potentially) all processes | ||
52 | * and thus needs to acquire multiple mmap_sems (consequtively, not | ||
53 | * concurrently), whereas uprobe_mmap() is called while holding mmap_sem | ||
54 | * for the particular process doing the mmap. | ||
55 | * | ||
56 | * uprobe_register()->register_for_each_vma() needs to drop/acquire mmap_sem | ||
57 | * because of lock order against i_mmap_mutex. This means there's a hole in | ||
58 | * the register vma iteration where a mmap() can happen. | ||
59 | * | ||
60 | * Thus uprobe_register() can race with uprobe_mmap() and we can try and | ||
61 | * install a probe where one is already installed. | ||
62 | */ | ||
63 | |||
48 | /* serialize (un)register */ | 64 | /* serialize (un)register */ |
49 | static struct mutex uprobes_mutex[UPROBES_HASH_SZ]; | 65 | static struct mutex uprobes_mutex[UPROBES_HASH_SZ]; |
50 | 66 | ||
@@ -61,17 +77,6 @@ static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ]; | |||
61 | */ | 77 | */ |
62 | static atomic_t uprobe_events = ATOMIC_INIT(0); | 78 | static atomic_t uprobe_events = ATOMIC_INIT(0); |
63 | 79 | ||
64 | /* | ||
65 | * Maintain a temporary per vma info that can be used to search if a vma | ||
66 | * has already been handled. This structure is introduced since extending | ||
67 | * vm_area_struct wasnt recommended. | ||
68 | */ | ||
69 | struct vma_info { | ||
70 | struct list_head probe_list; | ||
71 | struct mm_struct *mm; | ||
72 | loff_t vaddr; | ||
73 | }; | ||
74 | |||
75 | struct uprobe { | 80 | struct uprobe { |
76 | struct rb_node rb_node; /* node in the rb tree */ | 81 | struct rb_node rb_node; /* node in the rb tree */ |
77 | atomic_t ref; | 82 | atomic_t ref; |
@@ -100,7 +105,8 @@ static bool valid_vma(struct vm_area_struct *vma, bool is_register) | |||
100 | if (!is_register) | 105 | if (!is_register) |
101 | return true; | 106 | return true; |
102 | 107 | ||
103 | if ((vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) == (VM_READ|VM_EXEC)) | 108 | if ((vma->vm_flags & (VM_HUGETLB|VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) |
109 | == (VM_READ|VM_EXEC)) | ||
104 | return true; | 110 | return true; |
105 | 111 | ||
106 | return false; | 112 | return false; |
@@ -129,33 +135,17 @@ static loff_t vma_address(struct vm_area_struct *vma, loff_t offset) | |||
129 | static int __replace_page(struct vm_area_struct *vma, struct page *page, struct page *kpage) | 135 | static int __replace_page(struct vm_area_struct *vma, struct page *page, struct page *kpage) |
130 | { | 136 | { |
131 | struct mm_struct *mm = vma->vm_mm; | 137 | struct mm_struct *mm = vma->vm_mm; |
132 | pgd_t *pgd; | ||
133 | pud_t *pud; | ||
134 | pmd_t *pmd; | ||
135 | pte_t *ptep; | ||
136 | spinlock_t *ptl; | ||
137 | unsigned long addr; | 138 | unsigned long addr; |
138 | int err = -EFAULT; | 139 | spinlock_t *ptl; |
140 | pte_t *ptep; | ||
139 | 141 | ||
140 | addr = page_address_in_vma(page, vma); | 142 | addr = page_address_in_vma(page, vma); |
141 | if (addr == -EFAULT) | 143 | if (addr == -EFAULT) |
142 | goto out; | 144 | return -EFAULT; |
143 | |||
144 | pgd = pgd_offset(mm, addr); | ||
145 | if (!pgd_present(*pgd)) | ||
146 | goto out; | ||
147 | |||
148 | pud = pud_offset(pgd, addr); | ||
149 | if (!pud_present(*pud)) | ||
150 | goto out; | ||
151 | |||
152 | pmd = pmd_offset(pud, addr); | ||
153 | if (!pmd_present(*pmd)) | ||
154 | goto out; | ||
155 | 145 | ||
156 | ptep = pte_offset_map_lock(mm, pmd, addr, &ptl); | 146 | ptep = page_check_address(page, mm, addr, &ptl, 0); |
157 | if (!ptep) | 147 | if (!ptep) |
158 | goto out; | 148 | return -EAGAIN; |
159 | 149 | ||
160 | get_page(kpage); | 150 | get_page(kpage); |
161 | page_add_new_anon_rmap(kpage, vma, addr); | 151 | page_add_new_anon_rmap(kpage, vma, addr); |
@@ -174,10 +164,8 @@ static int __replace_page(struct vm_area_struct *vma, struct page *page, struct | |||
174 | try_to_free_swap(page); | 164 | try_to_free_swap(page); |
175 | put_page(page); | 165 | put_page(page); |
176 | pte_unmap_unlock(ptep, ptl); | 166 | pte_unmap_unlock(ptep, ptl); |
177 | err = 0; | ||
178 | 167 | ||
179 | out: | 168 | return 0; |
180 | return err; | ||
181 | } | 169 | } |
182 | 170 | ||
183 | /** | 171 | /** |
@@ -222,9 +210,8 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, | |||
222 | void *vaddr_old, *vaddr_new; | 210 | void *vaddr_old, *vaddr_new; |
223 | struct vm_area_struct *vma; | 211 | struct vm_area_struct *vma; |
224 | struct uprobe *uprobe; | 212 | struct uprobe *uprobe; |
225 | loff_t addr; | ||
226 | int ret; | 213 | int ret; |
227 | 214 | retry: | |
228 | /* Read the page with vaddr into memory */ | 215 | /* Read the page with vaddr into memory */ |
229 | ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma); | 216 | ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma); |
230 | if (ret <= 0) | 217 | if (ret <= 0) |
@@ -246,10 +233,6 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, | |||
246 | if (mapping != vma->vm_file->f_mapping) | 233 | if (mapping != vma->vm_file->f_mapping) |
247 | goto put_out; | 234 | goto put_out; |
248 | 235 | ||
249 | addr = vma_address(vma, uprobe->offset); | ||
250 | if (vaddr != (unsigned long)addr) | ||
251 | goto put_out; | ||
252 | |||
253 | ret = -ENOMEM; | 236 | ret = -ENOMEM; |
254 | new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr); | 237 | new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr); |
255 | if (!new_page) | 238 | if (!new_page) |
@@ -267,11 +250,7 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, | |||
267 | vaddr_new = kmap_atomic(new_page); | 250 | vaddr_new = kmap_atomic(new_page); |
268 | 251 | ||
269 | memcpy(vaddr_new, vaddr_old, PAGE_SIZE); | 252 | memcpy(vaddr_new, vaddr_old, PAGE_SIZE); |
270 | 253 | memcpy(vaddr_new + (vaddr & ~PAGE_MASK), &opcode, UPROBE_SWBP_INSN_SIZE); | |
271 | /* poke the new insn in, ASSUMES we don't cross page boundary */ | ||
272 | vaddr &= ~PAGE_MASK; | ||
273 | BUG_ON(vaddr + UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); | ||
274 | memcpy(vaddr_new + vaddr, &opcode, UPROBE_SWBP_INSN_SIZE); | ||
275 | 254 | ||
276 | kunmap_atomic(vaddr_new); | 255 | kunmap_atomic(vaddr_new); |
277 | kunmap_atomic(vaddr_old); | 256 | kunmap_atomic(vaddr_old); |
@@ -291,6 +270,8 @@ unlock_out: | |||
291 | put_out: | 270 | put_out: |
292 | put_page(old_page); | 271 | put_page(old_page); |
293 | 272 | ||
273 | if (unlikely(ret == -EAGAIN)) | ||
274 | goto retry; | ||
294 | return ret; | 275 | return ret; |
295 | } | 276 | } |
296 | 277 | ||
@@ -312,7 +293,7 @@ static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_ | |||
312 | void *vaddr_new; | 293 | void *vaddr_new; |
313 | int ret; | 294 | int ret; |
314 | 295 | ||
315 | ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &page, NULL); | 296 | ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL); |
316 | if (ret <= 0) | 297 | if (ret <= 0) |
317 | return ret; | 298 | return ret; |
318 | 299 | ||
@@ -333,10 +314,20 @@ static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr) | |||
333 | uprobe_opcode_t opcode; | 314 | uprobe_opcode_t opcode; |
334 | int result; | 315 | int result; |
335 | 316 | ||
317 | if (current->mm == mm) { | ||
318 | pagefault_disable(); | ||
319 | result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr, | ||
320 | sizeof(opcode)); | ||
321 | pagefault_enable(); | ||
322 | |||
323 | if (likely(result == 0)) | ||
324 | goto out; | ||
325 | } | ||
326 | |||
336 | result = read_opcode(mm, vaddr, &opcode); | 327 | result = read_opcode(mm, vaddr, &opcode); |
337 | if (result) | 328 | if (result) |
338 | return result; | 329 | return result; |
339 | 330 | out: | |
340 | if (is_swbp_insn(&opcode)) | 331 | if (is_swbp_insn(&opcode)) |
341 | return 1; | 332 | return 1; |
342 | 333 | ||
@@ -355,7 +346,9 @@ static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr) | |||
355 | int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr) | 346 | int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr) |
356 | { | 347 | { |
357 | int result; | 348 | int result; |
358 | 349 | /* | |
350 | * See the comment near uprobes_hash(). | ||
351 | */ | ||
359 | result = is_swbp_at_addr(mm, vaddr); | 352 | result = is_swbp_at_addr(mm, vaddr); |
360 | if (result == 1) | 353 | if (result == 1) |
361 | return -EEXIST; | 354 | return -EEXIST; |
@@ -520,7 +513,6 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset) | |||
520 | uprobe->inode = igrab(inode); | 513 | uprobe->inode = igrab(inode); |
521 | uprobe->offset = offset; | 514 | uprobe->offset = offset; |
522 | init_rwsem(&uprobe->consumer_rwsem); | 515 | init_rwsem(&uprobe->consumer_rwsem); |
523 | INIT_LIST_HEAD(&uprobe->pending_list); | ||
524 | 516 | ||
525 | /* add to uprobes_tree, sorted on inode:offset */ | 517 | /* add to uprobes_tree, sorted on inode:offset */ |
526 | cur_uprobe = insert_uprobe(uprobe); | 518 | cur_uprobe = insert_uprobe(uprobe); |
@@ -588,20 +580,22 @@ static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *uc) | |||
588 | } | 580 | } |
589 | 581 | ||
590 | static int | 582 | static int |
591 | __copy_insn(struct address_space *mapping, struct vm_area_struct *vma, char *insn, | 583 | __copy_insn(struct address_space *mapping, struct file *filp, char *insn, |
592 | unsigned long nbytes, unsigned long offset) | 584 | unsigned long nbytes, loff_t offset) |
593 | { | 585 | { |
594 | struct file *filp = vma->vm_file; | ||
595 | struct page *page; | 586 | struct page *page; |
596 | void *vaddr; | 587 | void *vaddr; |
597 | unsigned long off1; | 588 | unsigned long off; |
598 | unsigned long idx; | 589 | pgoff_t idx; |
599 | 590 | ||
600 | if (!filp) | 591 | if (!filp) |
601 | return -EINVAL; | 592 | return -EINVAL; |
602 | 593 | ||
603 | idx = (unsigned long)(offset >> PAGE_CACHE_SHIFT); | 594 | if (!mapping->a_ops->readpage) |
604 | off1 = offset &= ~PAGE_MASK; | 595 | return -EIO; |
596 | |||
597 | idx = offset >> PAGE_CACHE_SHIFT; | ||
598 | off = offset & ~PAGE_MASK; | ||
605 | 599 | ||
606 | /* | 600 | /* |
607 | * Ensure that the page that has the original instruction is | 601 | * Ensure that the page that has the original instruction is |
@@ -612,22 +606,20 @@ __copy_insn(struct address_space *mapping, struct vm_area_struct *vma, char *ins | |||
612 | return PTR_ERR(page); | 606 | return PTR_ERR(page); |
613 | 607 | ||
614 | vaddr = kmap_atomic(page); | 608 | vaddr = kmap_atomic(page); |
615 | memcpy(insn, vaddr + off1, nbytes); | 609 | memcpy(insn, vaddr + off, nbytes); |
616 | kunmap_atomic(vaddr); | 610 | kunmap_atomic(vaddr); |
617 | page_cache_release(page); | 611 | page_cache_release(page); |
618 | 612 | ||
619 | return 0; | 613 | return 0; |
620 | } | 614 | } |
621 | 615 | ||
622 | static int | 616 | static int copy_insn(struct uprobe *uprobe, struct file *filp) |
623 | copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr) | ||
624 | { | 617 | { |
625 | struct address_space *mapping; | 618 | struct address_space *mapping; |
626 | unsigned long nbytes; | 619 | unsigned long nbytes; |
627 | int bytes; | 620 | int bytes; |
628 | 621 | ||
629 | addr &= ~PAGE_MASK; | 622 | nbytes = PAGE_SIZE - (uprobe->offset & ~PAGE_MASK); |
630 | nbytes = PAGE_SIZE - addr; | ||
631 | mapping = uprobe->inode->i_mapping; | 623 | mapping = uprobe->inode->i_mapping; |
632 | 624 | ||
633 | /* Instruction at end of binary; copy only available bytes */ | 625 | /* Instruction at end of binary; copy only available bytes */ |
@@ -638,13 +630,13 @@ copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr) | |||
638 | 630 | ||
639 | /* Instruction at the page-boundary; copy bytes in second page */ | 631 | /* Instruction at the page-boundary; copy bytes in second page */ |
640 | if (nbytes < bytes) { | 632 | if (nbytes < bytes) { |
641 | if (__copy_insn(mapping, vma, uprobe->arch.insn + nbytes, | 633 | int err = __copy_insn(mapping, filp, uprobe->arch.insn + nbytes, |
642 | bytes - nbytes, uprobe->offset + nbytes)) | 634 | bytes - nbytes, uprobe->offset + nbytes); |
643 | return -ENOMEM; | 635 | if (err) |
644 | 636 | return err; | |
645 | bytes = nbytes; | 637 | bytes = nbytes; |
646 | } | 638 | } |
647 | return __copy_insn(mapping, vma, uprobe->arch.insn, bytes, uprobe->offset); | 639 | return __copy_insn(mapping, filp, uprobe->arch.insn, bytes, uprobe->offset); |
648 | } | 640 | } |
649 | 641 | ||
650 | /* | 642 | /* |
@@ -672,9 +664,8 @@ copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr) | |||
672 | */ | 664 | */ |
673 | static int | 665 | static int |
674 | install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, | 666 | install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, |
675 | struct vm_area_struct *vma, loff_t vaddr) | 667 | struct vm_area_struct *vma, unsigned long vaddr) |
676 | { | 668 | { |
677 | unsigned long addr; | ||
678 | int ret; | 669 | int ret; |
679 | 670 | ||
680 | /* | 671 | /* |
@@ -687,20 +678,22 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, | |||
687 | if (!uprobe->consumers) | 678 | if (!uprobe->consumers) |
688 | return -EEXIST; | 679 | return -EEXIST; |
689 | 680 | ||
690 | addr = (unsigned long)vaddr; | ||
691 | |||
692 | if (!(uprobe->flags & UPROBE_COPY_INSN)) { | 681 | if (!(uprobe->flags & UPROBE_COPY_INSN)) { |
693 | ret = copy_insn(uprobe, vma, addr); | 682 | ret = copy_insn(uprobe, vma->vm_file); |
694 | if (ret) | 683 | if (ret) |
695 | return ret; | 684 | return ret; |
696 | 685 | ||
697 | if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn)) | 686 | if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn)) |
698 | return -EEXIST; | 687 | return -ENOTSUPP; |
699 | 688 | ||
700 | ret = arch_uprobe_analyze_insn(&uprobe->arch, mm); | 689 | ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, vaddr); |
701 | if (ret) | 690 | if (ret) |
702 | return ret; | 691 | return ret; |
703 | 692 | ||
693 | /* write_opcode() assumes we don't cross page boundary */ | ||
694 | BUG_ON((uprobe->offset & ~PAGE_MASK) + | ||
695 | UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); | ||
696 | |||
704 | uprobe->flags |= UPROBE_COPY_INSN; | 697 | uprobe->flags |= UPROBE_COPY_INSN; |
705 | } | 698 | } |
706 | 699 | ||
@@ -713,7 +706,7 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, | |||
713 | * Hence increment before and decrement on failure. | 706 | * Hence increment before and decrement on failure. |
714 | */ | 707 | */ |
715 | atomic_inc(&mm->uprobes_state.count); | 708 | atomic_inc(&mm->uprobes_state.count); |
716 | ret = set_swbp(&uprobe->arch, mm, addr); | 709 | ret = set_swbp(&uprobe->arch, mm, vaddr); |
717 | if (ret) | 710 | if (ret) |
718 | atomic_dec(&mm->uprobes_state.count); | 711 | atomic_dec(&mm->uprobes_state.count); |
719 | 712 | ||
@@ -721,27 +714,21 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, | |||
721 | } | 714 | } |
722 | 715 | ||
723 | static void | 716 | static void |
724 | remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, loff_t vaddr) | 717 | remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, unsigned long vaddr) |
725 | { | 718 | { |
726 | if (!set_orig_insn(&uprobe->arch, mm, (unsigned long)vaddr, true)) | 719 | if (!set_orig_insn(&uprobe->arch, mm, vaddr, true)) |
727 | atomic_dec(&mm->uprobes_state.count); | 720 | atomic_dec(&mm->uprobes_state.count); |
728 | } | 721 | } |
729 | 722 | ||
730 | /* | 723 | /* |
731 | * There could be threads that have hit the breakpoint and are entering the | 724 | * There could be threads that have already hit the breakpoint. They |
732 | * notifier code and trying to acquire the uprobes_treelock. The thread | 725 | * will recheck the current insn and restart if find_uprobe() fails. |
733 | * calling delete_uprobe() that is removing the uprobe from the rb_tree can | 726 | * See find_active_uprobe(). |
734 | * race with these threads and might acquire the uprobes_treelock compared | ||
735 | * to some of the breakpoint hit threads. In such a case, the breakpoint | ||
736 | * hit threads will not find the uprobe. The current unregistering thread | ||
737 | * waits till all other threads have hit a breakpoint, to acquire the | ||
738 | * uprobes_treelock before the uprobe is removed from the rbtree. | ||
739 | */ | 727 | */ |
740 | static void delete_uprobe(struct uprobe *uprobe) | 728 | static void delete_uprobe(struct uprobe *uprobe) |
741 | { | 729 | { |
742 | unsigned long flags; | 730 | unsigned long flags; |
743 | 731 | ||
744 | synchronize_srcu(&uprobes_srcu); | ||
745 | spin_lock_irqsave(&uprobes_treelock, flags); | 732 | spin_lock_irqsave(&uprobes_treelock, flags); |
746 | rb_erase(&uprobe->rb_node, &uprobes_tree); | 733 | rb_erase(&uprobe->rb_node, &uprobes_tree); |
747 | spin_unlock_irqrestore(&uprobes_treelock, flags); | 734 | spin_unlock_irqrestore(&uprobes_treelock, flags); |
@@ -750,139 +737,135 @@ static void delete_uprobe(struct uprobe *uprobe) | |||
750 | atomic_dec(&uprobe_events); | 737 | atomic_dec(&uprobe_events); |
751 | } | 738 | } |
752 | 739 | ||
753 | static struct vma_info * | 740 | struct map_info { |
754 | __find_next_vma_info(struct address_space *mapping, struct list_head *head, | 741 | struct map_info *next; |
755 | struct vma_info *vi, loff_t offset, bool is_register) | 742 | struct mm_struct *mm; |
743 | unsigned long vaddr; | ||
744 | }; | ||
745 | |||
746 | static inline struct map_info *free_map_info(struct map_info *info) | ||
747 | { | ||
748 | struct map_info *next = info->next; | ||
749 | kfree(info); | ||
750 | return next; | ||
751 | } | ||
752 | |||
753 | static struct map_info * | ||
754 | build_map_info(struct address_space *mapping, loff_t offset, bool is_register) | ||
756 | { | 755 | { |
756 | unsigned long pgoff = offset >> PAGE_SHIFT; | ||
757 | struct prio_tree_iter iter; | 757 | struct prio_tree_iter iter; |
758 | struct vm_area_struct *vma; | 758 | struct vm_area_struct *vma; |
759 | struct vma_info *tmpvi; | 759 | struct map_info *curr = NULL; |
760 | unsigned long pgoff; | 760 | struct map_info *prev = NULL; |
761 | int existing_vma; | 761 | struct map_info *info; |
762 | loff_t vaddr; | 762 | int more = 0; |
763 | |||
764 | pgoff = offset >> PAGE_SHIFT; | ||
765 | 763 | ||
764 | again: | ||
765 | mutex_lock(&mapping->i_mmap_mutex); | ||
766 | vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { | 766 | vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) { |
767 | if (!valid_vma(vma, is_register)) | 767 | if (!valid_vma(vma, is_register)) |
768 | continue; | 768 | continue; |
769 | 769 | ||
770 | existing_vma = 0; | 770 | if (!prev && !more) { |
771 | vaddr = vma_address(vma, offset); | 771 | /* |
772 | 772 | * Needs GFP_NOWAIT to avoid i_mmap_mutex recursion through | |
773 | list_for_each_entry(tmpvi, head, probe_list) { | 773 | * reclaim. This is optimistic, no harm done if it fails. |
774 | if (tmpvi->mm == vma->vm_mm && tmpvi->vaddr == vaddr) { | 774 | */ |
775 | existing_vma = 1; | 775 | prev = kmalloc(sizeof(struct map_info), |
776 | break; | 776 | GFP_NOWAIT | __GFP_NOMEMALLOC | __GFP_NOWARN); |
777 | } | 777 | if (prev) |
778 | prev->next = NULL; | ||
778 | } | 779 | } |
779 | 780 | if (!prev) { | |
780 | /* | 781 | more++; |
781 | * Another vma needs a probe to be installed. However skip | 782 | continue; |
782 | * installing the probe if the vma is about to be unlinked. | ||
783 | */ | ||
784 | if (!existing_vma && atomic_inc_not_zero(&vma->vm_mm->mm_users)) { | ||
785 | vi->mm = vma->vm_mm; | ||
786 | vi->vaddr = vaddr; | ||
787 | list_add(&vi->probe_list, head); | ||
788 | |||
789 | return vi; | ||
790 | } | 783 | } |
791 | } | ||
792 | 784 | ||
793 | return NULL; | 785 | if (!atomic_inc_not_zero(&vma->vm_mm->mm_users)) |
794 | } | 786 | continue; |
795 | |||
796 | /* | ||
797 | * Iterate in the rmap prio tree and find a vma where a probe has not | ||
798 | * yet been inserted. | ||
799 | */ | ||
800 | static struct vma_info * | ||
801 | find_next_vma_info(struct address_space *mapping, struct list_head *head, | ||
802 | loff_t offset, bool is_register) | ||
803 | { | ||
804 | struct vma_info *vi, *retvi; | ||
805 | 787 | ||
806 | vi = kzalloc(sizeof(struct vma_info), GFP_KERNEL); | 788 | info = prev; |
807 | if (!vi) | 789 | prev = prev->next; |
808 | return ERR_PTR(-ENOMEM); | 790 | info->next = curr; |
791 | curr = info; | ||
809 | 792 | ||
810 | mutex_lock(&mapping->i_mmap_mutex); | 793 | info->mm = vma->vm_mm; |
811 | retvi = __find_next_vma_info(mapping, head, vi, offset, is_register); | 794 | info->vaddr = vma_address(vma, offset); |
795 | } | ||
812 | mutex_unlock(&mapping->i_mmap_mutex); | 796 | mutex_unlock(&mapping->i_mmap_mutex); |
813 | 797 | ||
814 | if (!retvi) | 798 | if (!more) |
815 | kfree(vi); | 799 | goto out; |
800 | |||
801 | prev = curr; | ||
802 | while (curr) { | ||
803 | mmput(curr->mm); | ||
804 | curr = curr->next; | ||
805 | } | ||
816 | 806 | ||
817 | return retvi; | 807 | do { |
808 | info = kmalloc(sizeof(struct map_info), GFP_KERNEL); | ||
809 | if (!info) { | ||
810 | curr = ERR_PTR(-ENOMEM); | ||
811 | goto out; | ||
812 | } | ||
813 | info->next = prev; | ||
814 | prev = info; | ||
815 | } while (--more); | ||
816 | |||
817 | goto again; | ||
818 | out: | ||
819 | while (prev) | ||
820 | prev = free_map_info(prev); | ||
821 | return curr; | ||
818 | } | 822 | } |
819 | 823 | ||
820 | static int register_for_each_vma(struct uprobe *uprobe, bool is_register) | 824 | static int register_for_each_vma(struct uprobe *uprobe, bool is_register) |
821 | { | 825 | { |
822 | struct list_head try_list; | 826 | struct map_info *info; |
823 | struct vm_area_struct *vma; | 827 | int err = 0; |
824 | struct address_space *mapping; | ||
825 | struct vma_info *vi, *tmpvi; | ||
826 | struct mm_struct *mm; | ||
827 | loff_t vaddr; | ||
828 | int ret; | ||
829 | 828 | ||
830 | mapping = uprobe->inode->i_mapping; | 829 | info = build_map_info(uprobe->inode->i_mapping, |
831 | INIT_LIST_HEAD(&try_list); | 830 | uprobe->offset, is_register); |
831 | if (IS_ERR(info)) | ||
832 | return PTR_ERR(info); | ||
832 | 833 | ||
833 | ret = 0; | 834 | while (info) { |
835 | struct mm_struct *mm = info->mm; | ||
836 | struct vm_area_struct *vma; | ||
834 | 837 | ||
835 | for (;;) { | 838 | if (err) |
836 | vi = find_next_vma_info(mapping, &try_list, uprobe->offset, is_register); | 839 | goto free; |
837 | if (!vi) | ||
838 | break; | ||
839 | 840 | ||
840 | if (IS_ERR(vi)) { | 841 | down_write(&mm->mmap_sem); |
841 | ret = PTR_ERR(vi); | 842 | vma = find_vma(mm, (unsigned long)info->vaddr); |
842 | break; | 843 | if (!vma || !valid_vma(vma, is_register)) |
843 | } | 844 | goto unlock; |
844 | 845 | ||
845 | mm = vi->mm; | ||
846 | down_read(&mm->mmap_sem); | ||
847 | vma = find_vma(mm, (unsigned long)vi->vaddr); | ||
848 | if (!vma || !valid_vma(vma, is_register)) { | ||
849 | list_del(&vi->probe_list); | ||
850 | kfree(vi); | ||
851 | up_read(&mm->mmap_sem); | ||
852 | mmput(mm); | ||
853 | continue; | ||
854 | } | ||
855 | vaddr = vma_address(vma, uprobe->offset); | ||
856 | if (vma->vm_file->f_mapping->host != uprobe->inode || | 846 | if (vma->vm_file->f_mapping->host != uprobe->inode || |
857 | vaddr != vi->vaddr) { | 847 | vma_address(vma, uprobe->offset) != info->vaddr) |
858 | list_del(&vi->probe_list); | 848 | goto unlock; |
859 | kfree(vi); | ||
860 | up_read(&mm->mmap_sem); | ||
861 | mmput(mm); | ||
862 | continue; | ||
863 | } | ||
864 | |||
865 | if (is_register) | ||
866 | ret = install_breakpoint(uprobe, mm, vma, vi->vaddr); | ||
867 | else | ||
868 | remove_breakpoint(uprobe, mm, vi->vaddr); | ||
869 | 849 | ||
870 | up_read(&mm->mmap_sem); | ||
871 | mmput(mm); | ||
872 | if (is_register) { | 850 | if (is_register) { |
873 | if (ret && ret == -EEXIST) | 851 | err = install_breakpoint(uprobe, mm, vma, info->vaddr); |
874 | ret = 0; | 852 | /* |
875 | if (ret) | 853 | * We can race against uprobe_mmap(), see the |
876 | break; | 854 | * comment near uprobe_hash(). |
855 | */ | ||
856 | if (err == -EEXIST) | ||
857 | err = 0; | ||
858 | } else { | ||
859 | remove_breakpoint(uprobe, mm, info->vaddr); | ||
877 | } | 860 | } |
861 | unlock: | ||
862 | up_write(&mm->mmap_sem); | ||
863 | free: | ||
864 | mmput(mm); | ||
865 | info = free_map_info(info); | ||
878 | } | 866 | } |
879 | 867 | ||
880 | list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) { | 868 | return err; |
881 | list_del(&vi->probe_list); | ||
882 | kfree(vi); | ||
883 | } | ||
884 | |||
885 | return ret; | ||
886 | } | 869 | } |
887 | 870 | ||
888 | static int __uprobe_register(struct uprobe *uprobe) | 871 | static int __uprobe_register(struct uprobe *uprobe) |
@@ -1048,7 +1031,7 @@ static void build_probe_list(struct inode *inode, struct list_head *head) | |||
1048 | int uprobe_mmap(struct vm_area_struct *vma) | 1031 | int uprobe_mmap(struct vm_area_struct *vma) |
1049 | { | 1032 | { |
1050 | struct list_head tmp_list; | 1033 | struct list_head tmp_list; |
1051 | struct uprobe *uprobe, *u; | 1034 | struct uprobe *uprobe; |
1052 | struct inode *inode; | 1035 | struct inode *inode; |
1053 | int ret, count; | 1036 | int ret, count; |
1054 | 1037 | ||
@@ -1066,12 +1049,9 @@ int uprobe_mmap(struct vm_area_struct *vma) | |||
1066 | ret = 0; | 1049 | ret = 0; |
1067 | count = 0; | 1050 | count = 0; |
1068 | 1051 | ||
1069 | list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { | 1052 | list_for_each_entry(uprobe, &tmp_list, pending_list) { |
1070 | loff_t vaddr; | ||
1071 | |||
1072 | list_del(&uprobe->pending_list); | ||
1073 | if (!ret) { | 1053 | if (!ret) { |
1074 | vaddr = vma_address(vma, uprobe->offset); | 1054 | loff_t vaddr = vma_address(vma, uprobe->offset); |
1075 | 1055 | ||
1076 | if (vaddr < vma->vm_start || vaddr >= vma->vm_end) { | 1056 | if (vaddr < vma->vm_start || vaddr >= vma->vm_end) { |
1077 | put_uprobe(uprobe); | 1057 | put_uprobe(uprobe); |
@@ -1079,8 +1059,10 @@ int uprobe_mmap(struct vm_area_struct *vma) | |||
1079 | } | 1059 | } |
1080 | 1060 | ||
1081 | ret = install_breakpoint(uprobe, vma->vm_mm, vma, vaddr); | 1061 | ret = install_breakpoint(uprobe, vma->vm_mm, vma, vaddr); |
1082 | 1062 | /* | |
1083 | /* Ignore double add: */ | 1063 | * We can race against uprobe_register(), see the |
1064 | * comment near uprobe_hash(). | ||
1065 | */ | ||
1084 | if (ret == -EEXIST) { | 1066 | if (ret == -EEXIST) { |
1085 | ret = 0; | 1067 | ret = 0; |
1086 | 1068 | ||
@@ -1115,7 +1097,7 @@ int uprobe_mmap(struct vm_area_struct *vma) | |||
1115 | void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end) | 1097 | void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end) |
1116 | { | 1098 | { |
1117 | struct list_head tmp_list; | 1099 | struct list_head tmp_list; |
1118 | struct uprobe *uprobe, *u; | 1100 | struct uprobe *uprobe; |
1119 | struct inode *inode; | 1101 | struct inode *inode; |
1120 | 1102 | ||
1121 | if (!atomic_read(&uprobe_events) || !valid_vma(vma, false)) | 1103 | if (!atomic_read(&uprobe_events) || !valid_vma(vma, false)) |
@@ -1132,11 +1114,8 @@ void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned lon | |||
1132 | mutex_lock(uprobes_mmap_hash(inode)); | 1114 | mutex_lock(uprobes_mmap_hash(inode)); |
1133 | build_probe_list(inode, &tmp_list); | 1115 | build_probe_list(inode, &tmp_list); |
1134 | 1116 | ||
1135 | list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { | 1117 | list_for_each_entry(uprobe, &tmp_list, pending_list) { |
1136 | loff_t vaddr; | 1118 | loff_t vaddr = vma_address(vma, uprobe->offset); |
1137 | |||
1138 | list_del(&uprobe->pending_list); | ||
1139 | vaddr = vma_address(vma, uprobe->offset); | ||
1140 | 1119 | ||
1141 | if (vaddr >= start && vaddr < end) { | 1120 | if (vaddr >= start && vaddr < end) { |
1142 | /* | 1121 | /* |
@@ -1378,9 +1357,6 @@ void uprobe_free_utask(struct task_struct *t) | |||
1378 | { | 1357 | { |
1379 | struct uprobe_task *utask = t->utask; | 1358 | struct uprobe_task *utask = t->utask; |
1380 | 1359 | ||
1381 | if (t->uprobe_srcu_id != -1) | ||
1382 | srcu_read_unlock_raw(&uprobes_srcu, t->uprobe_srcu_id); | ||
1383 | |||
1384 | if (!utask) | 1360 | if (!utask) |
1385 | return; | 1361 | return; |
1386 | 1362 | ||
@@ -1398,7 +1374,6 @@ void uprobe_free_utask(struct task_struct *t) | |||
1398 | void uprobe_copy_process(struct task_struct *t) | 1374 | void uprobe_copy_process(struct task_struct *t) |
1399 | { | 1375 | { |
1400 | t->utask = NULL; | 1376 | t->utask = NULL; |
1401 | t->uprobe_srcu_id = -1; | ||
1402 | } | 1377 | } |
1403 | 1378 | ||
1404 | /* | 1379 | /* |
@@ -1417,7 +1392,6 @@ static struct uprobe_task *add_utask(void) | |||
1417 | if (unlikely(!utask)) | 1392 | if (unlikely(!utask)) |
1418 | return NULL; | 1393 | return NULL; |
1419 | 1394 | ||
1420 | utask->active_uprobe = NULL; | ||
1421 | current->utask = utask; | 1395 | current->utask = utask; |
1422 | return utask; | 1396 | return utask; |
1423 | } | 1397 | } |
@@ -1479,41 +1453,64 @@ static bool can_skip_sstep(struct uprobe *uprobe, struct pt_regs *regs) | |||
1479 | return false; | 1453 | return false; |
1480 | } | 1454 | } |
1481 | 1455 | ||
1456 | static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) | ||
1457 | { | ||
1458 | struct mm_struct *mm = current->mm; | ||
1459 | struct uprobe *uprobe = NULL; | ||
1460 | struct vm_area_struct *vma; | ||
1461 | |||
1462 | down_read(&mm->mmap_sem); | ||
1463 | vma = find_vma(mm, bp_vaddr); | ||
1464 | if (vma && vma->vm_start <= bp_vaddr) { | ||
1465 | if (valid_vma(vma, false)) { | ||
1466 | struct inode *inode; | ||
1467 | loff_t offset; | ||
1468 | |||
1469 | inode = vma->vm_file->f_mapping->host; | ||
1470 | offset = bp_vaddr - vma->vm_start; | ||
1471 | offset += (vma->vm_pgoff << PAGE_SHIFT); | ||
1472 | uprobe = find_uprobe(inode, offset); | ||
1473 | } | ||
1474 | |||
1475 | if (!uprobe) | ||
1476 | *is_swbp = is_swbp_at_addr(mm, bp_vaddr); | ||
1477 | } else { | ||
1478 | *is_swbp = -EFAULT; | ||
1479 | } | ||
1480 | up_read(&mm->mmap_sem); | ||
1481 | |||
1482 | return uprobe; | ||
1483 | } | ||
1484 | |||
1482 | /* | 1485 | /* |
1483 | * Run handler and ask thread to singlestep. | 1486 | * Run handler and ask thread to singlestep. |
1484 | * Ensure all non-fatal signals cannot interrupt thread while it singlesteps. | 1487 | * Ensure all non-fatal signals cannot interrupt thread while it singlesteps. |
1485 | */ | 1488 | */ |
1486 | static void handle_swbp(struct pt_regs *regs) | 1489 | static void handle_swbp(struct pt_regs *regs) |
1487 | { | 1490 | { |
1488 | struct vm_area_struct *vma; | ||
1489 | struct uprobe_task *utask; | 1491 | struct uprobe_task *utask; |
1490 | struct uprobe *uprobe; | 1492 | struct uprobe *uprobe; |
1491 | struct mm_struct *mm; | ||
1492 | unsigned long bp_vaddr; | 1493 | unsigned long bp_vaddr; |
1494 | int uninitialized_var(is_swbp); | ||
1493 | 1495 | ||
1494 | uprobe = NULL; | ||
1495 | bp_vaddr = uprobe_get_swbp_addr(regs); | 1496 | bp_vaddr = uprobe_get_swbp_addr(regs); |
1496 | mm = current->mm; | 1497 | uprobe = find_active_uprobe(bp_vaddr, &is_swbp); |
1497 | down_read(&mm->mmap_sem); | ||
1498 | vma = find_vma(mm, bp_vaddr); | ||
1499 | |||
1500 | if (vma && vma->vm_start <= bp_vaddr && valid_vma(vma, false)) { | ||
1501 | struct inode *inode; | ||
1502 | loff_t offset; | ||
1503 | |||
1504 | inode = vma->vm_file->f_mapping->host; | ||
1505 | offset = bp_vaddr - vma->vm_start; | ||
1506 | offset += (vma->vm_pgoff << PAGE_SHIFT); | ||
1507 | uprobe = find_uprobe(inode, offset); | ||
1508 | } | ||
1509 | |||
1510 | srcu_read_unlock_raw(&uprobes_srcu, current->uprobe_srcu_id); | ||
1511 | current->uprobe_srcu_id = -1; | ||
1512 | up_read(&mm->mmap_sem); | ||
1513 | 1498 | ||
1514 | if (!uprobe) { | 1499 | if (!uprobe) { |
1515 | /* No matching uprobe; signal SIGTRAP. */ | 1500 | if (is_swbp > 0) { |
1516 | send_sig(SIGTRAP, current, 0); | 1501 | /* No matching uprobe; signal SIGTRAP. */ |
1502 | send_sig(SIGTRAP, current, 0); | ||
1503 | } else { | ||
1504 | /* | ||
1505 | * Either we raced with uprobe_unregister() or we can't | ||
1506 | * access this memory. The latter is only possible if | ||
1507 | * another thread plays with our ->mm. In both cases | ||
1508 | * we can simply restart. If this vma was unmapped we | ||
1509 | * can pretend this insn was not executed yet and get | ||
1510 | * the (correct) SIGSEGV after restart. | ||
1511 | */ | ||
1512 | instruction_pointer_set(regs, bp_vaddr); | ||
1513 | } | ||
1517 | return; | 1514 | return; |
1518 | } | 1515 | } |
1519 | 1516 | ||
@@ -1620,7 +1617,6 @@ int uprobe_pre_sstep_notifier(struct pt_regs *regs) | |||
1620 | utask->state = UTASK_BP_HIT; | 1617 | utask->state = UTASK_BP_HIT; |
1621 | 1618 | ||
1622 | set_thread_flag(TIF_UPROBE); | 1619 | set_thread_flag(TIF_UPROBE); |
1623 | current->uprobe_srcu_id = srcu_read_lock_raw(&uprobes_srcu); | ||
1624 | 1620 | ||
1625 | return 1; | 1621 | return 1; |
1626 | } | 1622 | } |
@@ -1655,7 +1651,6 @@ static int __init init_uprobes(void) | |||
1655 | mutex_init(&uprobes_mutex[i]); | 1651 | mutex_init(&uprobes_mutex[i]); |
1656 | mutex_init(&uprobes_mmap_mutex[i]); | 1652 | mutex_init(&uprobes_mmap_mutex[i]); |
1657 | } | 1653 | } |
1658 | init_srcu_struct(&uprobes_srcu); | ||
1659 | 1654 | ||
1660 | return register_die_notifier(&uprobe_exception_nb); | 1655 | return register_die_notifier(&uprobe_exception_nb); |
1661 | } | 1656 | } |
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 8b53db38a279..238025f5472e 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/syscore_ops.h> | 27 | #include <linux/syscore_ops.h> |
28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
29 | #include <linux/genhd.h> | 29 | #include <linux/genhd.h> |
30 | #include <scsi/scsi_scan.h> | ||
31 | 30 | ||
32 | #include "power.h" | 31 | #include "power.h" |
33 | 32 | ||
@@ -748,13 +747,6 @@ static int software_resume(void) | |||
748 | async_synchronize_full(); | 747 | async_synchronize_full(); |
749 | } | 748 | } |
750 | 749 | ||
751 | /* | ||
752 | * We can't depend on SCSI devices being available after loading | ||
753 | * one of their modules until scsi_complete_async_scans() is | ||
754 | * called and the resume device usually is a SCSI one. | ||
755 | */ | ||
756 | scsi_complete_async_scans(); | ||
757 | |||
758 | swsusp_resume_device = name_to_dev_t(resume_file); | 750 | swsusp_resume_device = name_to_dev_t(resume_file); |
759 | if (!swsusp_resume_device) { | 751 | if (!swsusp_resume_device) { |
760 | error = -ENODEV; | 752 | error = -ENODEV; |
diff --git a/kernel/power/user.c b/kernel/power/user.c index 91b0fd021a95..4ed81e74f86f 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/console.h> | 24 | #include <linux/console.h> |
25 | #include <linux/cpu.h> | 25 | #include <linux/cpu.h> |
26 | #include <linux/freezer.h> | 26 | #include <linux/freezer.h> |
27 | #include <scsi/scsi_scan.h> | ||
28 | 27 | ||
29 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
30 | 29 | ||
@@ -84,7 +83,6 @@ static int snapshot_open(struct inode *inode, struct file *filp) | |||
84 | * appear. | 83 | * appear. |
85 | */ | 84 | */ |
86 | wait_for_device_probe(); | 85 | wait_for_device_probe(); |
87 | scsi_complete_async_scans(); | ||
88 | 86 | ||
89 | data->swap = -1; | 87 | data->swap = -1; |
90 | data->mode = O_WRONLY; | 88 | data->mode = O_WRONLY; |
diff --git a/kernel/printk.c b/kernel/printk.c index 177fa49357a5..ac4bc9e79465 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -1192,21 +1192,6 @@ SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) | |||
1192 | return do_syslog(type, buf, len, SYSLOG_FROM_CALL); | 1192 | return do_syslog(type, buf, len, SYSLOG_FROM_CALL); |
1193 | } | 1193 | } |
1194 | 1194 | ||
1195 | #ifdef CONFIG_KGDB_KDB | ||
1196 | /* kdb dmesg command needs access to the syslog buffer. do_syslog() | ||
1197 | * uses locks so it cannot be used during debugging. Just tell kdb | ||
1198 | * where the start and end of the physical and logical logs are. This | ||
1199 | * is equivalent to do_syslog(3). | ||
1200 | */ | ||
1201 | void kdb_syslog_data(char *syslog_data[4]) | ||
1202 | { | ||
1203 | syslog_data[0] = log_buf; | ||
1204 | syslog_data[1] = log_buf + log_buf_len; | ||
1205 | syslog_data[2] = log_buf + log_first_idx; | ||
1206 | syslog_data[3] = log_buf + log_next_idx; | ||
1207 | } | ||
1208 | #endif /* CONFIG_KGDB_KDB */ | ||
1209 | |||
1210 | static bool __read_mostly ignore_loglevel; | 1195 | static bool __read_mostly ignore_loglevel; |
1211 | 1196 | ||
1212 | static int __init ignore_loglevel_setup(char *str) | 1197 | static int __init ignore_loglevel_setup(char *str) |
@@ -2525,7 +2510,7 @@ void kmsg_dump(enum kmsg_dump_reason reason) | |||
2525 | } | 2510 | } |
2526 | 2511 | ||
2527 | /** | 2512 | /** |
2528 | * kmsg_dump_get_line - retrieve one kmsg log line | 2513 | * kmsg_dump_get_line_nolock - retrieve one kmsg log line (unlocked version) |
2529 | * @dumper: registered kmsg dumper | 2514 | * @dumper: registered kmsg dumper |
2530 | * @syslog: include the "<4>" prefixes | 2515 | * @syslog: include the "<4>" prefixes |
2531 | * @line: buffer to copy the line to | 2516 | * @line: buffer to copy the line to |
@@ -2540,11 +2525,12 @@ void kmsg_dump(enum kmsg_dump_reason reason) | |||
2540 | * | 2525 | * |
2541 | * A return value of FALSE indicates that there are no more records to | 2526 | * A return value of FALSE indicates that there are no more records to |
2542 | * read. | 2527 | * read. |
2528 | * | ||
2529 | * The function is similar to kmsg_dump_get_line(), but grabs no locks. | ||
2543 | */ | 2530 | */ |
2544 | bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, | 2531 | bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog, |
2545 | char *line, size_t size, size_t *len) | 2532 | char *line, size_t size, size_t *len) |
2546 | { | 2533 | { |
2547 | unsigned long flags; | ||
2548 | struct log *msg; | 2534 | struct log *msg; |
2549 | size_t l = 0; | 2535 | size_t l = 0; |
2550 | bool ret = false; | 2536 | bool ret = false; |
@@ -2552,7 +2538,6 @@ bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, | |||
2552 | if (!dumper->active) | 2538 | if (!dumper->active) |
2553 | goto out; | 2539 | goto out; |
2554 | 2540 | ||
2555 | raw_spin_lock_irqsave(&logbuf_lock, flags); | ||
2556 | if (dumper->cur_seq < log_first_seq) { | 2541 | if (dumper->cur_seq < log_first_seq) { |
2557 | /* messages are gone, move to first available one */ | 2542 | /* messages are gone, move to first available one */ |
2558 | dumper->cur_seq = log_first_seq; | 2543 | dumper->cur_seq = log_first_seq; |
@@ -2560,10 +2545,8 @@ bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, | |||
2560 | } | 2545 | } |
2561 | 2546 | ||
2562 | /* last entry */ | 2547 | /* last entry */ |
2563 | if (dumper->cur_seq >= log_next_seq) { | 2548 | if (dumper->cur_seq >= log_next_seq) |
2564 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | ||
2565 | goto out; | 2549 | goto out; |
2566 | } | ||
2567 | 2550 | ||
2568 | msg = log_from_idx(dumper->cur_idx); | 2551 | msg = log_from_idx(dumper->cur_idx); |
2569 | l = msg_print_text(msg, 0, syslog, line, size); | 2552 | l = msg_print_text(msg, 0, syslog, line, size); |
@@ -2571,12 +2554,41 @@ bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, | |||
2571 | dumper->cur_idx = log_next(dumper->cur_idx); | 2554 | dumper->cur_idx = log_next(dumper->cur_idx); |
2572 | dumper->cur_seq++; | 2555 | dumper->cur_seq++; |
2573 | ret = true; | 2556 | ret = true; |
2574 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | ||
2575 | out: | 2557 | out: |
2576 | if (len) | 2558 | if (len) |
2577 | *len = l; | 2559 | *len = l; |
2578 | return ret; | 2560 | return ret; |
2579 | } | 2561 | } |
2562 | |||
2563 | /** | ||
2564 | * kmsg_dump_get_line - retrieve one kmsg log line | ||
2565 | * @dumper: registered kmsg dumper | ||
2566 | * @syslog: include the "<4>" prefixes | ||
2567 | * @line: buffer to copy the line to | ||
2568 | * @size: maximum size of the buffer | ||
2569 | * @len: length of line placed into buffer | ||
2570 | * | ||
2571 | * Start at the beginning of the kmsg buffer, with the oldest kmsg | ||
2572 | * record, and copy one record into the provided buffer. | ||
2573 | * | ||
2574 | * Consecutive calls will return the next available record moving | ||
2575 | * towards the end of the buffer with the youngest messages. | ||
2576 | * | ||
2577 | * A return value of FALSE indicates that there are no more records to | ||
2578 | * read. | ||
2579 | */ | ||
2580 | bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog, | ||
2581 | char *line, size_t size, size_t *len) | ||
2582 | { | ||
2583 | unsigned long flags; | ||
2584 | bool ret; | ||
2585 | |||
2586 | raw_spin_lock_irqsave(&logbuf_lock, flags); | ||
2587 | ret = kmsg_dump_get_line_nolock(dumper, syslog, line, size, len); | ||
2588 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | ||
2589 | |||
2590 | return ret; | ||
2591 | } | ||
2580 | EXPORT_SYMBOL_GPL(kmsg_dump_get_line); | 2592 | EXPORT_SYMBOL_GPL(kmsg_dump_get_line); |
2581 | 2593 | ||
2582 | /** | 2594 | /** |
@@ -2679,6 +2691,24 @@ out: | |||
2679 | EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer); | 2691 | EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer); |
2680 | 2692 | ||
2681 | /** | 2693 | /** |
2694 | * kmsg_dump_rewind_nolock - reset the interator (unlocked version) | ||
2695 | * @dumper: registered kmsg dumper | ||
2696 | * | ||
2697 | * Reset the dumper's iterator so that kmsg_dump_get_line() and | ||
2698 | * kmsg_dump_get_buffer() can be called again and used multiple | ||
2699 | * times within the same dumper.dump() callback. | ||
2700 | * | ||
2701 | * The function is similar to kmsg_dump_rewind(), but grabs no locks. | ||
2702 | */ | ||
2703 | void kmsg_dump_rewind_nolock(struct kmsg_dumper *dumper) | ||
2704 | { | ||
2705 | dumper->cur_seq = clear_seq; | ||
2706 | dumper->cur_idx = clear_idx; | ||
2707 | dumper->next_seq = log_next_seq; | ||
2708 | dumper->next_idx = log_next_idx; | ||
2709 | } | ||
2710 | |||
2711 | /** | ||
2682 | * kmsg_dump_rewind - reset the interator | 2712 | * kmsg_dump_rewind - reset the interator |
2683 | * @dumper: registered kmsg dumper | 2713 | * @dumper: registered kmsg dumper |
2684 | * | 2714 | * |
@@ -2691,10 +2721,7 @@ void kmsg_dump_rewind(struct kmsg_dumper *dumper) | |||
2691 | unsigned long flags; | 2721 | unsigned long flags; |
2692 | 2722 | ||
2693 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 2723 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
2694 | dumper->cur_seq = clear_seq; | 2724 | kmsg_dump_rewind_nolock(dumper); |
2695 | dumper->cur_idx = clear_idx; | ||
2696 | dumper->next_seq = log_next_seq; | ||
2697 | dumper->next_idx = log_next_idx; | ||
2698 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 2725 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
2699 | } | 2726 | } |
2700 | EXPORT_SYMBOL_GPL(kmsg_dump_rewind); | 2727 | EXPORT_SYMBOL_GPL(kmsg_dump_rewind); |
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 95cba41ce1e9..4e6a61b15e86 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
@@ -54,6 +54,50 @@ | |||
54 | #ifdef CONFIG_PREEMPT_RCU | 54 | #ifdef CONFIG_PREEMPT_RCU |
55 | 55 | ||
56 | /* | 56 | /* |
57 | * Preemptible RCU implementation for rcu_read_lock(). | ||
58 | * Just increment ->rcu_read_lock_nesting, shared state will be updated | ||
59 | * if we block. | ||
60 | */ | ||
61 | void __rcu_read_lock(void) | ||
62 | { | ||
63 | current->rcu_read_lock_nesting++; | ||
64 | barrier(); /* critical section after entry code. */ | ||
65 | } | ||
66 | EXPORT_SYMBOL_GPL(__rcu_read_lock); | ||
67 | |||
68 | /* | ||
69 | * Preemptible RCU implementation for rcu_read_unlock(). | ||
70 | * Decrement ->rcu_read_lock_nesting. If the result is zero (outermost | ||
71 | * rcu_read_unlock()) and ->rcu_read_unlock_special is non-zero, then | ||
72 | * invoke rcu_read_unlock_special() to clean up after a context switch | ||
73 | * in an RCU read-side critical section and other special cases. | ||
74 | */ | ||
75 | void __rcu_read_unlock(void) | ||
76 | { | ||
77 | struct task_struct *t = current; | ||
78 | |||
79 | if (t->rcu_read_lock_nesting != 1) { | ||
80 | --t->rcu_read_lock_nesting; | ||
81 | } else { | ||
82 | barrier(); /* critical section before exit code. */ | ||
83 | t->rcu_read_lock_nesting = INT_MIN; | ||
84 | barrier(); /* assign before ->rcu_read_unlock_special load */ | ||
85 | if (unlikely(ACCESS_ONCE(t->rcu_read_unlock_special))) | ||
86 | rcu_read_unlock_special(t); | ||
87 | barrier(); /* ->rcu_read_unlock_special load before assign */ | ||
88 | t->rcu_read_lock_nesting = 0; | ||
89 | } | ||
90 | #ifdef CONFIG_PROVE_LOCKING | ||
91 | { | ||
92 | int rrln = ACCESS_ONCE(t->rcu_read_lock_nesting); | ||
93 | |||
94 | WARN_ON_ONCE(rrln < 0 && rrln > INT_MIN / 2); | ||
95 | } | ||
96 | #endif /* #ifdef CONFIG_PROVE_LOCKING */ | ||
97 | } | ||
98 | EXPORT_SYMBOL_GPL(__rcu_read_unlock); | ||
99 | |||
100 | /* | ||
57 | * Check for a task exiting while in a preemptible-RCU read-side | 101 | * Check for a task exiting while in a preemptible-RCU read-side |
58 | * critical section, clean up if so. No need to issue warnings, | 102 | * critical section, clean up if so. No need to issue warnings, |
59 | * as debug_check_no_locks_held() already does this if lockdep | 103 | * as debug_check_no_locks_held() already does this if lockdep |
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c index 37a5444204d2..547b1fe5b052 100644 --- a/kernel/rcutiny.c +++ b/kernel/rcutiny.c | |||
@@ -172,7 +172,7 @@ void rcu_irq_enter(void) | |||
172 | local_irq_restore(flags); | 172 | local_irq_restore(flags); |
173 | } | 173 | } |
174 | 174 | ||
175 | #ifdef CONFIG_PROVE_RCU | 175 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
176 | 176 | ||
177 | /* | 177 | /* |
178 | * Test whether RCU thinks that the current CPU is idle. | 178 | * Test whether RCU thinks that the current CPU is idle. |
@@ -183,7 +183,7 @@ int rcu_is_cpu_idle(void) | |||
183 | } | 183 | } |
184 | EXPORT_SYMBOL(rcu_is_cpu_idle); | 184 | EXPORT_SYMBOL(rcu_is_cpu_idle); |
185 | 185 | ||
186 | #endif /* #ifdef CONFIG_PROVE_RCU */ | 186 | #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ |
187 | 187 | ||
188 | /* | 188 | /* |
189 | * Test whether the current CPU was interrupted from idle. Nested | 189 | * Test whether the current CPU was interrupted from idle. Nested |
diff --git a/kernel/rcutiny_plugin.h b/kernel/rcutiny_plugin.h index fc31a2d65100..918fd1e8509c 100644 --- a/kernel/rcutiny_plugin.h +++ b/kernel/rcutiny_plugin.h | |||
@@ -132,7 +132,6 @@ static struct rcu_preempt_ctrlblk rcu_preempt_ctrlblk = { | |||
132 | RCU_TRACE(.rcb.name = "rcu_preempt") | 132 | RCU_TRACE(.rcb.name = "rcu_preempt") |
133 | }; | 133 | }; |
134 | 134 | ||
135 | static void rcu_read_unlock_special(struct task_struct *t); | ||
136 | static int rcu_preempted_readers_exp(void); | 135 | static int rcu_preempted_readers_exp(void); |
137 | static void rcu_report_exp_done(void); | 136 | static void rcu_report_exp_done(void); |
138 | 137 | ||
@@ -351,8 +350,9 @@ static int rcu_initiate_boost(void) | |||
351 | rcu_preempt_ctrlblk.boost_tasks = | 350 | rcu_preempt_ctrlblk.boost_tasks = |
352 | rcu_preempt_ctrlblk.gp_tasks; | 351 | rcu_preempt_ctrlblk.gp_tasks; |
353 | invoke_rcu_callbacks(); | 352 | invoke_rcu_callbacks(); |
354 | } else | 353 | } else { |
355 | RCU_TRACE(rcu_initiate_boost_trace()); | 354 | RCU_TRACE(rcu_initiate_boost_trace()); |
355 | } | ||
356 | return 1; | 356 | return 1; |
357 | } | 357 | } |
358 | 358 | ||
@@ -527,23 +527,11 @@ void rcu_preempt_note_context_switch(void) | |||
527 | } | 527 | } |
528 | 528 | ||
529 | /* | 529 | /* |
530 | * Tiny-preemptible RCU implementation for rcu_read_lock(). | ||
531 | * Just increment ->rcu_read_lock_nesting, shared state will be updated | ||
532 | * if we block. | ||
533 | */ | ||
534 | void __rcu_read_lock(void) | ||
535 | { | ||
536 | current->rcu_read_lock_nesting++; | ||
537 | barrier(); /* needed if we ever invoke rcu_read_lock in rcutiny.c */ | ||
538 | } | ||
539 | EXPORT_SYMBOL_GPL(__rcu_read_lock); | ||
540 | |||
541 | /* | ||
542 | * Handle special cases during rcu_read_unlock(), such as needing to | 530 | * Handle special cases during rcu_read_unlock(), such as needing to |
543 | * notify RCU core processing or task having blocked during the RCU | 531 | * notify RCU core processing or task having blocked during the RCU |
544 | * read-side critical section. | 532 | * read-side critical section. |
545 | */ | 533 | */ |
546 | static noinline void rcu_read_unlock_special(struct task_struct *t) | 534 | void rcu_read_unlock_special(struct task_struct *t) |
547 | { | 535 | { |
548 | int empty; | 536 | int empty; |
549 | int empty_exp; | 537 | int empty_exp; |
@@ -627,38 +615,6 @@ static noinline void rcu_read_unlock_special(struct task_struct *t) | |||
627 | } | 615 | } |
628 | 616 | ||
629 | /* | 617 | /* |
630 | * Tiny-preemptible RCU implementation for rcu_read_unlock(). | ||
631 | * Decrement ->rcu_read_lock_nesting. If the result is zero (outermost | ||
632 | * rcu_read_unlock()) and ->rcu_read_unlock_special is non-zero, then | ||
633 | * invoke rcu_read_unlock_special() to clean up after a context switch | ||
634 | * in an RCU read-side critical section and other special cases. | ||
635 | */ | ||
636 | void __rcu_read_unlock(void) | ||
637 | { | ||
638 | struct task_struct *t = current; | ||
639 | |||
640 | barrier(); /* needed if we ever invoke rcu_read_unlock in rcutiny.c */ | ||
641 | if (t->rcu_read_lock_nesting != 1) | ||
642 | --t->rcu_read_lock_nesting; | ||
643 | else { | ||
644 | t->rcu_read_lock_nesting = INT_MIN; | ||
645 | barrier(); /* assign before ->rcu_read_unlock_special load */ | ||
646 | if (unlikely(ACCESS_ONCE(t->rcu_read_unlock_special))) | ||
647 | rcu_read_unlock_special(t); | ||
648 | barrier(); /* ->rcu_read_unlock_special load before assign */ | ||
649 | t->rcu_read_lock_nesting = 0; | ||
650 | } | ||
651 | #ifdef CONFIG_PROVE_LOCKING | ||
652 | { | ||
653 | int rrln = ACCESS_ONCE(t->rcu_read_lock_nesting); | ||
654 | |||
655 | WARN_ON_ONCE(rrln < 0 && rrln > INT_MIN / 2); | ||
656 | } | ||
657 | #endif /* #ifdef CONFIG_PROVE_LOCKING */ | ||
658 | } | ||
659 | EXPORT_SYMBOL_GPL(__rcu_read_unlock); | ||
660 | |||
661 | /* | ||
662 | * Check for a quiescent state from the current CPU. When a task blocks, | 618 | * Check for a quiescent state from the current CPU. When a task blocks, |
663 | * the task is recorded in the rcu_preempt_ctrlblk structure, which is | 619 | * the task is recorded in the rcu_preempt_ctrlblk structure, which is |
664 | * checked elsewhere. This is called from the scheduling-clock interrupt. | 620 | * checked elsewhere. This is called from the scheduling-clock interrupt. |
@@ -823,9 +779,9 @@ void synchronize_rcu_expedited(void) | |||
823 | rpcp->exp_tasks = NULL; | 779 | rpcp->exp_tasks = NULL; |
824 | 780 | ||
825 | /* Wait for tail of ->blkd_tasks list to drain. */ | 781 | /* Wait for tail of ->blkd_tasks list to drain. */ |
826 | if (!rcu_preempted_readers_exp()) | 782 | if (!rcu_preempted_readers_exp()) { |
827 | local_irq_restore(flags); | 783 | local_irq_restore(flags); |
828 | else { | 784 | } else { |
829 | rcu_initiate_boost(); | 785 | rcu_initiate_boost(); |
830 | local_irq_restore(flags); | 786 | local_irq_restore(flags); |
831 | wait_event(sync_rcu_preempt_exp_wq, | 787 | wait_event(sync_rcu_preempt_exp_wq, |
@@ -846,8 +802,6 @@ EXPORT_SYMBOL_GPL(synchronize_rcu_expedited); | |||
846 | */ | 802 | */ |
847 | int rcu_preempt_needs_cpu(void) | 803 | int rcu_preempt_needs_cpu(void) |
848 | { | 804 | { |
849 | if (!rcu_preempt_running_reader()) | ||
850 | rcu_preempt_cpu_qs(); | ||
851 | return rcu_preempt_ctrlblk.rcb.rcucblist != NULL; | 805 | return rcu_preempt_ctrlblk.rcb.rcucblist != NULL; |
852 | } | 806 | } |
853 | 807 | ||
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index e66b34ab7555..25b15033c61f 100644 --- a/kernel/rcutorture.c +++ b/kernel/rcutorture.c | |||
@@ -49,8 +49,7 @@ | |||
49 | #include <asm/byteorder.h> | 49 | #include <asm/byteorder.h> |
50 | 50 | ||
51 | MODULE_LICENSE("GPL"); | 51 | MODULE_LICENSE("GPL"); |
52 | MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and " | 52 | MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and Josh Triplett <josh@freedesktop.org>"); |
53 | "Josh Triplett <josh@freedesktop.org>"); | ||
54 | 53 | ||
55 | static int nreaders = -1; /* # reader threads, defaults to 2*ncpus */ | 54 | static int nreaders = -1; /* # reader threads, defaults to 2*ncpus */ |
56 | static int nfakewriters = 4; /* # fake writer threads */ | 55 | static int nfakewriters = 4; /* # fake writer threads */ |
@@ -206,6 +205,7 @@ static unsigned long boost_starttime; /* jiffies of next boost test start. */ | |||
206 | DEFINE_MUTEX(boost_mutex); /* protect setting boost_starttime */ | 205 | DEFINE_MUTEX(boost_mutex); /* protect setting boost_starttime */ |
207 | /* and boost task create/destroy. */ | 206 | /* and boost task create/destroy. */ |
208 | static atomic_t barrier_cbs_count; /* Barrier callbacks registered. */ | 207 | static atomic_t barrier_cbs_count; /* Barrier callbacks registered. */ |
208 | static bool barrier_phase; /* Test phase. */ | ||
209 | static atomic_t barrier_cbs_invoked; /* Barrier callbacks invoked. */ | 209 | static atomic_t barrier_cbs_invoked; /* Barrier callbacks invoked. */ |
210 | static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */ | 210 | static wait_queue_head_t *barrier_cbs_wq; /* Coordinate barrier testing. */ |
211 | static DECLARE_WAIT_QUEUE_HEAD(barrier_wq); | 211 | static DECLARE_WAIT_QUEUE_HEAD(barrier_wq); |
@@ -407,8 +407,9 @@ rcu_torture_cb(struct rcu_head *p) | |||
407 | if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) { | 407 | if (++rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) { |
408 | rp->rtort_mbtest = 0; | 408 | rp->rtort_mbtest = 0; |
409 | rcu_torture_free(rp); | 409 | rcu_torture_free(rp); |
410 | } else | 410 | } else { |
411 | cur_ops->deferred_free(rp); | 411 | cur_ops->deferred_free(rp); |
412 | } | ||
412 | } | 413 | } |
413 | 414 | ||
414 | static int rcu_no_completed(void) | 415 | static int rcu_no_completed(void) |
@@ -635,6 +636,17 @@ static void srcu_torture_synchronize(void) | |||
635 | synchronize_srcu(&srcu_ctl); | 636 | synchronize_srcu(&srcu_ctl); |
636 | } | 637 | } |
637 | 638 | ||
639 | static void srcu_torture_call(struct rcu_head *head, | ||
640 | void (*func)(struct rcu_head *head)) | ||
641 | { | ||
642 | call_srcu(&srcu_ctl, head, func); | ||
643 | } | ||
644 | |||
645 | static void srcu_torture_barrier(void) | ||
646 | { | ||
647 | srcu_barrier(&srcu_ctl); | ||
648 | } | ||
649 | |||
638 | static int srcu_torture_stats(char *page) | 650 | static int srcu_torture_stats(char *page) |
639 | { | 651 | { |
640 | int cnt = 0; | 652 | int cnt = 0; |
@@ -661,8 +673,8 @@ static struct rcu_torture_ops srcu_ops = { | |||
661 | .completed = srcu_torture_completed, | 673 | .completed = srcu_torture_completed, |
662 | .deferred_free = srcu_torture_deferred_free, | 674 | .deferred_free = srcu_torture_deferred_free, |
663 | .sync = srcu_torture_synchronize, | 675 | .sync = srcu_torture_synchronize, |
664 | .call = NULL, | 676 | .call = srcu_torture_call, |
665 | .cb_barrier = NULL, | 677 | .cb_barrier = srcu_torture_barrier, |
666 | .stats = srcu_torture_stats, | 678 | .stats = srcu_torture_stats, |
667 | .name = "srcu" | 679 | .name = "srcu" |
668 | }; | 680 | }; |
@@ -1013,7 +1025,11 @@ rcu_torture_fakewriter(void *arg) | |||
1013 | do { | 1025 | do { |
1014 | schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10); | 1026 | schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10); |
1015 | udelay(rcu_random(&rand) & 0x3ff); | 1027 | udelay(rcu_random(&rand) & 0x3ff); |
1016 | cur_ops->sync(); | 1028 | if (cur_ops->cb_barrier != NULL && |
1029 | rcu_random(&rand) % (nfakewriters * 8) == 0) | ||
1030 | cur_ops->cb_barrier(); | ||
1031 | else | ||
1032 | cur_ops->sync(); | ||
1017 | rcu_stutter_wait("rcu_torture_fakewriter"); | 1033 | rcu_stutter_wait("rcu_torture_fakewriter"); |
1018 | } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); | 1034 | } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); |
1019 | 1035 | ||
@@ -1183,27 +1199,27 @@ rcu_torture_printk(char *page) | |||
1183 | } | 1199 | } |
1184 | cnt += sprintf(&page[cnt], "%s%s ", torture_type, TORTURE_FLAG); | 1200 | cnt += sprintf(&page[cnt], "%s%s ", torture_type, TORTURE_FLAG); |
1185 | cnt += sprintf(&page[cnt], | 1201 | cnt += sprintf(&page[cnt], |
1186 | "rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d " | 1202 | "rtc: %p ver: %lu tfle: %d rta: %d rtaf: %d rtf: %d ", |
1187 | "rtmbe: %d rtbke: %ld rtbre: %ld " | ||
1188 | "rtbf: %ld rtb: %ld nt: %ld " | ||
1189 | "onoff: %ld/%ld:%ld/%ld " | ||
1190 | "barrier: %ld/%ld:%ld", | ||
1191 | rcu_torture_current, | 1203 | rcu_torture_current, |
1192 | rcu_torture_current_version, | 1204 | rcu_torture_current_version, |
1193 | list_empty(&rcu_torture_freelist), | 1205 | list_empty(&rcu_torture_freelist), |
1194 | atomic_read(&n_rcu_torture_alloc), | 1206 | atomic_read(&n_rcu_torture_alloc), |
1195 | atomic_read(&n_rcu_torture_alloc_fail), | 1207 | atomic_read(&n_rcu_torture_alloc_fail), |
1196 | atomic_read(&n_rcu_torture_free), | 1208 | atomic_read(&n_rcu_torture_free)); |
1209 | cnt += sprintf(&page[cnt], "rtmbe: %d rtbke: %ld rtbre: %ld ", | ||
1197 | atomic_read(&n_rcu_torture_mberror), | 1210 | atomic_read(&n_rcu_torture_mberror), |
1198 | n_rcu_torture_boost_ktrerror, | 1211 | n_rcu_torture_boost_ktrerror, |
1199 | n_rcu_torture_boost_rterror, | 1212 | n_rcu_torture_boost_rterror); |
1213 | cnt += sprintf(&page[cnt], "rtbf: %ld rtb: %ld nt: %ld ", | ||
1200 | n_rcu_torture_boost_failure, | 1214 | n_rcu_torture_boost_failure, |
1201 | n_rcu_torture_boosts, | 1215 | n_rcu_torture_boosts, |
1202 | n_rcu_torture_timers, | 1216 | n_rcu_torture_timers); |
1217 | cnt += sprintf(&page[cnt], "onoff: %ld/%ld:%ld/%ld ", | ||
1203 | n_online_successes, | 1218 | n_online_successes, |
1204 | n_online_attempts, | 1219 | n_online_attempts, |
1205 | n_offline_successes, | 1220 | n_offline_successes, |
1206 | n_offline_attempts, | 1221 | n_offline_attempts); |
1222 | cnt += sprintf(&page[cnt], "barrier: %ld/%ld:%ld", | ||
1207 | n_barrier_successes, | 1223 | n_barrier_successes, |
1208 | n_barrier_attempts, | 1224 | n_barrier_attempts, |
1209 | n_rcu_torture_barrier_error); | 1225 | n_rcu_torture_barrier_error); |
@@ -1445,8 +1461,7 @@ rcu_torture_shutdown(void *arg) | |||
1445 | delta = shutdown_time - jiffies_snap; | 1461 | delta = shutdown_time - jiffies_snap; |
1446 | if (verbose) | 1462 | if (verbose) |
1447 | printk(KERN_ALERT "%s" TORTURE_FLAG | 1463 | printk(KERN_ALERT "%s" TORTURE_FLAG |
1448 | "rcu_torture_shutdown task: %lu " | 1464 | "rcu_torture_shutdown task: %lu jiffies remaining\n", |
1449 | "jiffies remaining\n", | ||
1450 | torture_type, delta); | 1465 | torture_type, delta); |
1451 | schedule_timeout_interruptible(delta); | 1466 | schedule_timeout_interruptible(delta); |
1452 | jiffies_snap = ACCESS_ONCE(jiffies); | 1467 | jiffies_snap = ACCESS_ONCE(jiffies); |
@@ -1498,8 +1513,7 @@ rcu_torture_onoff(void *arg) | |||
1498 | if (cpu_down(cpu) == 0) { | 1513 | if (cpu_down(cpu) == 0) { |
1499 | if (verbose) | 1514 | if (verbose) |
1500 | printk(KERN_ALERT "%s" TORTURE_FLAG | 1515 | printk(KERN_ALERT "%s" TORTURE_FLAG |
1501 | "rcu_torture_onoff task: " | 1516 | "rcu_torture_onoff task: offlined %d\n", |
1502 | "offlined %d\n", | ||
1503 | torture_type, cpu); | 1517 | torture_type, cpu); |
1504 | n_offline_successes++; | 1518 | n_offline_successes++; |
1505 | } | 1519 | } |
@@ -1512,8 +1526,7 @@ rcu_torture_onoff(void *arg) | |||
1512 | if (cpu_up(cpu) == 0) { | 1526 | if (cpu_up(cpu) == 0) { |
1513 | if (verbose) | 1527 | if (verbose) |
1514 | printk(KERN_ALERT "%s" TORTURE_FLAG | 1528 | printk(KERN_ALERT "%s" TORTURE_FLAG |
1515 | "rcu_torture_onoff task: " | 1529 | "rcu_torture_onoff task: onlined %d\n", |
1516 | "onlined %d\n", | ||
1517 | torture_type, cpu); | 1530 | torture_type, cpu); |
1518 | n_online_successes++; | 1531 | n_online_successes++; |
1519 | } | 1532 | } |
@@ -1631,6 +1644,7 @@ void rcu_torture_barrier_cbf(struct rcu_head *rcu) | |||
1631 | static int rcu_torture_barrier_cbs(void *arg) | 1644 | static int rcu_torture_barrier_cbs(void *arg) |
1632 | { | 1645 | { |
1633 | long myid = (long)arg; | 1646 | long myid = (long)arg; |
1647 | bool lastphase = 0; | ||
1634 | struct rcu_head rcu; | 1648 | struct rcu_head rcu; |
1635 | 1649 | ||
1636 | init_rcu_head_on_stack(&rcu); | 1650 | init_rcu_head_on_stack(&rcu); |
@@ -1638,9 +1652,11 @@ static int rcu_torture_barrier_cbs(void *arg) | |||
1638 | set_user_nice(current, 19); | 1652 | set_user_nice(current, 19); |
1639 | do { | 1653 | do { |
1640 | wait_event(barrier_cbs_wq[myid], | 1654 | wait_event(barrier_cbs_wq[myid], |
1641 | atomic_read(&barrier_cbs_count) == n_barrier_cbs || | 1655 | barrier_phase != lastphase || |
1642 | kthread_should_stop() || | 1656 | kthread_should_stop() || |
1643 | fullstop != FULLSTOP_DONTSTOP); | 1657 | fullstop != FULLSTOP_DONTSTOP); |
1658 | lastphase = barrier_phase; | ||
1659 | smp_mb(); /* ensure barrier_phase load before ->call(). */ | ||
1644 | if (kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP) | 1660 | if (kthread_should_stop() || fullstop != FULLSTOP_DONTSTOP) |
1645 | break; | 1661 | break; |
1646 | cur_ops->call(&rcu, rcu_torture_barrier_cbf); | 1662 | cur_ops->call(&rcu, rcu_torture_barrier_cbf); |
@@ -1665,7 +1681,8 @@ static int rcu_torture_barrier(void *arg) | |||
1665 | do { | 1681 | do { |
1666 | atomic_set(&barrier_cbs_invoked, 0); | 1682 | atomic_set(&barrier_cbs_invoked, 0); |
1667 | atomic_set(&barrier_cbs_count, n_barrier_cbs); | 1683 | atomic_set(&barrier_cbs_count, n_barrier_cbs); |
1668 | /* wake_up() path contains the required barriers. */ | 1684 | smp_mb(); /* Ensure barrier_phase after prior assignments. */ |
1685 | barrier_phase = !barrier_phase; | ||
1669 | for (i = 0; i < n_barrier_cbs; i++) | 1686 | for (i = 0; i < n_barrier_cbs; i++) |
1670 | wake_up(&barrier_cbs_wq[i]); | 1687 | wake_up(&barrier_cbs_wq[i]); |
1671 | wait_event(barrier_wq, | 1688 | wait_event(barrier_wq, |
@@ -1684,7 +1701,7 @@ static int rcu_torture_barrier(void *arg) | |||
1684 | schedule_timeout_interruptible(HZ / 10); | 1701 | schedule_timeout_interruptible(HZ / 10); |
1685 | } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); | 1702 | } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP); |
1686 | VERBOSE_PRINTK_STRING("rcu_torture_barrier task stopping"); | 1703 | VERBOSE_PRINTK_STRING("rcu_torture_barrier task stopping"); |
1687 | rcutorture_shutdown_absorb("rcu_torture_barrier_cbs"); | 1704 | rcutorture_shutdown_absorb("rcu_torture_barrier"); |
1688 | while (!kthread_should_stop()) | 1705 | while (!kthread_should_stop()) |
1689 | schedule_timeout_interruptible(1); | 1706 | schedule_timeout_interruptible(1); |
1690 | return 0; | 1707 | return 0; |
@@ -1908,8 +1925,8 @@ rcu_torture_init(void) | |||
1908 | static struct rcu_torture_ops *torture_ops[] = | 1925 | static struct rcu_torture_ops *torture_ops[] = |
1909 | { &rcu_ops, &rcu_sync_ops, &rcu_expedited_ops, | 1926 | { &rcu_ops, &rcu_sync_ops, &rcu_expedited_ops, |
1910 | &rcu_bh_ops, &rcu_bh_sync_ops, &rcu_bh_expedited_ops, | 1927 | &rcu_bh_ops, &rcu_bh_sync_ops, &rcu_bh_expedited_ops, |
1911 | &srcu_ops, &srcu_sync_ops, &srcu_raw_ops, | 1928 | &srcu_ops, &srcu_sync_ops, &srcu_expedited_ops, |
1912 | &srcu_raw_sync_ops, &srcu_expedited_ops, | 1929 | &srcu_raw_ops, &srcu_raw_sync_ops, |
1913 | &sched_ops, &sched_sync_ops, &sched_expedited_ops, }; | 1930 | &sched_ops, &sched_sync_ops, &sched_expedited_ops, }; |
1914 | 1931 | ||
1915 | mutex_lock(&fullstop_mutex); | 1932 | mutex_lock(&fullstop_mutex); |
@@ -1931,8 +1948,7 @@ rcu_torture_init(void) | |||
1931 | return -EINVAL; | 1948 | return -EINVAL; |
1932 | } | 1949 | } |
1933 | if (cur_ops->fqs == NULL && fqs_duration != 0) { | 1950 | if (cur_ops->fqs == NULL && fqs_duration != 0) { |
1934 | printk(KERN_ALERT "rcu-torture: ->fqs NULL and non-zero " | 1951 | printk(KERN_ALERT "rcu-torture: ->fqs NULL and non-zero fqs_duration, fqs disabled.\n"); |
1935 | "fqs_duration, fqs disabled.\n"); | ||
1936 | fqs_duration = 0; | 1952 | fqs_duration = 0; |
1937 | } | 1953 | } |
1938 | if (cur_ops->init) | 1954 | if (cur_ops->init) |
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 4b97bba7396e..f280e542e3e9 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -60,36 +60,44 @@ | |||
60 | 60 | ||
61 | /* Data structures. */ | 61 | /* Data structures. */ |
62 | 62 | ||
63 | static struct lock_class_key rcu_node_class[NUM_RCU_LVLS]; | 63 | static struct lock_class_key rcu_node_class[RCU_NUM_LVLS]; |
64 | 64 | ||
65 | #define RCU_STATE_INITIALIZER(structname) { \ | 65 | #define RCU_STATE_INITIALIZER(sname, cr) { \ |
66 | .level = { &structname##_state.node[0] }, \ | 66 | .level = { &sname##_state.node[0] }, \ |
67 | .levelcnt = { \ | 67 | .call = cr, \ |
68 | NUM_RCU_LVL_0, /* root of hierarchy. */ \ | ||
69 | NUM_RCU_LVL_1, \ | ||
70 | NUM_RCU_LVL_2, \ | ||
71 | NUM_RCU_LVL_3, \ | ||
72 | NUM_RCU_LVL_4, /* == MAX_RCU_LVLS */ \ | ||
73 | }, \ | ||
74 | .fqs_state = RCU_GP_IDLE, \ | 68 | .fqs_state = RCU_GP_IDLE, \ |
75 | .gpnum = -300, \ | 69 | .gpnum = -300, \ |
76 | .completed = -300, \ | 70 | .completed = -300, \ |
77 | .onofflock = __RAW_SPIN_LOCK_UNLOCKED(&structname##_state.onofflock), \ | 71 | .onofflock = __RAW_SPIN_LOCK_UNLOCKED(&sname##_state.onofflock), \ |
78 | .orphan_nxttail = &structname##_state.orphan_nxtlist, \ | 72 | .orphan_nxttail = &sname##_state.orphan_nxtlist, \ |
79 | .orphan_donetail = &structname##_state.orphan_donelist, \ | 73 | .orphan_donetail = &sname##_state.orphan_donelist, \ |
80 | .fqslock = __RAW_SPIN_LOCK_UNLOCKED(&structname##_state.fqslock), \ | 74 | .barrier_mutex = __MUTEX_INITIALIZER(sname##_state.barrier_mutex), \ |
81 | .n_force_qs = 0, \ | 75 | .fqslock = __RAW_SPIN_LOCK_UNLOCKED(&sname##_state.fqslock), \ |
82 | .n_force_qs_ngp = 0, \ | 76 | .name = #sname, \ |
83 | .name = #structname, \ | ||
84 | } | 77 | } |
85 | 78 | ||
86 | struct rcu_state rcu_sched_state = RCU_STATE_INITIALIZER(rcu_sched); | 79 | struct rcu_state rcu_sched_state = |
80 | RCU_STATE_INITIALIZER(rcu_sched, call_rcu_sched); | ||
87 | DEFINE_PER_CPU(struct rcu_data, rcu_sched_data); | 81 | DEFINE_PER_CPU(struct rcu_data, rcu_sched_data); |
88 | 82 | ||
89 | struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh); | 83 | struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh, call_rcu_bh); |
90 | DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); | 84 | DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); |
91 | 85 | ||
92 | static struct rcu_state *rcu_state; | 86 | static struct rcu_state *rcu_state; |
87 | LIST_HEAD(rcu_struct_flavors); | ||
88 | |||
89 | /* Increase (but not decrease) the CONFIG_RCU_FANOUT_LEAF at boot time. */ | ||
90 | static int rcu_fanout_leaf = CONFIG_RCU_FANOUT_LEAF; | ||
91 | module_param(rcu_fanout_leaf, int, 0); | ||
92 | int rcu_num_lvls __read_mostly = RCU_NUM_LVLS; | ||
93 | static int num_rcu_lvl[] = { /* Number of rcu_nodes at specified level. */ | ||
94 | NUM_RCU_LVL_0, | ||
95 | NUM_RCU_LVL_1, | ||
96 | NUM_RCU_LVL_2, | ||
97 | NUM_RCU_LVL_3, | ||
98 | NUM_RCU_LVL_4, | ||
99 | }; | ||
100 | int rcu_num_nodes __read_mostly = NUM_RCU_NODES; /* Total # rcu_nodes in use. */ | ||
93 | 101 | ||
94 | /* | 102 | /* |
95 | * The rcu_scheduler_active variable transitions from zero to one just | 103 | * The rcu_scheduler_active variable transitions from zero to one just |
@@ -147,13 +155,6 @@ static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp); | |||
147 | unsigned long rcutorture_testseq; | 155 | unsigned long rcutorture_testseq; |
148 | unsigned long rcutorture_vernum; | 156 | unsigned long rcutorture_vernum; |
149 | 157 | ||
150 | /* State information for rcu_barrier() and friends. */ | ||
151 | |||
152 | static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL}; | ||
153 | static atomic_t rcu_barrier_cpu_count; | ||
154 | static DEFINE_MUTEX(rcu_barrier_mutex); | ||
155 | static struct completion rcu_barrier_completion; | ||
156 | |||
157 | /* | 158 | /* |
158 | * Return true if an RCU grace period is in progress. The ACCESS_ONCE()s | 159 | * Return true if an RCU grace period is in progress. The ACCESS_ONCE()s |
159 | * permit this function to be invoked without holding the root rcu_node | 160 | * permit this function to be invoked without holding the root rcu_node |
@@ -358,7 +359,7 @@ static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval) | |||
358 | struct task_struct *idle = idle_task(smp_processor_id()); | 359 | struct task_struct *idle = idle_task(smp_processor_id()); |
359 | 360 | ||
360 | trace_rcu_dyntick("Error on entry: not idle task", oldval, 0); | 361 | trace_rcu_dyntick("Error on entry: not idle task", oldval, 0); |
361 | ftrace_dump(DUMP_ALL); | 362 | ftrace_dump(DUMP_ORIG); |
362 | WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s", | 363 | WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s", |
363 | current->pid, current->comm, | 364 | current->pid, current->comm, |
364 | idle->pid, idle->comm); /* must be idle task! */ | 365 | idle->pid, idle->comm); /* must be idle task! */ |
@@ -468,7 +469,7 @@ static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval) | |||
468 | 469 | ||
469 | trace_rcu_dyntick("Error on exit: not idle task", | 470 | trace_rcu_dyntick("Error on exit: not idle task", |
470 | oldval, rdtp->dynticks_nesting); | 471 | oldval, rdtp->dynticks_nesting); |
471 | ftrace_dump(DUMP_ALL); | 472 | ftrace_dump(DUMP_ORIG); |
472 | WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s", | 473 | WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s", |
473 | current->pid, current->comm, | 474 | current->pid, current->comm, |
474 | idle->pid, idle->comm); /* must be idle task! */ | 475 | idle->pid, idle->comm); /* must be idle task! */ |
@@ -585,8 +586,6 @@ void rcu_nmi_exit(void) | |||
585 | WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1); | 586 | WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1); |
586 | } | 587 | } |
587 | 588 | ||
588 | #ifdef CONFIG_PROVE_RCU | ||
589 | |||
590 | /** | 589 | /** |
591 | * rcu_is_cpu_idle - see if RCU thinks that the current CPU is idle | 590 | * rcu_is_cpu_idle - see if RCU thinks that the current CPU is idle |
592 | * | 591 | * |
@@ -604,7 +603,7 @@ int rcu_is_cpu_idle(void) | |||
604 | } | 603 | } |
605 | EXPORT_SYMBOL(rcu_is_cpu_idle); | 604 | EXPORT_SYMBOL(rcu_is_cpu_idle); |
606 | 605 | ||
607 | #ifdef CONFIG_HOTPLUG_CPU | 606 | #if defined(CONFIG_PROVE_RCU) && defined(CONFIG_HOTPLUG_CPU) |
608 | 607 | ||
609 | /* | 608 | /* |
610 | * Is the current CPU online? Disable preemption to avoid false positives | 609 | * Is the current CPU online? Disable preemption to avoid false positives |
@@ -645,9 +644,7 @@ bool rcu_lockdep_current_cpu_online(void) | |||
645 | } | 644 | } |
646 | EXPORT_SYMBOL_GPL(rcu_lockdep_current_cpu_online); | 645 | EXPORT_SYMBOL_GPL(rcu_lockdep_current_cpu_online); |
647 | 646 | ||
648 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | 647 | #endif /* #if defined(CONFIG_PROVE_RCU) && defined(CONFIG_HOTPLUG_CPU) */ |
649 | |||
650 | #endif /* #ifdef CONFIG_PROVE_RCU */ | ||
651 | 648 | ||
652 | /** | 649 | /** |
653 | * rcu_is_cpu_rrupt_from_idle - see if idle or immediately interrupted from idle | 650 | * rcu_is_cpu_rrupt_from_idle - see if idle or immediately interrupted from idle |
@@ -733,7 +730,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp) | |||
733 | int cpu; | 730 | int cpu; |
734 | long delta; | 731 | long delta; |
735 | unsigned long flags; | 732 | unsigned long flags; |
736 | int ndetected; | 733 | int ndetected = 0; |
737 | struct rcu_node *rnp = rcu_get_root(rsp); | 734 | struct rcu_node *rnp = rcu_get_root(rsp); |
738 | 735 | ||
739 | /* Only let one CPU complain about others per time interval. */ | 736 | /* Only let one CPU complain about others per time interval. */ |
@@ -774,7 +771,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp) | |||
774 | */ | 771 | */ |
775 | rnp = rcu_get_root(rsp); | 772 | rnp = rcu_get_root(rsp); |
776 | raw_spin_lock_irqsave(&rnp->lock, flags); | 773 | raw_spin_lock_irqsave(&rnp->lock, flags); |
777 | ndetected = rcu_print_task_stall(rnp); | 774 | ndetected += rcu_print_task_stall(rnp); |
778 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | 775 | raw_spin_unlock_irqrestore(&rnp->lock, flags); |
779 | 776 | ||
780 | print_cpu_stall_info_end(); | 777 | print_cpu_stall_info_end(); |
@@ -860,9 +857,10 @@ static int rcu_panic(struct notifier_block *this, unsigned long ev, void *ptr) | |||
860 | */ | 857 | */ |
861 | void rcu_cpu_stall_reset(void) | 858 | void rcu_cpu_stall_reset(void) |
862 | { | 859 | { |
863 | rcu_sched_state.jiffies_stall = jiffies + ULONG_MAX / 2; | 860 | struct rcu_state *rsp; |
864 | rcu_bh_state.jiffies_stall = jiffies + ULONG_MAX / 2; | 861 | |
865 | rcu_preempt_stall_reset(); | 862 | for_each_rcu_flavor(rsp) |
863 | rsp->jiffies_stall = jiffies + ULONG_MAX / 2; | ||
866 | } | 864 | } |
867 | 865 | ||
868 | static struct notifier_block rcu_panic_block = { | 866 | static struct notifier_block rcu_panic_block = { |
@@ -894,8 +892,9 @@ static void __note_new_gpnum(struct rcu_state *rsp, struct rcu_node *rnp, struct | |||
894 | if (rnp->qsmask & rdp->grpmask) { | 892 | if (rnp->qsmask & rdp->grpmask) { |
895 | rdp->qs_pending = 1; | 893 | rdp->qs_pending = 1; |
896 | rdp->passed_quiesce = 0; | 894 | rdp->passed_quiesce = 0; |
897 | } else | 895 | } else { |
898 | rdp->qs_pending = 0; | 896 | rdp->qs_pending = 0; |
897 | } | ||
899 | zero_cpu_stall_ticks(rdp); | 898 | zero_cpu_stall_ticks(rdp); |
900 | } | 899 | } |
901 | } | 900 | } |
@@ -937,6 +936,18 @@ check_for_new_grace_period(struct rcu_state *rsp, struct rcu_data *rdp) | |||
937 | } | 936 | } |
938 | 937 | ||
939 | /* | 938 | /* |
939 | * Initialize the specified rcu_data structure's callback list to empty. | ||
940 | */ | ||
941 | static void init_callback_list(struct rcu_data *rdp) | ||
942 | { | ||
943 | int i; | ||
944 | |||
945 | rdp->nxtlist = NULL; | ||
946 | for (i = 0; i < RCU_NEXT_SIZE; i++) | ||
947 | rdp->nxttail[i] = &rdp->nxtlist; | ||
948 | } | ||
949 | |||
950 | /* | ||
940 | * Advance this CPU's callbacks, but only if the current grace period | 951 | * Advance this CPU's callbacks, but only if the current grace period |
941 | * has ended. This may be called only from the CPU to whom the rdp | 952 | * has ended. This may be called only from the CPU to whom the rdp |
942 | * belongs. In addition, the corresponding leaf rcu_node structure's | 953 | * belongs. In addition, the corresponding leaf rcu_node structure's |
@@ -1328,8 +1339,6 @@ static void | |||
1328 | rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp, | 1339 | rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp, |
1329 | struct rcu_node *rnp, struct rcu_data *rdp) | 1340 | struct rcu_node *rnp, struct rcu_data *rdp) |
1330 | { | 1341 | { |
1331 | int i; | ||
1332 | |||
1333 | /* | 1342 | /* |
1334 | * Orphan the callbacks. First adjust the counts. This is safe | 1343 | * Orphan the callbacks. First adjust the counts. This is safe |
1335 | * because ->onofflock excludes _rcu_barrier()'s adoption of | 1344 | * because ->onofflock excludes _rcu_barrier()'s adoption of |
@@ -1340,7 +1349,7 @@ rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp, | |||
1340 | rsp->qlen += rdp->qlen; | 1349 | rsp->qlen += rdp->qlen; |
1341 | rdp->n_cbs_orphaned += rdp->qlen; | 1350 | rdp->n_cbs_orphaned += rdp->qlen; |
1342 | rdp->qlen_lazy = 0; | 1351 | rdp->qlen_lazy = 0; |
1343 | rdp->qlen = 0; | 1352 | ACCESS_ONCE(rdp->qlen) = 0; |
1344 | } | 1353 | } |
1345 | 1354 | ||
1346 | /* | 1355 | /* |
@@ -1369,9 +1378,7 @@ rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp, | |||
1369 | } | 1378 | } |
1370 | 1379 | ||
1371 | /* Finally, initialize the rcu_data structure's list to empty. */ | 1380 | /* Finally, initialize the rcu_data structure's list to empty. */ |
1372 | rdp->nxtlist = NULL; | 1381 | init_callback_list(rdp); |
1373 | for (i = 0; i < RCU_NEXT_SIZE; i++) | ||
1374 | rdp->nxttail[i] = &rdp->nxtlist; | ||
1375 | } | 1382 | } |
1376 | 1383 | ||
1377 | /* | 1384 | /* |
@@ -1505,6 +1512,9 @@ static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp) | |||
1505 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | 1512 | raw_spin_unlock_irqrestore(&rnp->lock, flags); |
1506 | if (need_report & RCU_OFL_TASKS_EXP_GP) | 1513 | if (need_report & RCU_OFL_TASKS_EXP_GP) |
1507 | rcu_report_exp_rnp(rsp, rnp, true); | 1514 | rcu_report_exp_rnp(rsp, rnp, true); |
1515 | WARN_ONCE(rdp->qlen != 0 || rdp->nxtlist != NULL, | ||
1516 | "rcu_cleanup_dead_cpu: Callbacks on offline CPU %d: qlen=%lu, nxtlist=%p\n", | ||
1517 | cpu, rdp->qlen, rdp->nxtlist); | ||
1508 | } | 1518 | } |
1509 | 1519 | ||
1510 | #else /* #ifdef CONFIG_HOTPLUG_CPU */ | 1520 | #else /* #ifdef CONFIG_HOTPLUG_CPU */ |
@@ -1592,7 +1602,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) | |||
1592 | } | 1602 | } |
1593 | smp_mb(); /* List handling before counting for rcu_barrier(). */ | 1603 | smp_mb(); /* List handling before counting for rcu_barrier(). */ |
1594 | rdp->qlen_lazy -= count_lazy; | 1604 | rdp->qlen_lazy -= count_lazy; |
1595 | rdp->qlen -= count; | 1605 | ACCESS_ONCE(rdp->qlen) -= count; |
1596 | rdp->n_cbs_invoked += count; | 1606 | rdp->n_cbs_invoked += count; |
1597 | 1607 | ||
1598 | /* Reinstate batch limit if we have worked down the excess. */ | 1608 | /* Reinstate batch limit if we have worked down the excess. */ |
@@ -1605,6 +1615,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) | |||
1605 | rdp->n_force_qs_snap = rsp->n_force_qs; | 1615 | rdp->n_force_qs_snap = rsp->n_force_qs; |
1606 | } else if (rdp->qlen < rdp->qlen_last_fqs_check - qhimark) | 1616 | } else if (rdp->qlen < rdp->qlen_last_fqs_check - qhimark) |
1607 | rdp->qlen_last_fqs_check = rdp->qlen; | 1617 | rdp->qlen_last_fqs_check = rdp->qlen; |
1618 | WARN_ON_ONCE((rdp->nxtlist == NULL) != (rdp->qlen == 0)); | ||
1608 | 1619 | ||
1609 | local_irq_restore(flags); | 1620 | local_irq_restore(flags); |
1610 | 1621 | ||
@@ -1745,8 +1756,6 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed) | |||
1745 | break; /* grace period idle or initializing, ignore. */ | 1756 | break; /* grace period idle or initializing, ignore. */ |
1746 | 1757 | ||
1747 | case RCU_SAVE_DYNTICK: | 1758 | case RCU_SAVE_DYNTICK: |
1748 | if (RCU_SIGNAL_INIT != RCU_SAVE_DYNTICK) | ||
1749 | break; /* So gcc recognizes the dead code. */ | ||
1750 | 1759 | ||
1751 | raw_spin_unlock(&rnp->lock); /* irqs remain disabled */ | 1760 | raw_spin_unlock(&rnp->lock); /* irqs remain disabled */ |
1752 | 1761 | ||
@@ -1788,9 +1797,10 @@ unlock_fqs_ret: | |||
1788 | * whom the rdp belongs. | 1797 | * whom the rdp belongs. |
1789 | */ | 1798 | */ |
1790 | static void | 1799 | static void |
1791 | __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) | 1800 | __rcu_process_callbacks(struct rcu_state *rsp) |
1792 | { | 1801 | { |
1793 | unsigned long flags; | 1802 | unsigned long flags; |
1803 | struct rcu_data *rdp = __this_cpu_ptr(rsp->rda); | ||
1794 | 1804 | ||
1795 | WARN_ON_ONCE(rdp->beenonline == 0); | 1805 | WARN_ON_ONCE(rdp->beenonline == 0); |
1796 | 1806 | ||
@@ -1826,11 +1836,11 @@ __rcu_process_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) | |||
1826 | */ | 1836 | */ |
1827 | static void rcu_process_callbacks(struct softirq_action *unused) | 1837 | static void rcu_process_callbacks(struct softirq_action *unused) |
1828 | { | 1838 | { |
1839 | struct rcu_state *rsp; | ||
1840 | |||
1829 | trace_rcu_utilization("Start RCU core"); | 1841 | trace_rcu_utilization("Start RCU core"); |
1830 | __rcu_process_callbacks(&rcu_sched_state, | 1842 | for_each_rcu_flavor(rsp) |
1831 | &__get_cpu_var(rcu_sched_data)); | 1843 | __rcu_process_callbacks(rsp); |
1832 | __rcu_process_callbacks(&rcu_bh_state, &__get_cpu_var(rcu_bh_data)); | ||
1833 | rcu_preempt_process_callbacks(); | ||
1834 | trace_rcu_utilization("End RCU core"); | 1844 | trace_rcu_utilization("End RCU core"); |
1835 | } | 1845 | } |
1836 | 1846 | ||
@@ -1857,6 +1867,56 @@ static void invoke_rcu_core(void) | |||
1857 | raise_softirq(RCU_SOFTIRQ); | 1867 | raise_softirq(RCU_SOFTIRQ); |
1858 | } | 1868 | } |
1859 | 1869 | ||
1870 | /* | ||
1871 | * Handle any core-RCU processing required by a call_rcu() invocation. | ||
1872 | */ | ||
1873 | static void __call_rcu_core(struct rcu_state *rsp, struct rcu_data *rdp, | ||
1874 | struct rcu_head *head, unsigned long flags) | ||
1875 | { | ||
1876 | /* | ||
1877 | * If called from an extended quiescent state, invoke the RCU | ||
1878 | * core in order to force a re-evaluation of RCU's idleness. | ||
1879 | */ | ||
1880 | if (rcu_is_cpu_idle() && cpu_online(smp_processor_id())) | ||
1881 | invoke_rcu_core(); | ||
1882 | |||
1883 | /* If interrupts were disabled or CPU offline, don't invoke RCU core. */ | ||
1884 | if (irqs_disabled_flags(flags) || cpu_is_offline(smp_processor_id())) | ||
1885 | return; | ||
1886 | |||
1887 | /* | ||
1888 | * Force the grace period if too many callbacks or too long waiting. | ||
1889 | * Enforce hysteresis, and don't invoke force_quiescent_state() | ||
1890 | * if some other CPU has recently done so. Also, don't bother | ||
1891 | * invoking force_quiescent_state() if the newly enqueued callback | ||
1892 | * is the only one waiting for a grace period to complete. | ||
1893 | */ | ||
1894 | if (unlikely(rdp->qlen > rdp->qlen_last_fqs_check + qhimark)) { | ||
1895 | |||
1896 | /* Are we ignoring a completed grace period? */ | ||
1897 | rcu_process_gp_end(rsp, rdp); | ||
1898 | check_for_new_grace_period(rsp, rdp); | ||
1899 | |||
1900 | /* Start a new grace period if one not already started. */ | ||
1901 | if (!rcu_gp_in_progress(rsp)) { | ||
1902 | unsigned long nestflag; | ||
1903 | struct rcu_node *rnp_root = rcu_get_root(rsp); | ||
1904 | |||
1905 | raw_spin_lock_irqsave(&rnp_root->lock, nestflag); | ||
1906 | rcu_start_gp(rsp, nestflag); /* rlses rnp_root->lock */ | ||
1907 | } else { | ||
1908 | /* Give the grace period a kick. */ | ||
1909 | rdp->blimit = LONG_MAX; | ||
1910 | if (rsp->n_force_qs == rdp->n_force_qs_snap && | ||
1911 | *rdp->nxttail[RCU_DONE_TAIL] != head) | ||
1912 | force_quiescent_state(rsp, 0); | ||
1913 | rdp->n_force_qs_snap = rsp->n_force_qs; | ||
1914 | rdp->qlen_last_fqs_check = rdp->qlen; | ||
1915 | } | ||
1916 | } else if (ULONG_CMP_LT(ACCESS_ONCE(rsp->jiffies_force_qs), jiffies)) | ||
1917 | force_quiescent_state(rsp, 1); | ||
1918 | } | ||
1919 | |||
1860 | static void | 1920 | static void |
1861 | __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), | 1921 | __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), |
1862 | struct rcu_state *rsp, bool lazy) | 1922 | struct rcu_state *rsp, bool lazy) |
@@ -1881,7 +1941,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), | |||
1881 | rdp = this_cpu_ptr(rsp->rda); | 1941 | rdp = this_cpu_ptr(rsp->rda); |
1882 | 1942 | ||
1883 | /* Add the callback to our list. */ | 1943 | /* Add the callback to our list. */ |
1884 | rdp->qlen++; | 1944 | ACCESS_ONCE(rdp->qlen)++; |
1885 | if (lazy) | 1945 | if (lazy) |
1886 | rdp->qlen_lazy++; | 1946 | rdp->qlen_lazy++; |
1887 | else | 1947 | else |
@@ -1896,43 +1956,8 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), | |||
1896 | else | 1956 | else |
1897 | trace_rcu_callback(rsp->name, head, rdp->qlen_lazy, rdp->qlen); | 1957 | trace_rcu_callback(rsp->name, head, rdp->qlen_lazy, rdp->qlen); |
1898 | 1958 | ||
1899 | /* If interrupts were disabled, don't dive into RCU core. */ | 1959 | /* Go handle any RCU core processing required. */ |
1900 | if (irqs_disabled_flags(flags)) { | 1960 | __call_rcu_core(rsp, rdp, head, flags); |
1901 | local_irq_restore(flags); | ||
1902 | return; | ||
1903 | } | ||
1904 | |||
1905 | /* | ||
1906 | * Force the grace period if too many callbacks or too long waiting. | ||
1907 | * Enforce hysteresis, and don't invoke force_quiescent_state() | ||
1908 | * if some other CPU has recently done so. Also, don't bother | ||
1909 | * invoking force_quiescent_state() if the newly enqueued callback | ||
1910 | * is the only one waiting for a grace period to complete. | ||
1911 | */ | ||
1912 | if (unlikely(rdp->qlen > rdp->qlen_last_fqs_check + qhimark)) { | ||
1913 | |||
1914 | /* Are we ignoring a completed grace period? */ | ||
1915 | rcu_process_gp_end(rsp, rdp); | ||
1916 | check_for_new_grace_period(rsp, rdp); | ||
1917 | |||
1918 | /* Start a new grace period if one not already started. */ | ||
1919 | if (!rcu_gp_in_progress(rsp)) { | ||
1920 | unsigned long nestflag; | ||
1921 | struct rcu_node *rnp_root = rcu_get_root(rsp); | ||
1922 | |||
1923 | raw_spin_lock_irqsave(&rnp_root->lock, nestflag); | ||
1924 | rcu_start_gp(rsp, nestflag); /* rlses rnp_root->lock */ | ||
1925 | } else { | ||
1926 | /* Give the grace period a kick. */ | ||
1927 | rdp->blimit = LONG_MAX; | ||
1928 | if (rsp->n_force_qs == rdp->n_force_qs_snap && | ||
1929 | *rdp->nxttail[RCU_DONE_TAIL] != head) | ||
1930 | force_quiescent_state(rsp, 0); | ||
1931 | rdp->n_force_qs_snap = rsp->n_force_qs; | ||
1932 | rdp->qlen_last_fqs_check = rdp->qlen; | ||
1933 | } | ||
1934 | } else if (ULONG_CMP_LT(ACCESS_ONCE(rsp->jiffies_force_qs), jiffies)) | ||
1935 | force_quiescent_state(rsp, 1); | ||
1936 | local_irq_restore(flags); | 1961 | local_irq_restore(flags); |
1937 | } | 1962 | } |
1938 | 1963 | ||
@@ -1962,28 +1987,16 @@ EXPORT_SYMBOL_GPL(call_rcu_bh); | |||
1962 | * occasionally incorrectly indicate that there are multiple CPUs online | 1987 | * occasionally incorrectly indicate that there are multiple CPUs online |
1963 | * when there was in fact only one the whole time, as this just adds | 1988 | * when there was in fact only one the whole time, as this just adds |
1964 | * some overhead: RCU still operates correctly. | 1989 | * some overhead: RCU still operates correctly. |
1965 | * | ||
1966 | * Of course, sampling num_online_cpus() with preemption enabled can | ||
1967 | * give erroneous results if there are concurrent CPU-hotplug operations. | ||
1968 | * For example, given a demonic sequence of preemptions in num_online_cpus() | ||
1969 | * and CPU-hotplug operations, there could be two or more CPUs online at | ||
1970 | * all times, but num_online_cpus() might well return one (or even zero). | ||
1971 | * | ||
1972 | * However, all such demonic sequences require at least one CPU-offline | ||
1973 | * operation. Furthermore, rcu_blocking_is_gp() giving the wrong answer | ||
1974 | * is only a problem if there is an RCU read-side critical section executing | ||
1975 | * throughout. But RCU-sched and RCU-bh read-side critical sections | ||
1976 | * disable either preemption or bh, which prevents a CPU from going offline. | ||
1977 | * Therefore, the only way that rcu_blocking_is_gp() can incorrectly return | ||
1978 | * that there is only one CPU when in fact there was more than one throughout | ||
1979 | * is when there were no RCU readers in the system. If there are no | ||
1980 | * RCU readers, the grace period by definition can be of zero length, | ||
1981 | * regardless of the number of online CPUs. | ||
1982 | */ | 1990 | */ |
1983 | static inline int rcu_blocking_is_gp(void) | 1991 | static inline int rcu_blocking_is_gp(void) |
1984 | { | 1992 | { |
1993 | int ret; | ||
1994 | |||
1985 | might_sleep(); /* Check for RCU read-side critical section. */ | 1995 | might_sleep(); /* Check for RCU read-side critical section. */ |
1986 | return num_online_cpus() <= 1; | 1996 | preempt_disable(); |
1997 | ret = num_online_cpus() <= 1; | ||
1998 | preempt_enable(); | ||
1999 | return ret; | ||
1987 | } | 2000 | } |
1988 | 2001 | ||
1989 | /** | 2002 | /** |
@@ -2118,9 +2131,9 @@ void synchronize_sched_expedited(void) | |||
2118 | put_online_cpus(); | 2131 | put_online_cpus(); |
2119 | 2132 | ||
2120 | /* No joy, try again later. Or just synchronize_sched(). */ | 2133 | /* No joy, try again later. Or just synchronize_sched(). */ |
2121 | if (trycount++ < 10) | 2134 | if (trycount++ < 10) { |
2122 | udelay(trycount * num_online_cpus()); | 2135 | udelay(trycount * num_online_cpus()); |
2123 | else { | 2136 | } else { |
2124 | synchronize_sched(); | 2137 | synchronize_sched(); |
2125 | return; | 2138 | return; |
2126 | } | 2139 | } |
@@ -2241,9 +2254,12 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp) | |||
2241 | */ | 2254 | */ |
2242 | static int rcu_pending(int cpu) | 2255 | static int rcu_pending(int cpu) |
2243 | { | 2256 | { |
2244 | return __rcu_pending(&rcu_sched_state, &per_cpu(rcu_sched_data, cpu)) || | 2257 | struct rcu_state *rsp; |
2245 | __rcu_pending(&rcu_bh_state, &per_cpu(rcu_bh_data, cpu)) || | 2258 | |
2246 | rcu_preempt_pending(cpu); | 2259 | for_each_rcu_flavor(rsp) |
2260 | if (__rcu_pending(rsp, per_cpu_ptr(rsp->rda, cpu))) | ||
2261 | return 1; | ||
2262 | return 0; | ||
2247 | } | 2263 | } |
2248 | 2264 | ||
2249 | /* | 2265 | /* |
@@ -2253,20 +2269,41 @@ static int rcu_pending(int cpu) | |||
2253 | */ | 2269 | */ |
2254 | static int rcu_cpu_has_callbacks(int cpu) | 2270 | static int rcu_cpu_has_callbacks(int cpu) |
2255 | { | 2271 | { |
2272 | struct rcu_state *rsp; | ||
2273 | |||
2256 | /* RCU callbacks either ready or pending? */ | 2274 | /* RCU callbacks either ready or pending? */ |
2257 | return per_cpu(rcu_sched_data, cpu).nxtlist || | 2275 | for_each_rcu_flavor(rsp) |
2258 | per_cpu(rcu_bh_data, cpu).nxtlist || | 2276 | if (per_cpu_ptr(rsp->rda, cpu)->nxtlist) |
2259 | rcu_preempt_cpu_has_callbacks(cpu); | 2277 | return 1; |
2278 | return 0; | ||
2279 | } | ||
2280 | |||
2281 | /* | ||
2282 | * Helper function for _rcu_barrier() tracing. If tracing is disabled, | ||
2283 | * the compiler is expected to optimize this away. | ||
2284 | */ | ||
2285 | static void _rcu_barrier_trace(struct rcu_state *rsp, char *s, | ||
2286 | int cpu, unsigned long done) | ||
2287 | { | ||
2288 | trace_rcu_barrier(rsp->name, s, cpu, | ||
2289 | atomic_read(&rsp->barrier_cpu_count), done); | ||
2260 | } | 2290 | } |
2261 | 2291 | ||
2262 | /* | 2292 | /* |
2263 | * RCU callback function for _rcu_barrier(). If we are last, wake | 2293 | * RCU callback function for _rcu_barrier(). If we are last, wake |
2264 | * up the task executing _rcu_barrier(). | 2294 | * up the task executing _rcu_barrier(). |
2265 | */ | 2295 | */ |
2266 | static void rcu_barrier_callback(struct rcu_head *notused) | 2296 | static void rcu_barrier_callback(struct rcu_head *rhp) |
2267 | { | 2297 | { |
2268 | if (atomic_dec_and_test(&rcu_barrier_cpu_count)) | 2298 | struct rcu_data *rdp = container_of(rhp, struct rcu_data, barrier_head); |
2269 | complete(&rcu_barrier_completion); | 2299 | struct rcu_state *rsp = rdp->rsp; |
2300 | |||
2301 | if (atomic_dec_and_test(&rsp->barrier_cpu_count)) { | ||
2302 | _rcu_barrier_trace(rsp, "LastCB", -1, rsp->n_barrier_done); | ||
2303 | complete(&rsp->barrier_completion); | ||
2304 | } else { | ||
2305 | _rcu_barrier_trace(rsp, "CB", -1, rsp->n_barrier_done); | ||
2306 | } | ||
2270 | } | 2307 | } |
2271 | 2308 | ||
2272 | /* | 2309 | /* |
@@ -2274,35 +2311,63 @@ static void rcu_barrier_callback(struct rcu_head *notused) | |||
2274 | */ | 2311 | */ |
2275 | static void rcu_barrier_func(void *type) | 2312 | static void rcu_barrier_func(void *type) |
2276 | { | 2313 | { |
2277 | int cpu = smp_processor_id(); | 2314 | struct rcu_state *rsp = type; |
2278 | struct rcu_head *head = &per_cpu(rcu_barrier_head, cpu); | 2315 | struct rcu_data *rdp = __this_cpu_ptr(rsp->rda); |
2279 | void (*call_rcu_func)(struct rcu_head *head, | ||
2280 | void (*func)(struct rcu_head *head)); | ||
2281 | 2316 | ||
2282 | atomic_inc(&rcu_barrier_cpu_count); | 2317 | _rcu_barrier_trace(rsp, "IRQ", -1, rsp->n_barrier_done); |
2283 | call_rcu_func = type; | 2318 | atomic_inc(&rsp->barrier_cpu_count); |
2284 | call_rcu_func(head, rcu_barrier_callback); | 2319 | rsp->call(&rdp->barrier_head, rcu_barrier_callback); |
2285 | } | 2320 | } |
2286 | 2321 | ||
2287 | /* | 2322 | /* |
2288 | * Orchestrate the specified type of RCU barrier, waiting for all | 2323 | * Orchestrate the specified type of RCU barrier, waiting for all |
2289 | * RCU callbacks of the specified type to complete. | 2324 | * RCU callbacks of the specified type to complete. |
2290 | */ | 2325 | */ |
2291 | static void _rcu_barrier(struct rcu_state *rsp, | 2326 | static void _rcu_barrier(struct rcu_state *rsp) |
2292 | void (*call_rcu_func)(struct rcu_head *head, | ||
2293 | void (*func)(struct rcu_head *head))) | ||
2294 | { | 2327 | { |
2295 | int cpu; | 2328 | int cpu; |
2296 | unsigned long flags; | 2329 | unsigned long flags; |
2297 | struct rcu_data *rdp; | 2330 | struct rcu_data *rdp; |
2298 | struct rcu_head rh; | 2331 | struct rcu_data rd; |
2332 | unsigned long snap = ACCESS_ONCE(rsp->n_barrier_done); | ||
2333 | unsigned long snap_done; | ||
2299 | 2334 | ||
2300 | init_rcu_head_on_stack(&rh); | 2335 | init_rcu_head_on_stack(&rd.barrier_head); |
2336 | _rcu_barrier_trace(rsp, "Begin", -1, snap); | ||
2301 | 2337 | ||
2302 | /* Take mutex to serialize concurrent rcu_barrier() requests. */ | 2338 | /* Take mutex to serialize concurrent rcu_barrier() requests. */ |
2303 | mutex_lock(&rcu_barrier_mutex); | 2339 | mutex_lock(&rsp->barrier_mutex); |
2340 | |||
2341 | /* | ||
2342 | * Ensure that all prior references, including to ->n_barrier_done, | ||
2343 | * are ordered before the _rcu_barrier() machinery. | ||
2344 | */ | ||
2345 | smp_mb(); /* See above block comment. */ | ||
2346 | |||
2347 | /* | ||
2348 | * Recheck ->n_barrier_done to see if others did our work for us. | ||
2349 | * This means checking ->n_barrier_done for an even-to-odd-to-even | ||
2350 | * transition. The "if" expression below therefore rounds the old | ||
2351 | * value up to the next even number and adds two before comparing. | ||
2352 | */ | ||
2353 | snap_done = ACCESS_ONCE(rsp->n_barrier_done); | ||
2354 | _rcu_barrier_trace(rsp, "Check", -1, snap_done); | ||
2355 | if (ULONG_CMP_GE(snap_done, ((snap + 1) & ~0x1) + 2)) { | ||
2356 | _rcu_barrier_trace(rsp, "EarlyExit", -1, snap_done); | ||
2357 | smp_mb(); /* caller's subsequent code after above check. */ | ||
2358 | mutex_unlock(&rsp->barrier_mutex); | ||
2359 | return; | ||
2360 | } | ||
2304 | 2361 | ||
2305 | smp_mb(); /* Prevent any prior operations from leaking in. */ | 2362 | /* |
2363 | * Increment ->n_barrier_done to avoid duplicate work. Use | ||
2364 | * ACCESS_ONCE() to prevent the compiler from speculating | ||
2365 | * the increment to precede the early-exit check. | ||
2366 | */ | ||
2367 | ACCESS_ONCE(rsp->n_barrier_done)++; | ||
2368 | WARN_ON_ONCE((rsp->n_barrier_done & 0x1) != 1); | ||
2369 | _rcu_barrier_trace(rsp, "Inc1", -1, rsp->n_barrier_done); | ||
2370 | smp_mb(); /* Order ->n_barrier_done increment with below mechanism. */ | ||
2306 | 2371 | ||
2307 | /* | 2372 | /* |
2308 | * Initialize the count to one rather than to zero in order to | 2373 | * Initialize the count to one rather than to zero in order to |
@@ -2321,8 +2386,8 @@ static void _rcu_barrier(struct rcu_state *rsp, | |||
2321 | * 6. Both rcu_barrier_callback() callbacks are invoked, awakening | 2386 | * 6. Both rcu_barrier_callback() callbacks are invoked, awakening |
2322 | * us -- but before CPU 1's orphaned callbacks are invoked!!! | 2387 | * us -- but before CPU 1's orphaned callbacks are invoked!!! |
2323 | */ | 2388 | */ |
2324 | init_completion(&rcu_barrier_completion); | 2389 | init_completion(&rsp->barrier_completion); |
2325 | atomic_set(&rcu_barrier_cpu_count, 1); | 2390 | atomic_set(&rsp->barrier_cpu_count, 1); |
2326 | raw_spin_lock_irqsave(&rsp->onofflock, flags); | 2391 | raw_spin_lock_irqsave(&rsp->onofflock, flags); |
2327 | rsp->rcu_barrier_in_progress = current; | 2392 | rsp->rcu_barrier_in_progress = current; |
2328 | raw_spin_unlock_irqrestore(&rsp->onofflock, flags); | 2393 | raw_spin_unlock_irqrestore(&rsp->onofflock, flags); |
@@ -2338,14 +2403,19 @@ static void _rcu_barrier(struct rcu_state *rsp, | |||
2338 | preempt_disable(); | 2403 | preempt_disable(); |
2339 | rdp = per_cpu_ptr(rsp->rda, cpu); | 2404 | rdp = per_cpu_ptr(rsp->rda, cpu); |
2340 | if (cpu_is_offline(cpu)) { | 2405 | if (cpu_is_offline(cpu)) { |
2406 | _rcu_barrier_trace(rsp, "Offline", cpu, | ||
2407 | rsp->n_barrier_done); | ||
2341 | preempt_enable(); | 2408 | preempt_enable(); |
2342 | while (cpu_is_offline(cpu) && ACCESS_ONCE(rdp->qlen)) | 2409 | while (cpu_is_offline(cpu) && ACCESS_ONCE(rdp->qlen)) |
2343 | schedule_timeout_interruptible(1); | 2410 | schedule_timeout_interruptible(1); |
2344 | } else if (ACCESS_ONCE(rdp->qlen)) { | 2411 | } else if (ACCESS_ONCE(rdp->qlen)) { |
2345 | smp_call_function_single(cpu, rcu_barrier_func, | 2412 | _rcu_barrier_trace(rsp, "OnlineQ", cpu, |
2346 | (void *)call_rcu_func, 1); | 2413 | rsp->n_barrier_done); |
2414 | smp_call_function_single(cpu, rcu_barrier_func, rsp, 1); | ||
2347 | preempt_enable(); | 2415 | preempt_enable(); |
2348 | } else { | 2416 | } else { |
2417 | _rcu_barrier_trace(rsp, "OnlineNQ", cpu, | ||
2418 | rsp->n_barrier_done); | ||
2349 | preempt_enable(); | 2419 | preempt_enable(); |
2350 | } | 2420 | } |
2351 | } | 2421 | } |
@@ -2362,24 +2432,32 @@ static void _rcu_barrier(struct rcu_state *rsp, | |||
2362 | rcu_adopt_orphan_cbs(rsp); | 2432 | rcu_adopt_orphan_cbs(rsp); |
2363 | rsp->rcu_barrier_in_progress = NULL; | 2433 | rsp->rcu_barrier_in_progress = NULL; |
2364 | raw_spin_unlock_irqrestore(&rsp->onofflock, flags); | 2434 | raw_spin_unlock_irqrestore(&rsp->onofflock, flags); |
2365 | atomic_inc(&rcu_barrier_cpu_count); | 2435 | atomic_inc(&rsp->barrier_cpu_count); |
2366 | smp_mb__after_atomic_inc(); /* Ensure atomic_inc() before callback. */ | 2436 | smp_mb__after_atomic_inc(); /* Ensure atomic_inc() before callback. */ |
2367 | call_rcu_func(&rh, rcu_barrier_callback); | 2437 | rd.rsp = rsp; |
2438 | rsp->call(&rd.barrier_head, rcu_barrier_callback); | ||
2368 | 2439 | ||
2369 | /* | 2440 | /* |
2370 | * Now that we have an rcu_barrier_callback() callback on each | 2441 | * Now that we have an rcu_barrier_callback() callback on each |
2371 | * CPU, and thus each counted, remove the initial count. | 2442 | * CPU, and thus each counted, remove the initial count. |
2372 | */ | 2443 | */ |
2373 | if (atomic_dec_and_test(&rcu_barrier_cpu_count)) | 2444 | if (atomic_dec_and_test(&rsp->barrier_cpu_count)) |
2374 | complete(&rcu_barrier_completion); | 2445 | complete(&rsp->barrier_completion); |
2446 | |||
2447 | /* Increment ->n_barrier_done to prevent duplicate work. */ | ||
2448 | smp_mb(); /* Keep increment after above mechanism. */ | ||
2449 | ACCESS_ONCE(rsp->n_barrier_done)++; | ||
2450 | WARN_ON_ONCE((rsp->n_barrier_done & 0x1) != 0); | ||
2451 | _rcu_barrier_trace(rsp, "Inc2", -1, rsp->n_barrier_done); | ||
2452 | smp_mb(); /* Keep increment before caller's subsequent code. */ | ||
2375 | 2453 | ||
2376 | /* Wait for all rcu_barrier_callback() callbacks to be invoked. */ | 2454 | /* Wait for all rcu_barrier_callback() callbacks to be invoked. */ |
2377 | wait_for_completion(&rcu_barrier_completion); | 2455 | wait_for_completion(&rsp->barrier_completion); |
2378 | 2456 | ||
2379 | /* Other rcu_barrier() invocations can now safely proceed. */ | 2457 | /* Other rcu_barrier() invocations can now safely proceed. */ |
2380 | mutex_unlock(&rcu_barrier_mutex); | 2458 | mutex_unlock(&rsp->barrier_mutex); |
2381 | 2459 | ||
2382 | destroy_rcu_head_on_stack(&rh); | 2460 | destroy_rcu_head_on_stack(&rd.barrier_head); |
2383 | } | 2461 | } |
2384 | 2462 | ||
2385 | /** | 2463 | /** |
@@ -2387,7 +2465,7 @@ static void _rcu_barrier(struct rcu_state *rsp, | |||
2387 | */ | 2465 | */ |
2388 | void rcu_barrier_bh(void) | 2466 | void rcu_barrier_bh(void) |
2389 | { | 2467 | { |
2390 | _rcu_barrier(&rcu_bh_state, call_rcu_bh); | 2468 | _rcu_barrier(&rcu_bh_state); |
2391 | } | 2469 | } |
2392 | EXPORT_SYMBOL_GPL(rcu_barrier_bh); | 2470 | EXPORT_SYMBOL_GPL(rcu_barrier_bh); |
2393 | 2471 | ||
@@ -2396,7 +2474,7 @@ EXPORT_SYMBOL_GPL(rcu_barrier_bh); | |||
2396 | */ | 2474 | */ |
2397 | void rcu_barrier_sched(void) | 2475 | void rcu_barrier_sched(void) |
2398 | { | 2476 | { |
2399 | _rcu_barrier(&rcu_sched_state, call_rcu_sched); | 2477 | _rcu_barrier(&rcu_sched_state); |
2400 | } | 2478 | } |
2401 | EXPORT_SYMBOL_GPL(rcu_barrier_sched); | 2479 | EXPORT_SYMBOL_GPL(rcu_barrier_sched); |
2402 | 2480 | ||
@@ -2407,18 +2485,15 @@ static void __init | |||
2407 | rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp) | 2485 | rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp) |
2408 | { | 2486 | { |
2409 | unsigned long flags; | 2487 | unsigned long flags; |
2410 | int i; | ||
2411 | struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); | 2488 | struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); |
2412 | struct rcu_node *rnp = rcu_get_root(rsp); | 2489 | struct rcu_node *rnp = rcu_get_root(rsp); |
2413 | 2490 | ||
2414 | /* Set up local state, ensuring consistent view of global state. */ | 2491 | /* Set up local state, ensuring consistent view of global state. */ |
2415 | raw_spin_lock_irqsave(&rnp->lock, flags); | 2492 | raw_spin_lock_irqsave(&rnp->lock, flags); |
2416 | rdp->grpmask = 1UL << (cpu - rdp->mynode->grplo); | 2493 | rdp->grpmask = 1UL << (cpu - rdp->mynode->grplo); |
2417 | rdp->nxtlist = NULL; | 2494 | init_callback_list(rdp); |
2418 | for (i = 0; i < RCU_NEXT_SIZE; i++) | ||
2419 | rdp->nxttail[i] = &rdp->nxtlist; | ||
2420 | rdp->qlen_lazy = 0; | 2495 | rdp->qlen_lazy = 0; |
2421 | rdp->qlen = 0; | 2496 | ACCESS_ONCE(rdp->qlen) = 0; |
2422 | rdp->dynticks = &per_cpu(rcu_dynticks, cpu); | 2497 | rdp->dynticks = &per_cpu(rcu_dynticks, cpu); |
2423 | WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_EXIT_IDLE); | 2498 | WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_EXIT_IDLE); |
2424 | WARN_ON_ONCE(atomic_read(&rdp->dynticks->dynticks) != 1); | 2499 | WARN_ON_ONCE(atomic_read(&rdp->dynticks->dynticks) != 1); |
@@ -2492,9 +2567,11 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible) | |||
2492 | 2567 | ||
2493 | static void __cpuinit rcu_prepare_cpu(int cpu) | 2568 | static void __cpuinit rcu_prepare_cpu(int cpu) |
2494 | { | 2569 | { |
2495 | rcu_init_percpu_data(cpu, &rcu_sched_state, 0); | 2570 | struct rcu_state *rsp; |
2496 | rcu_init_percpu_data(cpu, &rcu_bh_state, 0); | 2571 | |
2497 | rcu_preempt_init_percpu_data(cpu); | 2572 | for_each_rcu_flavor(rsp) |
2573 | rcu_init_percpu_data(cpu, rsp, | ||
2574 | strcmp(rsp->name, "rcu_preempt") == 0); | ||
2498 | } | 2575 | } |
2499 | 2576 | ||
2500 | /* | 2577 | /* |
@@ -2506,6 +2583,7 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self, | |||
2506 | long cpu = (long)hcpu; | 2583 | long cpu = (long)hcpu; |
2507 | struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu); | 2584 | struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu); |
2508 | struct rcu_node *rnp = rdp->mynode; | 2585 | struct rcu_node *rnp = rdp->mynode; |
2586 | struct rcu_state *rsp; | ||
2509 | 2587 | ||
2510 | trace_rcu_utilization("Start CPU hotplug"); | 2588 | trace_rcu_utilization("Start CPU hotplug"); |
2511 | switch (action) { | 2589 | switch (action) { |
@@ -2530,18 +2608,16 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self, | |||
2530 | * touch any data without introducing corruption. We send the | 2608 | * touch any data without introducing corruption. We send the |
2531 | * dying CPU's callbacks to an arbitrarily chosen online CPU. | 2609 | * dying CPU's callbacks to an arbitrarily chosen online CPU. |
2532 | */ | 2610 | */ |
2533 | rcu_cleanup_dying_cpu(&rcu_bh_state); | 2611 | for_each_rcu_flavor(rsp) |
2534 | rcu_cleanup_dying_cpu(&rcu_sched_state); | 2612 | rcu_cleanup_dying_cpu(rsp); |
2535 | rcu_preempt_cleanup_dying_cpu(); | ||
2536 | rcu_cleanup_after_idle(cpu); | 2613 | rcu_cleanup_after_idle(cpu); |
2537 | break; | 2614 | break; |
2538 | case CPU_DEAD: | 2615 | case CPU_DEAD: |
2539 | case CPU_DEAD_FROZEN: | 2616 | case CPU_DEAD_FROZEN: |
2540 | case CPU_UP_CANCELED: | 2617 | case CPU_UP_CANCELED: |
2541 | case CPU_UP_CANCELED_FROZEN: | 2618 | case CPU_UP_CANCELED_FROZEN: |
2542 | rcu_cleanup_dead_cpu(cpu, &rcu_bh_state); | 2619 | for_each_rcu_flavor(rsp) |
2543 | rcu_cleanup_dead_cpu(cpu, &rcu_sched_state); | 2620 | rcu_cleanup_dead_cpu(cpu, rsp); |
2544 | rcu_preempt_cleanup_dead_cpu(cpu); | ||
2545 | break; | 2621 | break; |
2546 | default: | 2622 | default: |
2547 | break; | 2623 | break; |
@@ -2574,9 +2650,9 @@ static void __init rcu_init_levelspread(struct rcu_state *rsp) | |||
2574 | { | 2650 | { |
2575 | int i; | 2651 | int i; |
2576 | 2652 | ||
2577 | for (i = NUM_RCU_LVLS - 1; i > 0; i--) | 2653 | for (i = rcu_num_lvls - 1; i > 0; i--) |
2578 | rsp->levelspread[i] = CONFIG_RCU_FANOUT; | 2654 | rsp->levelspread[i] = CONFIG_RCU_FANOUT; |
2579 | rsp->levelspread[0] = CONFIG_RCU_FANOUT_LEAF; | 2655 | rsp->levelspread[0] = rcu_fanout_leaf; |
2580 | } | 2656 | } |
2581 | #else /* #ifdef CONFIG_RCU_FANOUT_EXACT */ | 2657 | #else /* #ifdef CONFIG_RCU_FANOUT_EXACT */ |
2582 | static void __init rcu_init_levelspread(struct rcu_state *rsp) | 2658 | static void __init rcu_init_levelspread(struct rcu_state *rsp) |
@@ -2586,7 +2662,7 @@ static void __init rcu_init_levelspread(struct rcu_state *rsp) | |||
2586 | int i; | 2662 | int i; |
2587 | 2663 | ||
2588 | cprv = NR_CPUS; | 2664 | cprv = NR_CPUS; |
2589 | for (i = NUM_RCU_LVLS - 1; i >= 0; i--) { | 2665 | for (i = rcu_num_lvls - 1; i >= 0; i--) { |
2590 | ccur = rsp->levelcnt[i]; | 2666 | ccur = rsp->levelcnt[i]; |
2591 | rsp->levelspread[i] = (cprv + ccur - 1) / ccur; | 2667 | rsp->levelspread[i] = (cprv + ccur - 1) / ccur; |
2592 | cprv = ccur; | 2668 | cprv = ccur; |
@@ -2613,13 +2689,15 @@ static void __init rcu_init_one(struct rcu_state *rsp, | |||
2613 | 2689 | ||
2614 | /* Initialize the level-tracking arrays. */ | 2690 | /* Initialize the level-tracking arrays. */ |
2615 | 2691 | ||
2616 | for (i = 1; i < NUM_RCU_LVLS; i++) | 2692 | for (i = 0; i < rcu_num_lvls; i++) |
2693 | rsp->levelcnt[i] = num_rcu_lvl[i]; | ||
2694 | for (i = 1; i < rcu_num_lvls; i++) | ||
2617 | rsp->level[i] = rsp->level[i - 1] + rsp->levelcnt[i - 1]; | 2695 | rsp->level[i] = rsp->level[i - 1] + rsp->levelcnt[i - 1]; |
2618 | rcu_init_levelspread(rsp); | 2696 | rcu_init_levelspread(rsp); |
2619 | 2697 | ||
2620 | /* Initialize the elements themselves, starting from the leaves. */ | 2698 | /* Initialize the elements themselves, starting from the leaves. */ |
2621 | 2699 | ||
2622 | for (i = NUM_RCU_LVLS - 1; i >= 0; i--) { | 2700 | for (i = rcu_num_lvls - 1; i >= 0; i--) { |
2623 | cpustride *= rsp->levelspread[i]; | 2701 | cpustride *= rsp->levelspread[i]; |
2624 | rnp = rsp->level[i]; | 2702 | rnp = rsp->level[i]; |
2625 | for (j = 0; j < rsp->levelcnt[i]; j++, rnp++) { | 2703 | for (j = 0; j < rsp->levelcnt[i]; j++, rnp++) { |
@@ -2649,13 +2727,74 @@ static void __init rcu_init_one(struct rcu_state *rsp, | |||
2649 | } | 2727 | } |
2650 | 2728 | ||
2651 | rsp->rda = rda; | 2729 | rsp->rda = rda; |
2652 | rnp = rsp->level[NUM_RCU_LVLS - 1]; | 2730 | rnp = rsp->level[rcu_num_lvls - 1]; |
2653 | for_each_possible_cpu(i) { | 2731 | for_each_possible_cpu(i) { |
2654 | while (i > rnp->grphi) | 2732 | while (i > rnp->grphi) |
2655 | rnp++; | 2733 | rnp++; |
2656 | per_cpu_ptr(rsp->rda, i)->mynode = rnp; | 2734 | per_cpu_ptr(rsp->rda, i)->mynode = rnp; |
2657 | rcu_boot_init_percpu_data(i, rsp); | 2735 | rcu_boot_init_percpu_data(i, rsp); |
2658 | } | 2736 | } |
2737 | list_add(&rsp->flavors, &rcu_struct_flavors); | ||
2738 | } | ||
2739 | |||
2740 | /* | ||
2741 | * Compute the rcu_node tree geometry from kernel parameters. This cannot | ||
2742 | * replace the definitions in rcutree.h because those are needed to size | ||
2743 | * the ->node array in the rcu_state structure. | ||
2744 | */ | ||
2745 | static void __init rcu_init_geometry(void) | ||
2746 | { | ||
2747 | int i; | ||
2748 | int j; | ||
2749 | int n = nr_cpu_ids; | ||
2750 | int rcu_capacity[MAX_RCU_LVLS + 1]; | ||
2751 | |||
2752 | /* If the compile-time values are accurate, just leave. */ | ||
2753 | if (rcu_fanout_leaf == CONFIG_RCU_FANOUT_LEAF) | ||
2754 | return; | ||
2755 | |||
2756 | /* | ||
2757 | * Compute number of nodes that can be handled an rcu_node tree | ||
2758 | * with the given number of levels. Setting rcu_capacity[0] makes | ||
2759 | * some of the arithmetic easier. | ||
2760 | */ | ||
2761 | rcu_capacity[0] = 1; | ||
2762 | rcu_capacity[1] = rcu_fanout_leaf; | ||
2763 | for (i = 2; i <= MAX_RCU_LVLS; i++) | ||
2764 | rcu_capacity[i] = rcu_capacity[i - 1] * CONFIG_RCU_FANOUT; | ||
2765 | |||
2766 | /* | ||
2767 | * The boot-time rcu_fanout_leaf parameter is only permitted | ||
2768 | * to increase the leaf-level fanout, not decrease it. Of course, | ||
2769 | * the leaf-level fanout cannot exceed the number of bits in | ||
2770 | * the rcu_node masks. Finally, the tree must be able to accommodate | ||
2771 | * the configured number of CPUs. Complain and fall back to the | ||
2772 | * compile-time values if these limits are exceeded. | ||
2773 | */ | ||
2774 | if (rcu_fanout_leaf < CONFIG_RCU_FANOUT_LEAF || | ||
2775 | rcu_fanout_leaf > sizeof(unsigned long) * 8 || | ||
2776 | n > rcu_capacity[MAX_RCU_LVLS]) { | ||
2777 | WARN_ON(1); | ||
2778 | return; | ||
2779 | } | ||
2780 | |||
2781 | /* Calculate the number of rcu_nodes at each level of the tree. */ | ||
2782 | for (i = 1; i <= MAX_RCU_LVLS; i++) | ||
2783 | if (n <= rcu_capacity[i]) { | ||
2784 | for (j = 0; j <= i; j++) | ||
2785 | num_rcu_lvl[j] = | ||
2786 | DIV_ROUND_UP(n, rcu_capacity[i - j]); | ||
2787 | rcu_num_lvls = i; | ||
2788 | for (j = i + 1; j <= MAX_RCU_LVLS; j++) | ||
2789 | num_rcu_lvl[j] = 0; | ||
2790 | break; | ||
2791 | } | ||
2792 | |||
2793 | /* Calculate the total number of rcu_node structures. */ | ||
2794 | rcu_num_nodes = 0; | ||
2795 | for (i = 0; i <= MAX_RCU_LVLS; i++) | ||
2796 | rcu_num_nodes += num_rcu_lvl[i]; | ||
2797 | rcu_num_nodes -= n; | ||
2659 | } | 2798 | } |
2660 | 2799 | ||
2661 | void __init rcu_init(void) | 2800 | void __init rcu_init(void) |
@@ -2663,6 +2802,7 @@ void __init rcu_init(void) | |||
2663 | int cpu; | 2802 | int cpu; |
2664 | 2803 | ||
2665 | rcu_bootup_announce(); | 2804 | rcu_bootup_announce(); |
2805 | rcu_init_geometry(); | ||
2666 | rcu_init_one(&rcu_sched_state, &rcu_sched_data); | 2806 | rcu_init_one(&rcu_sched_state, &rcu_sched_data); |
2667 | rcu_init_one(&rcu_bh_state, &rcu_bh_data); | 2807 | rcu_init_one(&rcu_bh_state, &rcu_bh_data); |
2668 | __rcu_init_preempt(); | 2808 | __rcu_init_preempt(); |
diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 19b61ac1079f..4d29169f2124 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h | |||
@@ -42,28 +42,28 @@ | |||
42 | #define RCU_FANOUT_4 (RCU_FANOUT_3 * CONFIG_RCU_FANOUT) | 42 | #define RCU_FANOUT_4 (RCU_FANOUT_3 * CONFIG_RCU_FANOUT) |
43 | 43 | ||
44 | #if NR_CPUS <= RCU_FANOUT_1 | 44 | #if NR_CPUS <= RCU_FANOUT_1 |
45 | # define NUM_RCU_LVLS 1 | 45 | # define RCU_NUM_LVLS 1 |
46 | # define NUM_RCU_LVL_0 1 | 46 | # define NUM_RCU_LVL_0 1 |
47 | # define NUM_RCU_LVL_1 (NR_CPUS) | 47 | # define NUM_RCU_LVL_1 (NR_CPUS) |
48 | # define NUM_RCU_LVL_2 0 | 48 | # define NUM_RCU_LVL_2 0 |
49 | # define NUM_RCU_LVL_3 0 | 49 | # define NUM_RCU_LVL_3 0 |
50 | # define NUM_RCU_LVL_4 0 | 50 | # define NUM_RCU_LVL_4 0 |
51 | #elif NR_CPUS <= RCU_FANOUT_2 | 51 | #elif NR_CPUS <= RCU_FANOUT_2 |
52 | # define NUM_RCU_LVLS 2 | 52 | # define RCU_NUM_LVLS 2 |
53 | # define NUM_RCU_LVL_0 1 | 53 | # define NUM_RCU_LVL_0 1 |
54 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) | 54 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) |
55 | # define NUM_RCU_LVL_2 (NR_CPUS) | 55 | # define NUM_RCU_LVL_2 (NR_CPUS) |
56 | # define NUM_RCU_LVL_3 0 | 56 | # define NUM_RCU_LVL_3 0 |
57 | # define NUM_RCU_LVL_4 0 | 57 | # define NUM_RCU_LVL_4 0 |
58 | #elif NR_CPUS <= RCU_FANOUT_3 | 58 | #elif NR_CPUS <= RCU_FANOUT_3 |
59 | # define NUM_RCU_LVLS 3 | 59 | # define RCU_NUM_LVLS 3 |
60 | # define NUM_RCU_LVL_0 1 | 60 | # define NUM_RCU_LVL_0 1 |
61 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) | 61 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) |
62 | # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) | 62 | # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_1) |
63 | # define NUM_RCU_LVL_3 (NR_CPUS) | 63 | # define NUM_RCU_LVL_3 (NR_CPUS) |
64 | # define NUM_RCU_LVL_4 0 | 64 | # define NUM_RCU_LVL_4 0 |
65 | #elif NR_CPUS <= RCU_FANOUT_4 | 65 | #elif NR_CPUS <= RCU_FANOUT_4 |
66 | # define NUM_RCU_LVLS 4 | 66 | # define RCU_NUM_LVLS 4 |
67 | # define NUM_RCU_LVL_0 1 | 67 | # define NUM_RCU_LVL_0 1 |
68 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_3) | 68 | # define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_3) |
69 | # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) | 69 | # define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_2) |
@@ -76,6 +76,9 @@ | |||
76 | #define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3 + NUM_RCU_LVL_4) | 76 | #define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3 + NUM_RCU_LVL_4) |
77 | #define NUM_RCU_NODES (RCU_SUM - NR_CPUS) | 77 | #define NUM_RCU_NODES (RCU_SUM - NR_CPUS) |
78 | 78 | ||
79 | extern int rcu_num_lvls; | ||
80 | extern int rcu_num_nodes; | ||
81 | |||
79 | /* | 82 | /* |
80 | * Dynticks per-CPU state. | 83 | * Dynticks per-CPU state. |
81 | */ | 84 | */ |
@@ -97,6 +100,7 @@ struct rcu_dynticks { | |||
97 | /* # times non-lazy CBs posted to CPU. */ | 100 | /* # times non-lazy CBs posted to CPU. */ |
98 | unsigned long nonlazy_posted_snap; | 101 | unsigned long nonlazy_posted_snap; |
99 | /* idle-period nonlazy_posted snapshot. */ | 102 | /* idle-period nonlazy_posted snapshot. */ |
103 | int tick_nohz_enabled_snap; /* Previously seen value from sysfs. */ | ||
100 | #endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ | 104 | #endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ |
101 | }; | 105 | }; |
102 | 106 | ||
@@ -206,7 +210,7 @@ struct rcu_node { | |||
206 | */ | 210 | */ |
207 | #define rcu_for_each_node_breadth_first(rsp, rnp) \ | 211 | #define rcu_for_each_node_breadth_first(rsp, rnp) \ |
208 | for ((rnp) = &(rsp)->node[0]; \ | 212 | for ((rnp) = &(rsp)->node[0]; \ |
209 | (rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++) | 213 | (rnp) < &(rsp)->node[rcu_num_nodes]; (rnp)++) |
210 | 214 | ||
211 | /* | 215 | /* |
212 | * Do a breadth-first scan of the non-leaf rcu_node structures for the | 216 | * Do a breadth-first scan of the non-leaf rcu_node structures for the |
@@ -215,7 +219,7 @@ struct rcu_node { | |||
215 | */ | 219 | */ |
216 | #define rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) \ | 220 | #define rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) \ |
217 | for ((rnp) = &(rsp)->node[0]; \ | 221 | for ((rnp) = &(rsp)->node[0]; \ |
218 | (rnp) < (rsp)->level[NUM_RCU_LVLS - 1]; (rnp)++) | 222 | (rnp) < (rsp)->level[rcu_num_lvls - 1]; (rnp)++) |
219 | 223 | ||
220 | /* | 224 | /* |
221 | * Scan the leaves of the rcu_node hierarchy for the specified rcu_state | 225 | * Scan the leaves of the rcu_node hierarchy for the specified rcu_state |
@@ -224,8 +228,8 @@ struct rcu_node { | |||
224 | * It is still a leaf node, even if it is also the root node. | 228 | * It is still a leaf node, even if it is also the root node. |
225 | */ | 229 | */ |
226 | #define rcu_for_each_leaf_node(rsp, rnp) \ | 230 | #define rcu_for_each_leaf_node(rsp, rnp) \ |
227 | for ((rnp) = (rsp)->level[NUM_RCU_LVLS - 1]; \ | 231 | for ((rnp) = (rsp)->level[rcu_num_lvls - 1]; \ |
228 | (rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++) | 232 | (rnp) < &(rsp)->node[rcu_num_nodes]; (rnp)++) |
229 | 233 | ||
230 | /* Index values for nxttail array in struct rcu_data. */ | 234 | /* Index values for nxttail array in struct rcu_data. */ |
231 | #define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ | 235 | #define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ |
@@ -311,6 +315,9 @@ struct rcu_data { | |||
311 | unsigned long n_rp_need_fqs; | 315 | unsigned long n_rp_need_fqs; |
312 | unsigned long n_rp_need_nothing; | 316 | unsigned long n_rp_need_nothing; |
313 | 317 | ||
318 | /* 6) _rcu_barrier() callback. */ | ||
319 | struct rcu_head barrier_head; | ||
320 | |||
314 | int cpu; | 321 | int cpu; |
315 | struct rcu_state *rsp; | 322 | struct rcu_state *rsp; |
316 | }; | 323 | }; |
@@ -357,10 +364,12 @@ do { \ | |||
357 | */ | 364 | */ |
358 | struct rcu_state { | 365 | struct rcu_state { |
359 | struct rcu_node node[NUM_RCU_NODES]; /* Hierarchy. */ | 366 | struct rcu_node node[NUM_RCU_NODES]; /* Hierarchy. */ |
360 | struct rcu_node *level[NUM_RCU_LVLS]; /* Hierarchy levels. */ | 367 | struct rcu_node *level[RCU_NUM_LVLS]; /* Hierarchy levels. */ |
361 | u32 levelcnt[MAX_RCU_LVLS + 1]; /* # nodes in each level. */ | 368 | u32 levelcnt[MAX_RCU_LVLS + 1]; /* # nodes in each level. */ |
362 | u8 levelspread[NUM_RCU_LVLS]; /* kids/node in each level. */ | 369 | u8 levelspread[RCU_NUM_LVLS]; /* kids/node in each level. */ |
363 | struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ | 370 | struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ |
371 | void (*call)(struct rcu_head *head, /* call_rcu() flavor. */ | ||
372 | void (*func)(struct rcu_head *head)); | ||
364 | 373 | ||
365 | /* The following fields are guarded by the root rcu_node's lock. */ | 374 | /* The following fields are guarded by the root rcu_node's lock. */ |
366 | 375 | ||
@@ -392,6 +401,11 @@ struct rcu_state { | |||
392 | struct task_struct *rcu_barrier_in_progress; | 401 | struct task_struct *rcu_barrier_in_progress; |
393 | /* Task doing rcu_barrier(), */ | 402 | /* Task doing rcu_barrier(), */ |
394 | /* or NULL if no barrier. */ | 403 | /* or NULL if no barrier. */ |
404 | struct mutex barrier_mutex; /* Guards barrier fields. */ | ||
405 | atomic_t barrier_cpu_count; /* # CPUs waiting on. */ | ||
406 | struct completion barrier_completion; /* Wake at barrier end. */ | ||
407 | unsigned long n_barrier_done; /* ++ at start and end of */ | ||
408 | /* _rcu_barrier(). */ | ||
395 | raw_spinlock_t fqslock; /* Only one task forcing */ | 409 | raw_spinlock_t fqslock; /* Only one task forcing */ |
396 | /* quiescent states. */ | 410 | /* quiescent states. */ |
397 | unsigned long jiffies_force_qs; /* Time at which to invoke */ | 411 | unsigned long jiffies_force_qs; /* Time at which to invoke */ |
@@ -409,8 +423,13 @@ struct rcu_state { | |||
409 | unsigned long gp_max; /* Maximum GP duration in */ | 423 | unsigned long gp_max; /* Maximum GP duration in */ |
410 | /* jiffies. */ | 424 | /* jiffies. */ |
411 | char *name; /* Name of structure. */ | 425 | char *name; /* Name of structure. */ |
426 | struct list_head flavors; /* List of RCU flavors. */ | ||
412 | }; | 427 | }; |
413 | 428 | ||
429 | extern struct list_head rcu_struct_flavors; | ||
430 | #define for_each_rcu_flavor(rsp) \ | ||
431 | list_for_each_entry((rsp), &rcu_struct_flavors, flavors) | ||
432 | |||
414 | /* Return values for rcu_preempt_offline_tasks(). */ | 433 | /* Return values for rcu_preempt_offline_tasks(). */ |
415 | 434 | ||
416 | #define RCU_OFL_TASKS_NORM_GP 0x1 /* Tasks blocking normal */ | 435 | #define RCU_OFL_TASKS_NORM_GP 0x1 /* Tasks blocking normal */ |
@@ -453,25 +472,18 @@ static void rcu_stop_cpu_kthread(int cpu); | |||
453 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | 472 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ |
454 | static void rcu_print_detail_task_stall(struct rcu_state *rsp); | 473 | static void rcu_print_detail_task_stall(struct rcu_state *rsp); |
455 | static int rcu_print_task_stall(struct rcu_node *rnp); | 474 | static int rcu_print_task_stall(struct rcu_node *rnp); |
456 | static void rcu_preempt_stall_reset(void); | ||
457 | static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); | 475 | static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp); |
458 | #ifdef CONFIG_HOTPLUG_CPU | 476 | #ifdef CONFIG_HOTPLUG_CPU |
459 | static int rcu_preempt_offline_tasks(struct rcu_state *rsp, | 477 | static int rcu_preempt_offline_tasks(struct rcu_state *rsp, |
460 | struct rcu_node *rnp, | 478 | struct rcu_node *rnp, |
461 | struct rcu_data *rdp); | 479 | struct rcu_data *rdp); |
462 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | 480 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ |
463 | static void rcu_preempt_cleanup_dead_cpu(int cpu); | ||
464 | static void rcu_preempt_check_callbacks(int cpu); | 481 | static void rcu_preempt_check_callbacks(int cpu); |
465 | static void rcu_preempt_process_callbacks(void); | ||
466 | void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); | 482 | void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); |
467 | #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) | 483 | #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) |
468 | static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp, | 484 | static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp, |
469 | bool wake); | 485 | bool wake); |
470 | #endif /* #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) */ | 486 | #endif /* #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) */ |
471 | static int rcu_preempt_pending(int cpu); | ||
472 | static int rcu_preempt_cpu_has_callbacks(int cpu); | ||
473 | static void __cpuinit rcu_preempt_init_percpu_data(int cpu); | ||
474 | static void rcu_preempt_cleanup_dying_cpu(void); | ||
475 | static void __init __rcu_init_preempt(void); | 487 | static void __init __rcu_init_preempt(void); |
476 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); | 488 | static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); |
477 | static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); | 489 | static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); |
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 3e4899459f3d..7f3244c0df01 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
@@ -68,17 +68,21 @@ static void __init rcu_bootup_announce_oddness(void) | |||
68 | printk(KERN_INFO "\tAdditional per-CPU info printed with stalls.\n"); | 68 | printk(KERN_INFO "\tAdditional per-CPU info printed with stalls.\n"); |
69 | #endif | 69 | #endif |
70 | #if NUM_RCU_LVL_4 != 0 | 70 | #if NUM_RCU_LVL_4 != 0 |
71 | printk(KERN_INFO "\tExperimental four-level hierarchy is enabled.\n"); | 71 | printk(KERN_INFO "\tFour-level hierarchy is enabled.\n"); |
72 | #endif | 72 | #endif |
73 | if (rcu_fanout_leaf != CONFIG_RCU_FANOUT_LEAF) | ||
74 | printk(KERN_INFO "\tExperimental boot-time adjustment of leaf fanout to %d.\n", rcu_fanout_leaf); | ||
75 | if (nr_cpu_ids != NR_CPUS) | ||
76 | printk(KERN_INFO "\tRCU restricting CPUs from NR_CPUS=%d to nr_cpu_ids=%d.\n", NR_CPUS, nr_cpu_ids); | ||
73 | } | 77 | } |
74 | 78 | ||
75 | #ifdef CONFIG_TREE_PREEMPT_RCU | 79 | #ifdef CONFIG_TREE_PREEMPT_RCU |
76 | 80 | ||
77 | struct rcu_state rcu_preempt_state = RCU_STATE_INITIALIZER(rcu_preempt); | 81 | struct rcu_state rcu_preempt_state = |
82 | RCU_STATE_INITIALIZER(rcu_preempt, call_rcu); | ||
78 | DEFINE_PER_CPU(struct rcu_data, rcu_preempt_data); | 83 | DEFINE_PER_CPU(struct rcu_data, rcu_preempt_data); |
79 | static struct rcu_state *rcu_state = &rcu_preempt_state; | 84 | static struct rcu_state *rcu_state = &rcu_preempt_state; |
80 | 85 | ||
81 | static void rcu_read_unlock_special(struct task_struct *t); | ||
82 | static int rcu_preempted_readers_exp(struct rcu_node *rnp); | 86 | static int rcu_preempted_readers_exp(struct rcu_node *rnp); |
83 | 87 | ||
84 | /* | 88 | /* |
@@ -233,18 +237,6 @@ static void rcu_preempt_note_context_switch(int cpu) | |||
233 | } | 237 | } |
234 | 238 | ||
235 | /* | 239 | /* |
236 | * Tree-preemptible RCU implementation for rcu_read_lock(). | ||
237 | * Just increment ->rcu_read_lock_nesting, shared state will be updated | ||
238 | * if we block. | ||
239 | */ | ||
240 | void __rcu_read_lock(void) | ||
241 | { | ||
242 | current->rcu_read_lock_nesting++; | ||
243 | barrier(); /* needed if we ever invoke rcu_read_lock in rcutree.c */ | ||
244 | } | ||
245 | EXPORT_SYMBOL_GPL(__rcu_read_lock); | ||
246 | |||
247 | /* | ||
248 | * Check for preempted RCU readers blocking the current grace period | 240 | * Check for preempted RCU readers blocking the current grace period |
249 | * for the specified rcu_node structure. If the caller needs a reliable | 241 | * for the specified rcu_node structure. If the caller needs a reliable |
250 | * answer, it must hold the rcu_node's ->lock. | 242 | * answer, it must hold the rcu_node's ->lock. |
@@ -310,7 +302,7 @@ static struct list_head *rcu_next_node_entry(struct task_struct *t, | |||
310 | * notify RCU core processing or task having blocked during the RCU | 302 | * notify RCU core processing or task having blocked during the RCU |
311 | * read-side critical section. | 303 | * read-side critical section. |
312 | */ | 304 | */ |
313 | static noinline void rcu_read_unlock_special(struct task_struct *t) | 305 | void rcu_read_unlock_special(struct task_struct *t) |
314 | { | 306 | { |
315 | int empty; | 307 | int empty; |
316 | int empty_exp; | 308 | int empty_exp; |
@@ -398,8 +390,9 @@ static noinline void rcu_read_unlock_special(struct task_struct *t) | |||
398 | rnp->grphi, | 390 | rnp->grphi, |
399 | !!rnp->gp_tasks); | 391 | !!rnp->gp_tasks); |
400 | rcu_report_unblock_qs_rnp(rnp, flags); | 392 | rcu_report_unblock_qs_rnp(rnp, flags); |
401 | } else | 393 | } else { |
402 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | 394 | raw_spin_unlock_irqrestore(&rnp->lock, flags); |
395 | } | ||
403 | 396 | ||
404 | #ifdef CONFIG_RCU_BOOST | 397 | #ifdef CONFIG_RCU_BOOST |
405 | /* Unboost if we were boosted. */ | 398 | /* Unboost if we were boosted. */ |
@@ -418,38 +411,6 @@ static noinline void rcu_read_unlock_special(struct task_struct *t) | |||
418 | } | 411 | } |
419 | } | 412 | } |
420 | 413 | ||
421 | /* | ||
422 | * Tree-preemptible RCU implementation for rcu_read_unlock(). | ||
423 | * Decrement ->rcu_read_lock_nesting. If the result is zero (outermost | ||
424 | * rcu_read_unlock()) and ->rcu_read_unlock_special is non-zero, then | ||
425 | * invoke rcu_read_unlock_special() to clean up after a context switch | ||
426 | * in an RCU read-side critical section and other special cases. | ||
427 | */ | ||
428 | void __rcu_read_unlock(void) | ||
429 | { | ||
430 | struct task_struct *t = current; | ||
431 | |||
432 | if (t->rcu_read_lock_nesting != 1) | ||
433 | --t->rcu_read_lock_nesting; | ||
434 | else { | ||
435 | barrier(); /* critical section before exit code. */ | ||
436 | t->rcu_read_lock_nesting = INT_MIN; | ||
437 | barrier(); /* assign before ->rcu_read_unlock_special load */ | ||
438 | if (unlikely(ACCESS_ONCE(t->rcu_read_unlock_special))) | ||
439 | rcu_read_unlock_special(t); | ||
440 | barrier(); /* ->rcu_read_unlock_special load before assign */ | ||
441 | t->rcu_read_lock_nesting = 0; | ||
442 | } | ||
443 | #ifdef CONFIG_PROVE_LOCKING | ||
444 | { | ||
445 | int rrln = ACCESS_ONCE(t->rcu_read_lock_nesting); | ||
446 | |||
447 | WARN_ON_ONCE(rrln < 0 && rrln > INT_MIN / 2); | ||
448 | } | ||
449 | #endif /* #ifdef CONFIG_PROVE_LOCKING */ | ||
450 | } | ||
451 | EXPORT_SYMBOL_GPL(__rcu_read_unlock); | ||
452 | |||
453 | #ifdef CONFIG_RCU_CPU_STALL_VERBOSE | 414 | #ifdef CONFIG_RCU_CPU_STALL_VERBOSE |
454 | 415 | ||
455 | /* | 416 | /* |
@@ -540,16 +501,6 @@ static int rcu_print_task_stall(struct rcu_node *rnp) | |||
540 | } | 501 | } |
541 | 502 | ||
542 | /* | 503 | /* |
543 | * Suppress preemptible RCU's CPU stall warnings by pushing the | ||
544 | * time of the next stall-warning message comfortably far into the | ||
545 | * future. | ||
546 | */ | ||
547 | static void rcu_preempt_stall_reset(void) | ||
548 | { | ||
549 | rcu_preempt_state.jiffies_stall = jiffies + ULONG_MAX / 2; | ||
550 | } | ||
551 | |||
552 | /* | ||
553 | * Check that the list of blocked tasks for the newly completed grace | 504 | * Check that the list of blocked tasks for the newly completed grace |
554 | * period is in fact empty. It is a serious bug to complete a grace | 505 | * period is in fact empty. It is a serious bug to complete a grace |
555 | * period that still has RCU readers blocked! This function must be | 506 | * period that still has RCU readers blocked! This function must be |
@@ -650,14 +601,6 @@ static int rcu_preempt_offline_tasks(struct rcu_state *rsp, | |||
650 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | 601 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ |
651 | 602 | ||
652 | /* | 603 | /* |
653 | * Do CPU-offline processing for preemptible RCU. | ||
654 | */ | ||
655 | static void rcu_preempt_cleanup_dead_cpu(int cpu) | ||
656 | { | ||
657 | rcu_cleanup_dead_cpu(cpu, &rcu_preempt_state); | ||
658 | } | ||
659 | |||
660 | /* | ||
661 | * Check for a quiescent state from the current CPU. When a task blocks, | 604 | * Check for a quiescent state from the current CPU. When a task blocks, |
662 | * the task is recorded in the corresponding CPU's rcu_node structure, | 605 | * the task is recorded in the corresponding CPU's rcu_node structure, |
663 | * which is checked elsewhere. | 606 | * which is checked elsewhere. |
@@ -677,15 +620,6 @@ static void rcu_preempt_check_callbacks(int cpu) | |||
677 | t->rcu_read_unlock_special |= RCU_READ_UNLOCK_NEED_QS; | 620 | t->rcu_read_unlock_special |= RCU_READ_UNLOCK_NEED_QS; |
678 | } | 621 | } |
679 | 622 | ||
680 | /* | ||
681 | * Process callbacks for preemptible RCU. | ||
682 | */ | ||
683 | static void rcu_preempt_process_callbacks(void) | ||
684 | { | ||
685 | __rcu_process_callbacks(&rcu_preempt_state, | ||
686 | &__get_cpu_var(rcu_preempt_data)); | ||
687 | } | ||
688 | |||
689 | #ifdef CONFIG_RCU_BOOST | 623 | #ifdef CONFIG_RCU_BOOST |
690 | 624 | ||
691 | static void rcu_preempt_do_callbacks(void) | 625 | static void rcu_preempt_do_callbacks(void) |
@@ -824,9 +758,9 @@ sync_rcu_preempt_exp_init(struct rcu_state *rsp, struct rcu_node *rnp) | |||
824 | int must_wait = 0; | 758 | int must_wait = 0; |
825 | 759 | ||
826 | raw_spin_lock_irqsave(&rnp->lock, flags); | 760 | raw_spin_lock_irqsave(&rnp->lock, flags); |
827 | if (list_empty(&rnp->blkd_tasks)) | 761 | if (list_empty(&rnp->blkd_tasks)) { |
828 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | 762 | raw_spin_unlock_irqrestore(&rnp->lock, flags); |
829 | else { | 763 | } else { |
830 | rnp->exp_tasks = rnp->blkd_tasks.next; | 764 | rnp->exp_tasks = rnp->blkd_tasks.next; |
831 | rcu_initiate_boost(rnp, flags); /* releases rnp->lock */ | 765 | rcu_initiate_boost(rnp, flags); /* releases rnp->lock */ |
832 | must_wait = 1; | 766 | must_wait = 1; |
@@ -870,9 +804,9 @@ void synchronize_rcu_expedited(void) | |||
870 | * expedited grace period for us, just leave. | 804 | * expedited grace period for us, just leave. |
871 | */ | 805 | */ |
872 | while (!mutex_trylock(&sync_rcu_preempt_exp_mutex)) { | 806 | while (!mutex_trylock(&sync_rcu_preempt_exp_mutex)) { |
873 | if (trycount++ < 10) | 807 | if (trycount++ < 10) { |
874 | udelay(trycount * num_online_cpus()); | 808 | udelay(trycount * num_online_cpus()); |
875 | else { | 809 | } else { |
876 | synchronize_rcu(); | 810 | synchronize_rcu(); |
877 | return; | 811 | return; |
878 | } | 812 | } |
@@ -917,51 +851,16 @@ mb_ret: | |||
917 | } | 851 | } |
918 | EXPORT_SYMBOL_GPL(synchronize_rcu_expedited); | 852 | EXPORT_SYMBOL_GPL(synchronize_rcu_expedited); |
919 | 853 | ||
920 | /* | ||
921 | * Check to see if there is any immediate preemptible-RCU-related work | ||
922 | * to be done. | ||
923 | */ | ||
924 | static int rcu_preempt_pending(int cpu) | ||
925 | { | ||
926 | return __rcu_pending(&rcu_preempt_state, | ||
927 | &per_cpu(rcu_preempt_data, cpu)); | ||
928 | } | ||
929 | |||
930 | /* | ||
931 | * Does preemptible RCU have callbacks on this CPU? | ||
932 | */ | ||
933 | static int rcu_preempt_cpu_has_callbacks(int cpu) | ||
934 | { | ||
935 | return !!per_cpu(rcu_preempt_data, cpu).nxtlist; | ||
936 | } | ||
937 | |||
938 | /** | 854 | /** |
939 | * rcu_barrier - Wait until all in-flight call_rcu() callbacks complete. | 855 | * rcu_barrier - Wait until all in-flight call_rcu() callbacks complete. |
940 | */ | 856 | */ |
941 | void rcu_barrier(void) | 857 | void rcu_barrier(void) |
942 | { | 858 | { |
943 | _rcu_barrier(&rcu_preempt_state, call_rcu); | 859 | _rcu_barrier(&rcu_preempt_state); |
944 | } | 860 | } |
945 | EXPORT_SYMBOL_GPL(rcu_barrier); | 861 | EXPORT_SYMBOL_GPL(rcu_barrier); |
946 | 862 | ||
947 | /* | 863 | /* |
948 | * Initialize preemptible RCU's per-CPU data. | ||
949 | */ | ||
950 | static void __cpuinit rcu_preempt_init_percpu_data(int cpu) | ||
951 | { | ||
952 | rcu_init_percpu_data(cpu, &rcu_preempt_state, 1); | ||
953 | } | ||
954 | |||
955 | /* | ||
956 | * Move preemptible RCU's callbacks from dying CPU to other online CPU | ||
957 | * and record a quiescent state. | ||
958 | */ | ||
959 | static void rcu_preempt_cleanup_dying_cpu(void) | ||
960 | { | ||
961 | rcu_cleanup_dying_cpu(&rcu_preempt_state); | ||
962 | } | ||
963 | |||
964 | /* | ||
965 | * Initialize preemptible RCU's state structures. | 864 | * Initialize preemptible RCU's state structures. |
966 | */ | 865 | */ |
967 | static void __init __rcu_init_preempt(void) | 866 | static void __init __rcu_init_preempt(void) |
@@ -1046,14 +945,6 @@ static int rcu_print_task_stall(struct rcu_node *rnp) | |||
1046 | } | 945 | } |
1047 | 946 | ||
1048 | /* | 947 | /* |
1049 | * Because preemptible RCU does not exist, there is no need to suppress | ||
1050 | * its CPU stall warnings. | ||
1051 | */ | ||
1052 | static void rcu_preempt_stall_reset(void) | ||
1053 | { | ||
1054 | } | ||
1055 | |||
1056 | /* | ||
1057 | * Because there is no preemptible RCU, there can be no readers blocked, | 948 | * Because there is no preemptible RCU, there can be no readers blocked, |
1058 | * so there is no need to check for blocked tasks. So check only for | 949 | * so there is no need to check for blocked tasks. So check only for |
1059 | * bogus qsmask values. | 950 | * bogus qsmask values. |
@@ -1081,14 +972,6 @@ static int rcu_preempt_offline_tasks(struct rcu_state *rsp, | |||
1081 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | 972 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ |
1082 | 973 | ||
1083 | /* | 974 | /* |
1084 | * Because preemptible RCU does not exist, it never needs CPU-offline | ||
1085 | * processing. | ||
1086 | */ | ||
1087 | static void rcu_preempt_cleanup_dead_cpu(int cpu) | ||
1088 | { | ||
1089 | } | ||
1090 | |||
1091 | /* | ||
1092 | * Because preemptible RCU does not exist, it never has any callbacks | 975 | * Because preemptible RCU does not exist, it never has any callbacks |
1093 | * to check. | 976 | * to check. |
1094 | */ | 977 | */ |
@@ -1097,14 +980,6 @@ static void rcu_preempt_check_callbacks(int cpu) | |||
1097 | } | 980 | } |
1098 | 981 | ||
1099 | /* | 982 | /* |
1100 | * Because preemptible RCU does not exist, it never has any callbacks | ||
1101 | * to process. | ||
1102 | */ | ||
1103 | static void rcu_preempt_process_callbacks(void) | ||
1104 | { | ||
1105 | } | ||
1106 | |||
1107 | /* | ||
1108 | * Queue an RCU callback for lazy invocation after a grace period. | 983 | * Queue an RCU callback for lazy invocation after a grace period. |
1109 | * This will likely be later named something like "call_rcu_lazy()", | 984 | * This will likely be later named something like "call_rcu_lazy()", |
1110 | * but this change will require some way of tagging the lazy RCU | 985 | * but this change will require some way of tagging the lazy RCU |
@@ -1145,22 +1020,6 @@ static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp, | |||
1145 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ | 1020 | #endif /* #ifdef CONFIG_HOTPLUG_CPU */ |
1146 | 1021 | ||
1147 | /* | 1022 | /* |
1148 | * Because preemptible RCU does not exist, it never has any work to do. | ||
1149 | */ | ||
1150 | static int rcu_preempt_pending(int cpu) | ||
1151 | { | ||
1152 | return 0; | ||
1153 | } | ||
1154 | |||
1155 | /* | ||
1156 | * Because preemptible RCU does not exist, it never has callbacks | ||
1157 | */ | ||
1158 | static int rcu_preempt_cpu_has_callbacks(int cpu) | ||
1159 | { | ||
1160 | return 0; | ||
1161 | } | ||
1162 | |||
1163 | /* | ||
1164 | * Because preemptible RCU does not exist, rcu_barrier() is just | 1023 | * Because preemptible RCU does not exist, rcu_barrier() is just |
1165 | * another name for rcu_barrier_sched(). | 1024 | * another name for rcu_barrier_sched(). |
1166 | */ | 1025 | */ |
@@ -1171,21 +1030,6 @@ void rcu_barrier(void) | |||
1171 | EXPORT_SYMBOL_GPL(rcu_barrier); | 1030 | EXPORT_SYMBOL_GPL(rcu_barrier); |
1172 | 1031 | ||
1173 | /* | 1032 | /* |
1174 | * Because preemptible RCU does not exist, there is no per-CPU | ||
1175 | * data to initialize. | ||
1176 | */ | ||
1177 | static void __cpuinit rcu_preempt_init_percpu_data(int cpu) | ||
1178 | { | ||
1179 | } | ||
1180 | |||
1181 | /* | ||
1182 | * Because there is no preemptible RCU, there is no cleanup to do. | ||
1183 | */ | ||
1184 | static void rcu_preempt_cleanup_dying_cpu(void) | ||
1185 | { | ||
1186 | } | ||
1187 | |||
1188 | /* | ||
1189 | * Because preemptible RCU does not exist, it need not be initialized. | 1033 | * Because preemptible RCU does not exist, it need not be initialized. |
1190 | */ | 1034 | */ |
1191 | static void __init __rcu_init_preempt(void) | 1035 | static void __init __rcu_init_preempt(void) |
@@ -1968,9 +1812,11 @@ static void rcu_idle_count_callbacks_posted(void) | |||
1968 | */ | 1812 | */ |
1969 | #define RCU_IDLE_FLUSHES 5 /* Number of dyntick-idle tries. */ | 1813 | #define RCU_IDLE_FLUSHES 5 /* Number of dyntick-idle tries. */ |
1970 | #define RCU_IDLE_OPT_FLUSHES 3 /* Optional dyntick-idle tries. */ | 1814 | #define RCU_IDLE_OPT_FLUSHES 3 /* Optional dyntick-idle tries. */ |
1971 | #define RCU_IDLE_GP_DELAY 6 /* Roughly one grace period. */ | 1815 | #define RCU_IDLE_GP_DELAY 4 /* Roughly one grace period. */ |
1972 | #define RCU_IDLE_LAZY_GP_DELAY (6 * HZ) /* Roughly six seconds. */ | 1816 | #define RCU_IDLE_LAZY_GP_DELAY (6 * HZ) /* Roughly six seconds. */ |
1973 | 1817 | ||
1818 | extern int tick_nohz_enabled; | ||
1819 | |||
1974 | /* | 1820 | /* |
1975 | * Does the specified flavor of RCU have non-lazy callbacks pending on | 1821 | * Does the specified flavor of RCU have non-lazy callbacks pending on |
1976 | * the specified CPU? Both RCU flavor and CPU are specified by the | 1822 | * the specified CPU? Both RCU flavor and CPU are specified by the |
@@ -2047,10 +1893,13 @@ int rcu_needs_cpu(int cpu, unsigned long *delta_jiffies) | |||
2047 | return 1; | 1893 | return 1; |
2048 | } | 1894 | } |
2049 | /* Set up for the possibility that RCU will post a timer. */ | 1895 | /* Set up for the possibility that RCU will post a timer. */ |
2050 | if (rcu_cpu_has_nonlazy_callbacks(cpu)) | 1896 | if (rcu_cpu_has_nonlazy_callbacks(cpu)) { |
2051 | *delta_jiffies = RCU_IDLE_GP_DELAY; | 1897 | *delta_jiffies = round_up(RCU_IDLE_GP_DELAY + jiffies, |
2052 | else | 1898 | RCU_IDLE_GP_DELAY) - jiffies; |
2053 | *delta_jiffies = RCU_IDLE_LAZY_GP_DELAY; | 1899 | } else { |
1900 | *delta_jiffies = jiffies + RCU_IDLE_LAZY_GP_DELAY; | ||
1901 | *delta_jiffies = round_jiffies(*delta_jiffies) - jiffies; | ||
1902 | } | ||
2054 | return 0; | 1903 | return 0; |
2055 | } | 1904 | } |
2056 | 1905 | ||
@@ -2109,6 +1958,7 @@ static void rcu_cleanup_after_idle(int cpu) | |||
2109 | 1958 | ||
2110 | del_timer(&rdtp->idle_gp_timer); | 1959 | del_timer(&rdtp->idle_gp_timer); |
2111 | trace_rcu_prep_idle("Cleanup after idle"); | 1960 | trace_rcu_prep_idle("Cleanup after idle"); |
1961 | rdtp->tick_nohz_enabled_snap = ACCESS_ONCE(tick_nohz_enabled); | ||
2112 | } | 1962 | } |
2113 | 1963 | ||
2114 | /* | 1964 | /* |
@@ -2134,6 +1984,18 @@ static void rcu_prepare_for_idle(int cpu) | |||
2134 | { | 1984 | { |
2135 | struct timer_list *tp; | 1985 | struct timer_list *tp; |
2136 | struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu); | 1986 | struct rcu_dynticks *rdtp = &per_cpu(rcu_dynticks, cpu); |
1987 | int tne; | ||
1988 | |||
1989 | /* Handle nohz enablement switches conservatively. */ | ||
1990 | tne = ACCESS_ONCE(tick_nohz_enabled); | ||
1991 | if (tne != rdtp->tick_nohz_enabled_snap) { | ||
1992 | if (rcu_cpu_has_callbacks(cpu)) | ||
1993 | invoke_rcu_core(); /* force nohz to see update. */ | ||
1994 | rdtp->tick_nohz_enabled_snap = tne; | ||
1995 | return; | ||
1996 | } | ||
1997 | if (!tne) | ||
1998 | return; | ||
2137 | 1999 | ||
2138 | /* | 2000 | /* |
2139 | * If this is an idle re-entry, for example, due to use of | 2001 | * If this is an idle re-entry, for example, due to use of |
@@ -2187,10 +2049,11 @@ static void rcu_prepare_for_idle(int cpu) | |||
2187 | if (rcu_cpu_has_nonlazy_callbacks(cpu)) { | 2049 | if (rcu_cpu_has_nonlazy_callbacks(cpu)) { |
2188 | trace_rcu_prep_idle("Dyntick with callbacks"); | 2050 | trace_rcu_prep_idle("Dyntick with callbacks"); |
2189 | rdtp->idle_gp_timer_expires = | 2051 | rdtp->idle_gp_timer_expires = |
2190 | jiffies + RCU_IDLE_GP_DELAY; | 2052 | round_up(jiffies + RCU_IDLE_GP_DELAY, |
2053 | RCU_IDLE_GP_DELAY); | ||
2191 | } else { | 2054 | } else { |
2192 | rdtp->idle_gp_timer_expires = | 2055 | rdtp->idle_gp_timer_expires = |
2193 | jiffies + RCU_IDLE_LAZY_GP_DELAY; | 2056 | round_jiffies(jiffies + RCU_IDLE_LAZY_GP_DELAY); |
2194 | trace_rcu_prep_idle("Dyntick with lazy callbacks"); | 2057 | trace_rcu_prep_idle("Dyntick with lazy callbacks"); |
2195 | } | 2058 | } |
2196 | tp = &rdtp->idle_gp_timer; | 2059 | tp = &rdtp->idle_gp_timer; |
@@ -2231,8 +2094,9 @@ static void rcu_prepare_for_idle(int cpu) | |||
2231 | if (rcu_cpu_has_callbacks(cpu)) { | 2094 | if (rcu_cpu_has_callbacks(cpu)) { |
2232 | trace_rcu_prep_idle("More callbacks"); | 2095 | trace_rcu_prep_idle("More callbacks"); |
2233 | invoke_rcu_core(); | 2096 | invoke_rcu_core(); |
2234 | } else | 2097 | } else { |
2235 | trace_rcu_prep_idle("Callbacks drained"); | 2098 | trace_rcu_prep_idle("Callbacks drained"); |
2099 | } | ||
2236 | } | 2100 | } |
2237 | 2101 | ||
2238 | /* | 2102 | /* |
@@ -2269,6 +2133,7 @@ static void print_cpu_stall_fast_no_hz(char *cp, int cpu) | |||
2269 | 2133 | ||
2270 | static void print_cpu_stall_fast_no_hz(char *cp, int cpu) | 2134 | static void print_cpu_stall_fast_no_hz(char *cp, int cpu) |
2271 | { | 2135 | { |
2136 | *cp = '\0'; | ||
2272 | } | 2137 | } |
2273 | 2138 | ||
2274 | #endif /* #else #ifdef CONFIG_RCU_FAST_NO_HZ */ | 2139 | #endif /* #else #ifdef CONFIG_RCU_FAST_NO_HZ */ |
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index d4bc16ddd1d4..abffb486e94e 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c | |||
@@ -46,6 +46,31 @@ | |||
46 | #define RCU_TREE_NONCORE | 46 | #define RCU_TREE_NONCORE |
47 | #include "rcutree.h" | 47 | #include "rcutree.h" |
48 | 48 | ||
49 | static int show_rcubarrier(struct seq_file *m, void *unused) | ||
50 | { | ||
51 | struct rcu_state *rsp; | ||
52 | |||
53 | for_each_rcu_flavor(rsp) | ||
54 | seq_printf(m, "%s: %c bcc: %d nbd: %lu\n", | ||
55 | rsp->name, rsp->rcu_barrier_in_progress ? 'B' : '.', | ||
56 | atomic_read(&rsp->barrier_cpu_count), | ||
57 | rsp->n_barrier_done); | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static int rcubarrier_open(struct inode *inode, struct file *file) | ||
62 | { | ||
63 | return single_open(file, show_rcubarrier, NULL); | ||
64 | } | ||
65 | |||
66 | static const struct file_operations rcubarrier_fops = { | ||
67 | .owner = THIS_MODULE, | ||
68 | .open = rcubarrier_open, | ||
69 | .read = seq_read, | ||
70 | .llseek = seq_lseek, | ||
71 | .release = single_release, | ||
72 | }; | ||
73 | |||
49 | #ifdef CONFIG_RCU_BOOST | 74 | #ifdef CONFIG_RCU_BOOST |
50 | 75 | ||
51 | static char convert_kthread_status(unsigned int kthread_status) | 76 | static char convert_kthread_status(unsigned int kthread_status) |
@@ -95,24 +120,16 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) | |||
95 | rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); | 120 | rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); |
96 | } | 121 | } |
97 | 122 | ||
98 | #define PRINT_RCU_DATA(name, func, m) \ | ||
99 | do { \ | ||
100 | int _p_r_d_i; \ | ||
101 | \ | ||
102 | for_each_possible_cpu(_p_r_d_i) \ | ||
103 | func(m, &per_cpu(name, _p_r_d_i)); \ | ||
104 | } while (0) | ||
105 | |||
106 | static int show_rcudata(struct seq_file *m, void *unused) | 123 | static int show_rcudata(struct seq_file *m, void *unused) |
107 | { | 124 | { |
108 | #ifdef CONFIG_TREE_PREEMPT_RCU | 125 | int cpu; |
109 | seq_puts(m, "rcu_preempt:\n"); | 126 | struct rcu_state *rsp; |
110 | PRINT_RCU_DATA(rcu_preempt_data, print_one_rcu_data, m); | 127 | |
111 | #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */ | 128 | for_each_rcu_flavor(rsp) { |
112 | seq_puts(m, "rcu_sched:\n"); | 129 | seq_printf(m, "%s:\n", rsp->name); |
113 | PRINT_RCU_DATA(rcu_sched_data, print_one_rcu_data, m); | 130 | for_each_possible_cpu(cpu) |
114 | seq_puts(m, "rcu_bh:\n"); | 131 | print_one_rcu_data(m, per_cpu_ptr(rsp->rda, cpu)); |
115 | PRINT_RCU_DATA(rcu_bh_data, print_one_rcu_data, m); | 132 | } |
116 | return 0; | 133 | return 0; |
117 | } | 134 | } |
118 | 135 | ||
@@ -166,6 +183,9 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp) | |||
166 | 183 | ||
167 | static int show_rcudata_csv(struct seq_file *m, void *unused) | 184 | static int show_rcudata_csv(struct seq_file *m, void *unused) |
168 | { | 185 | { |
186 | int cpu; | ||
187 | struct rcu_state *rsp; | ||
188 | |||
169 | seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pgp\",\"pq\","); | 189 | seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pgp\",\"pq\","); |
170 | seq_puts(m, "\"dt\",\"dt nesting\",\"dt NMI nesting\",\"df\","); | 190 | seq_puts(m, "\"dt\",\"dt nesting\",\"dt NMI nesting\",\"df\","); |
171 | seq_puts(m, "\"of\",\"qll\",\"ql\",\"qs\""); | 191 | seq_puts(m, "\"of\",\"qll\",\"ql\",\"qs\""); |
@@ -173,14 +193,11 @@ static int show_rcudata_csv(struct seq_file *m, void *unused) | |||
173 | seq_puts(m, "\"kt\",\"ktl\""); | 193 | seq_puts(m, "\"kt\",\"ktl\""); |
174 | #endif /* #ifdef CONFIG_RCU_BOOST */ | 194 | #endif /* #ifdef CONFIG_RCU_BOOST */ |
175 | seq_puts(m, ",\"b\",\"ci\",\"co\",\"ca\"\n"); | 195 | seq_puts(m, ",\"b\",\"ci\",\"co\",\"ca\"\n"); |
176 | #ifdef CONFIG_TREE_PREEMPT_RCU | 196 | for_each_rcu_flavor(rsp) { |
177 | seq_puts(m, "\"rcu_preempt:\"\n"); | 197 | seq_printf(m, "\"%s:\"\n", rsp->name); |
178 | PRINT_RCU_DATA(rcu_preempt_data, print_one_rcu_data_csv, m); | 198 | for_each_possible_cpu(cpu) |
179 | #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */ | 199 | print_one_rcu_data_csv(m, per_cpu_ptr(rsp->rda, cpu)); |
180 | seq_puts(m, "\"rcu_sched:\"\n"); | 200 | } |
181 | PRINT_RCU_DATA(rcu_sched_data, print_one_rcu_data_csv, m); | ||
182 | seq_puts(m, "\"rcu_bh:\"\n"); | ||
183 | PRINT_RCU_DATA(rcu_bh_data, print_one_rcu_data_csv, m); | ||
184 | return 0; | 201 | return 0; |
185 | } | 202 | } |
186 | 203 | ||
@@ -201,8 +218,7 @@ static const struct file_operations rcudata_csv_fops = { | |||
201 | 218 | ||
202 | static void print_one_rcu_node_boost(struct seq_file *m, struct rcu_node *rnp) | 219 | static void print_one_rcu_node_boost(struct seq_file *m, struct rcu_node *rnp) |
203 | { | 220 | { |
204 | seq_printf(m, "%d:%d tasks=%c%c%c%c kt=%c ntb=%lu neb=%lu nnb=%lu " | 221 | seq_printf(m, "%d:%d tasks=%c%c%c%c kt=%c ntb=%lu neb=%lu nnb=%lu ", |
205 | "j=%04x bt=%04x\n", | ||
206 | rnp->grplo, rnp->grphi, | 222 | rnp->grplo, rnp->grphi, |
207 | "T."[list_empty(&rnp->blkd_tasks)], | 223 | "T."[list_empty(&rnp->blkd_tasks)], |
208 | "N."[!rnp->gp_tasks], | 224 | "N."[!rnp->gp_tasks], |
@@ -210,11 +226,11 @@ static void print_one_rcu_node_boost(struct seq_file *m, struct rcu_node *rnp) | |||
210 | "B."[!rnp->boost_tasks], | 226 | "B."[!rnp->boost_tasks], |
211 | convert_kthread_status(rnp->boost_kthread_status), | 227 | convert_kthread_status(rnp->boost_kthread_status), |
212 | rnp->n_tasks_boosted, rnp->n_exp_boosts, | 228 | rnp->n_tasks_boosted, rnp->n_exp_boosts, |
213 | rnp->n_normal_boosts, | 229 | rnp->n_normal_boosts); |
230 | seq_printf(m, "j=%04x bt=%04x\n", | ||
214 | (int)(jiffies & 0xffff), | 231 | (int)(jiffies & 0xffff), |
215 | (int)(rnp->boost_time & 0xffff)); | 232 | (int)(rnp->boost_time & 0xffff)); |
216 | seq_printf(m, "%s: nt=%lu egt=%lu bt=%lu nb=%lu ny=%lu nos=%lu\n", | 233 | seq_printf(m, " balk: nt=%lu egt=%lu bt=%lu nb=%lu ny=%lu nos=%lu\n", |
217 | " balk", | ||
218 | rnp->n_balk_blkd_tasks, | 234 | rnp->n_balk_blkd_tasks, |
219 | rnp->n_balk_exp_gp_tasks, | 235 | rnp->n_balk_exp_gp_tasks, |
220 | rnp->n_balk_boost_tasks, | 236 | rnp->n_balk_boost_tasks, |
@@ -270,15 +286,15 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp) | |||
270 | struct rcu_node *rnp; | 286 | struct rcu_node *rnp; |
271 | 287 | ||
272 | gpnum = rsp->gpnum; | 288 | gpnum = rsp->gpnum; |
273 | seq_printf(m, "c=%lu g=%lu s=%d jfq=%ld j=%x " | 289 | seq_printf(m, "%s: c=%lu g=%lu s=%d jfq=%ld j=%x ", |
274 | "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld/%ld\n", | 290 | rsp->name, rsp->completed, gpnum, rsp->fqs_state, |
275 | rsp->completed, gpnum, rsp->fqs_state, | ||
276 | (long)(rsp->jiffies_force_qs - jiffies), | 291 | (long)(rsp->jiffies_force_qs - jiffies), |
277 | (int)(jiffies & 0xffff), | 292 | (int)(jiffies & 0xffff)); |
293 | seq_printf(m, "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld/%ld\n", | ||
278 | rsp->n_force_qs, rsp->n_force_qs_ngp, | 294 | rsp->n_force_qs, rsp->n_force_qs_ngp, |
279 | rsp->n_force_qs - rsp->n_force_qs_ngp, | 295 | rsp->n_force_qs - rsp->n_force_qs_ngp, |
280 | rsp->n_force_qs_lh, rsp->qlen_lazy, rsp->qlen); | 296 | rsp->n_force_qs_lh, rsp->qlen_lazy, rsp->qlen); |
281 | for (rnp = &rsp->node[0]; rnp - &rsp->node[0] < NUM_RCU_NODES; rnp++) { | 297 | for (rnp = &rsp->node[0]; rnp - &rsp->node[0] < rcu_num_nodes; rnp++) { |
282 | if (rnp->level != level) { | 298 | if (rnp->level != level) { |
283 | seq_puts(m, "\n"); | 299 | seq_puts(m, "\n"); |
284 | level = rnp->level; | 300 | level = rnp->level; |
@@ -295,14 +311,10 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp) | |||
295 | 311 | ||
296 | static int show_rcuhier(struct seq_file *m, void *unused) | 312 | static int show_rcuhier(struct seq_file *m, void *unused) |
297 | { | 313 | { |
298 | #ifdef CONFIG_TREE_PREEMPT_RCU | 314 | struct rcu_state *rsp; |
299 | seq_puts(m, "rcu_preempt:\n"); | 315 | |
300 | print_one_rcu_state(m, &rcu_preempt_state); | 316 | for_each_rcu_flavor(rsp) |
301 | #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */ | 317 | print_one_rcu_state(m, rsp); |
302 | seq_puts(m, "rcu_sched:\n"); | ||
303 | print_one_rcu_state(m, &rcu_sched_state); | ||
304 | seq_puts(m, "rcu_bh:\n"); | ||
305 | print_one_rcu_state(m, &rcu_bh_state); | ||
306 | return 0; | 318 | return 0; |
307 | } | 319 | } |
308 | 320 | ||
@@ -343,11 +355,10 @@ static void show_one_rcugp(struct seq_file *m, struct rcu_state *rsp) | |||
343 | 355 | ||
344 | static int show_rcugp(struct seq_file *m, void *unused) | 356 | static int show_rcugp(struct seq_file *m, void *unused) |
345 | { | 357 | { |
346 | #ifdef CONFIG_TREE_PREEMPT_RCU | 358 | struct rcu_state *rsp; |
347 | show_one_rcugp(m, &rcu_preempt_state); | 359 | |
348 | #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */ | 360 | for_each_rcu_flavor(rsp) |
349 | show_one_rcugp(m, &rcu_sched_state); | 361 | show_one_rcugp(m, rsp); |
350 | show_one_rcugp(m, &rcu_bh_state); | ||
351 | return 0; | 362 | return 0; |
352 | } | 363 | } |
353 | 364 | ||
@@ -366,44 +377,36 @@ static const struct file_operations rcugp_fops = { | |||
366 | 377 | ||
367 | static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp) | 378 | static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp) |
368 | { | 379 | { |
369 | seq_printf(m, "%3d%cnp=%ld " | 380 | seq_printf(m, "%3d%cnp=%ld ", |
370 | "qsp=%ld rpq=%ld cbr=%ld cng=%ld " | ||
371 | "gpc=%ld gps=%ld nf=%ld nn=%ld\n", | ||
372 | rdp->cpu, | 381 | rdp->cpu, |
373 | cpu_is_offline(rdp->cpu) ? '!' : ' ', | 382 | cpu_is_offline(rdp->cpu) ? '!' : ' ', |
374 | rdp->n_rcu_pending, | 383 | rdp->n_rcu_pending); |
384 | seq_printf(m, "qsp=%ld rpq=%ld cbr=%ld cng=%ld ", | ||
375 | rdp->n_rp_qs_pending, | 385 | rdp->n_rp_qs_pending, |
376 | rdp->n_rp_report_qs, | 386 | rdp->n_rp_report_qs, |
377 | rdp->n_rp_cb_ready, | 387 | rdp->n_rp_cb_ready, |
378 | rdp->n_rp_cpu_needs_gp, | 388 | rdp->n_rp_cpu_needs_gp); |
389 | seq_printf(m, "gpc=%ld gps=%ld nf=%ld nn=%ld\n", | ||
379 | rdp->n_rp_gp_completed, | 390 | rdp->n_rp_gp_completed, |
380 | rdp->n_rp_gp_started, | 391 | rdp->n_rp_gp_started, |
381 | rdp->n_rp_need_fqs, | 392 | rdp->n_rp_need_fqs, |
382 | rdp->n_rp_need_nothing); | 393 | rdp->n_rp_need_nothing); |
383 | } | 394 | } |
384 | 395 | ||
385 | static void print_rcu_pendings(struct seq_file *m, struct rcu_state *rsp) | 396 | static int show_rcu_pending(struct seq_file *m, void *unused) |
386 | { | 397 | { |
387 | int cpu; | 398 | int cpu; |
388 | struct rcu_data *rdp; | 399 | struct rcu_data *rdp; |
389 | 400 | struct rcu_state *rsp; | |
390 | for_each_possible_cpu(cpu) { | 401 | |
391 | rdp = per_cpu_ptr(rsp->rda, cpu); | 402 | for_each_rcu_flavor(rsp) { |
392 | if (rdp->beenonline) | 403 | seq_printf(m, "%s:\n", rsp->name); |
393 | print_one_rcu_pending(m, rdp); | 404 | for_each_possible_cpu(cpu) { |
405 | rdp = per_cpu_ptr(rsp->rda, cpu); | ||
406 | if (rdp->beenonline) | ||
407 | print_one_rcu_pending(m, rdp); | ||
408 | } | ||
394 | } | 409 | } |
395 | } | ||
396 | |||
397 | static int show_rcu_pending(struct seq_file *m, void *unused) | ||
398 | { | ||
399 | #ifdef CONFIG_TREE_PREEMPT_RCU | ||
400 | seq_puts(m, "rcu_preempt:\n"); | ||
401 | print_rcu_pendings(m, &rcu_preempt_state); | ||
402 | #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */ | ||
403 | seq_puts(m, "rcu_sched:\n"); | ||
404 | print_rcu_pendings(m, &rcu_sched_state); | ||
405 | seq_puts(m, "rcu_bh:\n"); | ||
406 | print_rcu_pendings(m, &rcu_bh_state); | ||
407 | return 0; | 410 | return 0; |
408 | } | 411 | } |
409 | 412 | ||
@@ -453,6 +456,11 @@ static int __init rcutree_trace_init(void) | |||
453 | if (!rcudir) | 456 | if (!rcudir) |
454 | goto free_out; | 457 | goto free_out; |
455 | 458 | ||
459 | retval = debugfs_create_file("rcubarrier", 0444, rcudir, | ||
460 | NULL, &rcubarrier_fops); | ||
461 | if (!retval) | ||
462 | goto free_out; | ||
463 | |||
456 | retval = debugfs_create_file("rcudata", 0444, rcudir, | 464 | retval = debugfs_create_file("rcudata", 0444, rcudir, |
457 | NULL, &rcudata_fops); | 465 | NULL, &rcudata_fops); |
458 | if (!retval) | 466 | if (!retval) |
diff --git a/kernel/smp.c b/kernel/smp.c index d0ae5b24875e..29dd40a9f2f4 100644 --- a/kernel/smp.c +++ b/kernel/smp.c | |||
@@ -581,26 +581,6 @@ int smp_call_function(smp_call_func_t func, void *info, int wait) | |||
581 | return 0; | 581 | return 0; |
582 | } | 582 | } |
583 | EXPORT_SYMBOL(smp_call_function); | 583 | EXPORT_SYMBOL(smp_call_function); |
584 | |||
585 | void ipi_call_lock(void) | ||
586 | { | ||
587 | raw_spin_lock(&call_function.lock); | ||
588 | } | ||
589 | |||
590 | void ipi_call_unlock(void) | ||
591 | { | ||
592 | raw_spin_unlock(&call_function.lock); | ||
593 | } | ||
594 | |||
595 | void ipi_call_lock_irq(void) | ||
596 | { | ||
597 | raw_spin_lock_irq(&call_function.lock); | ||
598 | } | ||
599 | |||
600 | void ipi_call_unlock_irq(void) | ||
601 | { | ||
602 | raw_spin_unlock_irq(&call_function.lock); | ||
603 | } | ||
604 | #endif /* USE_GENERIC_SMP_HELPERS */ | 584 | #endif /* USE_GENERIC_SMP_HELPERS */ |
605 | 585 | ||
606 | /* Setup configured maximum number of CPUs to activate */ | 586 | /* Setup configured maximum number of CPUs to activate */ |
diff --git a/kernel/smpboot.h b/kernel/smpboot.h index 80c0acfb8472..6ef9433e1c70 100644 --- a/kernel/smpboot.h +++ b/kernel/smpboot.h | |||
@@ -3,8 +3,6 @@ | |||
3 | 3 | ||
4 | struct task_struct; | 4 | struct task_struct; |
5 | 5 | ||
6 | int smpboot_prepare(unsigned int cpu); | ||
7 | |||
8 | #ifdef CONFIG_GENERIC_SMP_IDLE_THREAD | 6 | #ifdef CONFIG_GENERIC_SMP_IDLE_THREAD |
9 | struct task_struct *idle_thread_get(unsigned int cpu); | 7 | struct task_struct *idle_thread_get(unsigned int cpu); |
10 | void idle_thread_set_boot_cpu(void); | 8 | void idle_thread_set_boot_cpu(void); |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 41be02250e08..024540f97f74 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -105,7 +105,7 @@ static ktime_t tick_init_jiffy_update(void) | |||
105 | /* | 105 | /* |
106 | * NO HZ enabled ? | 106 | * NO HZ enabled ? |
107 | */ | 107 | */ |
108 | static int tick_nohz_enabled __read_mostly = 1; | 108 | int tick_nohz_enabled __read_mostly = 1; |
109 | 109 | ||
110 | /* | 110 | /* |
111 | * Enable / Disable tickless mode | 111 | * Enable / Disable tickless mode |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 8f2aba1246f2..cf364db5589f 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -745,6 +745,7 @@ static void timekeeping_resume(void) | |||
745 | timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); | 745 | timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); |
746 | timekeeper.ntp_error = 0; | 746 | timekeeper.ntp_error = 0; |
747 | timekeeping_suspended = 0; | 747 | timekeeping_suspended = 0; |
748 | timekeeping_update(&timekeeper, false); | ||
748 | write_sequnlock_irqrestore(&timekeeper.lock, flags); | 749 | write_sequnlock_irqrestore(&timekeeper.lock, flags); |
749 | 750 | ||
750 | touch_softlockup_watchdog(); | 751 | touch_softlockup_watchdog(); |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index a008663d86c8..b4f20fba09fc 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -312,7 +312,7 @@ static int remove_ftrace_list_ops(struct ftrace_ops **list, | |||
312 | 312 | ||
313 | static int __register_ftrace_function(struct ftrace_ops *ops) | 313 | static int __register_ftrace_function(struct ftrace_ops *ops) |
314 | { | 314 | { |
315 | if (ftrace_disabled) | 315 | if (unlikely(ftrace_disabled)) |
316 | return -ENODEV; | 316 | return -ENODEV; |
317 | 317 | ||
318 | if (FTRACE_WARN_ON(ops == &global_ops)) | 318 | if (FTRACE_WARN_ON(ops == &global_ops)) |
@@ -4299,16 +4299,12 @@ int register_ftrace_function(struct ftrace_ops *ops) | |||
4299 | 4299 | ||
4300 | mutex_lock(&ftrace_lock); | 4300 | mutex_lock(&ftrace_lock); |
4301 | 4301 | ||
4302 | if (unlikely(ftrace_disabled)) | ||
4303 | goto out_unlock; | ||
4304 | |||
4305 | ret = __register_ftrace_function(ops); | 4302 | ret = __register_ftrace_function(ops); |
4306 | if (!ret) | 4303 | if (!ret) |
4307 | ret = ftrace_startup(ops, 0); | 4304 | ret = ftrace_startup(ops, 0); |
4308 | 4305 | ||
4309 | |||
4310 | out_unlock: | ||
4311 | mutex_unlock(&ftrace_lock); | 4306 | mutex_unlock(&ftrace_lock); |
4307 | |||
4312 | return ret; | 4308 | return ret; |
4313 | } | 4309 | } |
4314 | EXPORT_SYMBOL_GPL(register_ftrace_function); | 4310 | EXPORT_SYMBOL_GPL(register_ftrace_function); |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index f765465bffe4..49491fa7daa2 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -3239,6 +3239,10 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) | |||
3239 | if (cpu_buffer->commit_page == cpu_buffer->reader_page) | 3239 | if (cpu_buffer->commit_page == cpu_buffer->reader_page) |
3240 | goto out; | 3240 | goto out; |
3241 | 3241 | ||
3242 | /* Don't bother swapping if the ring buffer is empty */ | ||
3243 | if (rb_num_of_entries(cpu_buffer) == 0) | ||
3244 | goto out; | ||
3245 | |||
3242 | /* | 3246 | /* |
3243 | * Reset the reader page to size zero. | 3247 | * Reset the reader page to size zero. |
3244 | */ | 3248 | */ |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a7fa0702be1c..a120f98c4112 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -830,6 +830,8 @@ int register_tracer(struct tracer *type) | |||
830 | current_trace = saved_tracer; | 830 | current_trace = saved_tracer; |
831 | if (ret) { | 831 | if (ret) { |
832 | printk(KERN_CONT "FAILED!\n"); | 832 | printk(KERN_CONT "FAILED!\n"); |
833 | /* Add the warning after printing 'FAILED' */ | ||
834 | WARN_ON(1); | ||
833 | goto out; | 835 | goto out; |
834 | } | 836 | } |
835 | /* Only reset on passing, to avoid touching corrupted buffers */ | 837 | /* Only reset on passing, to avoid touching corrupted buffers */ |
@@ -1708,9 +1710,11 @@ EXPORT_SYMBOL_GPL(trace_vprintk); | |||
1708 | 1710 | ||
1709 | static void trace_iterator_increment(struct trace_iterator *iter) | 1711 | static void trace_iterator_increment(struct trace_iterator *iter) |
1710 | { | 1712 | { |
1713 | struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, iter->cpu); | ||
1714 | |||
1711 | iter->idx++; | 1715 | iter->idx++; |
1712 | if (iter->buffer_iter[iter->cpu]) | 1716 | if (buf_iter) |
1713 | ring_buffer_read(iter->buffer_iter[iter->cpu], NULL); | 1717 | ring_buffer_read(buf_iter, NULL); |
1714 | } | 1718 | } |
1715 | 1719 | ||
1716 | static struct trace_entry * | 1720 | static struct trace_entry * |
@@ -1718,7 +1722,7 @@ peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts, | |||
1718 | unsigned long *lost_events) | 1722 | unsigned long *lost_events) |
1719 | { | 1723 | { |
1720 | struct ring_buffer_event *event; | 1724 | struct ring_buffer_event *event; |
1721 | struct ring_buffer_iter *buf_iter = iter->buffer_iter[cpu]; | 1725 | struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, cpu); |
1722 | 1726 | ||
1723 | if (buf_iter) | 1727 | if (buf_iter) |
1724 | event = ring_buffer_iter_peek(buf_iter, ts); | 1728 | event = ring_buffer_iter_peek(buf_iter, ts); |
@@ -1856,10 +1860,10 @@ void tracing_iter_reset(struct trace_iterator *iter, int cpu) | |||
1856 | 1860 | ||
1857 | tr->data[cpu]->skipped_entries = 0; | 1861 | tr->data[cpu]->skipped_entries = 0; |
1858 | 1862 | ||
1859 | if (!iter->buffer_iter[cpu]) | 1863 | buf_iter = trace_buffer_iter(iter, cpu); |
1864 | if (!buf_iter) | ||
1860 | return; | 1865 | return; |
1861 | 1866 | ||
1862 | buf_iter = iter->buffer_iter[cpu]; | ||
1863 | ring_buffer_iter_reset(buf_iter); | 1867 | ring_buffer_iter_reset(buf_iter); |
1864 | 1868 | ||
1865 | /* | 1869 | /* |
@@ -2205,13 +2209,15 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter) | |||
2205 | 2209 | ||
2206 | int trace_empty(struct trace_iterator *iter) | 2210 | int trace_empty(struct trace_iterator *iter) |
2207 | { | 2211 | { |
2212 | struct ring_buffer_iter *buf_iter; | ||
2208 | int cpu; | 2213 | int cpu; |
2209 | 2214 | ||
2210 | /* If we are looking at one CPU buffer, only check that one */ | 2215 | /* If we are looking at one CPU buffer, only check that one */ |
2211 | if (iter->cpu_file != TRACE_PIPE_ALL_CPU) { | 2216 | if (iter->cpu_file != TRACE_PIPE_ALL_CPU) { |
2212 | cpu = iter->cpu_file; | 2217 | cpu = iter->cpu_file; |
2213 | if (iter->buffer_iter[cpu]) { | 2218 | buf_iter = trace_buffer_iter(iter, cpu); |
2214 | if (!ring_buffer_iter_empty(iter->buffer_iter[cpu])) | 2219 | if (buf_iter) { |
2220 | if (!ring_buffer_iter_empty(buf_iter)) | ||
2215 | return 0; | 2221 | return 0; |
2216 | } else { | 2222 | } else { |
2217 | if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu)) | 2223 | if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu)) |
@@ -2221,8 +2227,9 @@ int trace_empty(struct trace_iterator *iter) | |||
2221 | } | 2227 | } |
2222 | 2228 | ||
2223 | for_each_tracing_cpu(cpu) { | 2229 | for_each_tracing_cpu(cpu) { |
2224 | if (iter->buffer_iter[cpu]) { | 2230 | buf_iter = trace_buffer_iter(iter, cpu); |
2225 | if (!ring_buffer_iter_empty(iter->buffer_iter[cpu])) | 2231 | if (buf_iter) { |
2232 | if (!ring_buffer_iter_empty(buf_iter)) | ||
2226 | return 0; | 2233 | return 0; |
2227 | } else { | 2234 | } else { |
2228 | if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu)) | 2235 | if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu)) |
@@ -2381,6 +2388,11 @@ __tracing_open(struct inode *inode, struct file *file) | |||
2381 | if (!iter) | 2388 | if (!iter) |
2382 | return ERR_PTR(-ENOMEM); | 2389 | return ERR_PTR(-ENOMEM); |
2383 | 2390 | ||
2391 | iter->buffer_iter = kzalloc(sizeof(*iter->buffer_iter) * num_possible_cpus(), | ||
2392 | GFP_KERNEL); | ||
2393 | if (!iter->buffer_iter) | ||
2394 | goto release; | ||
2395 | |||
2384 | /* | 2396 | /* |
2385 | * We make a copy of the current tracer to avoid concurrent | 2397 | * We make a copy of the current tracer to avoid concurrent |
2386 | * changes on it while we are reading. | 2398 | * changes on it while we are reading. |
@@ -2441,6 +2453,8 @@ __tracing_open(struct inode *inode, struct file *file) | |||
2441 | fail: | 2453 | fail: |
2442 | mutex_unlock(&trace_types_lock); | 2454 | mutex_unlock(&trace_types_lock); |
2443 | kfree(iter->trace); | 2455 | kfree(iter->trace); |
2456 | kfree(iter->buffer_iter); | ||
2457 | release: | ||
2444 | seq_release_private(inode, file); | 2458 | seq_release_private(inode, file); |
2445 | return ERR_PTR(-ENOMEM); | 2459 | return ERR_PTR(-ENOMEM); |
2446 | } | 2460 | } |
@@ -2481,6 +2495,7 @@ static int tracing_release(struct inode *inode, struct file *file) | |||
2481 | mutex_destroy(&iter->mutex); | 2495 | mutex_destroy(&iter->mutex); |
2482 | free_cpumask_var(iter->started); | 2496 | free_cpumask_var(iter->started); |
2483 | kfree(iter->trace); | 2497 | kfree(iter->trace); |
2498 | kfree(iter->buffer_iter); | ||
2484 | seq_release_private(inode, file); | 2499 | seq_release_private(inode, file); |
2485 | return 0; | 2500 | return 0; |
2486 | } | 2501 | } |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 5aec220d2de0..55e1f7f0db12 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -317,6 +317,14 @@ struct tracer { | |||
317 | 317 | ||
318 | #define TRACE_PIPE_ALL_CPU -1 | 318 | #define TRACE_PIPE_ALL_CPU -1 |
319 | 319 | ||
320 | static inline struct ring_buffer_iter * | ||
321 | trace_buffer_iter(struct trace_iterator *iter, int cpu) | ||
322 | { | ||
323 | if (iter->buffer_iter && iter->buffer_iter[cpu]) | ||
324 | return iter->buffer_iter[cpu]; | ||
325 | return NULL; | ||
326 | } | ||
327 | |||
320 | int tracer_init(struct tracer *t, struct trace_array *tr); | 328 | int tracer_init(struct tracer *t, struct trace_array *tr); |
321 | int tracing_is_enabled(void); | 329 | int tracing_is_enabled(void); |
322 | void trace_wake_up(void); | 330 | void trace_wake_up(void); |
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index a7d2a4c653d8..ce27c8ba8d31 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c | |||
@@ -538,7 +538,7 @@ get_return_for_leaf(struct trace_iterator *iter, | |||
538 | next = &data->ret; | 538 | next = &data->ret; |
539 | } else { | 539 | } else { |
540 | 540 | ||
541 | ring_iter = iter->buffer_iter[iter->cpu]; | 541 | ring_iter = trace_buffer_iter(iter, iter->cpu); |
542 | 542 | ||
543 | /* First peek to compare current entry and the next one */ | 543 | /* First peek to compare current entry and the next one */ |
544 | if (ring_iter) | 544 | if (ring_iter) |
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index df611a0e76c5..123b189c732c 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
@@ -1325,4 +1325,4 @@ __init static int init_events(void) | |||
1325 | 1325 | ||
1326 | return 0; | 1326 | return 0; |
1327 | } | 1327 | } |
1328 | device_initcall(init_events); | 1328 | early_initcall(init_events); |
diff --git a/lib/list_debug.c b/lib/list_debug.c index 23a5e031cd8b..c24c2f7e296f 100644 --- a/lib/list_debug.c +++ b/lib/list_debug.c | |||
@@ -87,12 +87,10 @@ void __list_add_rcu(struct list_head *new, | |||
87 | struct list_head *prev, struct list_head *next) | 87 | struct list_head *prev, struct list_head *next) |
88 | { | 88 | { |
89 | WARN(next->prev != prev, | 89 | WARN(next->prev != prev, |
90 | "list_add_rcu corruption. next->prev should be " | 90 | "list_add_rcu corruption. next->prev should be prev (%p), but was %p. (next=%p).\n", |
91 | "prev (%p), but was %p. (next=%p).\n", | ||
92 | prev, next->prev, next); | 91 | prev, next->prev, next); |
93 | WARN(prev->next != next, | 92 | WARN(prev->next != next, |
94 | "list_add_rcu corruption. prev->next should be " | 93 | "list_add_rcu corruption. prev->next should be next (%p), but was %p. (prev=%p).\n", |
95 | "next (%p), but was %p. (prev=%p).\n", | ||
96 | next, prev->next, prev); | 94 | next, prev->next, prev); |
97 | new->next = next; | 95 | new->next = next; |
98 | new->prev = prev; | 96 | new->prev = prev; |
diff --git a/mm/bootmem.c b/mm/bootmem.c index 73096630cb35..bcb63ac48cc5 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
@@ -710,6 +710,10 @@ again: | |||
710 | if (ptr) | 710 | if (ptr) |
711 | return ptr; | 711 | return ptr; |
712 | 712 | ||
713 | /* do not panic in alloc_bootmem_bdata() */ | ||
714 | if (limit && goal + size > limit) | ||
715 | limit = 0; | ||
716 | |||
713 | ptr = alloc_bootmem_bdata(pgdat->bdata, size, align, goal, limit); | 717 | ptr = alloc_bootmem_bdata(pgdat->bdata, size, align, goal, limit); |
714 | if (ptr) | 718 | if (ptr) |
715 | return ptr; | 719 | return ptr; |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 44030096da63..4a4f9219683f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -5635,7 +5635,12 @@ static struct page * | |||
5635 | __alloc_contig_migrate_alloc(struct page *page, unsigned long private, | 5635 | __alloc_contig_migrate_alloc(struct page *page, unsigned long private, |
5636 | int **resultp) | 5636 | int **resultp) |
5637 | { | 5637 | { |
5638 | return alloc_page(GFP_HIGHUSER_MOVABLE); | 5638 | gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE; |
5639 | |||
5640 | if (PageHighMem(page)) | ||
5641 | gfp_mask |= __GFP_HIGHMEM; | ||
5642 | |||
5643 | return alloc_page(gfp_mask); | ||
5639 | } | 5644 | } |
5640 | 5645 | ||
5641 | /* [start, end) must belong to a single zone. */ | 5646 | /* [start, end) must belong to a single zone. */ |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 661576324c7f..66e431060c05 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -2688,7 +2688,10 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx) | |||
2688 | * them before going back to sleep. | 2688 | * them before going back to sleep. |
2689 | */ | 2689 | */ |
2690 | set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold); | 2690 | set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold); |
2691 | schedule(); | 2691 | |
2692 | if (!kthread_should_stop()) | ||
2693 | schedule(); | ||
2694 | |||
2692 | set_pgdat_percpu_threshold(pgdat, calculate_pressure_threshold); | 2695 | set_pgdat_percpu_threshold(pgdat, calculate_pressure_threshold); |
2693 | } else { | 2696 | } else { |
2694 | if (remaining) | 2697 | if (remaining) |
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 6089f0cf23b4..9096bcb08132 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -403,6 +403,9 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, | |||
403 | break; | 403 | break; |
404 | 404 | ||
405 | case NETDEV_DOWN: | 405 | case NETDEV_DOWN: |
406 | if (dev->features & NETIF_F_HW_VLAN_FILTER) | ||
407 | vlan_vid_del(dev, 0); | ||
408 | |||
406 | /* Put all VLANs for this dev in the down state too. */ | 409 | /* Put all VLANs for this dev in the down state too. */ |
407 | for (i = 0; i < VLAN_N_VID; i++) { | 410 | for (i = 0; i < VLAN_N_VID; i++) { |
408 | vlandev = vlan_group_get_device(grp, i); | 411 | vlandev = vlan_group_get_device(grp, i); |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 051f7abae66d..779095ded689 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -842,6 +842,7 @@ static int ax25_create(struct net *net, struct socket *sock, int protocol, | |||
842 | case AX25_P_NETROM: | 842 | case AX25_P_NETROM: |
843 | if (ax25_protocol_is_registered(AX25_P_NETROM)) | 843 | if (ax25_protocol_is_registered(AX25_P_NETROM)) |
844 | return -ESOCKTNOSUPPORT; | 844 | return -ESOCKTNOSUPPORT; |
845 | break; | ||
845 | #endif | 846 | #endif |
846 | #ifdef CONFIG_ROSE_MODULE | 847 | #ifdef CONFIG_ROSE_MODULE |
847 | case AX25_P_ROSE: | 848 | case AX25_P_ROSE: |
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 8bf97515a77d..c5863f499133 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c | |||
@@ -1351,6 +1351,7 @@ void bla_free(struct bat_priv *bat_priv) | |||
1351 | * @bat_priv: the bat priv with all the soft interface information | 1351 | * @bat_priv: the bat priv with all the soft interface information |
1352 | * @skb: the frame to be checked | 1352 | * @skb: the frame to be checked |
1353 | * @vid: the VLAN ID of the frame | 1353 | * @vid: the VLAN ID of the frame |
1354 | * @is_bcast: the packet came in a broadcast packet type. | ||
1354 | * | 1355 | * |
1355 | * bla_rx avoidance checks if: | 1356 | * bla_rx avoidance checks if: |
1356 | * * we have to race for a claim | 1357 | * * we have to race for a claim |
@@ -1361,7 +1362,8 @@ void bla_free(struct bat_priv *bat_priv) | |||
1361 | * process the skb. | 1362 | * process the skb. |
1362 | * | 1363 | * |
1363 | */ | 1364 | */ |
1364 | int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) | 1365 | int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid, |
1366 | bool is_bcast) | ||
1365 | { | 1367 | { |
1366 | struct ethhdr *ethhdr; | 1368 | struct ethhdr *ethhdr; |
1367 | struct claim search_claim, *claim = NULL; | 1369 | struct claim search_claim, *claim = NULL; |
@@ -1380,7 +1382,7 @@ int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) | |||
1380 | 1382 | ||
1381 | if (unlikely(atomic_read(&bat_priv->bla_num_requests))) | 1383 | if (unlikely(atomic_read(&bat_priv->bla_num_requests))) |
1382 | /* don't allow broadcasts while requests are in flight */ | 1384 | /* don't allow broadcasts while requests are in flight */ |
1383 | if (is_multicast_ether_addr(ethhdr->h_dest)) | 1385 | if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) |
1384 | goto handled; | 1386 | goto handled; |
1385 | 1387 | ||
1386 | memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN); | 1388 | memcpy(search_claim.addr, ethhdr->h_source, ETH_ALEN); |
@@ -1406,8 +1408,13 @@ int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid) | |||
1406 | } | 1408 | } |
1407 | 1409 | ||
1408 | /* if it is a broadcast ... */ | 1410 | /* if it is a broadcast ... */ |
1409 | if (is_multicast_ether_addr(ethhdr->h_dest)) { | 1411 | if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) { |
1410 | /* ... drop it. the responsible gateway is in charge. */ | 1412 | /* ... drop it. the responsible gateway is in charge. |
1413 | * | ||
1414 | * We need to check is_bcast because with the gateway | ||
1415 | * feature, broadcasts (like DHCP requests) may be sent | ||
1416 | * using a unicast packet type. | ||
1417 | */ | ||
1411 | goto handled; | 1418 | goto handled; |
1412 | } else { | 1419 | } else { |
1413 | /* seems the client considers us as its best gateway. | 1420 | /* seems the client considers us as its best gateway. |
diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h index e39f93acc28f..dc5227b398d4 100644 --- a/net/batman-adv/bridge_loop_avoidance.h +++ b/net/batman-adv/bridge_loop_avoidance.h | |||
@@ -23,7 +23,8 @@ | |||
23 | #define _NET_BATMAN_ADV_BLA_H_ | 23 | #define _NET_BATMAN_ADV_BLA_H_ |
24 | 24 | ||
25 | #ifdef CONFIG_BATMAN_ADV_BLA | 25 | #ifdef CONFIG_BATMAN_ADV_BLA |
26 | int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid); | 26 | int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid, |
27 | bool is_bcast); | ||
27 | int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid); | 28 | int bla_tx(struct bat_priv *bat_priv, struct sk_buff *skb, short vid); |
28 | int bla_is_backbone_gw(struct sk_buff *skb, | 29 | int bla_is_backbone_gw(struct sk_buff *skb, |
29 | struct orig_node *orig_node, int hdr_size); | 30 | struct orig_node *orig_node, int hdr_size); |
@@ -41,7 +42,7 @@ void bla_free(struct bat_priv *bat_priv); | |||
41 | #else /* ifdef CONFIG_BATMAN_ADV_BLA */ | 42 | #else /* ifdef CONFIG_BATMAN_ADV_BLA */ |
42 | 43 | ||
43 | static inline int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, | 44 | static inline int bla_rx(struct bat_priv *bat_priv, struct sk_buff *skb, |
44 | short vid) | 45 | short vid, bool is_bcast) |
45 | { | 46 | { |
46 | return 0; | 47 | return 0; |
47 | } | 48 | } |
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 6e2530b02043..a0ec0e4ada4c 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -256,7 +256,11 @@ void interface_rx(struct net_device *soft_iface, | |||
256 | struct bat_priv *bat_priv = netdev_priv(soft_iface); | 256 | struct bat_priv *bat_priv = netdev_priv(soft_iface); |
257 | struct ethhdr *ethhdr; | 257 | struct ethhdr *ethhdr; |
258 | struct vlan_ethhdr *vhdr; | 258 | struct vlan_ethhdr *vhdr; |
259 | struct batman_header *batadv_header = (struct batman_header *)skb->data; | ||
259 | short vid __maybe_unused = -1; | 260 | short vid __maybe_unused = -1; |
261 | bool is_bcast; | ||
262 | |||
263 | is_bcast = (batadv_header->packet_type == BAT_BCAST); | ||
260 | 264 | ||
261 | /* check if enough space is available for pulling, and pull */ | 265 | /* check if enough space is available for pulling, and pull */ |
262 | if (!pskb_may_pull(skb, hdr_size)) | 266 | if (!pskb_may_pull(skb, hdr_size)) |
@@ -302,7 +306,7 @@ void interface_rx(struct net_device *soft_iface, | |||
302 | /* Let the bridge loop avoidance check the packet. If will | 306 | /* Let the bridge loop avoidance check the packet. If will |
303 | * not handle it, we can safely push it up. | 307 | * not handle it, we can safely push it up. |
304 | */ | 308 | */ |
305 | if (bla_rx(bat_priv, skb, vid)) | 309 | if (bla_rx(bat_priv, skb, vid, is_bcast)) |
306 | goto out; | 310 | goto out; |
307 | 311 | ||
308 | netif_rx(skb); | 312 | netif_rx(skb); |
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index 554b31289607..8c83c175b03a 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c | |||
@@ -561,9 +561,9 @@ static int __init caif_device_init(void) | |||
561 | 561 | ||
562 | static void __exit caif_device_exit(void) | 562 | static void __exit caif_device_exit(void) |
563 | { | 563 | { |
564 | unregister_pernet_subsys(&caif_net_ops); | ||
565 | unregister_netdevice_notifier(&caif_device_notifier); | 564 | unregister_netdevice_notifier(&caif_device_notifier); |
566 | dev_remove_pack(&caif_packet_type); | 565 | dev_remove_pack(&caif_packet_type); |
566 | unregister_pernet_subsys(&caif_net_ops); | ||
567 | } | 567 | } |
568 | 568 | ||
569 | module_init(caif_device_init); | 569 | module_init(caif_device_init); |
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index b332c3d76059..10255e81be79 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -1423,7 +1423,7 @@ static int process_connect(struct ceph_connection *con) | |||
1423 | * dropped messages. | 1423 | * dropped messages. |
1424 | */ | 1424 | */ |
1425 | dout("process_connect got RESET peer seq %u\n", | 1425 | dout("process_connect got RESET peer seq %u\n", |
1426 | le32_to_cpu(con->in_connect.connect_seq)); | 1426 | le32_to_cpu(con->in_reply.connect_seq)); |
1427 | pr_err("%s%lld %s connection reset\n", | 1427 | pr_err("%s%lld %s connection reset\n", |
1428 | ENTITY_NAME(con->peer_name), | 1428 | ENTITY_NAME(con->peer_name), |
1429 | ceph_pr_addr(&con->peer_addr.in_addr)); | 1429 | ceph_pr_addr(&con->peer_addr.in_addr)); |
@@ -1450,10 +1450,10 @@ static int process_connect(struct ceph_connection *con) | |||
1450 | * If we sent a smaller connect_seq than the peer has, try | 1450 | * If we sent a smaller connect_seq than the peer has, try |
1451 | * again with a larger value. | 1451 | * again with a larger value. |
1452 | */ | 1452 | */ |
1453 | dout("process_connect got RETRY my seq = %u, peer_seq = %u\n", | 1453 | dout("process_connect got RETRY_SESSION my seq %u, peer %u\n", |
1454 | le32_to_cpu(con->out_connect.connect_seq), | 1454 | le32_to_cpu(con->out_connect.connect_seq), |
1455 | le32_to_cpu(con->in_connect.connect_seq)); | 1455 | le32_to_cpu(con->in_reply.connect_seq)); |
1456 | con->connect_seq = le32_to_cpu(con->in_connect.connect_seq); | 1456 | con->connect_seq = le32_to_cpu(con->in_reply.connect_seq); |
1457 | ceph_con_out_kvec_reset(con); | 1457 | ceph_con_out_kvec_reset(con); |
1458 | ret = prepare_write_connect(con); | 1458 | ret = prepare_write_connect(con); |
1459 | if (ret < 0) | 1459 | if (ret < 0) |
@@ -1468,9 +1468,9 @@ static int process_connect(struct ceph_connection *con) | |||
1468 | */ | 1468 | */ |
1469 | dout("process_connect got RETRY_GLOBAL my %u peer_gseq %u\n", | 1469 | dout("process_connect got RETRY_GLOBAL my %u peer_gseq %u\n", |
1470 | con->peer_global_seq, | 1470 | con->peer_global_seq, |
1471 | le32_to_cpu(con->in_connect.global_seq)); | 1471 | le32_to_cpu(con->in_reply.global_seq)); |
1472 | get_global_seq(con->msgr, | 1472 | get_global_seq(con->msgr, |
1473 | le32_to_cpu(con->in_connect.global_seq)); | 1473 | le32_to_cpu(con->in_reply.global_seq)); |
1474 | ceph_con_out_kvec_reset(con); | 1474 | ceph_con_out_kvec_reset(con); |
1475 | ret = prepare_write_connect(con); | 1475 | ret = prepare_write_connect(con); |
1476 | if (ret < 0) | 1476 | if (ret < 0) |
diff --git a/net/core/dev.c b/net/core/dev.c index 84f01ba81a34..1cb0d8a6aa6c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2444,8 +2444,12 @@ static void skb_update_prio(struct sk_buff *skb) | |||
2444 | { | 2444 | { |
2445 | struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap); | 2445 | struct netprio_map *map = rcu_dereference_bh(skb->dev->priomap); |
2446 | 2446 | ||
2447 | if ((!skb->priority) && (skb->sk) && map) | 2447 | if (!skb->priority && skb->sk && map) { |
2448 | skb->priority = map->priomap[skb->sk->sk_cgrp_prioidx]; | 2448 | unsigned int prioidx = skb->sk->sk_cgrp_prioidx; |
2449 | |||
2450 | if (prioidx < map->priomap_len) | ||
2451 | skb->priority = map->priomap[prioidx]; | ||
2452 | } | ||
2449 | } | 2453 | } |
2450 | #else | 2454 | #else |
2451 | #define skb_update_prio(skb) | 2455 | #define skb_update_prio(skb) |
@@ -6279,7 +6283,8 @@ static struct hlist_head *netdev_create_hash(void) | |||
6279 | /* Initialize per network namespace state */ | 6283 | /* Initialize per network namespace state */ |
6280 | static int __net_init netdev_init(struct net *net) | 6284 | static int __net_init netdev_init(struct net *net) |
6281 | { | 6285 | { |
6282 | INIT_LIST_HEAD(&net->dev_base_head); | 6286 | if (net != &init_net) |
6287 | INIT_LIST_HEAD(&net->dev_base_head); | ||
6283 | 6288 | ||
6284 | net->dev_name_head = netdev_create_hash(); | 6289 | net->dev_name_head = netdev_create_hash(); |
6285 | if (net->dev_name_head == NULL) | 6290 | if (net->dev_name_head == NULL) |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index dddbacb8f28c..42f1e1c7514f 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -27,7 +27,9 @@ static DEFINE_MUTEX(net_mutex); | |||
27 | LIST_HEAD(net_namespace_list); | 27 | LIST_HEAD(net_namespace_list); |
28 | EXPORT_SYMBOL_GPL(net_namespace_list); | 28 | EXPORT_SYMBOL_GPL(net_namespace_list); |
29 | 29 | ||
30 | struct net init_net; | 30 | struct net init_net = { |
31 | .dev_base_head = LIST_HEAD_INIT(init_net.dev_base_head), | ||
32 | }; | ||
31 | EXPORT_SYMBOL(init_net); | 33 | EXPORT_SYMBOL(init_net); |
32 | 34 | ||
33 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ | 35 | #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ |
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index 5b8aa2fae48b..b2e9caa1ad1a 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c | |||
@@ -49,8 +49,9 @@ static int get_prioidx(u32 *prio) | |||
49 | return -ENOSPC; | 49 | return -ENOSPC; |
50 | } | 50 | } |
51 | set_bit(prioidx, prioidx_map); | 51 | set_bit(prioidx, prioidx_map); |
52 | if (atomic_read(&max_prioidx) < prioidx) | ||
53 | atomic_set(&max_prioidx, prioidx); | ||
52 | spin_unlock_irqrestore(&prioidx_map_lock, flags); | 54 | spin_unlock_irqrestore(&prioidx_map_lock, flags); |
53 | atomic_set(&max_prioidx, prioidx); | ||
54 | *prio = prioidx; | 55 | *prio = prioidx; |
55 | return 0; | 56 | return 0; |
56 | } | 57 | } |
@@ -64,7 +65,7 @@ static void put_prioidx(u32 idx) | |||
64 | spin_unlock_irqrestore(&prioidx_map_lock, flags); | 65 | spin_unlock_irqrestore(&prioidx_map_lock, flags); |
65 | } | 66 | } |
66 | 67 | ||
67 | static void extend_netdev_table(struct net_device *dev, u32 new_len) | 68 | static int extend_netdev_table(struct net_device *dev, u32 new_len) |
68 | { | 69 | { |
69 | size_t new_size = sizeof(struct netprio_map) + | 70 | size_t new_size = sizeof(struct netprio_map) + |
70 | ((sizeof(u32) * new_len)); | 71 | ((sizeof(u32) * new_len)); |
@@ -76,7 +77,7 @@ static void extend_netdev_table(struct net_device *dev, u32 new_len) | |||
76 | 77 | ||
77 | if (!new_priomap) { | 78 | if (!new_priomap) { |
78 | pr_warn("Unable to alloc new priomap!\n"); | 79 | pr_warn("Unable to alloc new priomap!\n"); |
79 | return; | 80 | return -ENOMEM; |
80 | } | 81 | } |
81 | 82 | ||
82 | for (i = 0; | 83 | for (i = 0; |
@@ -89,46 +90,79 @@ static void extend_netdev_table(struct net_device *dev, u32 new_len) | |||
89 | rcu_assign_pointer(dev->priomap, new_priomap); | 90 | rcu_assign_pointer(dev->priomap, new_priomap); |
90 | if (old_priomap) | 91 | if (old_priomap) |
91 | kfree_rcu(old_priomap, rcu); | 92 | kfree_rcu(old_priomap, rcu); |
93 | return 0; | ||
92 | } | 94 | } |
93 | 95 | ||
94 | static void update_netdev_tables(void) | 96 | static int write_update_netdev_table(struct net_device *dev) |
95 | { | 97 | { |
98 | int ret = 0; | ||
99 | u32 max_len; | ||
100 | struct netprio_map *map; | ||
101 | |||
102 | rtnl_lock(); | ||
103 | max_len = atomic_read(&max_prioidx) + 1; | ||
104 | map = rtnl_dereference(dev->priomap); | ||
105 | if (!map || map->priomap_len < max_len) | ||
106 | ret = extend_netdev_table(dev, max_len); | ||
107 | rtnl_unlock(); | ||
108 | |||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | static int update_netdev_tables(void) | ||
113 | { | ||
114 | int ret = 0; | ||
96 | struct net_device *dev; | 115 | struct net_device *dev; |
97 | u32 max_len = atomic_read(&max_prioidx) + 1; | 116 | u32 max_len; |
98 | struct netprio_map *map; | 117 | struct netprio_map *map; |
99 | 118 | ||
100 | rtnl_lock(); | 119 | rtnl_lock(); |
120 | max_len = atomic_read(&max_prioidx) + 1; | ||
101 | for_each_netdev(&init_net, dev) { | 121 | for_each_netdev(&init_net, dev) { |
102 | map = rtnl_dereference(dev->priomap); | 122 | map = rtnl_dereference(dev->priomap); |
103 | if ((!map) || | 123 | /* |
104 | (map->priomap_len < max_len)) | 124 | * don't allocate priomap if we didn't |
105 | extend_netdev_table(dev, max_len); | 125 | * change net_prio.ifpriomap (map == NULL), |
126 | * this will speed up skb_update_prio. | ||
127 | */ | ||
128 | if (map && map->priomap_len < max_len) { | ||
129 | ret = extend_netdev_table(dev, max_len); | ||
130 | if (ret < 0) | ||
131 | break; | ||
132 | } | ||
106 | } | 133 | } |
107 | rtnl_unlock(); | 134 | rtnl_unlock(); |
135 | return ret; | ||
108 | } | 136 | } |
109 | 137 | ||
110 | static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp) | 138 | static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp) |
111 | { | 139 | { |
112 | struct cgroup_netprio_state *cs; | 140 | struct cgroup_netprio_state *cs; |
113 | int ret; | 141 | int ret = -EINVAL; |
114 | 142 | ||
115 | cs = kzalloc(sizeof(*cs), GFP_KERNEL); | 143 | cs = kzalloc(sizeof(*cs), GFP_KERNEL); |
116 | if (!cs) | 144 | if (!cs) |
117 | return ERR_PTR(-ENOMEM); | 145 | return ERR_PTR(-ENOMEM); |
118 | 146 | ||
119 | if (cgrp->parent && cgrp_netprio_state(cgrp->parent)->prioidx) { | 147 | if (cgrp->parent && cgrp_netprio_state(cgrp->parent)->prioidx) |
120 | kfree(cs); | 148 | goto out; |
121 | return ERR_PTR(-EINVAL); | ||
122 | } | ||
123 | 149 | ||
124 | ret = get_prioidx(&cs->prioidx); | 150 | ret = get_prioidx(&cs->prioidx); |
125 | if (ret != 0) { | 151 | if (ret < 0) { |
126 | pr_warn("No space in priority index array\n"); | 152 | pr_warn("No space in priority index array\n"); |
127 | kfree(cs); | 153 | goto out; |
128 | return ERR_PTR(ret); | 154 | } |
155 | |||
156 | ret = update_netdev_tables(); | ||
157 | if (ret < 0) { | ||
158 | put_prioidx(cs->prioidx); | ||
159 | goto out; | ||
129 | } | 160 | } |
130 | 161 | ||
131 | return &cs->css; | 162 | return &cs->css; |
163 | out: | ||
164 | kfree(cs); | ||
165 | return ERR_PTR(ret); | ||
132 | } | 166 | } |
133 | 167 | ||
134 | static void cgrp_destroy(struct cgroup *cgrp) | 168 | static void cgrp_destroy(struct cgroup *cgrp) |
@@ -141,7 +175,7 @@ static void cgrp_destroy(struct cgroup *cgrp) | |||
141 | rtnl_lock(); | 175 | rtnl_lock(); |
142 | for_each_netdev(&init_net, dev) { | 176 | for_each_netdev(&init_net, dev) { |
143 | map = rtnl_dereference(dev->priomap); | 177 | map = rtnl_dereference(dev->priomap); |
144 | if (map) | 178 | if (map && cs->prioidx < map->priomap_len) |
145 | map->priomap[cs->prioidx] = 0; | 179 | map->priomap[cs->prioidx] = 0; |
146 | } | 180 | } |
147 | rtnl_unlock(); | 181 | rtnl_unlock(); |
@@ -165,7 +199,7 @@ static int read_priomap(struct cgroup *cont, struct cftype *cft, | |||
165 | rcu_read_lock(); | 199 | rcu_read_lock(); |
166 | for_each_netdev_rcu(&init_net, dev) { | 200 | for_each_netdev_rcu(&init_net, dev) { |
167 | map = rcu_dereference(dev->priomap); | 201 | map = rcu_dereference(dev->priomap); |
168 | priority = map ? map->priomap[prioidx] : 0; | 202 | priority = (map && prioidx < map->priomap_len) ? map->priomap[prioidx] : 0; |
169 | cb->fill(cb, dev->name, priority); | 203 | cb->fill(cb, dev->name, priority); |
170 | } | 204 | } |
171 | rcu_read_unlock(); | 205 | rcu_read_unlock(); |
@@ -220,13 +254,17 @@ static int write_priomap(struct cgroup *cgrp, struct cftype *cft, | |||
220 | if (!dev) | 254 | if (!dev) |
221 | goto out_free_devname; | 255 | goto out_free_devname; |
222 | 256 | ||
223 | update_netdev_tables(); | 257 | ret = write_update_netdev_table(dev); |
224 | ret = 0; | 258 | if (ret < 0) |
259 | goto out_put_dev; | ||
260 | |||
225 | rcu_read_lock(); | 261 | rcu_read_lock(); |
226 | map = rcu_dereference(dev->priomap); | 262 | map = rcu_dereference(dev->priomap); |
227 | if (map) | 263 | if (map) |
228 | map->priomap[prioidx] = priority; | 264 | map->priomap[prioidx] = priority; |
229 | rcu_read_unlock(); | 265 | rcu_read_unlock(); |
266 | |||
267 | out_put_dev: | ||
230 | dev_put(dev); | 268 | dev_put(dev); |
231 | 269 | ||
232 | out_free_devname: | 270 | out_free_devname: |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 46a3d23d259e..d124306b81fd 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -353,7 +353,7 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, | |||
353 | unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) + | 353 | unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) + |
354 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); | 354 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); |
355 | 355 | ||
356 | if (fragsz <= PAGE_SIZE && !(gfp_mask & __GFP_WAIT)) { | 356 | if (fragsz <= PAGE_SIZE && !(gfp_mask & (__GFP_WAIT | GFP_DMA))) { |
357 | void *data = netdev_alloc_frag(fragsz); | 357 | void *data = netdev_alloc_frag(fragsz); |
358 | 358 | ||
359 | if (likely(data)) { | 359 | if (likely(data)) { |
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index 6fbb2ad7bb6d..16705611589a 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c | |||
@@ -230,6 +230,12 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
230 | mtu = dev->mtu; | 230 | mtu = dev->mtu; |
231 | pr_debug("name = %s, mtu = %u\n", dev->name, mtu); | 231 | pr_debug("name = %s, mtu = %u\n", dev->name, mtu); |
232 | 232 | ||
233 | if (size > mtu) { | ||
234 | pr_debug("size = %Zu, mtu = %u\n", size, mtu); | ||
235 | err = -EINVAL; | ||
236 | goto out_dev; | ||
237 | } | ||
238 | |||
233 | hlen = LL_RESERVED_SPACE(dev); | 239 | hlen = LL_RESERVED_SPACE(dev); |
234 | tlen = dev->needed_tailroom; | 240 | tlen = dev->needed_tailroom; |
235 | skb = sock_alloc_send_skb(sk, hlen + tlen + size, | 241 | skb = sock_alloc_send_skb(sk, hlen + tlen + size, |
@@ -258,12 +264,6 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
258 | if (err < 0) | 264 | if (err < 0) |
259 | goto out_skb; | 265 | goto out_skb; |
260 | 266 | ||
261 | if (size > mtu) { | ||
262 | pr_debug("size = %Zu, mtu = %u\n", size, mtu); | ||
263 | err = -EINVAL; | ||
264 | goto out_skb; | ||
265 | } | ||
266 | |||
267 | skb->dev = dev; | 267 | skb->dev = dev; |
268 | skb->sk = sk; | 268 | skb->sk = sk; |
269 | skb->protocol = htons(ETH_P_IEEE802154); | 269 | skb->protocol = htons(ETH_P_IEEE802154); |
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index c48adc565e92..667c1d4ca984 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
@@ -1725,8 +1725,10 @@ int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option) | |||
1725 | case CIPSO_V4_TAG_LOCAL: | 1725 | case CIPSO_V4_TAG_LOCAL: |
1726 | /* This is a non-standard tag that we only allow for | 1726 | /* This is a non-standard tag that we only allow for |
1727 | * local connections, so if the incoming interface is | 1727 | * local connections, so if the incoming interface is |
1728 | * not the loopback device drop the packet. */ | 1728 | * not the loopback device drop the packet. Further, |
1729 | if (!(skb->dev->flags & IFF_LOOPBACK)) { | 1729 | * there is no legitimate reason for setting this from |
1730 | * userspace so reject it if skb is NULL. */ | ||
1731 | if (skb == NULL || !(skb->dev->flags & IFF_LOOPBACK)) { | ||
1730 | err_offset = opt_iter; | 1732 | err_offset = opt_iter; |
1731 | goto validate_return_locked; | 1733 | goto validate_return_locked; |
1732 | } | 1734 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a4bb856de08f..0db5d34a06b6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2174,15 +2174,13 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2174 | sdata->name, mgmt->sa, status_code); | 2174 | sdata->name, mgmt->sa, status_code); |
2175 | ieee80211_destroy_assoc_data(sdata, false); | 2175 | ieee80211_destroy_assoc_data(sdata, false); |
2176 | } else { | 2176 | } else { |
2177 | printk(KERN_DEBUG "%s: associated\n", sdata->name); | ||
2178 | |||
2179 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { | 2177 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { |
2180 | /* oops -- internal error -- send timeout for now */ | 2178 | /* oops -- internal error -- send timeout for now */ |
2181 | ieee80211_destroy_assoc_data(sdata, true); | 2179 | ieee80211_destroy_assoc_data(sdata, false); |
2182 | sta_info_destroy_addr(sdata, mgmt->bssid); | ||
2183 | cfg80211_put_bss(*bss); | 2180 | cfg80211_put_bss(*bss); |
2184 | return RX_MGMT_CFG80211_ASSOC_TIMEOUT; | 2181 | return RX_MGMT_CFG80211_ASSOC_TIMEOUT; |
2185 | } | 2182 | } |
2183 | printk(KERN_DEBUG "%s: associated\n", sdata->name); | ||
2186 | 2184 | ||
2187 | /* | 2185 | /* |
2188 | * destroy assoc_data afterwards, as otherwise an idle | 2186 | * destroy assoc_data afterwards, as otherwise an idle |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 2d1acc6c5445..f9e51ef8dfa2 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -809,7 +809,7 @@ minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | |||
809 | max_rates = sband->n_bitrates; | 809 | max_rates = sband->n_bitrates; |
810 | } | 810 | } |
811 | 811 | ||
812 | msp = kzalloc(sizeof(struct minstrel_ht_sta), gfp); | 812 | msp = kzalloc(sizeof(*msp), gfp); |
813 | if (!msp) | 813 | if (!msp) |
814 | return NULL; | 814 | return NULL; |
815 | 815 | ||
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index d43e3c122f7b..84444dda194b 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -1521,11 +1521,12 @@ static int ip_vs_dst_event(struct notifier_block *this, unsigned long event, | |||
1521 | { | 1521 | { |
1522 | struct net_device *dev = ptr; | 1522 | struct net_device *dev = ptr; |
1523 | struct net *net = dev_net(dev); | 1523 | struct net *net = dev_net(dev); |
1524 | struct netns_ipvs *ipvs = net_ipvs(net); | ||
1524 | struct ip_vs_service *svc; | 1525 | struct ip_vs_service *svc; |
1525 | struct ip_vs_dest *dest; | 1526 | struct ip_vs_dest *dest; |
1526 | unsigned int idx; | 1527 | unsigned int idx; |
1527 | 1528 | ||
1528 | if (event != NETDEV_UNREGISTER) | 1529 | if (event != NETDEV_UNREGISTER || !ipvs) |
1529 | return NOTIFY_DONE; | 1530 | return NOTIFY_DONE; |
1530 | IP_VS_DBG(3, "%s() dev=%s\n", __func__, dev->name); | 1531 | IP_VS_DBG(3, "%s() dev=%s\n", __func__, dev->name); |
1531 | EnterFunction(2); | 1532 | EnterFunction(2); |
@@ -1551,7 +1552,7 @@ static int ip_vs_dst_event(struct notifier_block *this, unsigned long event, | |||
1551 | } | 1552 | } |
1552 | } | 1553 | } |
1553 | 1554 | ||
1554 | list_for_each_entry(dest, &net_ipvs(net)->dest_trash, n_list) { | 1555 | list_for_each_entry(dest, &ipvs->dest_trash, n_list) { |
1555 | __ip_vs_dev_reset(dest, dev); | 1556 | __ip_vs_dev_reset(dest, dev); |
1556 | } | 1557 | } |
1557 | mutex_unlock(&__ip_vs_mutex); | 1558 | mutex_unlock(&__ip_vs_mutex); |
diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c index 035960ec5cb9..c6f7db720d84 100644 --- a/net/netfilter/xt_set.c +++ b/net/netfilter/xt_set.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/netfilter/x_tables.h> | 17 | #include <linux/netfilter/x_tables.h> |
18 | #include <linux/netfilter/xt_set.h> | 18 | #include <linux/netfilter/xt_set.h> |
19 | #include <linux/netfilter/ipset/ip_set_timeout.h> | ||
19 | 20 | ||
20 | MODULE_LICENSE("GPL"); | 21 | MODULE_LICENSE("GPL"); |
21 | MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); | 22 | MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); |
@@ -310,7 +311,8 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par) | |||
310 | info->del_set.flags, 0, UINT_MAX); | 311 | info->del_set.flags, 0, UINT_MAX); |
311 | 312 | ||
312 | /* Normalize to fit into jiffies */ | 313 | /* Normalize to fit into jiffies */ |
313 | if (add_opt.timeout > UINT_MAX/MSEC_PER_SEC) | 314 | if (add_opt.timeout != IPSET_NO_TIMEOUT && |
315 | add_opt.timeout > UINT_MAX/MSEC_PER_SEC) | ||
314 | add_opt.timeout = UINT_MAX/MSEC_PER_SEC; | 316 | add_opt.timeout = UINT_MAX/MSEC_PER_SEC; |
315 | if (info->add_set.index != IPSET_INVALID_ID) | 317 | if (info->add_set.index != IPSET_INVALID_ID) |
316 | ip_set_add(info->add_set.index, skb, par, &add_opt); | 318 | ip_set_add(info->add_set.index, skb, par, &add_opt); |
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index 17a707db40eb..e06d458fc719 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c | |||
@@ -292,7 +292,7 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr, | |||
292 | 292 | ||
293 | pr_debug("%p\n", sk); | 293 | pr_debug("%p\n", sk); |
294 | 294 | ||
295 | if (llcp_sock == NULL) | 295 | if (llcp_sock == NULL || llcp_sock->dev == NULL) |
296 | return -EBADFD; | 296 | return -EBADFD; |
297 | 297 | ||
298 | addr->sa_family = AF_NFC; | 298 | addr->sa_family = AF_NFC; |
diff --git a/net/rxrpc/ar-peer.c b/net/rxrpc/ar-peer.c index 2754f098d436..bebaa43484bc 100644 --- a/net/rxrpc/ar-peer.c +++ b/net/rxrpc/ar-peer.c | |||
@@ -229,7 +229,7 @@ found_UDP_peer: | |||
229 | return peer; | 229 | return peer; |
230 | 230 | ||
231 | new_UDP_peer: | 231 | new_UDP_peer: |
232 | _net("Rx UDP DGRAM from NEW peer %d", peer->debug_id); | 232 | _net("Rx UDP DGRAM from NEW peer"); |
233 | read_unlock_bh(&rxrpc_peer_lock); | 233 | read_unlock_bh(&rxrpc_peer_lock); |
234 | _leave(" = -EBUSY [new]"); | 234 | _leave(" = -EBUSY [new]"); |
235 | return ERR_PTR(-EBUSY); | 235 | return ERR_PTR(-EBUSY); |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index a2a95aabf9c2..c412ad0d0308 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -331,29 +331,22 @@ static psched_time_t packet_len_2_sched_time(unsigned int len, struct netem_sche | |||
331 | return PSCHED_NS2TICKS(ticks); | 331 | return PSCHED_NS2TICKS(ticks); |
332 | } | 332 | } |
333 | 333 | ||
334 | static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) | 334 | static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) |
335 | { | 335 | { |
336 | struct sk_buff_head *list = &sch->q; | 336 | struct sk_buff_head *list = &sch->q; |
337 | psched_time_t tnext = netem_skb_cb(nskb)->time_to_send; | 337 | psched_time_t tnext = netem_skb_cb(nskb)->time_to_send; |
338 | struct sk_buff *skb; | 338 | struct sk_buff *skb = skb_peek_tail(list); |
339 | |||
340 | if (likely(skb_queue_len(list) < sch->limit)) { | ||
341 | skb = skb_peek_tail(list); | ||
342 | /* Optimize for add at tail */ | ||
343 | if (likely(!skb || tnext >= netem_skb_cb(skb)->time_to_send)) | ||
344 | return qdisc_enqueue_tail(nskb, sch); | ||
345 | 339 | ||
346 | skb_queue_reverse_walk(list, skb) { | 340 | /* Optimize for add at tail */ |
347 | if (tnext >= netem_skb_cb(skb)->time_to_send) | 341 | if (likely(!skb || tnext >= netem_skb_cb(skb)->time_to_send)) |
348 | break; | 342 | return __skb_queue_tail(list, nskb); |
349 | } | ||
350 | 343 | ||
351 | __skb_queue_after(list, skb, nskb); | 344 | skb_queue_reverse_walk(list, skb) { |
352 | sch->qstats.backlog += qdisc_pkt_len(nskb); | 345 | if (tnext >= netem_skb_cb(skb)->time_to_send) |
353 | return NET_XMIT_SUCCESS; | 346 | break; |
354 | } | 347 | } |
355 | 348 | ||
356 | return qdisc_reshape_fail(nskb, sch); | 349 | __skb_queue_after(list, skb, nskb); |
357 | } | 350 | } |
358 | 351 | ||
359 | /* | 352 | /* |
@@ -368,7 +361,6 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
368 | /* We don't fill cb now as skb_unshare() may invalidate it */ | 361 | /* We don't fill cb now as skb_unshare() may invalidate it */ |
369 | struct netem_skb_cb *cb; | 362 | struct netem_skb_cb *cb; |
370 | struct sk_buff *skb2; | 363 | struct sk_buff *skb2; |
371 | int ret; | ||
372 | int count = 1; | 364 | int count = 1; |
373 | 365 | ||
374 | /* Random duplication */ | 366 | /* Random duplication */ |
@@ -419,6 +411,11 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
419 | skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8); | 411 | skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8); |
420 | } | 412 | } |
421 | 413 | ||
414 | if (unlikely(skb_queue_len(&sch->q) >= sch->limit)) | ||
415 | return qdisc_reshape_fail(skb, sch); | ||
416 | |||
417 | sch->qstats.backlog += qdisc_pkt_len(skb); | ||
418 | |||
422 | cb = netem_skb_cb(skb); | 419 | cb = netem_skb_cb(skb); |
423 | if (q->gap == 0 || /* not doing reordering */ | 420 | if (q->gap == 0 || /* not doing reordering */ |
424 | q->counter < q->gap - 1 || /* inside last reordering gap */ | 421 | q->counter < q->gap - 1 || /* inside last reordering gap */ |
@@ -450,7 +447,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
450 | 447 | ||
451 | cb->time_to_send = now + delay; | 448 | cb->time_to_send = now + delay; |
452 | ++q->counter; | 449 | ++q->counter; |
453 | ret = tfifo_enqueue(skb, sch); | 450 | tfifo_enqueue(skb, sch); |
454 | } else { | 451 | } else { |
455 | /* | 452 | /* |
456 | * Do re-ordering by putting one out of N packets at the front | 453 | * Do re-ordering by putting one out of N packets at the front |
@@ -460,16 +457,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
460 | q->counter = 0; | 457 | q->counter = 0; |
461 | 458 | ||
462 | __skb_queue_head(&sch->q, skb); | 459 | __skb_queue_head(&sch->q, skb); |
463 | sch->qstats.backlog += qdisc_pkt_len(skb); | ||
464 | sch->qstats.requeues++; | 460 | sch->qstats.requeues++; |
465 | ret = NET_XMIT_SUCCESS; | ||
466 | } | ||
467 | |||
468 | if (ret != NET_XMIT_SUCCESS) { | ||
469 | if (net_xmit_drop_count(ret)) { | ||
470 | sch->qstats.drops++; | ||
471 | return ret; | ||
472 | } | ||
473 | } | 461 | } |
474 | 462 | ||
475 | return NET_XMIT_SUCCESS; | 463 | return NET_XMIT_SUCCESS; |
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c index 74305c883bd3..30ea4674cabd 100644 --- a/net/sched/sch_sfb.c +++ b/net/sched/sch_sfb.c | |||
@@ -570,6 +570,8 @@ static int sfb_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
570 | 570 | ||
571 | sch->qstats.backlog = q->qdisc->qstats.backlog; | 571 | sch->qstats.backlog = q->qdisc->qstats.backlog; |
572 | opts = nla_nest_start(skb, TCA_OPTIONS); | 572 | opts = nla_nest_start(skb, TCA_OPTIONS); |
573 | if (opts == NULL) | ||
574 | goto nla_put_failure; | ||
573 | if (nla_put(skb, TCA_SFB_PARMS, sizeof(opt), &opt)) | 575 | if (nla_put(skb, TCA_SFB_PARMS, sizeof(opt), &opt)) |
574 | goto nla_put_failure; | 576 | goto nla_put_failure; |
575 | return nla_nest_end(skb, opts); | 577 | return nla_nest_end(skb, opts); |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 80564fe03024..8b9b6790a3df 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -736,15 +736,12 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) | |||
736 | 736 | ||
737 | epb = &ep->base; | 737 | epb = &ep->base; |
738 | 738 | ||
739 | if (hlist_unhashed(&epb->node)) | ||
740 | return; | ||
741 | |||
742 | epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); | 739 | epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); |
743 | 740 | ||
744 | head = &sctp_ep_hashtable[epb->hashent]; | 741 | head = &sctp_ep_hashtable[epb->hashent]; |
745 | 742 | ||
746 | sctp_write_lock(&head->lock); | 743 | sctp_write_lock(&head->lock); |
747 | __hlist_del(&epb->node); | 744 | hlist_del_init(&epb->node); |
748 | sctp_write_unlock(&head->lock); | 745 | sctp_write_unlock(&head->lock); |
749 | } | 746 | } |
750 | 747 | ||
@@ -825,7 +822,7 @@ static void __sctp_unhash_established(struct sctp_association *asoc) | |||
825 | head = &sctp_assoc_hashtable[epb->hashent]; | 822 | head = &sctp_assoc_hashtable[epb->hashent]; |
826 | 823 | ||
827 | sctp_write_lock(&head->lock); | 824 | sctp_write_lock(&head->lock); |
828 | __hlist_del(&epb->node); | 825 | hlist_del_init(&epb->node); |
829 | sctp_write_unlock(&head->lock); | 826 | sctp_write_unlock(&head->lock); |
830 | } | 827 | } |
831 | 828 | ||
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index b3b8a8d813eb..31c7bfcd9b58 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1231,8 +1231,14 @@ out_free: | |||
1231 | SCTP_DEBUG_PRINTK("About to exit __sctp_connect() free asoc: %p" | 1231 | SCTP_DEBUG_PRINTK("About to exit __sctp_connect() free asoc: %p" |
1232 | " kaddrs: %p err: %d\n", | 1232 | " kaddrs: %p err: %d\n", |
1233 | asoc, kaddrs, err); | 1233 | asoc, kaddrs, err); |
1234 | if (asoc) | 1234 | if (asoc) { |
1235 | /* sctp_primitive_ASSOCIATE may have added this association | ||
1236 | * To the hash table, try to unhash it, just in case, its a noop | ||
1237 | * if it wasn't hashed so we're safe | ||
1238 | */ | ||
1239 | sctp_unhash_established(asoc); | ||
1235 | sctp_association_free(asoc); | 1240 | sctp_association_free(asoc); |
1241 | } | ||
1236 | return err; | 1242 | return err; |
1237 | } | 1243 | } |
1238 | 1244 | ||
@@ -1942,8 +1948,10 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1942 | goto out_unlock; | 1948 | goto out_unlock; |
1943 | 1949 | ||
1944 | out_free: | 1950 | out_free: |
1945 | if (new_asoc) | 1951 | if (new_asoc) { |
1952 | sctp_unhash_established(asoc); | ||
1946 | sctp_association_free(asoc); | 1953 | sctp_association_free(asoc); |
1954 | } | ||
1947 | out_unlock: | 1955 | out_unlock: |
1948 | sctp_release_sock(sk); | 1956 | sctp_release_sock(sk); |
1949 | 1957 | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 372ec6502aa8..ffd8900a38e8 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2717,7 +2717,7 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | |||
2717 | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) | 2717 | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) |
2718 | return dentry_has_perm(cred, dentry, FILE__SETATTR); | 2718 | return dentry_has_perm(cred, dentry, FILE__SETATTR); |
2719 | 2719 | ||
2720 | if (ia_valid & ATTR_SIZE) | 2720 | if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE)) |
2721 | av |= FILE__OPEN; | 2721 | av |= FILE__OPEN; |
2722 | 2722 | ||
2723 | return dentry_has_perm(cred, dentry, av); | 2723 | return dentry_has_perm(cred, dentry, av); |
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index b8c53723e09b..df2de54a958d 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h | |||
@@ -145,7 +145,9 @@ struct security_class_mapping secclass_map[] = { | |||
145 | "node_bind", "name_connect", NULL } }, | 145 | "node_bind", "name_connect", NULL } }, |
146 | { "memprotect", { "mmap_zero", NULL } }, | 146 | { "memprotect", { "mmap_zero", NULL } }, |
147 | { "peer", { "recv", NULL } }, | 147 | { "peer", { "recv", NULL } }, |
148 | { "capability2", { "mac_override", "mac_admin", "syslog", NULL } }, | 148 | { "capability2", |
149 | { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", | ||
150 | NULL } }, | ||
149 | { "kernel_service", { "use_as_override", "create_files_as", NULL } }, | 151 | { "kernel_service", { "use_as_override", "create_files_as", NULL } }, |
150 | { "tun_socket", | 152 | { "tun_socket", |
151 | { COMMON_SOCK_PERMS, NULL } }, | 153 | { COMMON_SOCK_PERMS, NULL } }, |
diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index 3d69aa9ff51e..46c2f6b7b123 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile | |||
@@ -250,8 +250,12 @@ endef | |||
250 | all_objs := $(sort $(ALL_OBJS)) | 250 | all_objs := $(sort $(ALL_OBJS)) |
251 | all_deps := $(all_objs:%.o=.%.d) | 251 | all_deps := $(all_objs:%.o=.%.d) |
252 | 252 | ||
253 | # let .d file also depends on the source and header files | ||
253 | define check_deps | 254 | define check_deps |
254 | $(CC) -M $(CFLAGS) $< > $@; | 255 | @set -e; $(RM) $@; \ |
256 | $(CC) -M $(CFLAGS) $< > $@.$$$$; \ | ||
257 | sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ | ||
258 | $(RM) $@.$$$$ | ||
255 | endef | 259 | endef |
256 | 260 | ||
257 | $(gui_deps): ks_version.h | 261 | $(gui_deps): ks_version.h |
@@ -270,11 +274,13 @@ endif | |||
270 | 274 | ||
271 | tags: force | 275 | tags: force |
272 | $(RM) tags | 276 | $(RM) tags |
273 | find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px | 277 | find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \ |
278 | --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' | ||
274 | 279 | ||
275 | TAGS: force | 280 | TAGS: force |
276 | $(RM) TAGS | 281 | $(RM) TAGS |
277 | find . -name '*.[ch]' | xargs etags | 282 | find . -name '*.[ch]' | xargs etags \ |
283 | --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' | ||
278 | 284 | ||
279 | define do_install | 285 | define do_install |
280 | $(print_install) \ | 286 | $(print_install) \ |
@@ -290,7 +296,7 @@ install_lib: all_cmd install_plugins install_python | |||
290 | install: install_lib | 296 | install: install_lib |
291 | 297 | ||
292 | clean: | 298 | clean: |
293 | $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES).*.d | 299 | $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d |
294 | $(RM) tags TAGS | 300 | $(RM) tags TAGS |
295 | 301 | ||
296 | endif # skip-makefile | 302 | endif # skip-makefile |
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 554828219c33..5f34aa371b56 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
@@ -467,8 +467,10 @@ int pevent_register_function(struct pevent *pevent, char *func, | |||
467 | item->mod = NULL; | 467 | item->mod = NULL; |
468 | item->addr = addr; | 468 | item->addr = addr; |
469 | 469 | ||
470 | pevent->funclist = item; | 470 | if (!item->func || (mod && !item->mod)) |
471 | die("malloc func"); | ||
471 | 472 | ||
473 | pevent->funclist = item; | ||
472 | pevent->func_count++; | 474 | pevent->func_count++; |
473 | 475 | ||
474 | return 0; | 476 | return 0; |
@@ -511,12 +513,12 @@ struct printk_list { | |||
511 | 513 | ||
512 | static int printk_cmp(const void *a, const void *b) | 514 | static int printk_cmp(const void *a, const void *b) |
513 | { | 515 | { |
514 | const struct func_map *fa = a; | 516 | const struct printk_map *pa = a; |
515 | const struct func_map *fb = b; | 517 | const struct printk_map *pb = b; |
516 | 518 | ||
517 | if (fa->addr < fb->addr) | 519 | if (pa->addr < pb->addr) |
518 | return -1; | 520 | return -1; |
519 | if (fa->addr > fb->addr) | 521 | if (pa->addr > pb->addr) |
520 | return 1; | 522 | return 1; |
521 | 523 | ||
522 | return 0; | 524 | return 0; |
@@ -583,10 +585,13 @@ int pevent_register_print_string(struct pevent *pevent, char *fmt, | |||
583 | item = malloc_or_die(sizeof(*item)); | 585 | item = malloc_or_die(sizeof(*item)); |
584 | 586 | ||
585 | item->next = pevent->printklist; | 587 | item->next = pevent->printklist; |
586 | pevent->printklist = item; | ||
587 | item->printk = strdup(fmt); | 588 | item->printk = strdup(fmt); |
588 | item->addr = addr; | 589 | item->addr = addr; |
589 | 590 | ||
591 | if (!item->printk) | ||
592 | die("malloc fmt"); | ||
593 | |||
594 | pevent->printklist = item; | ||
590 | pevent->printk_count++; | 595 | pevent->printk_count++; |
591 | 596 | ||
592 | return 0; | 597 | return 0; |
@@ -616,7 +621,9 @@ static struct event_format *alloc_event(void) | |||
616 | { | 621 | { |
617 | struct event_format *event; | 622 | struct event_format *event; |
618 | 623 | ||
619 | event = malloc_or_die(sizeof(*event)); | 624 | event = malloc(sizeof(*event)); |
625 | if (!event) | ||
626 | return NULL; | ||
620 | memset(event, 0, sizeof(*event)); | 627 | memset(event, 0, sizeof(*event)); |
621 | 628 | ||
622 | return event; | 629 | return event; |
@@ -626,12 +633,8 @@ static void add_event(struct pevent *pevent, struct event_format *event) | |||
626 | { | 633 | { |
627 | int i; | 634 | int i; |
628 | 635 | ||
629 | if (!pevent->events) | 636 | pevent->events = realloc(pevent->events, sizeof(event) * |
630 | pevent->events = malloc_or_die(sizeof(event)); | 637 | (pevent->nr_events + 1)); |
631 | else | ||
632 | pevent->events = | ||
633 | realloc(pevent->events, sizeof(event) * | ||
634 | (pevent->nr_events + 1)); | ||
635 | if (!pevent->events) | 638 | if (!pevent->events) |
636 | die("Can not allocate events"); | 639 | die("Can not allocate events"); |
637 | 640 | ||
@@ -697,6 +700,10 @@ static void free_arg(struct print_arg *arg) | |||
697 | free_arg(arg->symbol.field); | 700 | free_arg(arg->symbol.field); |
698 | free_flag_sym(arg->symbol.symbols); | 701 | free_flag_sym(arg->symbol.symbols); |
699 | break; | 702 | break; |
703 | case PRINT_HEX: | ||
704 | free_arg(arg->hex.field); | ||
705 | free_arg(arg->hex.size); | ||
706 | break; | ||
700 | case PRINT_TYPE: | 707 | case PRINT_TYPE: |
701 | free(arg->typecast.type); | 708 | free(arg->typecast.type); |
702 | free_arg(arg->typecast.item); | 709 | free_arg(arg->typecast.item); |
@@ -775,6 +782,25 @@ int pevent_peek_char(void) | |||
775 | return __peek_char(); | 782 | return __peek_char(); |
776 | } | 783 | } |
777 | 784 | ||
785 | static int extend_token(char **tok, char *buf, int size) | ||
786 | { | ||
787 | char *newtok = realloc(*tok, size); | ||
788 | |||
789 | if (!newtok) { | ||
790 | free(*tok); | ||
791 | *tok = NULL; | ||
792 | return -1; | ||
793 | } | ||
794 | |||
795 | if (!*tok) | ||
796 | strcpy(newtok, buf); | ||
797 | else | ||
798 | strcat(newtok, buf); | ||
799 | *tok = newtok; | ||
800 | |||
801 | return 0; | ||
802 | } | ||
803 | |||
778 | static enum event_type force_token(const char *str, char **tok); | 804 | static enum event_type force_token(const char *str, char **tok); |
779 | 805 | ||
780 | static enum event_type __read_token(char **tok) | 806 | static enum event_type __read_token(char **tok) |
@@ -859,17 +885,10 @@ static enum event_type __read_token(char **tok) | |||
859 | do { | 885 | do { |
860 | if (i == (BUFSIZ - 1)) { | 886 | if (i == (BUFSIZ - 1)) { |
861 | buf[i] = 0; | 887 | buf[i] = 0; |
862 | if (*tok) { | 888 | tok_size += BUFSIZ; |
863 | *tok = realloc(*tok, tok_size + BUFSIZ); | ||
864 | if (!*tok) | ||
865 | return EVENT_NONE; | ||
866 | strcat(*tok, buf); | ||
867 | } else | ||
868 | *tok = strdup(buf); | ||
869 | 889 | ||
870 | if (!*tok) | 890 | if (extend_token(tok, buf, tok_size) < 0) |
871 | return EVENT_NONE; | 891 | return EVENT_NONE; |
872 | tok_size += BUFSIZ; | ||
873 | i = 0; | 892 | i = 0; |
874 | } | 893 | } |
875 | last_ch = ch; | 894 | last_ch = ch; |
@@ -908,17 +927,10 @@ static enum event_type __read_token(char **tok) | |||
908 | while (get_type(__peek_char()) == type) { | 927 | while (get_type(__peek_char()) == type) { |
909 | if (i == (BUFSIZ - 1)) { | 928 | if (i == (BUFSIZ - 1)) { |
910 | buf[i] = 0; | 929 | buf[i] = 0; |
911 | if (*tok) { | 930 | tok_size += BUFSIZ; |
912 | *tok = realloc(*tok, tok_size + BUFSIZ); | ||
913 | if (!*tok) | ||
914 | return EVENT_NONE; | ||
915 | strcat(*tok, buf); | ||
916 | } else | ||
917 | *tok = strdup(buf); | ||
918 | 931 | ||
919 | if (!*tok) | 932 | if (extend_token(tok, buf, tok_size) < 0) |
920 | return EVENT_NONE; | 933 | return EVENT_NONE; |
921 | tok_size += BUFSIZ; | ||
922 | i = 0; | 934 | i = 0; |
923 | } | 935 | } |
924 | ch = __read_char(); | 936 | ch = __read_char(); |
@@ -927,14 +939,7 @@ static enum event_type __read_token(char **tok) | |||
927 | 939 | ||
928 | out: | 940 | out: |
929 | buf[i] = 0; | 941 | buf[i] = 0; |
930 | if (*tok) { | 942 | if (extend_token(tok, buf, tok_size + i + 1) < 0) |
931 | *tok = realloc(*tok, tok_size + i); | ||
932 | if (!*tok) | ||
933 | return EVENT_NONE; | ||
934 | strcat(*tok, buf); | ||
935 | } else | ||
936 | *tok = strdup(buf); | ||
937 | if (!*tok) | ||
938 | return EVENT_NONE; | 943 | return EVENT_NONE; |
939 | 944 | ||
940 | if (type == EVENT_ITEM) { | 945 | if (type == EVENT_ITEM) { |
@@ -1255,9 +1260,15 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
1255 | field->flags |= FIELD_IS_POINTER; | 1260 | field->flags |= FIELD_IS_POINTER; |
1256 | 1261 | ||
1257 | if (field->type) { | 1262 | if (field->type) { |
1258 | field->type = realloc(field->type, | 1263 | char *new_type; |
1259 | strlen(field->type) + | 1264 | new_type = realloc(field->type, |
1260 | strlen(last_token) + 2); | 1265 | strlen(field->type) + |
1266 | strlen(last_token) + 2); | ||
1267 | if (!new_type) { | ||
1268 | free(last_token); | ||
1269 | goto fail; | ||
1270 | } | ||
1271 | field->type = new_type; | ||
1261 | strcat(field->type, " "); | 1272 | strcat(field->type, " "); |
1262 | strcat(field->type, last_token); | 1273 | strcat(field->type, last_token); |
1263 | free(last_token); | 1274 | free(last_token); |
@@ -1282,6 +1293,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
1282 | if (strcmp(token, "[") == 0) { | 1293 | if (strcmp(token, "[") == 0) { |
1283 | enum event_type last_type = type; | 1294 | enum event_type last_type = type; |
1284 | char *brackets = token; | 1295 | char *brackets = token; |
1296 | char *new_brackets; | ||
1285 | int len; | 1297 | int len; |
1286 | 1298 | ||
1287 | field->flags |= FIELD_IS_ARRAY; | 1299 | field->flags |= FIELD_IS_ARRAY; |
@@ -1301,9 +1313,14 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
1301 | len = 1; | 1313 | len = 1; |
1302 | last_type = type; | 1314 | last_type = type; |
1303 | 1315 | ||
1304 | brackets = realloc(brackets, | 1316 | new_brackets = realloc(brackets, |
1305 | strlen(brackets) + | 1317 | strlen(brackets) + |
1306 | strlen(token) + len); | 1318 | strlen(token) + len); |
1319 | if (!new_brackets) { | ||
1320 | free(brackets); | ||
1321 | goto fail; | ||
1322 | } | ||
1323 | brackets = new_brackets; | ||
1307 | if (len == 2) | 1324 | if (len == 2) |
1308 | strcat(brackets, " "); | 1325 | strcat(brackets, " "); |
1309 | strcat(brackets, token); | 1326 | strcat(brackets, token); |
@@ -1319,7 +1336,12 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
1319 | 1336 | ||
1320 | free_token(token); | 1337 | free_token(token); |
1321 | 1338 | ||
1322 | brackets = realloc(brackets, strlen(brackets) + 2); | 1339 | new_brackets = realloc(brackets, strlen(brackets) + 2); |
1340 | if (!new_brackets) { | ||
1341 | free(brackets); | ||
1342 | goto fail; | ||
1343 | } | ||
1344 | brackets = new_brackets; | ||
1323 | strcat(brackets, "]"); | 1345 | strcat(brackets, "]"); |
1324 | 1346 | ||
1325 | /* add brackets to type */ | 1347 | /* add brackets to type */ |
@@ -1330,10 +1352,16 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
1330 | * the format: type [] item; | 1352 | * the format: type [] item; |
1331 | */ | 1353 | */ |
1332 | if (type == EVENT_ITEM) { | 1354 | if (type == EVENT_ITEM) { |
1333 | field->type = realloc(field->type, | 1355 | char *new_type; |
1334 | strlen(field->type) + | 1356 | new_type = realloc(field->type, |
1335 | strlen(field->name) + | 1357 | strlen(field->type) + |
1336 | strlen(brackets) + 2); | 1358 | strlen(field->name) + |
1359 | strlen(brackets) + 2); | ||
1360 | if (!new_type) { | ||
1361 | free(brackets); | ||
1362 | goto fail; | ||
1363 | } | ||
1364 | field->type = new_type; | ||
1337 | strcat(field->type, " "); | 1365 | strcat(field->type, " "); |
1338 | strcat(field->type, field->name); | 1366 | strcat(field->type, field->name); |
1339 | free_token(field->name); | 1367 | free_token(field->name); |
@@ -1341,9 +1369,15 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
1341 | field->name = token; | 1369 | field->name = token; |
1342 | type = read_token(&token); | 1370 | type = read_token(&token); |
1343 | } else { | 1371 | } else { |
1344 | field->type = realloc(field->type, | 1372 | char *new_type; |
1345 | strlen(field->type) + | 1373 | new_type = realloc(field->type, |
1346 | strlen(brackets) + 1); | 1374 | strlen(field->type) + |
1375 | strlen(brackets) + 1); | ||
1376 | if (!new_type) { | ||
1377 | free(brackets); | ||
1378 | goto fail; | ||
1379 | } | ||
1380 | field->type = new_type; | ||
1347 | strcat(field->type, brackets); | 1381 | strcat(field->type, brackets); |
1348 | } | 1382 | } |
1349 | free(brackets); | 1383 | free(brackets); |
@@ -1726,10 +1760,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
1726 | /* could just be a type pointer */ | 1760 | /* could just be a type pointer */ |
1727 | if ((strcmp(arg->op.op, "*") == 0) && | 1761 | if ((strcmp(arg->op.op, "*") == 0) && |
1728 | type == EVENT_DELIM && (strcmp(token, ")") == 0)) { | 1762 | type == EVENT_DELIM && (strcmp(token, ")") == 0)) { |
1763 | char *new_atom; | ||
1764 | |||
1729 | if (left->type != PRINT_ATOM) | 1765 | if (left->type != PRINT_ATOM) |
1730 | die("bad pointer type"); | 1766 | die("bad pointer type"); |
1731 | left->atom.atom = realloc(left->atom.atom, | 1767 | new_atom = realloc(left->atom.atom, |
1732 | strlen(left->atom.atom) + 3); | 1768 | strlen(left->atom.atom) + 3); |
1769 | if (!new_atom) | ||
1770 | goto out_free; | ||
1771 | |||
1772 | left->atom.atom = new_atom; | ||
1733 | strcat(left->atom.atom, " *"); | 1773 | strcat(left->atom.atom, " *"); |
1734 | free(arg->op.op); | 1774 | free(arg->op.op); |
1735 | *arg = *left; | 1775 | *arg = *left; |
@@ -2146,6 +2186,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** | |||
2146 | if (value == NULL) | 2186 | if (value == NULL) |
2147 | goto out_free; | 2187 | goto out_free; |
2148 | field->value = strdup(value); | 2188 | field->value = strdup(value); |
2189 | if (field->value == NULL) | ||
2190 | goto out_free; | ||
2149 | 2191 | ||
2150 | free_arg(arg); | 2192 | free_arg(arg); |
2151 | arg = alloc_arg(); | 2193 | arg = alloc_arg(); |
@@ -2159,6 +2201,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** | |||
2159 | if (value == NULL) | 2201 | if (value == NULL) |
2160 | goto out_free; | 2202 | goto out_free; |
2161 | field->str = strdup(value); | 2203 | field->str = strdup(value); |
2204 | if (field->str == NULL) | ||
2205 | goto out_free; | ||
2162 | free_arg(arg); | 2206 | free_arg(arg); |
2163 | arg = NULL; | 2207 | arg = NULL; |
2164 | 2208 | ||
@@ -2260,6 +2304,45 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok) | |||
2260 | } | 2304 | } |
2261 | 2305 | ||
2262 | static enum event_type | 2306 | static enum event_type |
2307 | process_hex(struct event_format *event, struct print_arg *arg, char **tok) | ||
2308 | { | ||
2309 | struct print_arg *field; | ||
2310 | enum event_type type; | ||
2311 | char *token; | ||
2312 | |||
2313 | memset(arg, 0, sizeof(*arg)); | ||
2314 | arg->type = PRINT_HEX; | ||
2315 | |||
2316 | field = alloc_arg(); | ||
2317 | type = process_arg(event, field, &token); | ||
2318 | |||
2319 | if (test_type_token(type, token, EVENT_DELIM, ",")) | ||
2320 | goto out_free; | ||
2321 | |||
2322 | arg->hex.field = field; | ||
2323 | |||
2324 | free_token(token); | ||
2325 | |||
2326 | field = alloc_arg(); | ||
2327 | type = process_arg(event, field, &token); | ||
2328 | |||
2329 | if (test_type_token(type, token, EVENT_DELIM, ")")) | ||
2330 | goto out_free; | ||
2331 | |||
2332 | arg->hex.size = field; | ||
2333 | |||
2334 | free_token(token); | ||
2335 | type = read_token_item(tok); | ||
2336 | return type; | ||
2337 | |||
2338 | out_free: | ||
2339 | free_arg(field); | ||
2340 | free_token(token); | ||
2341 | *tok = NULL; | ||
2342 | return EVENT_ERROR; | ||
2343 | } | ||
2344 | |||
2345 | static enum event_type | ||
2263 | process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) | 2346 | process_dynamic_array(struct event_format *event, struct print_arg *arg, char **tok) |
2264 | { | 2347 | { |
2265 | struct format_field *field; | 2348 | struct format_field *field; |
@@ -2488,6 +2571,10 @@ process_function(struct event_format *event, struct print_arg *arg, | |||
2488 | is_symbolic_field = 1; | 2571 | is_symbolic_field = 1; |
2489 | return process_symbols(event, arg, tok); | 2572 | return process_symbols(event, arg, tok); |
2490 | } | 2573 | } |
2574 | if (strcmp(token, "__print_hex") == 0) { | ||
2575 | free_token(token); | ||
2576 | return process_hex(event, arg, tok); | ||
2577 | } | ||
2491 | if (strcmp(token, "__get_str") == 0) { | 2578 | if (strcmp(token, "__get_str") == 0) { |
2492 | free_token(token); | 2579 | free_token(token); |
2493 | return process_str(event, arg, tok); | 2580 | return process_str(event, arg, tok); |
@@ -2541,7 +2628,16 @@ process_arg_token(struct event_format *event, struct print_arg *arg, | |||
2541 | } | 2628 | } |
2542 | /* atoms can be more than one token long */ | 2629 | /* atoms can be more than one token long */ |
2543 | while (type == EVENT_ITEM) { | 2630 | while (type == EVENT_ITEM) { |
2544 | atom = realloc(atom, strlen(atom) + strlen(token) + 2); | 2631 | char *new_atom; |
2632 | new_atom = realloc(atom, | ||
2633 | strlen(atom) + strlen(token) + 2); | ||
2634 | if (!new_atom) { | ||
2635 | free(atom); | ||
2636 | *tok = NULL; | ||
2637 | free_token(token); | ||
2638 | return EVENT_ERROR; | ||
2639 | } | ||
2640 | atom = new_atom; | ||
2545 | strcat(atom, " "); | 2641 | strcat(atom, " "); |
2546 | strcat(atom, token); | 2642 | strcat(atom, token); |
2547 | free_token(token); | 2643 | free_token(token); |
@@ -2835,7 +2931,7 @@ static int get_common_info(struct pevent *pevent, | |||
2835 | event = pevent->events[0]; | 2931 | event = pevent->events[0]; |
2836 | field = pevent_find_common_field(event, type); | 2932 | field = pevent_find_common_field(event, type); |
2837 | if (!field) | 2933 | if (!field) |
2838 | die("field '%s' not found", type); | 2934 | return -1; |
2839 | 2935 | ||
2840 | *offset = field->offset; | 2936 | *offset = field->offset; |
2841 | *size = field->size; | 2937 | *size = field->size; |
@@ -2886,15 +2982,16 @@ static int parse_common_flags(struct pevent *pevent, void *data) | |||
2886 | 2982 | ||
2887 | static int parse_common_lock_depth(struct pevent *pevent, void *data) | 2983 | static int parse_common_lock_depth(struct pevent *pevent, void *data) |
2888 | { | 2984 | { |
2889 | int ret; | 2985 | return __parse_common(pevent, data, |
2890 | 2986 | &pevent->ld_size, &pevent->ld_offset, | |
2891 | ret = __parse_common(pevent, data, | 2987 | "common_lock_depth"); |
2892 | &pevent->ld_size, &pevent->ld_offset, | 2988 | } |
2893 | "common_lock_depth"); | ||
2894 | if (ret < 0) | ||
2895 | return -1; | ||
2896 | 2989 | ||
2897 | return ret; | 2990 | static int parse_common_migrate_disable(struct pevent *pevent, void *data) |
2991 | { | ||
2992 | return __parse_common(pevent, data, | ||
2993 | &pevent->ld_size, &pevent->ld_offset, | ||
2994 | "common_migrate_disable"); | ||
2898 | } | 2995 | } |
2899 | 2996 | ||
2900 | static int events_id_cmp(const void *a, const void *b); | 2997 | static int events_id_cmp(const void *a, const void *b); |
@@ -2995,6 +3092,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg | |||
2995 | break; | 3092 | break; |
2996 | case PRINT_FLAGS: | 3093 | case PRINT_FLAGS: |
2997 | case PRINT_SYMBOL: | 3094 | case PRINT_SYMBOL: |
3095 | case PRINT_HEX: | ||
2998 | break; | 3096 | break; |
2999 | case PRINT_TYPE: | 3097 | case PRINT_TYPE: |
3000 | val = eval_num_arg(data, size, event, arg->typecast.item); | 3098 | val = eval_num_arg(data, size, event, arg->typecast.item); |
@@ -3214,11 +3312,13 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
3214 | { | 3312 | { |
3215 | struct pevent *pevent = event->pevent; | 3313 | struct pevent *pevent = event->pevent; |
3216 | struct print_flag_sym *flag; | 3314 | struct print_flag_sym *flag; |
3315 | struct format_field *field; | ||
3217 | unsigned long long val, fval; | 3316 | unsigned long long val, fval; |
3218 | unsigned long addr; | 3317 | unsigned long addr; |
3219 | char *str; | 3318 | char *str; |
3319 | unsigned char *hex; | ||
3220 | int print; | 3320 | int print; |
3221 | int len; | 3321 | int i, len; |
3222 | 3322 | ||
3223 | switch (arg->type) { | 3323 | switch (arg->type) { |
3224 | case PRINT_NULL: | 3324 | case PRINT_NULL: |
@@ -3228,27 +3328,29 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
3228 | print_str_to_seq(s, format, len_arg, arg->atom.atom); | 3328 | print_str_to_seq(s, format, len_arg, arg->atom.atom); |
3229 | return; | 3329 | return; |
3230 | case PRINT_FIELD: | 3330 | case PRINT_FIELD: |
3231 | if (!arg->field.field) { | 3331 | field = arg->field.field; |
3232 | arg->field.field = pevent_find_any_field(event, arg->field.name); | 3332 | if (!field) { |
3233 | if (!arg->field.field) | 3333 | field = pevent_find_any_field(event, arg->field.name); |
3334 | if (!field) | ||
3234 | die("field %s not found", arg->field.name); | 3335 | die("field %s not found", arg->field.name); |
3336 | arg->field.field = field; | ||
3235 | } | 3337 | } |
3236 | /* Zero sized fields, mean the rest of the data */ | 3338 | /* Zero sized fields, mean the rest of the data */ |
3237 | len = arg->field.field->size ? : size - arg->field.field->offset; | 3339 | len = field->size ? : size - field->offset; |
3238 | 3340 | ||
3239 | /* | 3341 | /* |
3240 | * Some events pass in pointers. If this is not an array | 3342 | * Some events pass in pointers. If this is not an array |
3241 | * and the size is the same as long_size, assume that it | 3343 | * and the size is the same as long_size, assume that it |
3242 | * is a pointer. | 3344 | * is a pointer. |
3243 | */ | 3345 | */ |
3244 | if (!(arg->field.field->flags & FIELD_IS_ARRAY) && | 3346 | if (!(field->flags & FIELD_IS_ARRAY) && |
3245 | arg->field.field->size == pevent->long_size) { | 3347 | field->size == pevent->long_size) { |
3246 | addr = *(unsigned long *)(data + arg->field.field->offset); | 3348 | addr = *(unsigned long *)(data + field->offset); |
3247 | trace_seq_printf(s, "%lx", addr); | 3349 | trace_seq_printf(s, "%lx", addr); |
3248 | break; | 3350 | break; |
3249 | } | 3351 | } |
3250 | str = malloc_or_die(len + 1); | 3352 | str = malloc_or_die(len + 1); |
3251 | memcpy(str, data + arg->field.field->offset, len); | 3353 | memcpy(str, data + field->offset, len); |
3252 | str[len] = 0; | 3354 | str[len] = 0; |
3253 | print_str_to_seq(s, format, len_arg, str); | 3355 | print_str_to_seq(s, format, len_arg, str); |
3254 | free(str); | 3356 | free(str); |
@@ -3281,6 +3383,23 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
3281 | } | 3383 | } |
3282 | } | 3384 | } |
3283 | break; | 3385 | break; |
3386 | case PRINT_HEX: | ||
3387 | field = arg->hex.field->field.field; | ||
3388 | if (!field) { | ||
3389 | str = arg->hex.field->field.name; | ||
3390 | field = pevent_find_any_field(event, str); | ||
3391 | if (!field) | ||
3392 | die("field %s not found", str); | ||
3393 | arg->hex.field->field.field = field; | ||
3394 | } | ||
3395 | hex = data + field->offset; | ||
3396 | len = eval_num_arg(data, size, event, arg->hex.size); | ||
3397 | for (i = 0; i < len; i++) { | ||
3398 | if (i) | ||
3399 | trace_seq_putc(s, ' '); | ||
3400 | trace_seq_printf(s, "%02x", hex[i]); | ||
3401 | } | ||
3402 | break; | ||
3284 | 3403 | ||
3285 | case PRINT_TYPE: | 3404 | case PRINT_TYPE: |
3286 | break; | 3405 | break; |
@@ -3299,7 +3418,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
3299 | break; | 3418 | break; |
3300 | } | 3419 | } |
3301 | case PRINT_BSTRING: | 3420 | case PRINT_BSTRING: |
3302 | trace_seq_printf(s, format, arg->string.string); | 3421 | print_str_to_seq(s, format, len_arg, arg->string.string); |
3303 | break; | 3422 | break; |
3304 | case PRINT_OP: | 3423 | case PRINT_OP: |
3305 | /* | 3424 | /* |
@@ -3363,6 +3482,10 @@ process_defined_func(struct trace_seq *s, void *data, int size, | |||
3363 | string = malloc_or_die(sizeof(*string)); | 3482 | string = malloc_or_die(sizeof(*string)); |
3364 | string->next = strings; | 3483 | string->next = strings; |
3365 | string->str = strdup(str.buffer); | 3484 | string->str = strdup(str.buffer); |
3485 | if (!string->str) | ||
3486 | die("malloc str"); | ||
3487 | |||
3488 | args[i] = (unsigned long long)string->str; | ||
3366 | strings = string; | 3489 | strings = string; |
3367 | trace_seq_destroy(&str); | 3490 | trace_seq_destroy(&str); |
3368 | break; | 3491 | break; |
@@ -3400,6 +3523,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3400 | unsigned long long ip, val; | 3523 | unsigned long long ip, val; |
3401 | char *ptr; | 3524 | char *ptr; |
3402 | void *bptr; | 3525 | void *bptr; |
3526 | int vsize; | ||
3403 | 3527 | ||
3404 | field = pevent->bprint_buf_field; | 3528 | field = pevent->bprint_buf_field; |
3405 | ip_field = pevent->bprint_ip_field; | 3529 | ip_field = pevent->bprint_ip_field; |
@@ -3448,6 +3572,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3448 | goto process_again; | 3572 | goto process_again; |
3449 | case '0' ... '9': | 3573 | case '0' ... '9': |
3450 | goto process_again; | 3574 | goto process_again; |
3575 | case '.': | ||
3576 | goto process_again; | ||
3451 | case 'p': | 3577 | case 'p': |
3452 | ls = 1; | 3578 | ls = 1; |
3453 | /* fall through */ | 3579 | /* fall through */ |
@@ -3455,23 +3581,30 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3455 | case 'u': | 3581 | case 'u': |
3456 | case 'x': | 3582 | case 'x': |
3457 | case 'i': | 3583 | case 'i': |
3458 | /* the pointers are always 4 bytes aligned */ | ||
3459 | bptr = (void *)(((unsigned long)bptr + 3) & | ||
3460 | ~3); | ||
3461 | switch (ls) { | 3584 | switch (ls) { |
3462 | case 0: | 3585 | case 0: |
3463 | ls = 4; | 3586 | vsize = 4; |
3464 | break; | 3587 | break; |
3465 | case 1: | 3588 | case 1: |
3466 | ls = pevent->long_size; | 3589 | vsize = pevent->long_size; |
3467 | break; | 3590 | break; |
3468 | case 2: | 3591 | case 2: |
3469 | ls = 8; | 3592 | vsize = 8; |
3593 | break; | ||
3470 | default: | 3594 | default: |
3595 | vsize = ls; /* ? */ | ||
3471 | break; | 3596 | break; |
3472 | } | 3597 | } |
3473 | val = pevent_read_number(pevent, bptr, ls); | 3598 | /* fall through */ |
3474 | bptr += ls; | 3599 | case '*': |
3600 | if (*ptr == '*') | ||
3601 | vsize = 4; | ||
3602 | |||
3603 | /* the pointers are always 4 bytes aligned */ | ||
3604 | bptr = (void *)(((unsigned long)bptr + 3) & | ||
3605 | ~3); | ||
3606 | val = pevent_read_number(pevent, bptr, vsize); | ||
3607 | bptr += vsize; | ||
3475 | arg = alloc_arg(); | 3608 | arg = alloc_arg(); |
3476 | arg->next = NULL; | 3609 | arg->next = NULL; |
3477 | arg->type = PRINT_ATOM; | 3610 | arg->type = PRINT_ATOM; |
@@ -3479,12 +3612,21 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3479 | sprintf(arg->atom.atom, "%lld", val); | 3612 | sprintf(arg->atom.atom, "%lld", val); |
3480 | *next = arg; | 3613 | *next = arg; |
3481 | next = &arg->next; | 3614 | next = &arg->next; |
3615 | /* | ||
3616 | * The '*' case means that an arg is used as the length. | ||
3617 | * We need to continue to figure out for what. | ||
3618 | */ | ||
3619 | if (*ptr == '*') | ||
3620 | goto process_again; | ||
3621 | |||
3482 | break; | 3622 | break; |
3483 | case 's': | 3623 | case 's': |
3484 | arg = alloc_arg(); | 3624 | arg = alloc_arg(); |
3485 | arg->next = NULL; | 3625 | arg->next = NULL; |
3486 | arg->type = PRINT_BSTRING; | 3626 | arg->type = PRINT_BSTRING; |
3487 | arg->string.string = strdup(bptr); | 3627 | arg->string.string = strdup(bptr); |
3628 | if (!arg->string.string) | ||
3629 | break; | ||
3488 | bptr += strlen(bptr) + 1; | 3630 | bptr += strlen(bptr) + 1; |
3489 | *next = arg; | 3631 | *next = arg; |
3490 | next = &arg->next; | 3632 | next = &arg->next; |
@@ -3589,6 +3731,16 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size, | |||
3589 | trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); | 3731 | trace_seq_printf(s, fmt, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); |
3590 | } | 3732 | } |
3591 | 3733 | ||
3734 | static int is_printable_array(char *p, unsigned int len) | ||
3735 | { | ||
3736 | unsigned int i; | ||
3737 | |||
3738 | for (i = 0; i < len && p[i]; i++) | ||
3739 | if (!isprint(p[i])) | ||
3740 | return 0; | ||
3741 | return 1; | ||
3742 | } | ||
3743 | |||
3592 | static void print_event_fields(struct trace_seq *s, void *data, int size, | 3744 | static void print_event_fields(struct trace_seq *s, void *data, int size, |
3593 | struct event_format *event) | 3745 | struct event_format *event) |
3594 | { | 3746 | { |
@@ -3608,7 +3760,8 @@ static void print_event_fields(struct trace_seq *s, void *data, int size, | |||
3608 | len = offset >> 16; | 3760 | len = offset >> 16; |
3609 | offset &= 0xffff; | 3761 | offset &= 0xffff; |
3610 | } | 3762 | } |
3611 | if (field->flags & FIELD_IS_STRING) { | 3763 | if (field->flags & FIELD_IS_STRING && |
3764 | is_printable_array(data + offset, len)) { | ||
3612 | trace_seq_printf(s, "%s", (char *)data + offset); | 3765 | trace_seq_printf(s, "%s", (char *)data + offset); |
3613 | } else { | 3766 | } else { |
3614 | trace_seq_puts(s, "ARRAY["); | 3767 | trace_seq_puts(s, "ARRAY["); |
@@ -3619,6 +3772,7 @@ static void print_event_fields(struct trace_seq *s, void *data, int size, | |||
3619 | *((unsigned char *)data + offset + i)); | 3772 | *((unsigned char *)data + offset + i)); |
3620 | } | 3773 | } |
3621 | trace_seq_putc(s, ']'); | 3774 | trace_seq_putc(s, ']'); |
3775 | field->flags &= ~FIELD_IS_STRING; | ||
3622 | } | 3776 | } |
3623 | } else { | 3777 | } else { |
3624 | val = pevent_read_number(event->pevent, data + field->offset, | 3778 | val = pevent_read_number(event->pevent, data + field->offset, |
@@ -3758,6 +3912,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
3758 | } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') { | 3912 | } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') { |
3759 | print_mac_arg(s, *(ptr+1), data, size, event, arg); | 3913 | print_mac_arg(s, *(ptr+1), data, size, event, arg); |
3760 | ptr++; | 3914 | ptr++; |
3915 | arg = arg->next; | ||
3761 | break; | 3916 | break; |
3762 | } | 3917 | } |
3763 | 3918 | ||
@@ -3794,14 +3949,15 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
3794 | break; | 3949 | break; |
3795 | } | 3950 | } |
3796 | } | 3951 | } |
3797 | if (pevent->long_size == 8 && ls) { | 3952 | if (pevent->long_size == 8 && ls && |
3953 | sizeof(long) != 8) { | ||
3798 | char *p; | 3954 | char *p; |
3799 | 3955 | ||
3800 | ls = 2; | 3956 | ls = 2; |
3801 | /* make %l into %ll */ | 3957 | /* make %l into %ll */ |
3802 | p = strchr(format, 'l'); | 3958 | p = strchr(format, 'l'); |
3803 | if (p) | 3959 | if (p) |
3804 | memmove(p, p+1, strlen(p)+1); | 3960 | memmove(p+1, p, strlen(p)+1); |
3805 | else if (strcmp(format, "%p") == 0) | 3961 | else if (strcmp(format, "%p") == 0) |
3806 | strcpy(format, "0x%llx"); | 3962 | strcpy(format, "0x%llx"); |
3807 | } | 3963 | } |
@@ -3878,8 +4034,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
3878 | * pevent_data_lat_fmt - parse the data for the latency format | 4034 | * pevent_data_lat_fmt - parse the data for the latency format |
3879 | * @pevent: a handle to the pevent | 4035 | * @pevent: a handle to the pevent |
3880 | * @s: the trace_seq to write to | 4036 | * @s: the trace_seq to write to |
3881 | * @data: the raw data to read from | 4037 | * @record: the record to read from |
3882 | * @size: currently unused. | ||
3883 | * | 4038 | * |
3884 | * This parses out the Latency format (interrupts disabled, | 4039 | * This parses out the Latency format (interrupts disabled, |
3885 | * need rescheduling, in hard/soft interrupt, preempt count | 4040 | * need rescheduling, in hard/soft interrupt, preempt count |
@@ -3889,10 +4044,13 @@ void pevent_data_lat_fmt(struct pevent *pevent, | |||
3889 | struct trace_seq *s, struct pevent_record *record) | 4044 | struct trace_seq *s, struct pevent_record *record) |
3890 | { | 4045 | { |
3891 | static int check_lock_depth = 1; | 4046 | static int check_lock_depth = 1; |
4047 | static int check_migrate_disable = 1; | ||
3892 | static int lock_depth_exists; | 4048 | static int lock_depth_exists; |
4049 | static int migrate_disable_exists; | ||
3893 | unsigned int lat_flags; | 4050 | unsigned int lat_flags; |
3894 | unsigned int pc; | 4051 | unsigned int pc; |
3895 | int lock_depth; | 4052 | int lock_depth; |
4053 | int migrate_disable; | ||
3896 | int hardirq; | 4054 | int hardirq; |
3897 | int softirq; | 4055 | int softirq; |
3898 | void *data = record->data; | 4056 | void *data = record->data; |
@@ -3900,18 +4058,26 @@ void pevent_data_lat_fmt(struct pevent *pevent, | |||
3900 | lat_flags = parse_common_flags(pevent, data); | 4058 | lat_flags = parse_common_flags(pevent, data); |
3901 | pc = parse_common_pc(pevent, data); | 4059 | pc = parse_common_pc(pevent, data); |
3902 | /* lock_depth may not always exist */ | 4060 | /* lock_depth may not always exist */ |
3903 | if (check_lock_depth) { | ||
3904 | struct format_field *field; | ||
3905 | struct event_format *event; | ||
3906 | |||
3907 | check_lock_depth = 0; | ||
3908 | event = pevent->events[0]; | ||
3909 | field = pevent_find_common_field(event, "common_lock_depth"); | ||
3910 | if (field) | ||
3911 | lock_depth_exists = 1; | ||
3912 | } | ||
3913 | if (lock_depth_exists) | 4061 | if (lock_depth_exists) |
3914 | lock_depth = parse_common_lock_depth(pevent, data); | 4062 | lock_depth = parse_common_lock_depth(pevent, data); |
4063 | else if (check_lock_depth) { | ||
4064 | lock_depth = parse_common_lock_depth(pevent, data); | ||
4065 | if (lock_depth < 0) | ||
4066 | check_lock_depth = 0; | ||
4067 | else | ||
4068 | lock_depth_exists = 1; | ||
4069 | } | ||
4070 | |||
4071 | /* migrate_disable may not always exist */ | ||
4072 | if (migrate_disable_exists) | ||
4073 | migrate_disable = parse_common_migrate_disable(pevent, data); | ||
4074 | else if (check_migrate_disable) { | ||
4075 | migrate_disable = parse_common_migrate_disable(pevent, data); | ||
4076 | if (migrate_disable < 0) | ||
4077 | check_migrate_disable = 0; | ||
4078 | else | ||
4079 | migrate_disable_exists = 1; | ||
4080 | } | ||
3915 | 4081 | ||
3916 | hardirq = lat_flags & TRACE_FLAG_HARDIRQ; | 4082 | hardirq = lat_flags & TRACE_FLAG_HARDIRQ; |
3917 | softirq = lat_flags & TRACE_FLAG_SOFTIRQ; | 4083 | softirq = lat_flags & TRACE_FLAG_SOFTIRQ; |
@@ -3930,6 +4096,13 @@ void pevent_data_lat_fmt(struct pevent *pevent, | |||
3930 | else | 4096 | else |
3931 | trace_seq_putc(s, '.'); | 4097 | trace_seq_putc(s, '.'); |
3932 | 4098 | ||
4099 | if (migrate_disable_exists) { | ||
4100 | if (migrate_disable < 0) | ||
4101 | trace_seq_putc(s, '.'); | ||
4102 | else | ||
4103 | trace_seq_printf(s, "%d", migrate_disable); | ||
4104 | } | ||
4105 | |||
3933 | if (lock_depth_exists) { | 4106 | if (lock_depth_exists) { |
3934 | if (lock_depth < 0) | 4107 | if (lock_depth < 0) |
3935 | trace_seq_putc(s, '.'); | 4108 | trace_seq_putc(s, '.'); |
@@ -3996,10 +4169,7 @@ const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid) | |||
3996 | * pevent_data_comm_from_pid - parse the data into the print format | 4169 | * pevent_data_comm_from_pid - parse the data into the print format |
3997 | * @s: the trace_seq to write to | 4170 | * @s: the trace_seq to write to |
3998 | * @event: the handle to the event | 4171 | * @event: the handle to the event |
3999 | * @cpu: the cpu the event was recorded on | 4172 | * @record: the record to read from |
4000 | * @data: the raw data | ||
4001 | * @size: the size of the raw data | ||
4002 | * @nsecs: the timestamp of the event | ||
4003 | * | 4173 | * |
4004 | * This parses the raw @data using the given @event information and | 4174 | * This parses the raw @data using the given @event information and |
4005 | * writes the print format into the trace_seq. | 4175 | * writes the print format into the trace_seq. |
@@ -4279,6 +4449,13 @@ static void print_args(struct print_arg *args) | |||
4279 | trace_seq_destroy(&s); | 4449 | trace_seq_destroy(&s); |
4280 | printf(")"); | 4450 | printf(")"); |
4281 | break; | 4451 | break; |
4452 | case PRINT_HEX: | ||
4453 | printf("__print_hex("); | ||
4454 | print_args(args->hex.field); | ||
4455 | printf(", "); | ||
4456 | print_args(args->hex.size); | ||
4457 | printf(")"); | ||
4458 | break; | ||
4282 | case PRINT_STRING: | 4459 | case PRINT_STRING: |
4283 | case PRINT_BSTRING: | 4460 | case PRINT_BSTRING: |
4284 | printf("__get_str(%s)", args->string.string); | 4461 | printf("__get_str(%s)", args->string.string); |
@@ -4541,6 +4718,8 @@ int pevent_parse_event(struct pevent *pevent, | |||
4541 | die("failed to read event id"); | 4718 | die("failed to read event id"); |
4542 | 4719 | ||
4543 | event->system = strdup(sys); | 4720 | event->system = strdup(sys); |
4721 | if (!event->system) | ||
4722 | die("failed to allocate system"); | ||
4544 | 4723 | ||
4545 | /* Add pevent to event so that it can be referenced */ | 4724 | /* Add pevent to event so that it can be referenced */ |
4546 | event->pevent = pevent; | 4725 | event->pevent = pevent; |
@@ -4582,6 +4761,11 @@ int pevent_parse_event(struct pevent *pevent, | |||
4582 | list = &arg->next; | 4761 | list = &arg->next; |
4583 | arg->type = PRINT_FIELD; | 4762 | arg->type = PRINT_FIELD; |
4584 | arg->field.name = strdup(field->name); | 4763 | arg->field.name = strdup(field->name); |
4764 | if (!arg->field.name) { | ||
4765 | do_warning("failed to allocate field name"); | ||
4766 | event->flags |= EVENT_FL_FAILED; | ||
4767 | return -1; | ||
4768 | } | ||
4585 | arg->field.field = field; | 4769 | arg->field.field = field; |
4586 | } | 4770 | } |
4587 | return 0; | 4771 | return 0; |
@@ -4753,7 +4937,7 @@ int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event, | |||
4753 | * @record: The record with the field name. | 4937 | * @record: The record with the field name. |
4754 | * @err: print default error if failed. | 4938 | * @err: print default error if failed. |
4755 | * | 4939 | * |
4756 | * Returns: 0 on success, -1 field not fould, or 1 if buffer is full. | 4940 | * Returns: 0 on success, -1 field not found, or 1 if buffer is full. |
4757 | */ | 4941 | */ |
4758 | int pevent_print_num_field(struct trace_seq *s, const char *fmt, | 4942 | int pevent_print_num_field(struct trace_seq *s, const char *fmt, |
4759 | struct event_format *event, const char *name, | 4943 | struct event_format *event, const char *name, |
@@ -4795,11 +4979,12 @@ static void free_func_handle(struct pevent_function_handler *func) | |||
4795 | * pevent_register_print_function - register a helper function | 4979 | * pevent_register_print_function - register a helper function |
4796 | * @pevent: the handle to the pevent | 4980 | * @pevent: the handle to the pevent |
4797 | * @func: the function to process the helper function | 4981 | * @func: the function to process the helper function |
4982 | * @ret_type: the return type of the helper function | ||
4798 | * @name: the name of the helper function | 4983 | * @name: the name of the helper function |
4799 | * @parameters: A list of enum pevent_func_arg_type | 4984 | * @parameters: A list of enum pevent_func_arg_type |
4800 | * | 4985 | * |
4801 | * Some events may have helper functions in the print format arguments. | 4986 | * Some events may have helper functions in the print format arguments. |
4802 | * This allows a plugin to dynmically create a way to process one | 4987 | * This allows a plugin to dynamically create a way to process one |
4803 | * of these functions. | 4988 | * of these functions. |
4804 | * | 4989 | * |
4805 | * The @parameters is a variable list of pevent_func_arg_type enums that | 4990 | * The @parameters is a variable list of pevent_func_arg_type enums that |
@@ -4870,12 +5055,13 @@ int pevent_register_print_function(struct pevent *pevent, | |||
4870 | } | 5055 | } |
4871 | 5056 | ||
4872 | /** | 5057 | /** |
4873 | * pevent_register_event_handle - register a way to parse an event | 5058 | * pevent_register_event_handler - register a way to parse an event |
4874 | * @pevent: the handle to the pevent | 5059 | * @pevent: the handle to the pevent |
4875 | * @id: the id of the event to register | 5060 | * @id: the id of the event to register |
4876 | * @sys_name: the system name the event belongs to | 5061 | * @sys_name: the system name the event belongs to |
4877 | * @event_name: the name of the event | 5062 | * @event_name: the name of the event |
4878 | * @func: the function to call to parse the event information | 5063 | * @func: the function to call to parse the event information |
5064 | * @context: the data to be passed to @func | ||
4879 | * | 5065 | * |
4880 | * This function allows a developer to override the parsing of | 5066 | * This function allows a developer to override the parsing of |
4881 | * a given event. If for some reason the default print format | 5067 | * a given event. If for some reason the default print format |
@@ -4925,6 +5111,11 @@ int pevent_register_event_handler(struct pevent *pevent, | |||
4925 | if (sys_name) | 5111 | if (sys_name) |
4926 | handle->sys_name = strdup(sys_name); | 5112 | handle->sys_name = strdup(sys_name); |
4927 | 5113 | ||
5114 | if ((event_name && !handle->event_name) || | ||
5115 | (sys_name && !handle->sys_name)) { | ||
5116 | die("Failed to allocate event/sys name"); | ||
5117 | } | ||
5118 | |||
4928 | handle->func = func; | 5119 | handle->func = func; |
4929 | handle->next = pevent->handlers; | 5120 | handle->next = pevent->handlers; |
4930 | pevent->handlers = handle; | 5121 | pevent->handlers = handle; |
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index ac997bc7b592..5772ad8cb386 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h | |||
@@ -226,6 +226,11 @@ struct print_arg_symbol { | |||
226 | struct print_flag_sym *symbols; | 226 | struct print_flag_sym *symbols; |
227 | }; | 227 | }; |
228 | 228 | ||
229 | struct print_arg_hex { | ||
230 | struct print_arg *field; | ||
231 | struct print_arg *size; | ||
232 | }; | ||
233 | |||
229 | struct print_arg_dynarray { | 234 | struct print_arg_dynarray { |
230 | struct format_field *field; | 235 | struct format_field *field; |
231 | struct print_arg *index; | 236 | struct print_arg *index; |
@@ -253,6 +258,7 @@ enum print_arg_type { | |||
253 | PRINT_FIELD, | 258 | PRINT_FIELD, |
254 | PRINT_FLAGS, | 259 | PRINT_FLAGS, |
255 | PRINT_SYMBOL, | 260 | PRINT_SYMBOL, |
261 | PRINT_HEX, | ||
256 | PRINT_TYPE, | 262 | PRINT_TYPE, |
257 | PRINT_STRING, | 263 | PRINT_STRING, |
258 | PRINT_BSTRING, | 264 | PRINT_BSTRING, |
@@ -270,6 +276,7 @@ struct print_arg { | |||
270 | struct print_arg_typecast typecast; | 276 | struct print_arg_typecast typecast; |
271 | struct print_arg_flags flags; | 277 | struct print_arg_flags flags; |
272 | struct print_arg_symbol symbol; | 278 | struct print_arg_symbol symbol; |
279 | struct print_arg_hex hex; | ||
273 | struct print_arg_func func; | 280 | struct print_arg_func func; |
274 | struct print_arg_string string; | 281 | struct print_arg_string string; |
275 | struct print_arg_op op; | 282 | struct print_arg_op op; |
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c index dfcfe2c131de..ad17855528f9 100644 --- a/tools/lib/traceevent/parse-filter.c +++ b/tools/lib/traceevent/parse-filter.c | |||
@@ -96,7 +96,7 @@ static enum event_type read_token(char **tok) | |||
96 | (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) && | 96 | (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) && |
97 | pevent_peek_char() == '~') { | 97 | pevent_peek_char() == '~') { |
98 | /* append it */ | 98 | /* append it */ |
99 | *tok = malloc(3); | 99 | *tok = malloc_or_die(3); |
100 | sprintf(*tok, "%c%c", *token, '~'); | 100 | sprintf(*tok, "%c%c", *token, '~'); |
101 | free_token(token); | 101 | free_token(token); |
102 | /* Now remove the '~' from the buffer */ | 102 | /* Now remove the '~' from the buffer */ |
@@ -148,17 +148,11 @@ add_filter_type(struct event_filter *filter, int id) | |||
148 | if (filter_type) | 148 | if (filter_type) |
149 | return filter_type; | 149 | return filter_type; |
150 | 150 | ||
151 | if (!filter->filters) | 151 | filter->event_filters = realloc(filter->event_filters, |
152 | filter->event_filters = | 152 | sizeof(*filter->event_filters) * |
153 | malloc_or_die(sizeof(*filter->event_filters)); | 153 | (filter->filters + 1)); |
154 | else { | 154 | if (!filter->event_filters) |
155 | filter->event_filters = | 155 | die("Could not allocate filter"); |
156 | realloc(filter->event_filters, | ||
157 | sizeof(*filter->event_filters) * | ||
158 | (filter->filters + 1)); | ||
159 | if (!filter->event_filters) | ||
160 | die("Could not allocate filter"); | ||
161 | } | ||
162 | 156 | ||
163 | for (i = 0; i < filter->filters; i++) { | 157 | for (i = 0; i < filter->filters; i++) { |
164 | if (filter->event_filters[i].event_id > id) | 158 | if (filter->event_filters[i].event_id > id) |
@@ -1480,7 +1474,7 @@ void pevent_filter_clear_trivial(struct event_filter *filter, | |||
1480 | { | 1474 | { |
1481 | struct filter_type *filter_type; | 1475 | struct filter_type *filter_type; |
1482 | int count = 0; | 1476 | int count = 0; |
1483 | int *ids; | 1477 | int *ids = NULL; |
1484 | int i; | 1478 | int i; |
1485 | 1479 | ||
1486 | if (!filter->filters) | 1480 | if (!filter->filters) |
@@ -1504,10 +1498,8 @@ void pevent_filter_clear_trivial(struct event_filter *filter, | |||
1504 | default: | 1498 | default: |
1505 | break; | 1499 | break; |
1506 | } | 1500 | } |
1507 | if (count) | 1501 | |
1508 | ids = realloc(ids, sizeof(*ids) * (count + 1)); | 1502 | ids = realloc(ids, sizeof(*ids) * (count + 1)); |
1509 | else | ||
1510 | ids = malloc(sizeof(*ids)); | ||
1511 | if (!ids) | 1503 | if (!ids) |
1512 | die("Can't allocate ids"); | 1504 | die("Can't allocate ids"); |
1513 | ids[count++] = filter_type->event_id; | 1505 | ids[count++] = filter_type->event_id; |
@@ -1710,18 +1702,43 @@ static int test_num(struct event_format *event, | |||
1710 | 1702 | ||
1711 | static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record) | 1703 | static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record) |
1712 | { | 1704 | { |
1713 | const char *val = record->data + arg->str.field->offset; | 1705 | struct event_format *event; |
1706 | struct pevent *pevent; | ||
1707 | unsigned long long addr; | ||
1708 | const char *val = NULL; | ||
1709 | char hex[64]; | ||
1714 | 1710 | ||
1715 | /* | 1711 | /* If the field is not a string convert it */ |
1716 | * We need to copy the data since we can't be sure the field | 1712 | if (arg->str.field->flags & FIELD_IS_STRING) { |
1717 | * is null terminated. | 1713 | val = record->data + arg->str.field->offset; |
1718 | */ | 1714 | |
1719 | if (*(val + arg->str.field->size - 1)) { | 1715 | /* |
1720 | /* copy it */ | 1716 | * We need to copy the data since we can't be sure the field |
1721 | memcpy(arg->str.buffer, val, arg->str.field->size); | 1717 | * is null terminated. |
1722 | /* the buffer is already NULL terminated */ | 1718 | */ |
1723 | val = arg->str.buffer; | 1719 | if (*(val + arg->str.field->size - 1)) { |
1720 | /* copy it */ | ||
1721 | memcpy(arg->str.buffer, val, arg->str.field->size); | ||
1722 | /* the buffer is already NULL terminated */ | ||
1723 | val = arg->str.buffer; | ||
1724 | } | ||
1725 | |||
1726 | } else { | ||
1727 | event = arg->str.field->event; | ||
1728 | pevent = event->pevent; | ||
1729 | addr = get_value(event, arg->str.field, record); | ||
1730 | |||
1731 | if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG)) | ||
1732 | /* convert to a kernel symbol */ | ||
1733 | val = pevent_find_function(pevent, addr); | ||
1734 | |||
1735 | if (val == NULL) { | ||
1736 | /* just use the hex of the string name */ | ||
1737 | snprintf(hex, 64, "0x%llx", addr); | ||
1738 | val = hex; | ||
1739 | } | ||
1724 | } | 1740 | } |
1741 | |||
1725 | return val; | 1742 | return val; |
1726 | } | 1743 | } |
1727 | 1744 | ||
@@ -2001,11 +2018,13 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg) | |||
2001 | char *lstr; | 2018 | char *lstr; |
2002 | char *rstr; | 2019 | char *rstr; |
2003 | char *op; | 2020 | char *op; |
2004 | char *str; | 2021 | char *str = NULL; |
2005 | int len; | 2022 | int len; |
2006 | 2023 | ||
2007 | lstr = arg_to_str(filter, arg->exp.left); | 2024 | lstr = arg_to_str(filter, arg->exp.left); |
2008 | rstr = arg_to_str(filter, arg->exp.right); | 2025 | rstr = arg_to_str(filter, arg->exp.right); |
2026 | if (!lstr || !rstr) | ||
2027 | goto out; | ||
2009 | 2028 | ||
2010 | switch (arg->exp.type) { | 2029 | switch (arg->exp.type) { |
2011 | case FILTER_EXP_ADD: | 2030 | case FILTER_EXP_ADD: |
@@ -2045,6 +2064,7 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg) | |||
2045 | len = strlen(op) + strlen(lstr) + strlen(rstr) + 4; | 2064 | len = strlen(op) + strlen(lstr) + strlen(rstr) + 4; |
2046 | str = malloc_or_die(len); | 2065 | str = malloc_or_die(len); |
2047 | snprintf(str, len, "%s %s %s", lstr, op, rstr); | 2066 | snprintf(str, len, "%s %s %s", lstr, op, rstr); |
2067 | out: | ||
2048 | free(lstr); | 2068 | free(lstr); |
2049 | free(rstr); | 2069 | free(rstr); |
2050 | 2070 | ||
@@ -2061,6 +2081,8 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg) | |||
2061 | 2081 | ||
2062 | lstr = arg_to_str(filter, arg->num.left); | 2082 | lstr = arg_to_str(filter, arg->num.left); |
2063 | rstr = arg_to_str(filter, arg->num.right); | 2083 | rstr = arg_to_str(filter, arg->num.right); |
2084 | if (!lstr || !rstr) | ||
2085 | goto out; | ||
2064 | 2086 | ||
2065 | switch (arg->num.type) { | 2087 | switch (arg->num.type) { |
2066 | case FILTER_CMP_EQ: | 2088 | case FILTER_CMP_EQ: |
@@ -2097,6 +2119,7 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg) | |||
2097 | break; | 2119 | break; |
2098 | } | 2120 | } |
2099 | 2121 | ||
2122 | out: | ||
2100 | free(lstr); | 2123 | free(lstr); |
2101 | free(rstr); | 2124 | free(rstr); |
2102 | return str; | 2125 | return str; |
@@ -2247,7 +2270,12 @@ int pevent_filter_compare(struct event_filter *filter1, struct event_filter *fil | |||
2247 | /* The best way to compare complex filters is with strings */ | 2270 | /* The best way to compare complex filters is with strings */ |
2248 | str1 = arg_to_str(filter1, filter_type1->filter); | 2271 | str1 = arg_to_str(filter1, filter_type1->filter); |
2249 | str2 = arg_to_str(filter2, filter_type2->filter); | 2272 | str2 = arg_to_str(filter2, filter_type2->filter); |
2250 | result = strcmp(str1, str2) != 0; | 2273 | if (str1 && str2) |
2274 | result = strcmp(str1, str2) != 0; | ||
2275 | else | ||
2276 | /* bail out if allocation fails */ | ||
2277 | result = 1; | ||
2278 | |||
2251 | free(str1); | 2279 | free(str1); |
2252 | free(str2); | 2280 | free(str2); |
2253 | if (result) | 2281 | if (result) |
diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt index a3dbadb26ef5..7065cd6fbdfc 100644 --- a/tools/perf/Documentation/perf-bench.txt +++ b/tools/perf/Documentation/perf-bench.txt | |||
@@ -12,7 +12,7 @@ SYNOPSIS | |||
12 | 12 | ||
13 | DESCRIPTION | 13 | DESCRIPTION |
14 | ----------- | 14 | ----------- |
15 | This 'perf bench' command is general framework for benchmark suites. | 15 | This 'perf bench' command is a general framework for benchmark suites. |
16 | 16 | ||
17 | COMMON OPTIONS | 17 | COMMON OPTIONS |
18 | -------------- | 18 | -------------- |
@@ -45,14 +45,20 @@ SUBSYSTEM | |||
45 | 'sched':: | 45 | 'sched':: |
46 | Scheduler and IPC mechanisms. | 46 | Scheduler and IPC mechanisms. |
47 | 47 | ||
48 | 'mem':: | ||
49 | Memory access performance. | ||
50 | |||
51 | 'all':: | ||
52 | All benchmark subsystems. | ||
53 | |||
48 | SUITES FOR 'sched' | 54 | SUITES FOR 'sched' |
49 | ~~~~~~~~~~~~~~~~~~ | 55 | ~~~~~~~~~~~~~~~~~~ |
50 | *messaging*:: | 56 | *messaging*:: |
51 | Suite for evaluating performance of scheduler and IPC mechanisms. | 57 | Suite for evaluating performance of scheduler and IPC mechanisms. |
52 | Based on hackbench by Rusty Russell. | 58 | Based on hackbench by Rusty Russell. |
53 | 59 | ||
54 | Options of *pipe* | 60 | Options of *messaging* |
55 | ^^^^^^^^^^^^^^^^^ | 61 | ^^^^^^^^^^^^^^^^^^^^^^ |
56 | -p:: | 62 | -p:: |
57 | --pipe:: | 63 | --pipe:: |
58 | Use pipe() instead of socketpair() | 64 | Use pipe() instead of socketpair() |
@@ -115,6 +121,72 @@ Example of *pipe* | |||
115 | 59004 ops/sec | 121 | 59004 ops/sec |
116 | --------------------- | 122 | --------------------- |
117 | 123 | ||
124 | SUITES FOR 'mem' | ||
125 | ~~~~~~~~~~~~~~~~ | ||
126 | *memcpy*:: | ||
127 | Suite for evaluating performance of simple memory copy in various ways. | ||
128 | |||
129 | Options of *memcpy* | ||
130 | ^^^^^^^^^^^^^^^^^^^ | ||
131 | -l:: | ||
132 | --length:: | ||
133 | Specify length of memory to copy (default: 1MB). | ||
134 | Available units are B, KB, MB, GB and TB (case insensitive). | ||
135 | |||
136 | -r:: | ||
137 | --routine:: | ||
138 | Specify routine to copy (default: default). | ||
139 | Available routines are depend on the architecture. | ||
140 | On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported. | ||
141 | |||
142 | -i:: | ||
143 | --iterations:: | ||
144 | Repeat memcpy invocation this number of times. | ||
145 | |||
146 | -c:: | ||
147 | --cycle:: | ||
148 | Use perf's cpu-cycles event instead of gettimeofday syscall. | ||
149 | |||
150 | -o:: | ||
151 | --only-prefault:: | ||
152 | Show only the result with page faults before memcpy. | ||
153 | |||
154 | -n:: | ||
155 | --no-prefault:: | ||
156 | Show only the result without page faults before memcpy. | ||
157 | |||
158 | *memset*:: | ||
159 | Suite for evaluating performance of simple memory set in various ways. | ||
160 | |||
161 | Options of *memset* | ||
162 | ^^^^^^^^^^^^^^^^^^^ | ||
163 | -l:: | ||
164 | --length:: | ||
165 | Specify length of memory to set (default: 1MB). | ||
166 | Available units are B, KB, MB, GB and TB (case insensitive). | ||
167 | |||
168 | -r:: | ||
169 | --routine:: | ||
170 | Specify routine to set (default: default). | ||
171 | Available routines are depend on the architecture. | ||
172 | On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported. | ||
173 | |||
174 | -i:: | ||
175 | --iterations:: | ||
176 | Repeat memset invocation this number of times. | ||
177 | |||
178 | -c:: | ||
179 | --cycle:: | ||
180 | Use perf's cpu-cycles event instead of gettimeofday syscall. | ||
181 | |||
182 | -o:: | ||
183 | --only-prefault:: | ||
184 | Show only the result with page faults before memset. | ||
185 | |||
186 | -n:: | ||
187 | --no-prefault:: | ||
188 | Show only the result without page faults before memset. | ||
189 | |||
118 | SEE ALSO | 190 | SEE ALSO |
119 | -------- | 191 | -------- |
120 | linkperf:perf[1] | 192 | linkperf:perf[1] |
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 2d89f02719b5..495210a612c4 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt | |||
@@ -57,7 +57,7 @@ OPTIONS | |||
57 | 57 | ||
58 | -s:: | 58 | -s:: |
59 | --sort=:: | 59 | --sort=:: |
60 | Sort by key(s): pid, comm, dso, symbol, parent. | 60 | Sort by key(s): pid, comm, dso, symbol, parent, srcline. |
61 | 61 | ||
62 | -p:: | 62 | -p:: |
63 | --parent=<regex>:: | 63 | --parent=<regex>:: |
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index 4a5680cb242e..5b80d84d6b4a 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt | |||
@@ -112,7 +112,7 @@ Default is to monitor all CPUS. | |||
112 | 112 | ||
113 | -s:: | 113 | -s:: |
114 | --sort:: | 114 | --sort:: |
115 | Sort by key(s): pid, comm, dso, symbol, parent | 115 | Sort by key(s): pid, comm, dso, symbol, parent, srcline. |
116 | 116 | ||
117 | -n:: | 117 | -n:: |
118 | --show-nr-samples:: | 118 | --show-nr-samples:: |
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 0eee64cfe9a0..75d74e5db8d5 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -155,7 +155,7 @@ endif | |||
155 | 155 | ||
156 | ### --- END CONFIGURATION SECTION --- | 156 | ### --- END CONFIGURATION SECTION --- |
157 | 157 | ||
158 | BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)/util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE | 158 | BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE |
159 | BASIC_LDFLAGS = | 159 | BASIC_LDFLAGS = |
160 | 160 | ||
161 | # Guard against environment variables | 161 | # Guard against environment variables |
@@ -503,6 +503,7 @@ else | |||
503 | LIB_OBJS += $(OUTPUT)ui/progress.o | 503 | LIB_OBJS += $(OUTPUT)ui/progress.o |
504 | LIB_OBJS += $(OUTPUT)ui/util.o | 504 | LIB_OBJS += $(OUTPUT)ui/util.o |
505 | LIB_OBJS += $(OUTPUT)ui/tui/setup.o | 505 | LIB_OBJS += $(OUTPUT)ui/tui/setup.o |
506 | LIB_OBJS += $(OUTPUT)ui/tui/util.o | ||
506 | LIB_H += ui/browser.h | 507 | LIB_H += ui/browser.h |
507 | LIB_H += ui/browsers/map.h | 508 | LIB_H += ui/browsers/map.h |
508 | LIB_H += ui/helpline.h | 509 | LIB_H += ui/helpline.h |
@@ -522,13 +523,18 @@ else | |||
522 | msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); | 523 | msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); |
523 | BASIC_CFLAGS += -DNO_GTK2_SUPPORT | 524 | BASIC_CFLAGS += -DNO_GTK2_SUPPORT |
524 | else | 525 | else |
526 | ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2)),y) | ||
527 | BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR | ||
528 | endif | ||
525 | BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0) | 529 | BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0) |
526 | EXTLIBS += $(shell pkg-config --libs gtk+-2.0) | 530 | EXTLIBS += $(shell pkg-config --libs gtk+-2.0) |
527 | LIB_OBJS += $(OUTPUT)ui/gtk/browser.o | 531 | LIB_OBJS += $(OUTPUT)ui/gtk/browser.o |
528 | LIB_OBJS += $(OUTPUT)ui/gtk/setup.o | 532 | LIB_OBJS += $(OUTPUT)ui/gtk/setup.o |
533 | LIB_OBJS += $(OUTPUT)ui/gtk/util.o | ||
529 | # Make sure that it'd be included only once. | 534 | # Make sure that it'd be included only once. |
530 | ifneq ($(findstring -DNO_NEWT_SUPPORT,$(BASIC_CFLAGS)),) | 535 | ifneq ($(findstring -DNO_NEWT_SUPPORT,$(BASIC_CFLAGS)),) |
531 | LIB_OBJS += $(OUTPUT)ui/setup.o | 536 | LIB_OBJS += $(OUTPUT)ui/setup.o |
537 | LIB_OBJS += $(OUTPUT)ui/util.o | ||
532 | endif | 538 | endif |
533 | endif | 539 | endif |
534 | endif | 540 | endif |
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c index 71557225bf92..02dad5d3359b 100644 --- a/tools/perf/bench/mem-memcpy.c +++ b/tools/perf/bench/mem-memcpy.c | |||
@@ -24,21 +24,21 @@ | |||
24 | static const char *length_str = "1MB"; | 24 | static const char *length_str = "1MB"; |
25 | static const char *routine = "default"; | 25 | static const char *routine = "default"; |
26 | static int iterations = 1; | 26 | static int iterations = 1; |
27 | static bool use_clock; | 27 | static bool use_cycle; |
28 | static int clock_fd; | 28 | static int cycle_fd; |
29 | static bool only_prefault; | 29 | static bool only_prefault; |
30 | static bool no_prefault; | 30 | static bool no_prefault; |
31 | 31 | ||
32 | static const struct option options[] = { | 32 | static const struct option options[] = { |
33 | OPT_STRING('l', "length", &length_str, "1MB", | 33 | OPT_STRING('l', "length", &length_str, "1MB", |
34 | "Specify length of memory to copy. " | 34 | "Specify length of memory to copy. " |
35 | "available unit: B, MB, GB (upper and lower)"), | 35 | "Available units: B, KB, MB, GB and TB (upper and lower)"), |
36 | OPT_STRING('r', "routine", &routine, "default", | 36 | OPT_STRING('r', "routine", &routine, "default", |
37 | "Specify routine to copy"), | 37 | "Specify routine to copy"), |
38 | OPT_INTEGER('i', "iterations", &iterations, | 38 | OPT_INTEGER('i', "iterations", &iterations, |
39 | "repeat memcpy() invocation this number of times"), | 39 | "repeat memcpy() invocation this number of times"), |
40 | OPT_BOOLEAN('c', "clock", &use_clock, | 40 | OPT_BOOLEAN('c', "cycle", &use_cycle, |
41 | "Use CPU clock for measuring"), | 41 | "Use cycles event instead of gettimeofday() for measuring"), |
42 | OPT_BOOLEAN('o', "only-prefault", &only_prefault, | 42 | OPT_BOOLEAN('o', "only-prefault", &only_prefault, |
43 | "Show only the result with page faults before memcpy()"), | 43 | "Show only the result with page faults before memcpy()"), |
44 | OPT_BOOLEAN('n', "no-prefault", &no_prefault, | 44 | OPT_BOOLEAN('n', "no-prefault", &no_prefault, |
@@ -76,27 +76,27 @@ static const char * const bench_mem_memcpy_usage[] = { | |||
76 | NULL | 76 | NULL |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static struct perf_event_attr clock_attr = { | 79 | static struct perf_event_attr cycle_attr = { |
80 | .type = PERF_TYPE_HARDWARE, | 80 | .type = PERF_TYPE_HARDWARE, |
81 | .config = PERF_COUNT_HW_CPU_CYCLES | 81 | .config = PERF_COUNT_HW_CPU_CYCLES |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static void init_clock(void) | 84 | static void init_cycle(void) |
85 | { | 85 | { |
86 | clock_fd = sys_perf_event_open(&clock_attr, getpid(), -1, -1, 0); | 86 | cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, 0); |
87 | 87 | ||
88 | if (clock_fd < 0 && errno == ENOSYS) | 88 | if (cycle_fd < 0 && errno == ENOSYS) |
89 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); | 89 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); |
90 | else | 90 | else |
91 | BUG_ON(clock_fd < 0); | 91 | BUG_ON(cycle_fd < 0); |
92 | } | 92 | } |
93 | 93 | ||
94 | static u64 get_clock(void) | 94 | static u64 get_cycle(void) |
95 | { | 95 | { |
96 | int ret; | 96 | int ret; |
97 | u64 clk; | 97 | u64 clk; |
98 | 98 | ||
99 | ret = read(clock_fd, &clk, sizeof(u64)); | 99 | ret = read(cycle_fd, &clk, sizeof(u64)); |
100 | BUG_ON(ret != sizeof(u64)); | 100 | BUG_ON(ret != sizeof(u64)); |
101 | 101 | ||
102 | return clk; | 102 | return clk; |
@@ -119,9 +119,9 @@ static void alloc_mem(void **dst, void **src, size_t length) | |||
119 | die("memory allocation failed - maybe length is too large?\n"); | 119 | die("memory allocation failed - maybe length is too large?\n"); |
120 | } | 120 | } |
121 | 121 | ||
122 | static u64 do_memcpy_clock(memcpy_t fn, size_t len, bool prefault) | 122 | static u64 do_memcpy_cycle(memcpy_t fn, size_t len, bool prefault) |
123 | { | 123 | { |
124 | u64 clock_start = 0ULL, clock_end = 0ULL; | 124 | u64 cycle_start = 0ULL, cycle_end = 0ULL; |
125 | void *src = NULL, *dst = NULL; | 125 | void *src = NULL, *dst = NULL; |
126 | int i; | 126 | int i; |
127 | 127 | ||
@@ -130,14 +130,14 @@ static u64 do_memcpy_clock(memcpy_t fn, size_t len, bool prefault) | |||
130 | if (prefault) | 130 | if (prefault) |
131 | fn(dst, src, len); | 131 | fn(dst, src, len); |
132 | 132 | ||
133 | clock_start = get_clock(); | 133 | cycle_start = get_cycle(); |
134 | for (i = 0; i < iterations; ++i) | 134 | for (i = 0; i < iterations; ++i) |
135 | fn(dst, src, len); | 135 | fn(dst, src, len); |
136 | clock_end = get_clock(); | 136 | cycle_end = get_cycle(); |
137 | 137 | ||
138 | free(src); | 138 | free(src); |
139 | free(dst); | 139 | free(dst); |
140 | return clock_end - clock_start; | 140 | return cycle_end - cycle_start; |
141 | } | 141 | } |
142 | 142 | ||
143 | static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault) | 143 | static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault) |
@@ -182,17 +182,17 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
182 | int i; | 182 | int i; |
183 | size_t len; | 183 | size_t len; |
184 | double result_bps[2]; | 184 | double result_bps[2]; |
185 | u64 result_clock[2]; | 185 | u64 result_cycle[2]; |
186 | 186 | ||
187 | argc = parse_options(argc, argv, options, | 187 | argc = parse_options(argc, argv, options, |
188 | bench_mem_memcpy_usage, 0); | 188 | bench_mem_memcpy_usage, 0); |
189 | 189 | ||
190 | if (use_clock) | 190 | if (use_cycle) |
191 | init_clock(); | 191 | init_cycle(); |
192 | 192 | ||
193 | len = (size_t)perf_atoll((char *)length_str); | 193 | len = (size_t)perf_atoll((char *)length_str); |
194 | 194 | ||
195 | result_clock[0] = result_clock[1] = 0ULL; | 195 | result_cycle[0] = result_cycle[1] = 0ULL; |
196 | result_bps[0] = result_bps[1] = 0.0; | 196 | result_bps[0] = result_bps[1] = 0.0; |
197 | 197 | ||
198 | if ((s64)len <= 0) { | 198 | if ((s64)len <= 0) { |
@@ -223,11 +223,11 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
223 | 223 | ||
224 | if (!only_prefault && !no_prefault) { | 224 | if (!only_prefault && !no_prefault) { |
225 | /* show both of results */ | 225 | /* show both of results */ |
226 | if (use_clock) { | 226 | if (use_cycle) { |
227 | result_clock[0] = | 227 | result_cycle[0] = |
228 | do_memcpy_clock(routines[i].fn, len, false); | 228 | do_memcpy_cycle(routines[i].fn, len, false); |
229 | result_clock[1] = | 229 | result_cycle[1] = |
230 | do_memcpy_clock(routines[i].fn, len, true); | 230 | do_memcpy_cycle(routines[i].fn, len, true); |
231 | } else { | 231 | } else { |
232 | result_bps[0] = | 232 | result_bps[0] = |
233 | do_memcpy_gettimeofday(routines[i].fn, | 233 | do_memcpy_gettimeofday(routines[i].fn, |
@@ -237,9 +237,9 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
237 | len, true); | 237 | len, true); |
238 | } | 238 | } |
239 | } else { | 239 | } else { |
240 | if (use_clock) { | 240 | if (use_cycle) { |
241 | result_clock[pf] = | 241 | result_cycle[pf] = |
242 | do_memcpy_clock(routines[i].fn, | 242 | do_memcpy_cycle(routines[i].fn, |
243 | len, only_prefault); | 243 | len, only_prefault); |
244 | } else { | 244 | } else { |
245 | result_bps[pf] = | 245 | result_bps[pf] = |
@@ -251,12 +251,12 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
251 | switch (bench_format) { | 251 | switch (bench_format) { |
252 | case BENCH_FORMAT_DEFAULT: | 252 | case BENCH_FORMAT_DEFAULT: |
253 | if (!only_prefault && !no_prefault) { | 253 | if (!only_prefault && !no_prefault) { |
254 | if (use_clock) { | 254 | if (use_cycle) { |
255 | printf(" %14lf Clock/Byte\n", | 255 | printf(" %14lf Cycle/Byte\n", |
256 | (double)result_clock[0] | 256 | (double)result_cycle[0] |
257 | / (double)len); | 257 | / (double)len); |
258 | printf(" %14lf Clock/Byte (with prefault)\n", | 258 | printf(" %14lf Cycle/Byte (with prefault)\n", |
259 | (double)result_clock[1] | 259 | (double)result_cycle[1] |
260 | / (double)len); | 260 | / (double)len); |
261 | } else { | 261 | } else { |
262 | print_bps(result_bps[0]); | 262 | print_bps(result_bps[0]); |
@@ -265,9 +265,9 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
265 | printf(" (with prefault)\n"); | 265 | printf(" (with prefault)\n"); |
266 | } | 266 | } |
267 | } else { | 267 | } else { |
268 | if (use_clock) { | 268 | if (use_cycle) { |
269 | printf(" %14lf Clock/Byte", | 269 | printf(" %14lf Cycle/Byte", |
270 | (double)result_clock[pf] | 270 | (double)result_cycle[pf] |
271 | / (double)len); | 271 | / (double)len); |
272 | } else | 272 | } else |
273 | print_bps(result_bps[pf]); | 273 | print_bps(result_bps[pf]); |
@@ -277,17 +277,17 @@ int bench_mem_memcpy(int argc, const char **argv, | |||
277 | break; | 277 | break; |
278 | case BENCH_FORMAT_SIMPLE: | 278 | case BENCH_FORMAT_SIMPLE: |
279 | if (!only_prefault && !no_prefault) { | 279 | if (!only_prefault && !no_prefault) { |
280 | if (use_clock) { | 280 | if (use_cycle) { |
281 | printf("%lf %lf\n", | 281 | printf("%lf %lf\n", |
282 | (double)result_clock[0] / (double)len, | 282 | (double)result_cycle[0] / (double)len, |
283 | (double)result_clock[1] / (double)len); | 283 | (double)result_cycle[1] / (double)len); |
284 | } else { | 284 | } else { |
285 | printf("%lf %lf\n", | 285 | printf("%lf %lf\n", |
286 | result_bps[0], result_bps[1]); | 286 | result_bps[0], result_bps[1]); |
287 | } | 287 | } |
288 | } else { | 288 | } else { |
289 | if (use_clock) { | 289 | if (use_cycle) { |
290 | printf("%lf\n", (double)result_clock[pf] | 290 | printf("%lf\n", (double)result_cycle[pf] |
291 | / (double)len); | 291 | / (double)len); |
292 | } else | 292 | } else |
293 | printf("%lf\n", result_bps[pf]); | 293 | printf("%lf\n", result_bps[pf]); |
diff --git a/tools/perf/bench/mem-memset.c b/tools/perf/bench/mem-memset.c index e9079185bd72..350cc9557265 100644 --- a/tools/perf/bench/mem-memset.c +++ b/tools/perf/bench/mem-memset.c | |||
@@ -24,21 +24,21 @@ | |||
24 | static const char *length_str = "1MB"; | 24 | static const char *length_str = "1MB"; |
25 | static const char *routine = "default"; | 25 | static const char *routine = "default"; |
26 | static int iterations = 1; | 26 | static int iterations = 1; |
27 | static bool use_clock; | 27 | static bool use_cycle; |
28 | static int clock_fd; | 28 | static int cycle_fd; |
29 | static bool only_prefault; | 29 | static bool only_prefault; |
30 | static bool no_prefault; | 30 | static bool no_prefault; |
31 | 31 | ||
32 | static const struct option options[] = { | 32 | static const struct option options[] = { |
33 | OPT_STRING('l', "length", &length_str, "1MB", | 33 | OPT_STRING('l', "length", &length_str, "1MB", |
34 | "Specify length of memory to copy. " | 34 | "Specify length of memory to set. " |
35 | "available unit: B, MB, GB (upper and lower)"), | 35 | "Available units: B, KB, MB, GB and TB (upper and lower)"), |
36 | OPT_STRING('r', "routine", &routine, "default", | 36 | OPT_STRING('r', "routine", &routine, "default", |
37 | "Specify routine to copy"), | 37 | "Specify routine to set"), |
38 | OPT_INTEGER('i', "iterations", &iterations, | 38 | OPT_INTEGER('i', "iterations", &iterations, |
39 | "repeat memset() invocation this number of times"), | 39 | "repeat memset() invocation this number of times"), |
40 | OPT_BOOLEAN('c', "clock", &use_clock, | 40 | OPT_BOOLEAN('c', "cycle", &use_cycle, |
41 | "Use CPU clock for measuring"), | 41 | "Use cycles event instead of gettimeofday() for measuring"), |
42 | OPT_BOOLEAN('o', "only-prefault", &only_prefault, | 42 | OPT_BOOLEAN('o', "only-prefault", &only_prefault, |
43 | "Show only the result with page faults before memset()"), | 43 | "Show only the result with page faults before memset()"), |
44 | OPT_BOOLEAN('n', "no-prefault", &no_prefault, | 44 | OPT_BOOLEAN('n', "no-prefault", &no_prefault, |
@@ -76,27 +76,27 @@ static const char * const bench_mem_memset_usage[] = { | |||
76 | NULL | 76 | NULL |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static struct perf_event_attr clock_attr = { | 79 | static struct perf_event_attr cycle_attr = { |
80 | .type = PERF_TYPE_HARDWARE, | 80 | .type = PERF_TYPE_HARDWARE, |
81 | .config = PERF_COUNT_HW_CPU_CYCLES | 81 | .config = PERF_COUNT_HW_CPU_CYCLES |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static void init_clock(void) | 84 | static void init_cycle(void) |
85 | { | 85 | { |
86 | clock_fd = sys_perf_event_open(&clock_attr, getpid(), -1, -1, 0); | 86 | cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, 0); |
87 | 87 | ||
88 | if (clock_fd < 0 && errno == ENOSYS) | 88 | if (cycle_fd < 0 && errno == ENOSYS) |
89 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); | 89 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); |
90 | else | 90 | else |
91 | BUG_ON(clock_fd < 0); | 91 | BUG_ON(cycle_fd < 0); |
92 | } | 92 | } |
93 | 93 | ||
94 | static u64 get_clock(void) | 94 | static u64 get_cycle(void) |
95 | { | 95 | { |
96 | int ret; | 96 | int ret; |
97 | u64 clk; | 97 | u64 clk; |
98 | 98 | ||
99 | ret = read(clock_fd, &clk, sizeof(u64)); | 99 | ret = read(cycle_fd, &clk, sizeof(u64)); |
100 | BUG_ON(ret != sizeof(u64)); | 100 | BUG_ON(ret != sizeof(u64)); |
101 | 101 | ||
102 | return clk; | 102 | return clk; |
@@ -115,9 +115,9 @@ static void alloc_mem(void **dst, size_t length) | |||
115 | die("memory allocation failed - maybe length is too large?\n"); | 115 | die("memory allocation failed - maybe length is too large?\n"); |
116 | } | 116 | } |
117 | 117 | ||
118 | static u64 do_memset_clock(memset_t fn, size_t len, bool prefault) | 118 | static u64 do_memset_cycle(memset_t fn, size_t len, bool prefault) |
119 | { | 119 | { |
120 | u64 clock_start = 0ULL, clock_end = 0ULL; | 120 | u64 cycle_start = 0ULL, cycle_end = 0ULL; |
121 | void *dst = NULL; | 121 | void *dst = NULL; |
122 | int i; | 122 | int i; |
123 | 123 | ||
@@ -126,13 +126,13 @@ static u64 do_memset_clock(memset_t fn, size_t len, bool prefault) | |||
126 | if (prefault) | 126 | if (prefault) |
127 | fn(dst, -1, len); | 127 | fn(dst, -1, len); |
128 | 128 | ||
129 | clock_start = get_clock(); | 129 | cycle_start = get_cycle(); |
130 | for (i = 0; i < iterations; ++i) | 130 | for (i = 0; i < iterations; ++i) |
131 | fn(dst, i, len); | 131 | fn(dst, i, len); |
132 | clock_end = get_clock(); | 132 | cycle_end = get_cycle(); |
133 | 133 | ||
134 | free(dst); | 134 | free(dst); |
135 | return clock_end - clock_start; | 135 | return cycle_end - cycle_start; |
136 | } | 136 | } |
137 | 137 | ||
138 | static double do_memset_gettimeofday(memset_t fn, size_t len, bool prefault) | 138 | static double do_memset_gettimeofday(memset_t fn, size_t len, bool prefault) |
@@ -176,17 +176,17 @@ int bench_mem_memset(int argc, const char **argv, | |||
176 | int i; | 176 | int i; |
177 | size_t len; | 177 | size_t len; |
178 | double result_bps[2]; | 178 | double result_bps[2]; |
179 | u64 result_clock[2]; | 179 | u64 result_cycle[2]; |
180 | 180 | ||
181 | argc = parse_options(argc, argv, options, | 181 | argc = parse_options(argc, argv, options, |
182 | bench_mem_memset_usage, 0); | 182 | bench_mem_memset_usage, 0); |
183 | 183 | ||
184 | if (use_clock) | 184 | if (use_cycle) |
185 | init_clock(); | 185 | init_cycle(); |
186 | 186 | ||
187 | len = (size_t)perf_atoll((char *)length_str); | 187 | len = (size_t)perf_atoll((char *)length_str); |
188 | 188 | ||
189 | result_clock[0] = result_clock[1] = 0ULL; | 189 | result_cycle[0] = result_cycle[1] = 0ULL; |
190 | result_bps[0] = result_bps[1] = 0.0; | 190 | result_bps[0] = result_bps[1] = 0.0; |
191 | 191 | ||
192 | if ((s64)len <= 0) { | 192 | if ((s64)len <= 0) { |
@@ -217,11 +217,11 @@ int bench_mem_memset(int argc, const char **argv, | |||
217 | 217 | ||
218 | if (!only_prefault && !no_prefault) { | 218 | if (!only_prefault && !no_prefault) { |
219 | /* show both of results */ | 219 | /* show both of results */ |
220 | if (use_clock) { | 220 | if (use_cycle) { |
221 | result_clock[0] = | 221 | result_cycle[0] = |
222 | do_memset_clock(routines[i].fn, len, false); | 222 | do_memset_cycle(routines[i].fn, len, false); |
223 | result_clock[1] = | 223 | result_cycle[1] = |
224 | do_memset_clock(routines[i].fn, len, true); | 224 | do_memset_cycle(routines[i].fn, len, true); |
225 | } else { | 225 | } else { |
226 | result_bps[0] = | 226 | result_bps[0] = |
227 | do_memset_gettimeofday(routines[i].fn, | 227 | do_memset_gettimeofday(routines[i].fn, |
@@ -231,9 +231,9 @@ int bench_mem_memset(int argc, const char **argv, | |||
231 | len, true); | 231 | len, true); |
232 | } | 232 | } |
233 | } else { | 233 | } else { |
234 | if (use_clock) { | 234 | if (use_cycle) { |
235 | result_clock[pf] = | 235 | result_cycle[pf] = |
236 | do_memset_clock(routines[i].fn, | 236 | do_memset_cycle(routines[i].fn, |
237 | len, only_prefault); | 237 | len, only_prefault); |
238 | } else { | 238 | } else { |
239 | result_bps[pf] = | 239 | result_bps[pf] = |
@@ -245,12 +245,12 @@ int bench_mem_memset(int argc, const char **argv, | |||
245 | switch (bench_format) { | 245 | switch (bench_format) { |
246 | case BENCH_FORMAT_DEFAULT: | 246 | case BENCH_FORMAT_DEFAULT: |
247 | if (!only_prefault && !no_prefault) { | 247 | if (!only_prefault && !no_prefault) { |
248 | if (use_clock) { | 248 | if (use_cycle) { |
249 | printf(" %14lf Clock/Byte\n", | 249 | printf(" %14lf Cycle/Byte\n", |
250 | (double)result_clock[0] | 250 | (double)result_cycle[0] |
251 | / (double)len); | 251 | / (double)len); |
252 | printf(" %14lf Clock/Byte (with prefault)\n ", | 252 | printf(" %14lf Cycle/Byte (with prefault)\n ", |
253 | (double)result_clock[1] | 253 | (double)result_cycle[1] |
254 | / (double)len); | 254 | / (double)len); |
255 | } else { | 255 | } else { |
256 | print_bps(result_bps[0]); | 256 | print_bps(result_bps[0]); |
@@ -259,9 +259,9 @@ int bench_mem_memset(int argc, const char **argv, | |||
259 | printf(" (with prefault)\n"); | 259 | printf(" (with prefault)\n"); |
260 | } | 260 | } |
261 | } else { | 261 | } else { |
262 | if (use_clock) { | 262 | if (use_cycle) { |
263 | printf(" %14lf Clock/Byte", | 263 | printf(" %14lf Cycle/Byte", |
264 | (double)result_clock[pf] | 264 | (double)result_cycle[pf] |
265 | / (double)len); | 265 | / (double)len); |
266 | } else | 266 | } else |
267 | print_bps(result_bps[pf]); | 267 | print_bps(result_bps[pf]); |
@@ -271,17 +271,17 @@ int bench_mem_memset(int argc, const char **argv, | |||
271 | break; | 271 | break; |
272 | case BENCH_FORMAT_SIMPLE: | 272 | case BENCH_FORMAT_SIMPLE: |
273 | if (!only_prefault && !no_prefault) { | 273 | if (!only_prefault && !no_prefault) { |
274 | if (use_clock) { | 274 | if (use_cycle) { |
275 | printf("%lf %lf\n", | 275 | printf("%lf %lf\n", |
276 | (double)result_clock[0] / (double)len, | 276 | (double)result_cycle[0] / (double)len, |
277 | (double)result_clock[1] / (double)len); | 277 | (double)result_cycle[1] / (double)len); |
278 | } else { | 278 | } else { |
279 | printf("%lf %lf\n", | 279 | printf("%lf %lf\n", |
280 | result_bps[0], result_bps[1]); | 280 | result_bps[0], result_bps[1]); |
281 | } | 281 | } |
282 | } else { | 282 | } else { |
283 | if (use_clock) { | 283 | if (use_cycle) { |
284 | printf("%lf\n", (double)result_clock[pf] | 284 | printf("%lf\n", (double)result_cycle[pf] |
285 | / (double)len); | 285 | / (double)len); |
286 | } else | 286 | } else |
287 | printf("%lf\n", result_bps[pf]); | 287 | printf("%lf\n", result_bps[pf]); |
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index b0e74ab2d7a2..1f3100216448 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c | |||
@@ -33,7 +33,7 @@ struct bench_suite { | |||
33 | }; | 33 | }; |
34 | \ | 34 | \ |
35 | /* sentinel: easy for help */ | 35 | /* sentinel: easy for help */ |
36 | #define suite_all { "all", "test all suite (pseudo suite)", NULL } | 36 | #define suite_all { "all", "Test all benchmark suites", NULL } |
37 | 37 | ||
38 | static struct bench_suite sched_suites[] = { | 38 | static struct bench_suite sched_suites[] = { |
39 | { "messaging", | 39 | { "messaging", |
@@ -75,7 +75,7 @@ static struct bench_subsys subsystems[] = { | |||
75 | "memory access performance", | 75 | "memory access performance", |
76 | mem_suites }, | 76 | mem_suites }, |
77 | { "all", /* sentinel: easy for help */ | 77 | { "all", /* sentinel: easy for help */ |
78 | "test all subsystem (pseudo subsystem)", | 78 | "all benchmark subsystem", |
79 | NULL }, | 79 | NULL }, |
80 | { NULL, | 80 | { NULL, |
81 | NULL, | 81 | NULL, |
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index acd78dc28341..0dd5a058f766 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c | |||
@@ -60,7 +60,7 @@ static int __cmd_evlist(const char *input_name, struct perf_attr_details *detail | |||
60 | list_for_each_entry(pos, &session->evlist->entries, node) { | 60 | list_for_each_entry(pos, &session->evlist->entries, node) { |
61 | bool first = true; | 61 | bool first = true; |
62 | 62 | ||
63 | printf("%s", event_name(pos)); | 63 | printf("%s", perf_evsel__name(pos)); |
64 | 64 | ||
65 | if (details->verbose || details->freq) { | 65 | if (details->verbose || details->freq) { |
66 | comma_printf(&first, " sample_freq=%" PRIu64, | 66 | comma_printf(&first, " sample_freq=%" PRIu64, |
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 547af48deb4f..ce35015f2dc6 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
@@ -57,6 +57,11 @@ static unsigned long nr_allocs, nr_cross_allocs; | |||
57 | 57 | ||
58 | #define PATH_SYS_NODE "/sys/devices/system/node" | 58 | #define PATH_SYS_NODE "/sys/devices/system/node" |
59 | 59 | ||
60 | struct perf_kmem { | ||
61 | struct perf_tool tool; | ||
62 | struct perf_session *session; | ||
63 | }; | ||
64 | |||
60 | static void init_cpunode_map(void) | 65 | static void init_cpunode_map(void) |
61 | { | 66 | { |
62 | FILE *fp; | 67 | FILE *fp; |
@@ -278,14 +283,16 @@ static void process_free_event(void *data, | |||
278 | s_alloc->alloc_cpu = -1; | 283 | s_alloc->alloc_cpu = -1; |
279 | } | 284 | } |
280 | 285 | ||
281 | static void process_raw_event(union perf_event *raw_event __used, void *data, | 286 | static void process_raw_event(struct perf_tool *tool, |
287 | union perf_event *raw_event __used, void *data, | ||
282 | int cpu, u64 timestamp, struct thread *thread) | 288 | int cpu, u64 timestamp, struct thread *thread) |
283 | { | 289 | { |
290 | struct perf_kmem *kmem = container_of(tool, struct perf_kmem, tool); | ||
284 | struct event_format *event; | 291 | struct event_format *event; |
285 | int type; | 292 | int type; |
286 | 293 | ||
287 | type = trace_parse_common_type(data); | 294 | type = trace_parse_common_type(kmem->session->pevent, data); |
288 | event = trace_find_event(type); | 295 | event = pevent_find_event(kmem->session->pevent, type); |
289 | 296 | ||
290 | if (!strcmp(event->name, "kmalloc") || | 297 | if (!strcmp(event->name, "kmalloc") || |
291 | !strcmp(event->name, "kmem_cache_alloc")) { | 298 | !strcmp(event->name, "kmem_cache_alloc")) { |
@@ -306,7 +313,7 @@ static void process_raw_event(union perf_event *raw_event __used, void *data, | |||
306 | } | 313 | } |
307 | } | 314 | } |
308 | 315 | ||
309 | static int process_sample_event(struct perf_tool *tool __used, | 316 | static int process_sample_event(struct perf_tool *tool, |
310 | union perf_event *event, | 317 | union perf_event *event, |
311 | struct perf_sample *sample, | 318 | struct perf_sample *sample, |
312 | struct perf_evsel *evsel __used, | 319 | struct perf_evsel *evsel __used, |
@@ -322,16 +329,18 @@ static int process_sample_event(struct perf_tool *tool __used, | |||
322 | 329 | ||
323 | dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); | 330 | dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); |
324 | 331 | ||
325 | process_raw_event(event, sample->raw_data, sample->cpu, | 332 | process_raw_event(tool, event, sample->raw_data, sample->cpu, |
326 | sample->time, thread); | 333 | sample->time, thread); |
327 | 334 | ||
328 | return 0; | 335 | return 0; |
329 | } | 336 | } |
330 | 337 | ||
331 | static struct perf_tool perf_kmem = { | 338 | static struct perf_kmem perf_kmem = { |
332 | .sample = process_sample_event, | 339 | .tool = { |
333 | .comm = perf_event__process_comm, | 340 | .sample = process_sample_event, |
334 | .ordered_samples = true, | 341 | .comm = perf_event__process_comm, |
342 | .ordered_samples = true, | ||
343 | }, | ||
335 | }; | 344 | }; |
336 | 345 | ||
337 | static double fragmentation(unsigned long n_req, unsigned long n_alloc) | 346 | static double fragmentation(unsigned long n_req, unsigned long n_alloc) |
@@ -486,11 +495,15 @@ static void sort_result(void) | |||
486 | static int __cmd_kmem(void) | 495 | static int __cmd_kmem(void) |
487 | { | 496 | { |
488 | int err = -EINVAL; | 497 | int err = -EINVAL; |
489 | struct perf_session *session = perf_session__new(input_name, O_RDONLY, | 498 | struct perf_session *session; |
490 | 0, false, &perf_kmem); | 499 | |
500 | session = perf_session__new(input_name, O_RDONLY, 0, false, | ||
501 | &perf_kmem.tool); | ||
491 | if (session == NULL) | 502 | if (session == NULL) |
492 | return -ENOMEM; | 503 | return -ENOMEM; |
493 | 504 | ||
505 | perf_kmem.session = session; | ||
506 | |||
494 | if (perf_session__create_kernel_maps(session) < 0) | 507 | if (perf_session__create_kernel_maps(session) < 0) |
495 | goto out_delete; | 508 | goto out_delete; |
496 | 509 | ||
@@ -498,7 +511,7 @@ static int __cmd_kmem(void) | |||
498 | goto out_delete; | 511 | goto out_delete; |
499 | 512 | ||
500 | setup_pager(); | 513 | setup_pager(); |
501 | err = perf_session__process_events(session, &perf_kmem); | 514 | err = perf_session__process_events(session, &perf_kmem.tool); |
502 | if (err != 0) | 515 | if (err != 0) |
503 | goto out_delete; | 516 | goto out_delete; |
504 | sort_result(); | 517 | sort_result(); |
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index fd53319de20d..b3c428548868 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c | |||
@@ -724,8 +724,8 @@ process_raw_event(void *data, int cpu, u64 timestamp, struct thread *thread) | |||
724 | struct event_format *event; | 724 | struct event_format *event; |
725 | int type; | 725 | int type; |
726 | 726 | ||
727 | type = trace_parse_common_type(data); | 727 | type = trace_parse_common_type(session->pevent, data); |
728 | event = trace_find_event(type); | 728 | event = pevent_find_event(session->pevent, type); |
729 | 729 | ||
730 | if (!strcmp(event->name, "lock_acquire")) | 730 | if (!strcmp(event->name, "lock_acquire")) |
731 | process_lock_acquire_event(data, event, cpu, timestamp, thread); | 731 | process_lock_acquire_event(data, event, cpu, timestamp, thread); |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f95840d04e4c..f5a6452931e6 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -265,7 +265,7 @@ try_again: | |||
265 | 265 | ||
266 | if (err == ENOENT) { | 266 | if (err == ENOENT) { |
267 | ui__error("The %s event is not supported.\n", | 267 | ui__error("The %s event is not supported.\n", |
268 | event_name(pos)); | 268 | perf_evsel__name(pos)); |
269 | exit(EXIT_FAILURE); | 269 | exit(EXIT_FAILURE); |
270 | } | 270 | } |
271 | 271 | ||
@@ -916,7 +916,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
916 | usage_with_options(record_usage, record_options); | 916 | usage_with_options(record_usage, record_options); |
917 | 917 | ||
918 | list_for_each_entry(pos, &evsel_list->entries, node) { | 918 | list_for_each_entry(pos, &evsel_list->entries, node) { |
919 | if (perf_header__push_event(pos->attr.config, event_name(pos))) | 919 | if (perf_header__push_event(pos->attr.config, perf_evsel__name(pos))) |
920 | goto out_free_fd; | 920 | goto out_free_fd; |
921 | } | 921 | } |
922 | 922 | ||
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 25249f76329d..69b1c1185159 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -69,7 +69,7 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool, | |||
69 | 69 | ||
70 | if ((sort__has_parent || symbol_conf.use_callchain) | 70 | if ((sort__has_parent || symbol_conf.use_callchain) |
71 | && sample->callchain) { | 71 | && sample->callchain) { |
72 | err = machine__resolve_callchain(machine, evsel, al->thread, | 72 | err = machine__resolve_callchain(machine, al->thread, |
73 | sample->callchain, &parent); | 73 | sample->callchain, &parent); |
74 | if (err) | 74 | if (err) |
75 | return err; | 75 | return err; |
@@ -140,7 +140,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel, | |||
140 | struct hist_entry *he; | 140 | struct hist_entry *he; |
141 | 141 | ||
142 | if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { | 142 | if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { |
143 | err = machine__resolve_callchain(machine, evsel, al->thread, | 143 | err = machine__resolve_callchain(machine, al->thread, |
144 | sample->callchain, &parent); | 144 | sample->callchain, &parent); |
145 | if (err) | 145 | if (err) |
146 | return err; | 146 | return err; |
@@ -230,7 +230,7 @@ static int process_read_event(struct perf_tool *tool, | |||
230 | struct perf_report *rep = container_of(tool, struct perf_report, tool); | 230 | struct perf_report *rep = container_of(tool, struct perf_report, tool); |
231 | 231 | ||
232 | if (rep->show_threads) { | 232 | if (rep->show_threads) { |
233 | const char *name = evsel ? event_name(evsel) : "unknown"; | 233 | const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; |
234 | perf_read_values_add_value(&rep->show_threads_values, | 234 | perf_read_values_add_value(&rep->show_threads_values, |
235 | event->read.pid, event->read.tid, | 235 | event->read.pid, event->read.tid, |
236 | event->read.id, | 236 | event->read.id, |
@@ -239,17 +239,18 @@ static int process_read_event(struct perf_tool *tool, | |||
239 | } | 239 | } |
240 | 240 | ||
241 | dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, | 241 | dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, |
242 | evsel ? event_name(evsel) : "FAIL", | 242 | evsel ? perf_evsel__name(evsel) : "FAIL", |
243 | event->read.value); | 243 | event->read.value); |
244 | 244 | ||
245 | return 0; | 245 | return 0; |
246 | } | 246 | } |
247 | 247 | ||
248 | /* For pipe mode, sample_type is not currently set */ | ||
248 | static int perf_report__setup_sample_type(struct perf_report *rep) | 249 | static int perf_report__setup_sample_type(struct perf_report *rep) |
249 | { | 250 | { |
250 | struct perf_session *self = rep->session; | 251 | struct perf_session *self = rep->session; |
251 | 252 | ||
252 | if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { | 253 | if (!self->fd_pipe && !(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { |
253 | if (sort__has_parent) { | 254 | if (sort__has_parent) { |
254 | ui__error("Selected --sort parent, but no " | 255 | ui__error("Selected --sort parent, but no " |
255 | "callchain data. Did you call " | 256 | "callchain data. Did you call " |
@@ -272,7 +273,8 @@ static int perf_report__setup_sample_type(struct perf_report *rep) | |||
272 | } | 273 | } |
273 | 274 | ||
274 | if (sort__branch_mode == 1) { | 275 | if (sort__branch_mode == 1) { |
275 | if (!(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { | 276 | if (!self->fd_pipe && |
277 | !(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { | ||
276 | ui__error("Selected -b but no branch data. " | 278 | ui__error("Selected -b but no branch data. " |
277 | "Did you call perf record without -b?\n"); | 279 | "Did you call perf record without -b?\n"); |
278 | return -1; | 280 | return -1; |
@@ -314,7 +316,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, | |||
314 | 316 | ||
315 | list_for_each_entry(pos, &evlist->entries, node) { | 317 | list_for_each_entry(pos, &evlist->entries, node) { |
316 | struct hists *hists = &pos->hists; | 318 | struct hists *hists = &pos->hists; |
317 | const char *evname = event_name(pos); | 319 | const char *evname = perf_evsel__name(pos); |
318 | 320 | ||
319 | hists__fprintf_nr_sample_events(hists, evname, stdout); | 321 | hists__fprintf_nr_sample_events(hists, evname, stdout); |
320 | hists__fprintf(hists, NULL, false, true, 0, 0, stdout); | 322 | hists__fprintf(hists, NULL, false, true, 0, 0, stdout); |
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index b125e07eb399..7a9ad2b1ee76 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
@@ -43,6 +43,11 @@ static u64 sleep_measurement_overhead; | |||
43 | 43 | ||
44 | static unsigned long nr_tasks; | 44 | static unsigned long nr_tasks; |
45 | 45 | ||
46 | struct perf_sched { | ||
47 | struct perf_tool tool; | ||
48 | struct perf_session *session; | ||
49 | }; | ||
50 | |||
46 | struct sched_atom; | 51 | struct sched_atom; |
47 | 52 | ||
48 | struct task_desc { | 53 | struct task_desc { |
@@ -1597,11 +1602,13 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, | |||
1597 | struct perf_evsel *evsel, | 1602 | struct perf_evsel *evsel, |
1598 | struct machine *machine) | 1603 | struct machine *machine) |
1599 | { | 1604 | { |
1605 | struct perf_sched *sched = container_of(tool, struct perf_sched, tool); | ||
1606 | struct pevent *pevent = sched->session->pevent; | ||
1600 | struct thread *thread = machine__findnew_thread(machine, sample->pid); | 1607 | struct thread *thread = machine__findnew_thread(machine, sample->pid); |
1601 | 1608 | ||
1602 | if (thread == NULL) { | 1609 | if (thread == NULL) { |
1603 | pr_debug("problem processing %s event, skipping it.\n", | 1610 | pr_debug("problem processing %s event, skipping it.\n", |
1604 | evsel->name); | 1611 | perf_evsel__name(evsel)); |
1605 | return -1; | 1612 | return -1; |
1606 | } | 1613 | } |
1607 | 1614 | ||
@@ -1612,7 +1619,8 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, | |||
1612 | tracepoint_handler f = evsel->handler.func; | 1619 | tracepoint_handler f = evsel->handler.func; |
1613 | 1620 | ||
1614 | if (evsel->handler.data == NULL) | 1621 | if (evsel->handler.data == NULL) |
1615 | evsel->handler.data = trace_find_event(evsel->attr.config); | 1622 | evsel->handler.data = pevent_find_event(pevent, |
1623 | evsel->attr.config); | ||
1616 | 1624 | ||
1617 | f(tool, evsel->handler.data, sample, machine, thread); | 1625 | f(tool, evsel->handler.data, sample, machine, thread); |
1618 | } | 1626 | } |
@@ -1620,12 +1628,14 @@ static int perf_sched__process_tracepoint_sample(struct perf_tool *tool, | |||
1620 | return 0; | 1628 | return 0; |
1621 | } | 1629 | } |
1622 | 1630 | ||
1623 | static struct perf_tool perf_sched = { | 1631 | static struct perf_sched perf_sched = { |
1624 | .sample = perf_sched__process_tracepoint_sample, | 1632 | .tool = { |
1625 | .comm = perf_event__process_comm, | 1633 | .sample = perf_sched__process_tracepoint_sample, |
1626 | .lost = perf_event__process_lost, | 1634 | .comm = perf_event__process_comm, |
1627 | .fork = perf_event__process_task, | 1635 | .lost = perf_event__process_lost, |
1628 | .ordered_samples = true, | 1636 | .fork = perf_event__process_task, |
1637 | .ordered_samples = true, | ||
1638 | }, | ||
1629 | }; | 1639 | }; |
1630 | 1640 | ||
1631 | static void read_events(bool destroy, struct perf_session **psession) | 1641 | static void read_events(bool destroy, struct perf_session **psession) |
@@ -1640,16 +1650,20 @@ static void read_events(bool destroy, struct perf_session **psession) | |||
1640 | { "sched:sched_process_exit", process_sched_exit_event, }, | 1650 | { "sched:sched_process_exit", process_sched_exit_event, }, |
1641 | { "sched:sched_migrate_task", process_sched_migrate_task_event, }, | 1651 | { "sched:sched_migrate_task", process_sched_migrate_task_event, }, |
1642 | }; | 1652 | }; |
1643 | struct perf_session *session = perf_session__new(input_name, O_RDONLY, | 1653 | struct perf_session *session; |
1644 | 0, false, &perf_sched); | 1654 | |
1655 | session = perf_session__new(input_name, O_RDONLY, 0, false, | ||
1656 | &perf_sched.tool); | ||
1645 | if (session == NULL) | 1657 | if (session == NULL) |
1646 | die("No Memory"); | 1658 | die("No Memory"); |
1647 | 1659 | ||
1648 | err = perf_evlist__set_tracepoints_handlers_array(session->evlist, handlers); | 1660 | perf_sched.session = session; |
1661 | |||
1662 | err = perf_session__set_tracepoints_handlers(session, handlers); | ||
1649 | assert(err == 0); | 1663 | assert(err == 0); |
1650 | 1664 | ||
1651 | if (perf_session__has_traces(session, "record -R")) { | 1665 | if (perf_session__has_traces(session, "record -R")) { |
1652 | err = perf_session__process_events(session, &perf_sched); | 1666 | err = perf_session__process_events(session, &perf_sched.tool); |
1653 | if (err) | 1667 | if (err) |
1654 | die("Failed to process events, error %d", err); | 1668 | die("Failed to process events, error %d", err); |
1655 | 1669 | ||
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 8e395a538eb9..1e60ab70b2b1 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -28,6 +28,11 @@ static bool system_wide; | |||
28 | static const char *cpu_list; | 28 | static const char *cpu_list; |
29 | static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); | 29 | static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); |
30 | 30 | ||
31 | struct perf_script { | ||
32 | struct perf_tool tool; | ||
33 | struct perf_session *session; | ||
34 | }; | ||
35 | |||
31 | enum perf_output_field { | 36 | enum perf_output_field { |
32 | PERF_OUTPUT_COMM = 1U << 0, | 37 | PERF_OUTPUT_COMM = 1U << 0, |
33 | PERF_OUTPUT_TID = 1U << 1, | 38 | PERF_OUTPUT_TID = 1U << 1, |
@@ -137,10 +142,11 @@ static const char *output_field2str(enum perf_output_field field) | |||
137 | 142 | ||
138 | #define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x) | 143 | #define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x) |
139 | 144 | ||
140 | static int perf_event_attr__check_stype(struct perf_event_attr *attr, | 145 | static int perf_evsel__check_stype(struct perf_evsel *evsel, |
141 | u64 sample_type, const char *sample_msg, | 146 | u64 sample_type, const char *sample_msg, |
142 | enum perf_output_field field) | 147 | enum perf_output_field field) |
143 | { | 148 | { |
149 | struct perf_event_attr *attr = &evsel->attr; | ||
144 | int type = attr->type; | 150 | int type = attr->type; |
145 | const char *evname; | 151 | const char *evname; |
146 | 152 | ||
@@ -148,7 +154,7 @@ static int perf_event_attr__check_stype(struct perf_event_attr *attr, | |||
148 | return 0; | 154 | return 0; |
149 | 155 | ||
150 | if (output[type].user_set) { | 156 | if (output[type].user_set) { |
151 | evname = __event_name(attr->type, attr->config); | 157 | evname = perf_evsel__name(evsel); |
152 | pr_err("Samples for '%s' event do not have %s attribute set. " | 158 | pr_err("Samples for '%s' event do not have %s attribute set. " |
153 | "Cannot print '%s' field.\n", | 159 | "Cannot print '%s' field.\n", |
154 | evname, sample_msg, output_field2str(field)); | 160 | evname, sample_msg, output_field2str(field)); |
@@ -157,7 +163,7 @@ static int perf_event_attr__check_stype(struct perf_event_attr *attr, | |||
157 | 163 | ||
158 | /* user did not ask for it explicitly so remove from the default list */ | 164 | /* user did not ask for it explicitly so remove from the default list */ |
159 | output[type].fields &= ~field; | 165 | output[type].fields &= ~field; |
160 | evname = __event_name(attr->type, attr->config); | 166 | evname = perf_evsel__name(evsel); |
161 | pr_debug("Samples for '%s' event do not have %s attribute set. " | 167 | pr_debug("Samples for '%s' event do not have %s attribute set. " |
162 | "Skipping '%s' field.\n", | 168 | "Skipping '%s' field.\n", |
163 | evname, sample_msg, output_field2str(field)); | 169 | evname, sample_msg, output_field2str(field)); |
@@ -175,8 +181,8 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, | |||
175 | return -EINVAL; | 181 | return -EINVAL; |
176 | 182 | ||
177 | if (PRINT_FIELD(IP)) { | 183 | if (PRINT_FIELD(IP)) { |
178 | if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP", | 184 | if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", |
179 | PERF_OUTPUT_IP)) | 185 | PERF_OUTPUT_IP)) |
180 | return -EINVAL; | 186 | return -EINVAL; |
181 | 187 | ||
182 | if (!no_callchain && | 188 | if (!no_callchain && |
@@ -185,8 +191,8 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, | |||
185 | } | 191 | } |
186 | 192 | ||
187 | if (PRINT_FIELD(ADDR) && | 193 | if (PRINT_FIELD(ADDR) && |
188 | perf_event_attr__check_stype(attr, PERF_SAMPLE_ADDR, "ADDR", | 194 | perf_evsel__check_stype(evsel, PERF_SAMPLE_ADDR, "ADDR", |
189 | PERF_OUTPUT_ADDR)) | 195 | PERF_OUTPUT_ADDR)) |
190 | return -EINVAL; | 196 | return -EINVAL; |
191 | 197 | ||
192 | if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { | 198 | if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { |
@@ -208,18 +214,18 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, | |||
208 | } | 214 | } |
209 | 215 | ||
210 | if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && | 216 | if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && |
211 | perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID", | 217 | perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID", |
212 | PERF_OUTPUT_TID|PERF_OUTPUT_PID)) | 218 | PERF_OUTPUT_TID|PERF_OUTPUT_PID)) |
213 | return -EINVAL; | 219 | return -EINVAL; |
214 | 220 | ||
215 | if (PRINT_FIELD(TIME) && | 221 | if (PRINT_FIELD(TIME) && |
216 | perf_event_attr__check_stype(attr, PERF_SAMPLE_TIME, "TIME", | 222 | perf_evsel__check_stype(evsel, PERF_SAMPLE_TIME, "TIME", |
217 | PERF_OUTPUT_TIME)) | 223 | PERF_OUTPUT_TIME)) |
218 | return -EINVAL; | 224 | return -EINVAL; |
219 | 225 | ||
220 | if (PRINT_FIELD(CPU) && | 226 | if (PRINT_FIELD(CPU) && |
221 | perf_event_attr__check_stype(attr, PERF_SAMPLE_CPU, "CPU", | 227 | perf_evsel__check_stype(evsel, PERF_SAMPLE_CPU, "CPU", |
222 | PERF_OUTPUT_CPU)) | 228 | PERF_OUTPUT_CPU)) |
223 | return -EINVAL; | 229 | return -EINVAL; |
224 | 230 | ||
225 | return 0; | 231 | return 0; |
@@ -256,11 +262,13 @@ static int perf_session__check_output_opt(struct perf_session *session) | |||
256 | return 0; | 262 | return 0; |
257 | } | 263 | } |
258 | 264 | ||
259 | static void print_sample_start(struct perf_sample *sample, | 265 | static void print_sample_start(struct pevent *pevent, |
266 | struct perf_sample *sample, | ||
260 | struct thread *thread, | 267 | struct thread *thread, |
261 | struct perf_event_attr *attr) | 268 | struct perf_evsel *evsel) |
262 | { | 269 | { |
263 | int type; | 270 | int type; |
271 | struct perf_event_attr *attr = &evsel->attr; | ||
264 | struct event_format *event; | 272 | struct event_format *event; |
265 | const char *evname = NULL; | 273 | const char *evname = NULL; |
266 | unsigned long secs; | 274 | unsigned long secs; |
@@ -300,12 +308,18 @@ static void print_sample_start(struct perf_sample *sample, | |||
300 | 308 | ||
301 | if (PRINT_FIELD(EVNAME)) { | 309 | if (PRINT_FIELD(EVNAME)) { |
302 | if (attr->type == PERF_TYPE_TRACEPOINT) { | 310 | if (attr->type == PERF_TYPE_TRACEPOINT) { |
303 | type = trace_parse_common_type(sample->raw_data); | 311 | /* |
304 | event = trace_find_event(type); | 312 | * XXX Do we really need this here? |
313 | * perf_evlist__set_tracepoint_names should have done | ||
314 | * this already | ||
315 | */ | ||
316 | type = trace_parse_common_type(pevent, | ||
317 | sample->raw_data); | ||
318 | event = pevent_find_event(pevent, type); | ||
305 | if (event) | 319 | if (event) |
306 | evname = event->name; | 320 | evname = event->name; |
307 | } else | 321 | } else |
308 | evname = __event_name(attr->type, attr->config); | 322 | evname = perf_evsel__name(evsel); |
309 | 323 | ||
310 | printf("%s: ", evname ? evname : "[unknown]"); | 324 | printf("%s: ", evname ? evname : "[unknown]"); |
311 | } | 325 | } |
@@ -387,7 +401,7 @@ static void print_sample_bts(union perf_event *event, | |||
387 | printf(" "); | 401 | printf(" "); |
388 | else | 402 | else |
389 | printf("\n"); | 403 | printf("\n"); |
390 | perf_event__print_ip(event, sample, machine, evsel, | 404 | perf_event__print_ip(event, sample, machine, |
391 | PRINT_FIELD(SYM), PRINT_FIELD(DSO), | 405 | PRINT_FIELD(SYM), PRINT_FIELD(DSO), |
392 | PRINT_FIELD(SYMOFFSET)); | 406 | PRINT_FIELD(SYMOFFSET)); |
393 | } | 407 | } |
@@ -402,6 +416,7 @@ static void print_sample_bts(union perf_event *event, | |||
402 | } | 416 | } |
403 | 417 | ||
404 | static void process_event(union perf_event *event __unused, | 418 | static void process_event(union perf_event *event __unused, |
419 | struct pevent *pevent, | ||
405 | struct perf_sample *sample, | 420 | struct perf_sample *sample, |
406 | struct perf_evsel *evsel, | 421 | struct perf_evsel *evsel, |
407 | struct machine *machine, | 422 | struct machine *machine, |
@@ -412,7 +427,7 @@ static void process_event(union perf_event *event __unused, | |||
412 | if (output[attr->type].fields == 0) | 427 | if (output[attr->type].fields == 0) |
413 | return; | 428 | return; |
414 | 429 | ||
415 | print_sample_start(sample, thread, attr); | 430 | print_sample_start(pevent, sample, thread, evsel); |
416 | 431 | ||
417 | if (is_bts_event(attr)) { | 432 | if (is_bts_event(attr)) { |
418 | print_sample_bts(event, sample, evsel, machine, thread); | 433 | print_sample_bts(event, sample, evsel, machine, thread); |
@@ -420,7 +435,7 @@ static void process_event(union perf_event *event __unused, | |||
420 | } | 435 | } |
421 | 436 | ||
422 | if (PRINT_FIELD(TRACE)) | 437 | if (PRINT_FIELD(TRACE)) |
423 | print_trace_event(sample->cpu, sample->raw_data, | 438 | print_trace_event(pevent, sample->cpu, sample->raw_data, |
424 | sample->raw_size); | 439 | sample->raw_size); |
425 | 440 | ||
426 | if (PRINT_FIELD(ADDR)) | 441 | if (PRINT_FIELD(ADDR)) |
@@ -431,7 +446,7 @@ static void process_event(union perf_event *event __unused, | |||
431 | printf(" "); | 446 | printf(" "); |
432 | else | 447 | else |
433 | printf("\n"); | 448 | printf("\n"); |
434 | perf_event__print_ip(event, sample, machine, evsel, | 449 | perf_event__print_ip(event, sample, machine, |
435 | PRINT_FIELD(SYM), PRINT_FIELD(DSO), | 450 | PRINT_FIELD(SYM), PRINT_FIELD(DSO), |
436 | PRINT_FIELD(SYMOFFSET)); | 451 | PRINT_FIELD(SYMOFFSET)); |
437 | } | 452 | } |
@@ -451,7 +466,8 @@ static int default_stop_script(void) | |||
451 | return 0; | 466 | return 0; |
452 | } | 467 | } |
453 | 468 | ||
454 | static int default_generate_script(const char *outfile __unused) | 469 | static int default_generate_script(struct pevent *pevent __unused, |
470 | const char *outfile __unused) | ||
455 | { | 471 | { |
456 | return 0; | 472 | return 0; |
457 | } | 473 | } |
@@ -489,6 +505,7 @@ static int process_sample_event(struct perf_tool *tool __used, | |||
489 | struct machine *machine) | 505 | struct machine *machine) |
490 | { | 506 | { |
491 | struct addr_location al; | 507 | struct addr_location al; |
508 | struct perf_script *scr = container_of(tool, struct perf_script, tool); | ||
492 | struct thread *thread = machine__findnew_thread(machine, event->ip.tid); | 509 | struct thread *thread = machine__findnew_thread(machine, event->ip.tid); |
493 | 510 | ||
494 | if (thread == NULL) { | 511 | if (thread == NULL) { |
@@ -520,24 +537,27 @@ static int process_sample_event(struct perf_tool *tool __used, | |||
520 | if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) | 537 | if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) |
521 | return 0; | 538 | return 0; |
522 | 539 | ||
523 | scripting_ops->process_event(event, sample, evsel, machine, thread); | 540 | scripting_ops->process_event(event, scr->session->pevent, |
541 | sample, evsel, machine, thread); | ||
524 | 542 | ||
525 | evsel->hists.stats.total_period += sample->period; | 543 | evsel->hists.stats.total_period += sample->period; |
526 | return 0; | 544 | return 0; |
527 | } | 545 | } |
528 | 546 | ||
529 | static struct perf_tool perf_script = { | 547 | static struct perf_script perf_script = { |
530 | .sample = process_sample_event, | 548 | .tool = { |
531 | .mmap = perf_event__process_mmap, | 549 | .sample = process_sample_event, |
532 | .comm = perf_event__process_comm, | 550 | .mmap = perf_event__process_mmap, |
533 | .exit = perf_event__process_task, | 551 | .comm = perf_event__process_comm, |
534 | .fork = perf_event__process_task, | 552 | .exit = perf_event__process_task, |
535 | .attr = perf_event__process_attr, | 553 | .fork = perf_event__process_task, |
536 | .event_type = perf_event__process_event_type, | 554 | .attr = perf_event__process_attr, |
537 | .tracing_data = perf_event__process_tracing_data, | 555 | .event_type = perf_event__process_event_type, |
538 | .build_id = perf_event__process_build_id, | 556 | .tracing_data = perf_event__process_tracing_data, |
539 | .ordered_samples = true, | 557 | .build_id = perf_event__process_build_id, |
540 | .ordering_requires_timestamps = true, | 558 | .ordered_samples = true, |
559 | .ordering_requires_timestamps = true, | ||
560 | }, | ||
541 | }; | 561 | }; |
542 | 562 | ||
543 | extern volatile int session_done; | 563 | extern volatile int session_done; |
@@ -553,7 +573,7 @@ static int __cmd_script(struct perf_session *session) | |||
553 | 573 | ||
554 | signal(SIGINT, sig_handler); | 574 | signal(SIGINT, sig_handler); |
555 | 575 | ||
556 | ret = perf_session__process_events(session, &perf_script); | 576 | ret = perf_session__process_events(session, &perf_script.tool); |
557 | 577 | ||
558 | if (debug_mode) | 578 | if (debug_mode) |
559 | pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); | 579 | pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); |
@@ -1335,10 +1355,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) | |||
1335 | if (!script_name) | 1355 | if (!script_name) |
1336 | setup_pager(); | 1356 | setup_pager(); |
1337 | 1357 | ||
1338 | session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_script); | 1358 | session = perf_session__new(input_name, O_RDONLY, 0, false, |
1359 | &perf_script.tool); | ||
1339 | if (session == NULL) | 1360 | if (session == NULL) |
1340 | return -ENOMEM; | 1361 | return -ENOMEM; |
1341 | 1362 | ||
1363 | perf_script.session = session; | ||
1364 | |||
1342 | if (cpu_list) { | 1365 | if (cpu_list) { |
1343 | if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) | 1366 | if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) |
1344 | return -1; | 1367 | return -1; |
@@ -1384,7 +1407,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) | |||
1384 | return -1; | 1407 | return -1; |
1385 | } | 1408 | } |
1386 | 1409 | ||
1387 | err = scripting_ops->generate_script("perf-script"); | 1410 | err = scripting_ops->generate_script(session->pevent, |
1411 | "perf-script"); | ||
1388 | goto out; | 1412 | goto out; |
1389 | } | 1413 | } |
1390 | 1414 | ||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 07b5c7703dd1..861f0aec77ae 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -391,7 +391,7 @@ static int read_counter_aggr(struct perf_evsel *counter) | |||
391 | 391 | ||
392 | if (verbose) { | 392 | if (verbose) { |
393 | fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", | 393 | fprintf(output, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n", |
394 | event_name(counter), count[0], count[1], count[2]); | 394 | perf_evsel__name(counter), count[0], count[1], count[2]); |
395 | } | 395 | } |
396 | 396 | ||
397 | /* | 397 | /* |
@@ -496,7 +496,7 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
496 | errno == ENXIO) { | 496 | errno == ENXIO) { |
497 | if (verbose) | 497 | if (verbose) |
498 | ui__warning("%s event is not supported by the kernel.\n", | 498 | ui__warning("%s event is not supported by the kernel.\n", |
499 | event_name(counter)); | 499 | perf_evsel__name(counter)); |
500 | counter->supported = false; | 500 | counter->supported = false; |
501 | continue; | 501 | continue; |
502 | } | 502 | } |
@@ -594,7 +594,7 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg) | |||
594 | csv_output ? 0 : -4, | 594 | csv_output ? 0 : -4, |
595 | evsel_list->cpus->map[cpu], csv_sep); | 595 | evsel_list->cpus->map[cpu], csv_sep); |
596 | 596 | ||
597 | fprintf(output, fmt, cpustr, msecs, csv_sep, event_name(evsel)); | 597 | fprintf(output, fmt, cpustr, msecs, csv_sep, perf_evsel__name(evsel)); |
598 | 598 | ||
599 | if (evsel->cgrp) | 599 | if (evsel->cgrp) |
600 | fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); | 600 | fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); |
@@ -792,7 +792,7 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) | |||
792 | else | 792 | else |
793 | cpu = 0; | 793 | cpu = 0; |
794 | 794 | ||
795 | fprintf(output, fmt, cpustr, avg, csv_sep, event_name(evsel)); | 795 | fprintf(output, fmt, cpustr, avg, csv_sep, perf_evsel__name(evsel)); |
796 | 796 | ||
797 | if (evsel->cgrp) | 797 | if (evsel->cgrp) |
798 | fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); | 798 | fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); |
@@ -908,7 +908,7 @@ static void print_counter_aggr(struct perf_evsel *counter) | |||
908 | counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, | 908 | counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, |
909 | csv_sep, | 909 | csv_sep, |
910 | csv_output ? 0 : -24, | 910 | csv_output ? 0 : -24, |
911 | event_name(counter)); | 911 | perf_evsel__name(counter)); |
912 | 912 | ||
913 | if (counter->cgrp) | 913 | if (counter->cgrp) |
914 | fprintf(output, "%s%s", csv_sep, counter->cgrp->name); | 914 | fprintf(output, "%s%s", csv_sep, counter->cgrp->name); |
@@ -961,7 +961,7 @@ static void print_counter(struct perf_evsel *counter) | |||
961 | counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, | 961 | counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, |
962 | csv_sep, | 962 | csv_sep, |
963 | csv_output ? 0 : -24, | 963 | csv_output ? 0 : -24, |
964 | event_name(counter)); | 964 | perf_evsel__name(counter)); |
965 | 965 | ||
966 | if (counter->cgrp) | 966 | if (counter->cgrp) |
967 | fprintf(output, "%s%s", | 967 | fprintf(output, "%s%s", |
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 5a8727c08757..5ce30305462b 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
@@ -583,7 +583,7 @@ static int test__basic_mmap(void) | |||
583 | if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) { | 583 | if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) { |
584 | pr_debug("expected %d %s events, got %d\n", | 584 | pr_debug("expected %d %s events, got %d\n", |
585 | expected_nr_events[evsel->idx], | 585 | expected_nr_events[evsel->idx], |
586 | event_name(evsel), nr_events[evsel->idx]); | 586 | perf_evsel__name(evsel), nr_events[evsel->idx]); |
587 | goto out_munmap; | 587 | goto out_munmap; |
588 | } | 588 | } |
589 | } | 589 | } |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 6bb0277b7dfe..e3cab5f088f8 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -245,7 +245,7 @@ static void perf_top__show_details(struct perf_top *top) | |||
245 | if (notes->src == NULL) | 245 | if (notes->src == NULL) |
246 | goto out_unlock; | 246 | goto out_unlock; |
247 | 247 | ||
248 | printf("Showing %s for %s\n", event_name(top->sym_evsel), symbol->name); | 248 | printf("Showing %s for %s\n", perf_evsel__name(top->sym_evsel), symbol->name); |
249 | printf(" Events Pcnt (>=%d%%)\n", top->sym_pcnt_filter); | 249 | printf(" Events Pcnt (>=%d%%)\n", top->sym_pcnt_filter); |
250 | 250 | ||
251 | more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel->idx, | 251 | more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel->idx, |
@@ -408,7 +408,7 @@ static void perf_top__print_mapped_keys(struct perf_top *top) | |||
408 | fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", top->print_entries); | 408 | fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", top->print_entries); |
409 | 409 | ||
410 | if (top->evlist->nr_entries > 1) | 410 | if (top->evlist->nr_entries > 1) |
411 | fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(top->sym_evsel)); | 411 | fprintf(stdout, "\t[E] active event counter. \t(%s)\n", perf_evsel__name(top->sym_evsel)); |
412 | 412 | ||
413 | fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", top->count_filter); | 413 | fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", top->count_filter); |
414 | 414 | ||
@@ -503,13 +503,13 @@ static void perf_top__handle_keypress(struct perf_top *top, int c) | |||
503 | fprintf(stderr, "\nAvailable events:"); | 503 | fprintf(stderr, "\nAvailable events:"); |
504 | 504 | ||
505 | list_for_each_entry(top->sym_evsel, &top->evlist->entries, node) | 505 | list_for_each_entry(top->sym_evsel, &top->evlist->entries, node) |
506 | fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, event_name(top->sym_evsel)); | 506 | fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, perf_evsel__name(top->sym_evsel)); |
507 | 507 | ||
508 | prompt_integer(&counter, "Enter details event counter"); | 508 | prompt_integer(&counter, "Enter details event counter"); |
509 | 509 | ||
510 | if (counter >= top->evlist->nr_entries) { | 510 | if (counter >= top->evlist->nr_entries) { |
511 | top->sym_evsel = list_entry(top->evlist->entries.next, struct perf_evsel, node); | 511 | top->sym_evsel = list_entry(top->evlist->entries.next, struct perf_evsel, node); |
512 | fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(top->sym_evsel)); | 512 | fprintf(stderr, "Sorry, no such event, using %s.\n", perf_evsel__name(top->sym_evsel)); |
513 | sleep(1); | 513 | sleep(1); |
514 | break; | 514 | break; |
515 | } | 515 | } |
@@ -774,7 +774,7 @@ static void perf_event__process_sample(struct perf_tool *tool, | |||
774 | 774 | ||
775 | if ((sort__has_parent || symbol_conf.use_callchain) && | 775 | if ((sort__has_parent || symbol_conf.use_callchain) && |
776 | sample->callchain) { | 776 | sample->callchain) { |
777 | err = machine__resolve_callchain(machine, evsel, al.thread, | 777 | err = machine__resolve_callchain(machine, al.thread, |
778 | sample->callchain, &parent); | 778 | sample->callchain, &parent); |
779 | if (err) | 779 | if (err) |
780 | return; | 780 | return; |
@@ -960,7 +960,7 @@ try_again: | |||
960 | 960 | ||
961 | if (err == ENOENT) { | 961 | if (err == ENOENT) { |
962 | ui__error("The %s event is not supported.\n", | 962 | ui__error("The %s event is not supported.\n", |
963 | event_name(counter)); | 963 | perf_evsel__name(counter)); |
964 | goto out_err; | 964 | goto out_err; |
965 | } else if (err == EMFILE) { | 965 | } else if (err == EMFILE) { |
966 | ui__error("Too many events are opened.\n" | 966 | ui__error("Too many events are opened.\n" |
diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index d9084e03ce56..6c18785a6417 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak | |||
@@ -78,6 +78,19 @@ int main(int argc, char *argv[]) | |||
78 | return 0; | 78 | return 0; |
79 | } | 79 | } |
80 | endef | 80 | endef |
81 | |||
82 | define SOURCE_GTK2_INFOBAR | ||
83 | #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" | ||
84 | #include <gtk/gtk.h> | ||
85 | #pragma GCC diagnostic error \"-Wstrict-prototypes\" | ||
86 | |||
87 | int main(void) | ||
88 | { | ||
89 | gtk_info_bar_new(); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | endef | ||
81 | endif | 94 | endif |
82 | 95 | ||
83 | ifndef NO_LIBPERL | 96 | ifndef NO_LIBPERL |
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 34b1c46eaf42..67a2703e666a 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -814,7 +814,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
814 | { | 814 | { |
815 | struct disasm_line *pos, *n; | 815 | struct disasm_line *pos, *n; |
816 | struct annotation *notes; | 816 | struct annotation *notes; |
817 | const size_t size = symbol__size(sym); | 817 | size_t size; |
818 | struct map_symbol ms = { | 818 | struct map_symbol ms = { |
819 | .map = map, | 819 | .map = map, |
820 | .sym = sym, | 820 | .sym = sym, |
@@ -834,6 +834,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
834 | if (sym == NULL) | 834 | if (sym == NULL) |
835 | return -1; | 835 | return -1; |
836 | 836 | ||
837 | size = symbol__size(sym); | ||
838 | |||
837 | if (map->dso->annotate_warned) | 839 | if (map->dso->annotate_warned) |
838 | return -1; | 840 | return -1; |
839 | 841 | ||
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 53f6697d014e..482f0517b61e 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
@@ -23,6 +23,7 @@ struct hist_browser { | |||
23 | struct hists *hists; | 23 | struct hists *hists; |
24 | struct hist_entry *he_selection; | 24 | struct hist_entry *he_selection; |
25 | struct map_symbol *selection; | 25 | struct map_symbol *selection; |
26 | int print_seq; | ||
26 | bool has_symbols; | 27 | bool has_symbols; |
27 | }; | 28 | }; |
28 | 29 | ||
@@ -800,6 +801,196 @@ do_offset: | |||
800 | } | 801 | } |
801 | } | 802 | } |
802 | 803 | ||
804 | static int hist_browser__fprintf_callchain_node_rb_tree(struct hist_browser *browser, | ||
805 | struct callchain_node *chain_node, | ||
806 | u64 total, int level, | ||
807 | FILE *fp) | ||
808 | { | ||
809 | struct rb_node *node; | ||
810 | int offset = level * LEVEL_OFFSET_STEP; | ||
811 | u64 new_total, remaining; | ||
812 | int printed = 0; | ||
813 | |||
814 | if (callchain_param.mode == CHAIN_GRAPH_REL) | ||
815 | new_total = chain_node->children_hit; | ||
816 | else | ||
817 | new_total = total; | ||
818 | |||
819 | remaining = new_total; | ||
820 | node = rb_first(&chain_node->rb_root); | ||
821 | while (node) { | ||
822 | struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node); | ||
823 | struct rb_node *next = rb_next(node); | ||
824 | u64 cumul = callchain_cumul_hits(child); | ||
825 | struct callchain_list *chain; | ||
826 | char folded_sign = ' '; | ||
827 | int first = true; | ||
828 | int extra_offset = 0; | ||
829 | |||
830 | remaining -= cumul; | ||
831 | |||
832 | list_for_each_entry(chain, &child->val, list) { | ||
833 | char ipstr[BITS_PER_LONG / 4 + 1], *alloc_str; | ||
834 | const char *str; | ||
835 | bool was_first = first; | ||
836 | |||
837 | if (first) | ||
838 | first = false; | ||
839 | else | ||
840 | extra_offset = LEVEL_OFFSET_STEP; | ||
841 | |||
842 | folded_sign = callchain_list__folded(chain); | ||
843 | |||
844 | alloc_str = NULL; | ||
845 | str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr)); | ||
846 | if (was_first) { | ||
847 | double percent = cumul * 100.0 / new_total; | ||
848 | |||
849 | if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0) | ||
850 | str = "Not enough memory!"; | ||
851 | else | ||
852 | str = alloc_str; | ||
853 | } | ||
854 | |||
855 | printed += fprintf(fp, "%*s%c %s\n", offset + extra_offset, " ", folded_sign, str); | ||
856 | free(alloc_str); | ||
857 | if (folded_sign == '+') | ||
858 | break; | ||
859 | } | ||
860 | |||
861 | if (folded_sign == '-') { | ||
862 | const int new_level = level + (extra_offset ? 2 : 1); | ||
863 | printed += hist_browser__fprintf_callchain_node_rb_tree(browser, child, new_total, | ||
864 | new_level, fp); | ||
865 | } | ||
866 | |||
867 | node = next; | ||
868 | } | ||
869 | |||
870 | return printed; | ||
871 | } | ||
872 | |||
873 | static int hist_browser__fprintf_callchain_node(struct hist_browser *browser, | ||
874 | struct callchain_node *node, | ||
875 | int level, FILE *fp) | ||
876 | { | ||
877 | struct callchain_list *chain; | ||
878 | int offset = level * LEVEL_OFFSET_STEP; | ||
879 | char folded_sign = ' '; | ||
880 | int printed = 0; | ||
881 | |||
882 | list_for_each_entry(chain, &node->val, list) { | ||
883 | char ipstr[BITS_PER_LONG / 4 + 1], *s; | ||
884 | |||
885 | folded_sign = callchain_list__folded(chain); | ||
886 | s = callchain_list__sym_name(chain, ipstr, sizeof(ipstr)); | ||
887 | printed += fprintf(fp, "%*s%c %s\n", offset, " ", folded_sign, s); | ||
888 | } | ||
889 | |||
890 | if (folded_sign == '-') | ||
891 | printed += hist_browser__fprintf_callchain_node_rb_tree(browser, node, | ||
892 | browser->hists->stats.total_period, | ||
893 | level + 1, fp); | ||
894 | return printed; | ||
895 | } | ||
896 | |||
897 | static int hist_browser__fprintf_callchain(struct hist_browser *browser, | ||
898 | struct rb_root *chain, int level, FILE *fp) | ||
899 | { | ||
900 | struct rb_node *nd; | ||
901 | int printed = 0; | ||
902 | |||
903 | for (nd = rb_first(chain); nd; nd = rb_next(nd)) { | ||
904 | struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); | ||
905 | |||
906 | printed += hist_browser__fprintf_callchain_node(browser, node, level, fp); | ||
907 | } | ||
908 | |||
909 | return printed; | ||
910 | } | ||
911 | |||
912 | static int hist_browser__fprintf_entry(struct hist_browser *browser, | ||
913 | struct hist_entry *he, FILE *fp) | ||
914 | { | ||
915 | char s[8192]; | ||
916 | double percent; | ||
917 | int printed = 0; | ||
918 | char folded_sign = ' '; | ||
919 | |||
920 | if (symbol_conf.use_callchain) | ||
921 | folded_sign = hist_entry__folded(he); | ||
922 | |||
923 | hist_entry__snprintf(he, s, sizeof(s), browser->hists); | ||
924 | percent = (he->period * 100.0) / browser->hists->stats.total_period; | ||
925 | |||
926 | if (symbol_conf.use_callchain) | ||
927 | printed += fprintf(fp, "%c ", folded_sign); | ||
928 | |||
929 | printed += fprintf(fp, " %5.2f%%", percent); | ||
930 | |||
931 | if (symbol_conf.show_nr_samples) | ||
932 | printed += fprintf(fp, " %11u", he->nr_events); | ||
933 | |||
934 | if (symbol_conf.show_total_period) | ||
935 | printed += fprintf(fp, " %12" PRIu64, he->period); | ||
936 | |||
937 | printed += fprintf(fp, "%s\n", rtrim(s)); | ||
938 | |||
939 | if (folded_sign == '-') | ||
940 | printed += hist_browser__fprintf_callchain(browser, &he->sorted_chain, 1, fp); | ||
941 | |||
942 | return printed; | ||
943 | } | ||
944 | |||
945 | static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp) | ||
946 | { | ||
947 | struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries)); | ||
948 | int printed = 0; | ||
949 | |||
950 | while (nd) { | ||
951 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | ||
952 | |||
953 | printed += hist_browser__fprintf_entry(browser, h, fp); | ||
954 | nd = hists__filter_entries(rb_next(nd)); | ||
955 | } | ||
956 | |||
957 | return printed; | ||
958 | } | ||
959 | |||
960 | static int hist_browser__dump(struct hist_browser *browser) | ||
961 | { | ||
962 | char filename[64]; | ||
963 | FILE *fp; | ||
964 | |||
965 | while (1) { | ||
966 | scnprintf(filename, sizeof(filename), "perf.hist.%d", browser->print_seq); | ||
967 | if (access(filename, F_OK)) | ||
968 | break; | ||
969 | /* | ||
970 | * XXX: Just an arbitrary lazy upper limit | ||
971 | */ | ||
972 | if (++browser->print_seq == 8192) { | ||
973 | ui_helpline__fpush("Too many perf.hist.N files, nothing written!"); | ||
974 | return -1; | ||
975 | } | ||
976 | } | ||
977 | |||
978 | fp = fopen(filename, "w"); | ||
979 | if (fp == NULL) { | ||
980 | char bf[64]; | ||
981 | strerror_r(errno, bf, sizeof(bf)); | ||
982 | ui_helpline__fpush("Couldn't write to %s: %s", filename, bf); | ||
983 | return -1; | ||
984 | } | ||
985 | |||
986 | ++browser->print_seq; | ||
987 | hist_browser__fprintf(browser, fp); | ||
988 | fclose(fp); | ||
989 | ui_helpline__fpush("%s written!", filename); | ||
990 | |||
991 | return 0; | ||
992 | } | ||
993 | |||
803 | static struct hist_browser *hist_browser__new(struct hists *hists) | 994 | static struct hist_browser *hist_browser__new(struct hists *hists) |
804 | { | 995 | { |
805 | struct hist_browser *browser = zalloc(sizeof(*browser)); | 996 | struct hist_browser *browser = zalloc(sizeof(*browser)); |
@@ -937,6 +1128,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
937 | browser->selection->map->dso->annotate_warned) | 1128 | browser->selection->map->dso->annotate_warned) |
938 | continue; | 1129 | continue; |
939 | goto do_annotate; | 1130 | goto do_annotate; |
1131 | case 'P': | ||
1132 | hist_browser__dump(browser); | ||
1133 | continue; | ||
940 | case 'd': | 1134 | case 'd': |
941 | goto zoom_dso; | 1135 | goto zoom_dso; |
942 | case 't': | 1136 | case 't': |
@@ -969,6 +1163,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
969 | "E Expand all callchains\n" | 1163 | "E Expand all callchains\n" |
970 | "d Zoom into current DSO\n" | 1164 | "d Zoom into current DSO\n" |
971 | "t Zoom into current Thread\n" | 1165 | "t Zoom into current Thread\n" |
1166 | "P Print histograms to perf.hist.N\n" | ||
972 | "/ Filter symbol by name"); | 1167 | "/ Filter symbol by name"); |
973 | continue; | 1168 | continue; |
974 | case K_ENTER: | 1169 | case K_ENTER: |
@@ -1172,7 +1367,7 @@ static void perf_evsel_menu__write(struct ui_browser *browser, | |||
1172 | struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); | 1367 | struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); |
1173 | bool current_entry = ui_browser__is_current_entry(browser, row); | 1368 | bool current_entry = ui_browser__is_current_entry(browser, row); |
1174 | unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE]; | 1369 | unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE]; |
1175 | const char *ev_name = event_name(evsel); | 1370 | const char *ev_name = perf_evsel__name(evsel); |
1176 | char bf[256], unit; | 1371 | char bf[256], unit; |
1177 | const char *warn = " "; | 1372 | const char *warn = " "; |
1178 | size_t printed; | 1373 | size_t printed; |
@@ -1240,7 +1435,7 @@ browse_hists: | |||
1240 | */ | 1435 | */ |
1241 | if (timer) | 1436 | if (timer) |
1242 | timer(arg); | 1437 | timer(arg); |
1243 | ev_name = event_name(pos); | 1438 | ev_name = perf_evsel__name(pos); |
1244 | key = perf_evsel__hists_browse(pos, nr_events, help, | 1439 | key = perf_evsel__hists_browse(pos, nr_events, help, |
1245 | ev_name, true, timer, | 1440 | ev_name, true, timer, |
1246 | arg, delay_secs); | 1441 | arg, delay_secs); |
@@ -1309,17 +1504,11 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, | |||
1309 | ui_helpline__push("Press ESC to exit"); | 1504 | ui_helpline__push("Press ESC to exit"); |
1310 | 1505 | ||
1311 | list_for_each_entry(pos, &evlist->entries, node) { | 1506 | list_for_each_entry(pos, &evlist->entries, node) { |
1312 | const char *ev_name = event_name(pos); | 1507 | const char *ev_name = perf_evsel__name(pos); |
1313 | size_t line_len = strlen(ev_name) + 7; | 1508 | size_t line_len = strlen(ev_name) + 7; |
1314 | 1509 | ||
1315 | if (menu.b.width < line_len) | 1510 | if (menu.b.width < line_len) |
1316 | menu.b.width = line_len; | 1511 | menu.b.width = line_len; |
1317 | /* | ||
1318 | * Cache the evsel name, tracepoints have a _high_ cost per | ||
1319 | * event_name() call. | ||
1320 | */ | ||
1321 | if (pos->name == NULL) | ||
1322 | pos->name = strdup(ev_name); | ||
1323 | } | 1512 | } |
1324 | 1513 | ||
1325 | return perf_evsel_menu__run(&menu, evlist->nr_entries, help, timer, | 1514 | return perf_evsel_menu__run(&menu, evlist->nr_entries, help, timer, |
@@ -1330,11 +1519,10 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, | |||
1330 | void(*timer)(void *arg), void *arg, | 1519 | void(*timer)(void *arg), void *arg, |
1331 | int delay_secs) | 1520 | int delay_secs) |
1332 | { | 1521 | { |
1333 | |||
1334 | if (evlist->nr_entries == 1) { | 1522 | if (evlist->nr_entries == 1) { |
1335 | struct perf_evsel *first = list_entry(evlist->entries.next, | 1523 | struct perf_evsel *first = list_entry(evlist->entries.next, |
1336 | struct perf_evsel, node); | 1524 | struct perf_evsel, node); |
1337 | const char *ev_name = event_name(first); | 1525 | const char *ev_name = perf_evsel__name(first); |
1338 | return perf_evsel__hists_browse(first, evlist->nr_entries, help, | 1526 | return perf_evsel__hists_browse(first, evlist->nr_entries, help, |
1339 | ev_name, false, timer, arg, | 1527 | ev_name, false, timer, arg, |
1340 | delay_secs); | 1528 | delay_secs); |
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c index 0656c381a89c..ec12e0b4ded6 100644 --- a/tools/perf/ui/gtk/browser.c +++ b/tools/perf/ui/gtk/browser.c | |||
@@ -11,8 +11,8 @@ | |||
11 | 11 | ||
12 | static void perf_gtk__signal(int sig) | 12 | static void perf_gtk__signal(int sig) |
13 | { | 13 | { |
14 | perf_gtk__exit(false); | ||
14 | psignal(sig, "perf"); | 15 | psignal(sig, "perf"); |
15 | gtk_main_quit(); | ||
16 | } | 16 | } |
17 | 17 | ||
18 | static void perf_gtk__resize_window(GtkWidget *window) | 18 | static void perf_gtk__resize_window(GtkWidget *window) |
@@ -122,13 +122,59 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists) | |||
122 | gtk_container_add(GTK_CONTAINER(window), view); | 122 | gtk_container_add(GTK_CONTAINER(window), view); |
123 | } | 123 | } |
124 | 124 | ||
125 | #ifdef HAVE_GTK_INFO_BAR | ||
126 | static GtkWidget *perf_gtk__setup_info_bar(void) | ||
127 | { | ||
128 | GtkWidget *info_bar; | ||
129 | GtkWidget *label; | ||
130 | GtkWidget *content_area; | ||
131 | |||
132 | info_bar = gtk_info_bar_new(); | ||
133 | gtk_widget_set_no_show_all(info_bar, TRUE); | ||
134 | |||
135 | label = gtk_label_new(""); | ||
136 | gtk_widget_show(label); | ||
137 | |||
138 | content_area = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_bar)); | ||
139 | gtk_container_add(GTK_CONTAINER(content_area), label); | ||
140 | |||
141 | gtk_info_bar_add_button(GTK_INFO_BAR(info_bar), GTK_STOCK_OK, | ||
142 | GTK_RESPONSE_OK); | ||
143 | g_signal_connect(info_bar, "response", | ||
144 | G_CALLBACK(gtk_widget_hide), NULL); | ||
145 | |||
146 | pgctx->info_bar = info_bar; | ||
147 | pgctx->message_label = label; | ||
148 | |||
149 | return info_bar; | ||
150 | } | ||
151 | #endif | ||
152 | |||
153 | static GtkWidget *perf_gtk__setup_statusbar(void) | ||
154 | { | ||
155 | GtkWidget *stbar; | ||
156 | unsigned ctxid; | ||
157 | |||
158 | stbar = gtk_statusbar_new(); | ||
159 | |||
160 | ctxid = gtk_statusbar_get_context_id(GTK_STATUSBAR(stbar), | ||
161 | "perf report"); | ||
162 | pgctx->statbar = stbar; | ||
163 | pgctx->statbar_ctx_id = ctxid; | ||
164 | |||
165 | return stbar; | ||
166 | } | ||
167 | |||
125 | int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, | 168 | int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, |
126 | const char *help __used, | 169 | const char *help __used, |
127 | void (*timer) (void *arg)__used, | 170 | void (*timer) (void *arg)__used, |
128 | void *arg __used, int delay_secs __used) | 171 | void *arg __used, int delay_secs __used) |
129 | { | 172 | { |
130 | struct perf_evsel *pos; | 173 | struct perf_evsel *pos; |
174 | GtkWidget *vbox; | ||
131 | GtkWidget *notebook; | 175 | GtkWidget *notebook; |
176 | GtkWidget *info_bar; | ||
177 | GtkWidget *statbar; | ||
132 | GtkWidget *window; | 178 | GtkWidget *window; |
133 | 179 | ||
134 | signal(SIGSEGV, perf_gtk__signal); | 180 | signal(SIGSEGV, perf_gtk__signal); |
@@ -143,11 +189,17 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, | |||
143 | 189 | ||
144 | g_signal_connect(window, "delete_event", gtk_main_quit, NULL); | 190 | g_signal_connect(window, "delete_event", gtk_main_quit, NULL); |
145 | 191 | ||
192 | pgctx = perf_gtk__activate_context(window); | ||
193 | if (!pgctx) | ||
194 | return -1; | ||
195 | |||
196 | vbox = gtk_vbox_new(FALSE, 0); | ||
197 | |||
146 | notebook = gtk_notebook_new(); | 198 | notebook = gtk_notebook_new(); |
147 | 199 | ||
148 | list_for_each_entry(pos, &evlist->entries, node) { | 200 | list_for_each_entry(pos, &evlist->entries, node) { |
149 | struct hists *hists = &pos->hists; | 201 | struct hists *hists = &pos->hists; |
150 | const char *evname = event_name(pos); | 202 | const char *evname = perf_evsel__name(pos); |
151 | GtkWidget *scrolled_window; | 203 | GtkWidget *scrolled_window; |
152 | GtkWidget *tab_label; | 204 | GtkWidget *tab_label; |
153 | 205 | ||
@@ -164,7 +216,16 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, | |||
164 | gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window, tab_label); | 216 | gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window, tab_label); |
165 | } | 217 | } |
166 | 218 | ||
167 | gtk_container_add(GTK_CONTAINER(window), notebook); | 219 | gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); |
220 | |||
221 | info_bar = perf_gtk__setup_info_bar(); | ||
222 | if (info_bar) | ||
223 | gtk_box_pack_start(GTK_BOX(vbox), info_bar, FALSE, FALSE, 0); | ||
224 | |||
225 | statbar = perf_gtk__setup_statusbar(); | ||
226 | gtk_box_pack_start(GTK_BOX(vbox), statbar, FALSE, FALSE, 0); | ||
227 | |||
228 | gtk_container_add(GTK_CONTAINER(window), vbox); | ||
168 | 229 | ||
169 | gtk_widget_show_all(window); | 230 | gtk_widget_show_all(window); |
170 | 231 | ||
@@ -174,5 +235,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, | |||
174 | 235 | ||
175 | gtk_main(); | 236 | gtk_main(); |
176 | 237 | ||
238 | perf_gtk__deactivate_context(&pgctx); | ||
239 | |||
177 | return 0; | 240 | return 0; |
178 | } | 241 | } |
diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h index 75177ee04032..a4d0f2b4a2dc 100644 --- a/tools/perf/ui/gtk/gtk.h +++ b/tools/perf/ui/gtk/gtk.h | |||
@@ -1,8 +1,39 @@ | |||
1 | #ifndef _PERF_GTK_H_ | 1 | #ifndef _PERF_GTK_H_ |
2 | #define _PERF_GTK_H_ 1 | 2 | #define _PERF_GTK_H_ 1 |
3 | 3 | ||
4 | #include <stdbool.h> | ||
5 | |||
4 | #pragma GCC diagnostic ignored "-Wstrict-prototypes" | 6 | #pragma GCC diagnostic ignored "-Wstrict-prototypes" |
5 | #include <gtk/gtk.h> | 7 | #include <gtk/gtk.h> |
6 | #pragma GCC diagnostic error "-Wstrict-prototypes" | 8 | #pragma GCC diagnostic error "-Wstrict-prototypes" |
7 | 9 | ||
10 | |||
11 | struct perf_gtk_context { | ||
12 | GtkWidget *main_window; | ||
13 | |||
14 | #ifdef HAVE_GTK_INFO_BAR | ||
15 | GtkWidget *info_bar; | ||
16 | GtkWidget *message_label; | ||
17 | #endif | ||
18 | GtkWidget *statbar; | ||
19 | guint statbar_ctx_id; | ||
20 | }; | ||
21 | |||
22 | extern struct perf_gtk_context *pgctx; | ||
23 | |||
24 | static inline bool perf_gtk__is_active_context(struct perf_gtk_context *ctx) | ||
25 | { | ||
26 | return ctx && ctx->main_window; | ||
27 | } | ||
28 | |||
29 | struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window); | ||
30 | int perf_gtk__deactivate_context(struct perf_gtk_context **ctx); | ||
31 | |||
32 | #ifndef HAVE_GTK_INFO_BAR | ||
33 | static inline GtkWidget *perf_gtk__setup_info_bar(void) | ||
34 | { | ||
35 | return NULL; | ||
36 | } | ||
37 | #endif | ||
38 | |||
8 | #endif /* _PERF_GTK_H_ */ | 39 | #endif /* _PERF_GTK_H_ */ |
diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c index 829529957766..92879ce61e2f 100644 --- a/tools/perf/ui/gtk/setup.c +++ b/tools/perf/ui/gtk/setup.c | |||
@@ -1,12 +1,17 @@ | |||
1 | #include "gtk.h" | 1 | #include "gtk.h" |
2 | #include "../../util/cache.h" | 2 | #include "../../util/cache.h" |
3 | #include "../../util/debug.h" | ||
4 | |||
5 | extern struct perf_error_ops perf_gtk_eops; | ||
3 | 6 | ||
4 | int perf_gtk__init(void) | 7 | int perf_gtk__init(void) |
5 | { | 8 | { |
9 | perf_error__register(&perf_gtk_eops); | ||
6 | return gtk_init_check(NULL, NULL) ? 0 : -1; | 10 | return gtk_init_check(NULL, NULL) ? 0 : -1; |
7 | } | 11 | } |
8 | 12 | ||
9 | void perf_gtk__exit(bool wait_for_ok __used) | 13 | void perf_gtk__exit(bool wait_for_ok __used) |
10 | { | 14 | { |
15 | perf_error__unregister(&perf_gtk_eops); | ||
11 | gtk_main_quit(); | 16 | gtk_main_quit(); |
12 | } | 17 | } |
diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c new file mode 100644 index 000000000000..0ead373c0dfb --- /dev/null +++ b/tools/perf/ui/gtk/util.c | |||
@@ -0,0 +1,129 @@ | |||
1 | #include "../util.h" | ||
2 | #include "../../util/debug.h" | ||
3 | #include "gtk.h" | ||
4 | |||
5 | #include <string.h> | ||
6 | |||
7 | |||
8 | struct perf_gtk_context *pgctx; | ||
9 | |||
10 | struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window) | ||
11 | { | ||
12 | struct perf_gtk_context *ctx; | ||
13 | |||
14 | ctx = malloc(sizeof(*pgctx)); | ||
15 | if (ctx) | ||
16 | ctx->main_window = window; | ||
17 | |||
18 | return ctx; | ||
19 | } | ||
20 | |||
21 | int perf_gtk__deactivate_context(struct perf_gtk_context **ctx) | ||
22 | { | ||
23 | if (!perf_gtk__is_active_context(*ctx)) | ||
24 | return -1; | ||
25 | |||
26 | free(*ctx); | ||
27 | *ctx = NULL; | ||
28 | return 0; | ||
29 | } | ||
30 | |||
31 | static int perf_gtk__error(const char *format, va_list args) | ||
32 | { | ||
33 | char *msg; | ||
34 | GtkWidget *dialog; | ||
35 | |||
36 | if (!perf_gtk__is_active_context(pgctx) || | ||
37 | vasprintf(&msg, format, args) < 0) { | ||
38 | fprintf(stderr, "Error:\n"); | ||
39 | vfprintf(stderr, format, args); | ||
40 | fprintf(stderr, "\n"); | ||
41 | return -1; | ||
42 | } | ||
43 | |||
44 | dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(pgctx->main_window), | ||
45 | GTK_DIALOG_DESTROY_WITH_PARENT, | ||
46 | GTK_MESSAGE_ERROR, | ||
47 | GTK_BUTTONS_CLOSE, | ||
48 | "<b>Error</b>\n\n%s", msg); | ||
49 | gtk_dialog_run(GTK_DIALOG(dialog)); | ||
50 | |||
51 | gtk_widget_destroy(dialog); | ||
52 | free(msg); | ||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | #ifdef HAVE_GTK_INFO_BAR | ||
57 | static int perf_gtk__warning_info_bar(const char *format, va_list args) | ||
58 | { | ||
59 | char *msg; | ||
60 | |||
61 | if (!perf_gtk__is_active_context(pgctx) || | ||
62 | vasprintf(&msg, format, args) < 0) { | ||
63 | fprintf(stderr, "Warning:\n"); | ||
64 | vfprintf(stderr, format, args); | ||
65 | fprintf(stderr, "\n"); | ||
66 | return -1; | ||
67 | } | ||
68 | |||
69 | gtk_label_set_text(GTK_LABEL(pgctx->message_label), msg); | ||
70 | gtk_info_bar_set_message_type(GTK_INFO_BAR(pgctx->info_bar), | ||
71 | GTK_MESSAGE_WARNING); | ||
72 | gtk_widget_show(pgctx->info_bar); | ||
73 | |||
74 | free(msg); | ||
75 | return 0; | ||
76 | } | ||
77 | #else | ||
78 | static int perf_gtk__warning_statusbar(const char *format, va_list args) | ||
79 | { | ||
80 | char *msg, *p; | ||
81 | |||
82 | if (!perf_gtk__is_active_context(pgctx) || | ||
83 | vasprintf(&msg, format, args) < 0) { | ||
84 | fprintf(stderr, "Warning:\n"); | ||
85 | vfprintf(stderr, format, args); | ||
86 | fprintf(stderr, "\n"); | ||
87 | return -1; | ||
88 | } | ||
89 | |||
90 | gtk_statusbar_pop(GTK_STATUSBAR(pgctx->statbar), | ||
91 | pgctx->statbar_ctx_id); | ||
92 | |||
93 | /* Only first line can be displayed */ | ||
94 | p = strchr(msg, '\n'); | ||
95 | if (p) | ||
96 | *p = '\0'; | ||
97 | |||
98 | gtk_statusbar_push(GTK_STATUSBAR(pgctx->statbar), | ||
99 | pgctx->statbar_ctx_id, msg); | ||
100 | |||
101 | free(msg); | ||
102 | return 0; | ||
103 | } | ||
104 | #endif | ||
105 | |||
106 | struct perf_error_ops perf_gtk_eops = { | ||
107 | .error = perf_gtk__error, | ||
108 | #ifdef HAVE_GTK_INFO_BAR | ||
109 | .warning = perf_gtk__warning_info_bar, | ||
110 | #else | ||
111 | .warning = perf_gtk__warning_statusbar, | ||
112 | #endif | ||
113 | }; | ||
114 | |||
115 | /* | ||
116 | * FIXME: Functions below should be implemented properly. | ||
117 | * For now, just add stubs for NO_NEWT=1 build. | ||
118 | */ | ||
119 | #ifdef NO_NEWT_SUPPORT | ||
120 | int ui_helpline__show_help(const char *format __used, va_list ap __used) | ||
121 | { | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | void ui_progress__update(u64 curr __used, u64 total __used, | ||
126 | const char *title __used) | ||
127 | { | ||
128 | } | ||
129 | #endif | ||
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index d33e943ac434..e813c1d17346 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c | |||
@@ -15,6 +15,8 @@ pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; | |||
15 | 15 | ||
16 | static volatile int ui__need_resize; | 16 | static volatile int ui__need_resize; |
17 | 17 | ||
18 | extern struct perf_error_ops perf_tui_eops; | ||
19 | |||
18 | void ui__refresh_dimensions(bool force) | 20 | void ui__refresh_dimensions(bool force) |
19 | { | 21 | { |
20 | if (force || ui__need_resize) { | 22 | if (force || ui__need_resize) { |
@@ -122,6 +124,8 @@ int ui__init(void) | |||
122 | signal(SIGINT, ui__signal); | 124 | signal(SIGINT, ui__signal); |
123 | signal(SIGQUIT, ui__signal); | 125 | signal(SIGQUIT, ui__signal); |
124 | signal(SIGTERM, ui__signal); | 126 | signal(SIGTERM, ui__signal); |
127 | |||
128 | perf_error__register(&perf_tui_eops); | ||
125 | out: | 129 | out: |
126 | return err; | 130 | return err; |
127 | } | 131 | } |
@@ -137,4 +141,6 @@ void ui__exit(bool wait_for_ok) | |||
137 | SLsmg_refresh(); | 141 | SLsmg_refresh(); |
138 | SLsmg_reset_smg(); | 142 | SLsmg_reset_smg(); |
139 | SLang_reset_tty(); | 143 | SLang_reset_tty(); |
144 | |||
145 | perf_error__unregister(&perf_tui_eops); | ||
140 | } | 146 | } |
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c new file mode 100644 index 000000000000..092902e30cee --- /dev/null +++ b/tools/perf/ui/tui/util.c | |||
@@ -0,0 +1,243 @@ | |||
1 | #include "../../util/util.h" | ||
2 | #include <signal.h> | ||
3 | #include <stdbool.h> | ||
4 | #include <string.h> | ||
5 | #include <sys/ttydefaults.h> | ||
6 | |||
7 | #include "../../util/cache.h" | ||
8 | #include "../../util/debug.h" | ||
9 | #include "../browser.h" | ||
10 | #include "../keysyms.h" | ||
11 | #include "../helpline.h" | ||
12 | #include "../ui.h" | ||
13 | #include "../util.h" | ||
14 | #include "../libslang.h" | ||
15 | |||
16 | static void ui_browser__argv_write(struct ui_browser *browser, | ||
17 | void *entry, int row) | ||
18 | { | ||
19 | char **arg = entry; | ||
20 | bool current_entry = ui_browser__is_current_entry(browser, row); | ||
21 | |||
22 | ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : | ||
23 | HE_COLORSET_NORMAL); | ||
24 | slsmg_write_nstring(*arg, browser->width); | ||
25 | } | ||
26 | |||
27 | static int popup_menu__run(struct ui_browser *menu) | ||
28 | { | ||
29 | int key; | ||
30 | |||
31 | if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0) | ||
32 | return -1; | ||
33 | |||
34 | while (1) { | ||
35 | key = ui_browser__run(menu, 0); | ||
36 | |||
37 | switch (key) { | ||
38 | case K_RIGHT: | ||
39 | case K_ENTER: | ||
40 | key = menu->index; | ||
41 | break; | ||
42 | case K_LEFT: | ||
43 | case K_ESC: | ||
44 | case 'q': | ||
45 | case CTRL('c'): | ||
46 | key = -1; | ||
47 | break; | ||
48 | default: | ||
49 | continue; | ||
50 | } | ||
51 | |||
52 | break; | ||
53 | } | ||
54 | |||
55 | ui_browser__hide(menu); | ||
56 | return key; | ||
57 | } | ||
58 | |||
59 | int ui__popup_menu(int argc, char * const argv[]) | ||
60 | { | ||
61 | struct ui_browser menu = { | ||
62 | .entries = (void *)argv, | ||
63 | .refresh = ui_browser__argv_refresh, | ||
64 | .seek = ui_browser__argv_seek, | ||
65 | .write = ui_browser__argv_write, | ||
66 | .nr_entries = argc, | ||
67 | }; | ||
68 | |||
69 | return popup_menu__run(&menu); | ||
70 | } | ||
71 | |||
72 | int ui_browser__input_window(const char *title, const char *text, char *input, | ||
73 | const char *exit_msg, int delay_secs) | ||
74 | { | ||
75 | int x, y, len, key; | ||
76 | int max_len = 60, nr_lines = 0; | ||
77 | static char buf[50]; | ||
78 | const char *t; | ||
79 | |||
80 | t = text; | ||
81 | while (1) { | ||
82 | const char *sep = strchr(t, '\n'); | ||
83 | |||
84 | if (sep == NULL) | ||
85 | sep = strchr(t, '\0'); | ||
86 | len = sep - t; | ||
87 | if (max_len < len) | ||
88 | max_len = len; | ||
89 | ++nr_lines; | ||
90 | if (*sep == '\0') | ||
91 | break; | ||
92 | t = sep + 1; | ||
93 | } | ||
94 | |||
95 | max_len += 2; | ||
96 | nr_lines += 8; | ||
97 | y = SLtt_Screen_Rows / 2 - nr_lines / 2; | ||
98 | x = SLtt_Screen_Cols / 2 - max_len / 2; | ||
99 | |||
100 | SLsmg_set_color(0); | ||
101 | SLsmg_draw_box(y, x++, nr_lines, max_len); | ||
102 | if (title) { | ||
103 | SLsmg_gotorc(y, x + 1); | ||
104 | SLsmg_write_string((char *)title); | ||
105 | } | ||
106 | SLsmg_gotorc(++y, x); | ||
107 | nr_lines -= 7; | ||
108 | max_len -= 2; | ||
109 | SLsmg_write_wrapped_string((unsigned char *)text, y, x, | ||
110 | nr_lines, max_len, 1); | ||
111 | y += nr_lines; | ||
112 | len = 5; | ||
113 | while (len--) { | ||
114 | SLsmg_gotorc(y + len - 1, x); | ||
115 | SLsmg_write_nstring((char *)" ", max_len); | ||
116 | } | ||
117 | SLsmg_draw_box(y++, x + 1, 3, max_len - 2); | ||
118 | |||
119 | SLsmg_gotorc(y + 3, x); | ||
120 | SLsmg_write_nstring((char *)exit_msg, max_len); | ||
121 | SLsmg_refresh(); | ||
122 | |||
123 | x += 2; | ||
124 | len = 0; | ||
125 | key = ui__getch(delay_secs); | ||
126 | while (key != K_TIMER && key != K_ENTER && key != K_ESC) { | ||
127 | if (key == K_BKSPC) { | ||
128 | if (len == 0) | ||
129 | goto next_key; | ||
130 | SLsmg_gotorc(y, x + --len); | ||
131 | SLsmg_write_char(' '); | ||
132 | } else { | ||
133 | buf[len] = key; | ||
134 | SLsmg_gotorc(y, x + len++); | ||
135 | SLsmg_write_char(key); | ||
136 | } | ||
137 | SLsmg_refresh(); | ||
138 | |||
139 | /* XXX more graceful overflow handling needed */ | ||
140 | if (len == sizeof(buf) - 1) { | ||
141 | ui_helpline__push("maximum size of symbol name reached!"); | ||
142 | key = K_ENTER; | ||
143 | break; | ||
144 | } | ||
145 | next_key: | ||
146 | key = ui__getch(delay_secs); | ||
147 | } | ||
148 | |||
149 | buf[len] = '\0'; | ||
150 | strncpy(input, buf, len+1); | ||
151 | return key; | ||
152 | } | ||
153 | |||
154 | int ui__question_window(const char *title, const char *text, | ||
155 | const char *exit_msg, int delay_secs) | ||
156 | { | ||
157 | int x, y; | ||
158 | int max_len = 0, nr_lines = 0; | ||
159 | const char *t; | ||
160 | |||
161 | t = text; | ||
162 | while (1) { | ||
163 | const char *sep = strchr(t, '\n'); | ||
164 | int len; | ||
165 | |||
166 | if (sep == NULL) | ||
167 | sep = strchr(t, '\0'); | ||
168 | len = sep - t; | ||
169 | if (max_len < len) | ||
170 | max_len = len; | ||
171 | ++nr_lines; | ||
172 | if (*sep == '\0') | ||
173 | break; | ||
174 | t = sep + 1; | ||
175 | } | ||
176 | |||
177 | max_len += 2; | ||
178 | nr_lines += 4; | ||
179 | y = SLtt_Screen_Rows / 2 - nr_lines / 2, | ||
180 | x = SLtt_Screen_Cols / 2 - max_len / 2; | ||
181 | |||
182 | SLsmg_set_color(0); | ||
183 | SLsmg_draw_box(y, x++, nr_lines, max_len); | ||
184 | if (title) { | ||
185 | SLsmg_gotorc(y, x + 1); | ||
186 | SLsmg_write_string((char *)title); | ||
187 | } | ||
188 | SLsmg_gotorc(++y, x); | ||
189 | nr_lines -= 2; | ||
190 | max_len -= 2; | ||
191 | SLsmg_write_wrapped_string((unsigned char *)text, y, x, | ||
192 | nr_lines, max_len, 1); | ||
193 | SLsmg_gotorc(y + nr_lines - 2, x); | ||
194 | SLsmg_write_nstring((char *)" ", max_len); | ||
195 | SLsmg_gotorc(y + nr_lines - 1, x); | ||
196 | SLsmg_write_nstring((char *)exit_msg, max_len); | ||
197 | SLsmg_refresh(); | ||
198 | return ui__getch(delay_secs); | ||
199 | } | ||
200 | |||
201 | int ui__help_window(const char *text) | ||
202 | { | ||
203 | return ui__question_window("Help", text, "Press any key...", 0); | ||
204 | } | ||
205 | |||
206 | int ui__dialog_yesno(const char *msg) | ||
207 | { | ||
208 | return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0); | ||
209 | } | ||
210 | |||
211 | static int __ui__warning(const char *title, const char *format, va_list args) | ||
212 | { | ||
213 | char *s; | ||
214 | |||
215 | if (vasprintf(&s, format, args) > 0) { | ||
216 | int key; | ||
217 | |||
218 | pthread_mutex_lock(&ui__lock); | ||
219 | key = ui__question_window(title, s, "Press any key...", 0); | ||
220 | pthread_mutex_unlock(&ui__lock); | ||
221 | free(s); | ||
222 | return key; | ||
223 | } | ||
224 | |||
225 | fprintf(stderr, "%s\n", title); | ||
226 | vfprintf(stderr, format, args); | ||
227 | return K_ESC; | ||
228 | } | ||
229 | |||
230 | static int perf_tui__error(const char *format, va_list args) | ||
231 | { | ||
232 | return __ui__warning("Error:", format, args); | ||
233 | } | ||
234 | |||
235 | static int perf_tui__warning(const char *format, va_list args) | ||
236 | { | ||
237 | return __ui__warning("Warning:", format, args); | ||
238 | } | ||
239 | |||
240 | struct perf_error_ops perf_tui_eops = { | ||
241 | .error = perf_tui__error, | ||
242 | .warning = perf_tui__warning, | ||
243 | }; | ||
diff --git a/tools/perf/ui/util.c b/tools/perf/ui/util.c index ad4374a16bb0..4f989774c8c6 100644 --- a/tools/perf/ui/util.c +++ b/tools/perf/ui/util.c | |||
@@ -1,250 +1,85 @@ | |||
1 | #include "../util.h" | ||
2 | #include <signal.h> | ||
3 | #include <stdbool.h> | ||
4 | #include <string.h> | ||
5 | #include <sys/ttydefaults.h> | ||
6 | |||
7 | #include "../cache.h" | ||
8 | #include "../debug.h" | ||
9 | #include "browser.h" | ||
10 | #include "keysyms.h" | ||
11 | #include "helpline.h" | ||
12 | #include "ui.h" | ||
13 | #include "util.h" | 1 | #include "util.h" |
14 | #include "libslang.h" | 2 | #include "../debug.h" |
15 | |||
16 | static void ui_browser__argv_write(struct ui_browser *browser, | ||
17 | void *entry, int row) | ||
18 | { | ||
19 | char **arg = entry; | ||
20 | bool current_entry = ui_browser__is_current_entry(browser, row); | ||
21 | |||
22 | ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : | ||
23 | HE_COLORSET_NORMAL); | ||
24 | slsmg_write_nstring(*arg, browser->width); | ||
25 | } | ||
26 | |||
27 | static int popup_menu__run(struct ui_browser *menu) | ||
28 | { | ||
29 | int key; | ||
30 | |||
31 | if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0) | ||
32 | return -1; | ||
33 | 3 | ||
34 | while (1) { | ||
35 | key = ui_browser__run(menu, 0); | ||
36 | |||
37 | switch (key) { | ||
38 | case K_RIGHT: | ||
39 | case K_ENTER: | ||
40 | key = menu->index; | ||
41 | break; | ||
42 | case K_LEFT: | ||
43 | case K_ESC: | ||
44 | case 'q': | ||
45 | case CTRL('c'): | ||
46 | key = -1; | ||
47 | break; | ||
48 | default: | ||
49 | continue; | ||
50 | } | ||
51 | |||
52 | break; | ||
53 | } | ||
54 | |||
55 | ui_browser__hide(menu); | ||
56 | return key; | ||
57 | } | ||
58 | 4 | ||
59 | int ui__popup_menu(int argc, char * const argv[]) | 5 | /* |
6 | * Default error logging functions | ||
7 | */ | ||
8 | static int perf_stdio__error(const char *format, va_list args) | ||
60 | { | 9 | { |
61 | struct ui_browser menu = { | 10 | fprintf(stderr, "Error:\n"); |
62 | .entries = (void *)argv, | 11 | vfprintf(stderr, format, args); |
63 | .refresh = ui_browser__argv_refresh, | 12 | return 0; |
64 | .seek = ui_browser__argv_seek, | ||
65 | .write = ui_browser__argv_write, | ||
66 | .nr_entries = argc, | ||
67 | }; | ||
68 | |||
69 | return popup_menu__run(&menu); | ||
70 | } | 13 | } |
71 | 14 | ||
72 | int ui_browser__input_window(const char *title, const char *text, char *input, | 15 | static int perf_stdio__warning(const char *format, va_list args) |
73 | const char *exit_msg, int delay_secs) | ||
74 | { | 16 | { |
75 | int x, y, len, key; | 17 | fprintf(stderr, "Warning:\n"); |
76 | int max_len = 60, nr_lines = 0; | 18 | vfprintf(stderr, format, args); |
77 | static char buf[50]; | 19 | return 0; |
78 | const char *t; | ||
79 | |||
80 | t = text; | ||
81 | while (1) { | ||
82 | const char *sep = strchr(t, '\n'); | ||
83 | |||
84 | if (sep == NULL) | ||
85 | sep = strchr(t, '\0'); | ||
86 | len = sep - t; | ||
87 | if (max_len < len) | ||
88 | max_len = len; | ||
89 | ++nr_lines; | ||
90 | if (*sep == '\0') | ||
91 | break; | ||
92 | t = sep + 1; | ||
93 | } | ||
94 | |||
95 | max_len += 2; | ||
96 | nr_lines += 8; | ||
97 | y = SLtt_Screen_Rows / 2 - nr_lines / 2; | ||
98 | x = SLtt_Screen_Cols / 2 - max_len / 2; | ||
99 | |||
100 | SLsmg_set_color(0); | ||
101 | SLsmg_draw_box(y, x++, nr_lines, max_len); | ||
102 | if (title) { | ||
103 | SLsmg_gotorc(y, x + 1); | ||
104 | SLsmg_write_string((char *)title); | ||
105 | } | ||
106 | SLsmg_gotorc(++y, x); | ||
107 | nr_lines -= 7; | ||
108 | max_len -= 2; | ||
109 | SLsmg_write_wrapped_string((unsigned char *)text, y, x, | ||
110 | nr_lines, max_len, 1); | ||
111 | y += nr_lines; | ||
112 | len = 5; | ||
113 | while (len--) { | ||
114 | SLsmg_gotorc(y + len - 1, x); | ||
115 | SLsmg_write_nstring((char *)" ", max_len); | ||
116 | } | ||
117 | SLsmg_draw_box(y++, x + 1, 3, max_len - 2); | ||
118 | |||
119 | SLsmg_gotorc(y + 3, x); | ||
120 | SLsmg_write_nstring((char *)exit_msg, max_len); | ||
121 | SLsmg_refresh(); | ||
122 | |||
123 | x += 2; | ||
124 | len = 0; | ||
125 | key = ui__getch(delay_secs); | ||
126 | while (key != K_TIMER && key != K_ENTER && key != K_ESC) { | ||
127 | if (key == K_BKSPC) { | ||
128 | if (len == 0) | ||
129 | goto next_key; | ||
130 | SLsmg_gotorc(y, x + --len); | ||
131 | SLsmg_write_char(' '); | ||
132 | } else { | ||
133 | buf[len] = key; | ||
134 | SLsmg_gotorc(y, x + len++); | ||
135 | SLsmg_write_char(key); | ||
136 | } | ||
137 | SLsmg_refresh(); | ||
138 | |||
139 | /* XXX more graceful overflow handling needed */ | ||
140 | if (len == sizeof(buf) - 1) { | ||
141 | ui_helpline__push("maximum size of symbol name reached!"); | ||
142 | key = K_ENTER; | ||
143 | break; | ||
144 | } | ||
145 | next_key: | ||
146 | key = ui__getch(delay_secs); | ||
147 | } | ||
148 | |||
149 | buf[len] = '\0'; | ||
150 | strncpy(input, buf, len+1); | ||
151 | return key; | ||
152 | } | 20 | } |
153 | 21 | ||
154 | int ui__question_window(const char *title, const char *text, | 22 | static struct perf_error_ops default_eops = |
155 | const char *exit_msg, int delay_secs) | ||
156 | { | 23 | { |
157 | int x, y; | 24 | .error = perf_stdio__error, |
158 | int max_len = 0, nr_lines = 0; | 25 | .warning = perf_stdio__warning, |
159 | const char *t; | 26 | }; |
160 | |||
161 | t = text; | ||
162 | while (1) { | ||
163 | const char *sep = strchr(t, '\n'); | ||
164 | int len; | ||
165 | |||
166 | if (sep == NULL) | ||
167 | sep = strchr(t, '\0'); | ||
168 | len = sep - t; | ||
169 | if (max_len < len) | ||
170 | max_len = len; | ||
171 | ++nr_lines; | ||
172 | if (*sep == '\0') | ||
173 | break; | ||
174 | t = sep + 1; | ||
175 | } | ||
176 | |||
177 | max_len += 2; | ||
178 | nr_lines += 4; | ||
179 | y = SLtt_Screen_Rows / 2 - nr_lines / 2, | ||
180 | x = SLtt_Screen_Cols / 2 - max_len / 2; | ||
181 | |||
182 | SLsmg_set_color(0); | ||
183 | SLsmg_draw_box(y, x++, nr_lines, max_len); | ||
184 | if (title) { | ||
185 | SLsmg_gotorc(y, x + 1); | ||
186 | SLsmg_write_string((char *)title); | ||
187 | } | ||
188 | SLsmg_gotorc(++y, x); | ||
189 | nr_lines -= 2; | ||
190 | max_len -= 2; | ||
191 | SLsmg_write_wrapped_string((unsigned char *)text, y, x, | ||
192 | nr_lines, max_len, 1); | ||
193 | SLsmg_gotorc(y + nr_lines - 2, x); | ||
194 | SLsmg_write_nstring((char *)" ", max_len); | ||
195 | SLsmg_gotorc(y + nr_lines - 1, x); | ||
196 | SLsmg_write_nstring((char *)exit_msg, max_len); | ||
197 | SLsmg_refresh(); | ||
198 | return ui__getch(delay_secs); | ||
199 | } | ||
200 | 27 | ||
201 | int ui__help_window(const char *text) | 28 | static struct perf_error_ops *perf_eops = &default_eops; |
202 | { | ||
203 | return ui__question_window("Help", text, "Press any key...", 0); | ||
204 | } | ||
205 | 29 | ||
206 | int ui__dialog_yesno(const char *msg) | ||
207 | { | ||
208 | return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0); | ||
209 | } | ||
210 | 30 | ||
211 | int __ui__warning(const char *title, const char *format, va_list args) | 31 | int ui__error(const char *format, ...) |
212 | { | 32 | { |
213 | char *s; | 33 | int ret; |
214 | 34 | va_list args; | |
215 | if (use_browser > 0 && vasprintf(&s, format, args) > 0) { | ||
216 | int key; | ||
217 | 35 | ||
218 | pthread_mutex_lock(&ui__lock); | 36 | va_start(args, format); |
219 | key = ui__question_window(title, s, "Press any key...", 0); | 37 | ret = perf_eops->error(format, args); |
220 | pthread_mutex_unlock(&ui__lock); | 38 | va_end(args); |
221 | free(s); | ||
222 | return key; | ||
223 | } | ||
224 | 39 | ||
225 | fprintf(stderr, "%s:\n", title); | 40 | return ret; |
226 | vfprintf(stderr, format, args); | ||
227 | return K_ESC; | ||
228 | } | 41 | } |
229 | 42 | ||
230 | int ui__warning(const char *format, ...) | 43 | int ui__warning(const char *format, ...) |
231 | { | 44 | { |
232 | int key; | 45 | int ret; |
233 | va_list args; | 46 | va_list args; |
234 | 47 | ||
235 | va_start(args, format); | 48 | va_start(args, format); |
236 | key = __ui__warning("Warning", format, args); | 49 | ret = perf_eops->warning(format, args); |
237 | va_end(args); | 50 | va_end(args); |
238 | return key; | 51 | |
52 | return ret; | ||
239 | } | 53 | } |
240 | 54 | ||
241 | int ui__error(const char *format, ...) | 55 | |
56 | /** | ||
57 | * perf_error__register - Register error logging functions | ||
58 | * @eops: The pointer to error logging function struct | ||
59 | * | ||
60 | * Register UI-specific error logging functions. Before calling this, | ||
61 | * other logging functions should be unregistered, if any. | ||
62 | */ | ||
63 | int perf_error__register(struct perf_error_ops *eops) | ||
242 | { | 64 | { |
243 | int key; | 65 | if (perf_eops != &default_eops) |
244 | va_list args; | 66 | return -1; |
245 | 67 | ||
246 | va_start(args, format); | 68 | perf_eops = eops; |
247 | key = __ui__warning("Error", format, args); | 69 | return 0; |
248 | va_end(args); | 70 | } |
249 | return key; | 71 | |
72 | /** | ||
73 | * perf_error__unregister - Unregister error logging functions | ||
74 | * @eops: The pointer to error logging function struct | ||
75 | * | ||
76 | * Unregister already registered error logging functions. | ||
77 | */ | ||
78 | int perf_error__unregister(struct perf_error_ops *eops) | ||
79 | { | ||
80 | if (perf_eops != eops) | ||
81 | return -1; | ||
82 | |||
83 | perf_eops = &default_eops; | ||
84 | return 0; | ||
250 | } | 85 | } |
diff --git a/tools/perf/ui/util.h b/tools/perf/ui/util.h index 2d1738bd71c8..361f08c52d37 100644 --- a/tools/perf/ui/util.h +++ b/tools/perf/ui/util.h | |||
@@ -9,6 +9,13 @@ int ui__help_window(const char *text); | |||
9 | int ui__dialog_yesno(const char *msg); | 9 | int ui__dialog_yesno(const char *msg); |
10 | int ui__question_window(const char *title, const char *text, | 10 | int ui__question_window(const char *title, const char *text, |
11 | const char *exit_msg, int delay_secs); | 11 | const char *exit_msg, int delay_secs); |
12 | int __ui__warning(const char *title, const char *format, va_list args); | 12 | |
13 | struct perf_error_ops { | ||
14 | int (*error)(const char *format, va_list args); | ||
15 | int (*warning)(const char *format, va_list args); | ||
16 | }; | ||
17 | |||
18 | int perf_error__register(struct perf_error_ops *eops); | ||
19 | int perf_error__unregister(struct perf_error_ops *eops); | ||
13 | 20 | ||
14 | #endif /* _PERF_UI_UTIL_H_ */ | 21 | #endif /* _PERF_UI_UTIL_H_ */ |
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index efb1fce259a4..4dfe0bb3c322 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c | |||
@@ -47,7 +47,7 @@ int dump_printf(const char *fmt, ...) | |||
47 | return ret; | 47 | return ret; |
48 | } | 48 | } |
49 | 49 | ||
50 | #ifdef NO_NEWT_SUPPORT | 50 | #if defined(NO_NEWT_SUPPORT) && defined(NO_GTK2_SUPPORT) |
51 | int ui__warning(const char *format, ...) | 51 | int ui__warning(const char *format, ...) |
52 | { | 52 | { |
53 | va_list args; | 53 | va_list args; |
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 6bebe7f0a20c..015c91dbc096 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h | |||
@@ -12,8 +12,9 @@ int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); | |||
12 | void trace_event(union perf_event *event); | 12 | void trace_event(union perf_event *event); |
13 | 13 | ||
14 | struct ui_progress; | 14 | struct ui_progress; |
15 | struct perf_error_ops; | ||
15 | 16 | ||
16 | #ifdef NO_NEWT_SUPPORT | 17 | #if defined(NO_NEWT_SUPPORT) && defined(NO_GTK2_SUPPORT) |
17 | static inline int ui_helpline__show_help(const char *format __used, va_list ap __used) | 18 | static inline int ui_helpline__show_help(const char *format __used, va_list ap __used) |
18 | { | 19 | { |
19 | return 0; | 20 | return 0; |
@@ -23,12 +24,28 @@ static inline void ui_progress__update(u64 curr __used, u64 total __used, | |||
23 | const char *title __used) {} | 24 | const char *title __used) {} |
24 | 25 | ||
25 | #define ui__error(format, arg...) ui__warning(format, ##arg) | 26 | #define ui__error(format, arg...) ui__warning(format, ##arg) |
26 | #else | 27 | |
28 | static inline int | ||
29 | perf_error__register(struct perf_error_ops *eops __used) | ||
30 | { | ||
31 | return 0; | ||
32 | } | ||
33 | |||
34 | static inline int | ||
35 | perf_error__unregister(struct perf_error_ops *eops __used) | ||
36 | { | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | #else /* NO_NEWT_SUPPORT && NO_GTK2_SUPPORT */ | ||
41 | |||
27 | extern char ui_helpline__last_msg[]; | 42 | extern char ui_helpline__last_msg[]; |
28 | int ui_helpline__show_help(const char *format, va_list ap); | 43 | int ui_helpline__show_help(const char *format, va_list ap); |
29 | #include "../ui/progress.h" | 44 | #include "../ui/progress.h" |
30 | int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); | 45 | int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); |
31 | #endif | 46 | #include "../ui/util.h" |
47 | |||
48 | #endif /* NO_NEWT_SUPPORT && NO_GTK2_SUPPORT */ | ||
32 | 49 | ||
33 | int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); | 50 | int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); |
34 | int ui__error_paranoid(void); | 51 | int ui__error_paranoid(void); |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 7400fb3fc50c..f74e9560350e 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -224,8 +224,8 @@ out_free_attrs: | |||
224 | return err; | 224 | return err; |
225 | } | 225 | } |
226 | 226 | ||
227 | static struct perf_evsel * | 227 | struct perf_evsel * |
228 | perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) | 228 | perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) |
229 | { | 229 | { |
230 | struct perf_evsel *evsel; | 230 | struct perf_evsel *evsel; |
231 | 231 | ||
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 989bee9624c2..40d4d3cdced0 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -73,6 +73,9 @@ int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist, | |||
73 | #define perf_evlist__set_tracepoints_handlers_array(evlist, array) \ | 73 | #define perf_evlist__set_tracepoints_handlers_array(evlist, array) \ |
74 | perf_evlist__set_tracepoints_handlers(evlist, array, ARRAY_SIZE(array)) | 74 | perf_evlist__set_tracepoints_handlers(evlist, array, ARRAY_SIZE(array)) |
75 | 75 | ||
76 | struct perf_evsel * | ||
77 | perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id); | ||
78 | |||
76 | void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, | 79 | void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, |
77 | int cpu, int thread, u64 id); | 80 | int cpu, int thread, u64 id); |
78 | 81 | ||
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 9f6cebd798ee..e81771364867 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include "cpumap.h" | 15 | #include "cpumap.h" |
16 | #include "thread_map.h" | 16 | #include "thread_map.h" |
17 | #include "target.h" | 17 | #include "target.h" |
18 | #include "../../include/linux/perf_event.h" | 18 | #include "../../../include/linux/hw_breakpoint.h" |
19 | 19 | ||
20 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 20 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
21 | #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) | 21 | #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) |
@@ -78,7 +78,7 @@ static const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = { | |||
78 | "ref-cycles", | 78 | "ref-cycles", |
79 | }; | 79 | }; |
80 | 80 | ||
81 | const char *__perf_evsel__hw_name(u64 config) | 81 | static const char *__perf_evsel__hw_name(u64 config) |
82 | { | 82 | { |
83 | if (config < PERF_COUNT_HW_MAX && perf_evsel__hw_names[config]) | 83 | if (config < PERF_COUNT_HW_MAX && perf_evsel__hw_names[config]) |
84 | return perf_evsel__hw_names[config]; | 84 | return perf_evsel__hw_names[config]; |
@@ -86,16 +86,15 @@ const char *__perf_evsel__hw_name(u64 config) | |||
86 | return "unknown-hardware"; | 86 | return "unknown-hardware"; |
87 | } | 87 | } |
88 | 88 | ||
89 | static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) | 89 | static int perf_evsel__add_modifiers(struct perf_evsel *evsel, char *bf, size_t size) |
90 | { | 90 | { |
91 | int colon = 0; | 91 | int colon = 0, r = 0; |
92 | struct perf_event_attr *attr = &evsel->attr; | 92 | struct perf_event_attr *attr = &evsel->attr; |
93 | int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(attr->config)); | ||
94 | bool exclude_guest_default = false; | 93 | bool exclude_guest_default = false; |
95 | 94 | ||
96 | #define MOD_PRINT(context, mod) do { \ | 95 | #define MOD_PRINT(context, mod) do { \ |
97 | if (!attr->exclude_##context) { \ | 96 | if (!attr->exclude_##context) { \ |
98 | if (!colon) colon = r++; \ | 97 | if (!colon) colon = ++r; \ |
99 | r += scnprintf(bf + r, size - r, "%c", mod); \ | 98 | r += scnprintf(bf + r, size - r, "%c", mod); \ |
100 | } } while(0) | 99 | } } while(0) |
101 | 100 | ||
@@ -108,7 +107,7 @@ static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) | |||
108 | 107 | ||
109 | if (attr->precise_ip) { | 108 | if (attr->precise_ip) { |
110 | if (!colon) | 109 | if (!colon) |
111 | colon = r++; | 110 | colon = ++r; |
112 | r += scnprintf(bf + r, size - r, "%.*s", attr->precise_ip, "ppp"); | 111 | r += scnprintf(bf + r, size - r, "%.*s", attr->precise_ip, "ppp"); |
113 | exclude_guest_default = true; | 112 | exclude_guest_default = true; |
114 | } | 113 | } |
@@ -119,39 +118,211 @@ static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) | |||
119 | } | 118 | } |
120 | #undef MOD_PRINT | 119 | #undef MOD_PRINT |
121 | if (colon) | 120 | if (colon) |
122 | bf[colon] = ':'; | 121 | bf[colon - 1] = ':'; |
123 | return r; | 122 | return r; |
124 | } | 123 | } |
125 | 124 | ||
126 | int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) | 125 | static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) |
126 | { | ||
127 | int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(evsel->attr.config)); | ||
128 | return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); | ||
129 | } | ||
130 | |||
131 | static const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX] = { | ||
132 | "cpu-clock", | ||
133 | "task-clock", | ||
134 | "page-faults", | ||
135 | "context-switches", | ||
136 | "CPU-migrations", | ||
137 | "minor-faults", | ||
138 | "major-faults", | ||
139 | "alignment-faults", | ||
140 | "emulation-faults", | ||
141 | }; | ||
142 | |||
143 | static const char *__perf_evsel__sw_name(u64 config) | ||
127 | { | 144 | { |
128 | int ret; | 145 | if (config < PERF_COUNT_SW_MAX && perf_evsel__sw_names[config]) |
146 | return perf_evsel__sw_names[config]; | ||
147 | return "unknown-software"; | ||
148 | } | ||
149 | |||
150 | static int perf_evsel__sw_name(struct perf_evsel *evsel, char *bf, size_t size) | ||
151 | { | ||
152 | int r = scnprintf(bf, size, "%s", __perf_evsel__sw_name(evsel->attr.config)); | ||
153 | return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); | ||
154 | } | ||
155 | |||
156 | static int __perf_evsel__bp_name(char *bf, size_t size, u64 addr, u64 type) | ||
157 | { | ||
158 | int r; | ||
159 | |||
160 | r = scnprintf(bf, size, "mem:0x%" PRIx64 ":", addr); | ||
161 | |||
162 | if (type & HW_BREAKPOINT_R) | ||
163 | r += scnprintf(bf + r, size - r, "r"); | ||
164 | |||
165 | if (type & HW_BREAKPOINT_W) | ||
166 | r += scnprintf(bf + r, size - r, "w"); | ||
167 | |||
168 | if (type & HW_BREAKPOINT_X) | ||
169 | r += scnprintf(bf + r, size - r, "x"); | ||
170 | |||
171 | return r; | ||
172 | } | ||
173 | |||
174 | static int perf_evsel__bp_name(struct perf_evsel *evsel, char *bf, size_t size) | ||
175 | { | ||
176 | struct perf_event_attr *attr = &evsel->attr; | ||
177 | int r = __perf_evsel__bp_name(bf, size, attr->bp_addr, attr->bp_type); | ||
178 | return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); | ||
179 | } | ||
180 | |||
181 | const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] | ||
182 | [PERF_EVSEL__MAX_ALIASES] = { | ||
183 | { "L1-dcache", "l1-d", "l1d", "L1-data", }, | ||
184 | { "L1-icache", "l1-i", "l1i", "L1-instruction", }, | ||
185 | { "LLC", "L2", }, | ||
186 | { "dTLB", "d-tlb", "Data-TLB", }, | ||
187 | { "iTLB", "i-tlb", "Instruction-TLB", }, | ||
188 | { "branch", "branches", "bpu", "btb", "bpc", }, | ||
189 | { "node", }, | ||
190 | }; | ||
191 | |||
192 | const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX] | ||
193 | [PERF_EVSEL__MAX_ALIASES] = { | ||
194 | { "load", "loads", "read", }, | ||
195 | { "store", "stores", "write", }, | ||
196 | { "prefetch", "prefetches", "speculative-read", "speculative-load", }, | ||
197 | }; | ||
198 | |||
199 | const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] | ||
200 | [PERF_EVSEL__MAX_ALIASES] = { | ||
201 | { "refs", "Reference", "ops", "access", }, | ||
202 | { "misses", "miss", }, | ||
203 | }; | ||
204 | |||
205 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
206 | #define CACHE_READ (1 << C(OP_READ)) | ||
207 | #define CACHE_WRITE (1 << C(OP_WRITE)) | ||
208 | #define CACHE_PREFETCH (1 << C(OP_PREFETCH)) | ||
209 | #define COP(x) (1 << x) | ||
210 | |||
211 | /* | ||
212 | * cache operartion stat | ||
213 | * L1I : Read and prefetch only | ||
214 | * ITLB and BPU : Read-only | ||
215 | */ | ||
216 | static unsigned long perf_evsel__hw_cache_stat[C(MAX)] = { | ||
217 | [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), | ||
218 | [C(L1I)] = (CACHE_READ | CACHE_PREFETCH), | ||
219 | [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), | ||
220 | [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), | ||
221 | [C(ITLB)] = (CACHE_READ), | ||
222 | [C(BPU)] = (CACHE_READ), | ||
223 | [C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), | ||
224 | }; | ||
225 | |||
226 | bool perf_evsel__is_cache_op_valid(u8 type, u8 op) | ||
227 | { | ||
228 | if (perf_evsel__hw_cache_stat[type] & COP(op)) | ||
229 | return true; /* valid */ | ||
230 | else | ||
231 | return false; /* invalid */ | ||
232 | } | ||
233 | |||
234 | int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, | ||
235 | char *bf, size_t size) | ||
236 | { | ||
237 | if (result) { | ||
238 | return scnprintf(bf, size, "%s-%s-%s", perf_evsel__hw_cache[type][0], | ||
239 | perf_evsel__hw_cache_op[op][0], | ||
240 | perf_evsel__hw_cache_result[result][0]); | ||
241 | } | ||
242 | |||
243 | return scnprintf(bf, size, "%s-%s", perf_evsel__hw_cache[type][0], | ||
244 | perf_evsel__hw_cache_op[op][1]); | ||
245 | } | ||
246 | |||
247 | static int __perf_evsel__hw_cache_name(u64 config, char *bf, size_t size) | ||
248 | { | ||
249 | u8 op, result, type = (config >> 0) & 0xff; | ||
250 | const char *err = "unknown-ext-hardware-cache-type"; | ||
251 | |||
252 | if (type > PERF_COUNT_HW_CACHE_MAX) | ||
253 | goto out_err; | ||
254 | |||
255 | op = (config >> 8) & 0xff; | ||
256 | err = "unknown-ext-hardware-cache-op"; | ||
257 | if (op > PERF_COUNT_HW_CACHE_OP_MAX) | ||
258 | goto out_err; | ||
259 | |||
260 | result = (config >> 16) & 0xff; | ||
261 | err = "unknown-ext-hardware-cache-result"; | ||
262 | if (result > PERF_COUNT_HW_CACHE_RESULT_MAX) | ||
263 | goto out_err; | ||
264 | |||
265 | err = "invalid-cache"; | ||
266 | if (!perf_evsel__is_cache_op_valid(type, op)) | ||
267 | goto out_err; | ||
268 | |||
269 | return __perf_evsel__hw_cache_type_op_res_name(type, op, result, bf, size); | ||
270 | out_err: | ||
271 | return scnprintf(bf, size, "%s", err); | ||
272 | } | ||
273 | |||
274 | static int perf_evsel__hw_cache_name(struct perf_evsel *evsel, char *bf, size_t size) | ||
275 | { | ||
276 | int ret = __perf_evsel__hw_cache_name(evsel->attr.config, bf, size); | ||
277 | return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); | ||
278 | } | ||
279 | |||
280 | static int perf_evsel__raw_name(struct perf_evsel *evsel, char *bf, size_t size) | ||
281 | { | ||
282 | int ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config); | ||
283 | return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); | ||
284 | } | ||
285 | |||
286 | const char *perf_evsel__name(struct perf_evsel *evsel) | ||
287 | { | ||
288 | char bf[128]; | ||
289 | |||
290 | if (evsel->name) | ||
291 | return evsel->name; | ||
129 | 292 | ||
130 | switch (evsel->attr.type) { | 293 | switch (evsel->attr.type) { |
131 | case PERF_TYPE_RAW: | 294 | case PERF_TYPE_RAW: |
132 | ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config); | 295 | perf_evsel__raw_name(evsel, bf, sizeof(bf)); |
133 | break; | 296 | break; |
134 | 297 | ||
135 | case PERF_TYPE_HARDWARE: | 298 | case PERF_TYPE_HARDWARE: |
136 | ret = perf_evsel__hw_name(evsel, bf, size); | 299 | perf_evsel__hw_name(evsel, bf, sizeof(bf)); |
300 | break; | ||
301 | |||
302 | case PERF_TYPE_HW_CACHE: | ||
303 | perf_evsel__hw_cache_name(evsel, bf, sizeof(bf)); | ||
304 | break; | ||
305 | |||
306 | case PERF_TYPE_SOFTWARE: | ||
307 | perf_evsel__sw_name(evsel, bf, sizeof(bf)); | ||
137 | break; | 308 | break; |
309 | |||
310 | case PERF_TYPE_TRACEPOINT: | ||
311 | scnprintf(bf, sizeof(bf), "%s", "unknown tracepoint"); | ||
312 | break; | ||
313 | |||
314 | case PERF_TYPE_BREAKPOINT: | ||
315 | perf_evsel__bp_name(evsel, bf, sizeof(bf)); | ||
316 | break; | ||
317 | |||
138 | default: | 318 | default: |
139 | /* | 319 | scnprintf(bf, sizeof(bf), "%s", "unknown attr type"); |
140 | * FIXME | 320 | break; |
141 | * | 321 | } |
142 | * This is the minimal perf_evsel__name so that we can | 322 | |
143 | * reconstruct event names taking into account event modifiers. | 323 | evsel->name = strdup(bf); |
144 | * | 324 | |
145 | * The old event_name uses it now for raw anr hw events, so that | 325 | return evsel->name ?: "unknown"; |
146 | * we don't drag all the parsing stuff into the python binding. | ||
147 | * | ||
148 | * On the next devel cycle the rest of the event naming will be | ||
149 | * brought here. | ||
150 | */ | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | return ret; | ||
155 | } | 326 | } |
156 | 327 | ||
157 | void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, | 328 | void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 4ba8b564e6f4..67cc5033d192 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -83,8 +83,19 @@ void perf_evsel__config(struct perf_evsel *evsel, | |||
83 | struct perf_record_opts *opts, | 83 | struct perf_record_opts *opts, |
84 | struct perf_evsel *first); | 84 | struct perf_evsel *first); |
85 | 85 | ||
86 | const char* __perf_evsel__hw_name(u64 config); | 86 | bool perf_evsel__is_cache_op_valid(u8 type, u8 op); |
87 | int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size); | 87 | |
88 | #define PERF_EVSEL__MAX_ALIASES 8 | ||
89 | |||
90 | extern const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] | ||
91 | [PERF_EVSEL__MAX_ALIASES]; | ||
92 | extern const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX] | ||
93 | [PERF_EVSEL__MAX_ALIASES]; | ||
94 | const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] | ||
95 | [PERF_EVSEL__MAX_ALIASES]; | ||
96 | int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, | ||
97 | char *bf, size_t size); | ||
98 | const char *perf_evsel__name(struct perf_evsel *evsel); | ||
88 | 99 | ||
89 | int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); | 100 | int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); |
90 | int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); | 101 | int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index e909d43cf542..5a47aba46759 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -641,7 +641,7 @@ static int write_event_desc(int fd, struct perf_header *h __used, | |||
641 | /* | 641 | /* |
642 | * write event string as passed on cmdline | 642 | * write event string as passed on cmdline |
643 | */ | 643 | */ |
644 | ret = do_write_string(fd, event_name(attr)); | 644 | ret = do_write_string(fd, perf_evsel__name(attr)); |
645 | if (ret < 0) | 645 | if (ret < 0) |
646 | return ret; | 646 | return ret; |
647 | /* | 647 | /* |
@@ -1474,15 +1474,15 @@ out: | |||
1474 | 1474 | ||
1475 | static int process_tracing_data(struct perf_file_section *section __unused, | 1475 | static int process_tracing_data(struct perf_file_section *section __unused, |
1476 | struct perf_header *ph __unused, | 1476 | struct perf_header *ph __unused, |
1477 | int feat __unused, int fd) | 1477 | int feat __unused, int fd, void *data) |
1478 | { | 1478 | { |
1479 | trace_report(fd, false); | 1479 | trace_report(fd, data, false); |
1480 | return 0; | 1480 | return 0; |
1481 | } | 1481 | } |
1482 | 1482 | ||
1483 | static int process_build_id(struct perf_file_section *section, | 1483 | static int process_build_id(struct perf_file_section *section, |
1484 | struct perf_header *ph, | 1484 | struct perf_header *ph, |
1485 | int feat __unused, int fd) | 1485 | int feat __unused, int fd, void *data __used) |
1486 | { | 1486 | { |
1487 | if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) | 1487 | if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) |
1488 | pr_debug("Failed to read buildids, continuing...\n"); | 1488 | pr_debug("Failed to read buildids, continuing...\n"); |
@@ -1493,7 +1493,7 @@ struct feature_ops { | |||
1493 | int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist); | 1493 | int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist); |
1494 | void (*print)(struct perf_header *h, int fd, FILE *fp); | 1494 | void (*print)(struct perf_header *h, int fd, FILE *fp); |
1495 | int (*process)(struct perf_file_section *section, | 1495 | int (*process)(struct perf_file_section *section, |
1496 | struct perf_header *h, int feat, int fd); | 1496 | struct perf_header *h, int feat, int fd, void *data); |
1497 | const char *name; | 1497 | const char *name; |
1498 | bool full_only; | 1498 | bool full_only; |
1499 | }; | 1499 | }; |
@@ -1988,7 +1988,7 @@ int perf_file_header__read(struct perf_file_header *header, | |||
1988 | 1988 | ||
1989 | static int perf_file_section__process(struct perf_file_section *section, | 1989 | static int perf_file_section__process(struct perf_file_section *section, |
1990 | struct perf_header *ph, | 1990 | struct perf_header *ph, |
1991 | int feat, int fd, void *data __used) | 1991 | int feat, int fd, void *data) |
1992 | { | 1992 | { |
1993 | if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) { | 1993 | if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) { |
1994 | pr_debug("Failed to lseek to %" PRIu64 " offset for feature " | 1994 | pr_debug("Failed to lseek to %" PRIu64 " offset for feature " |
@@ -2004,7 +2004,7 @@ static int perf_file_section__process(struct perf_file_section *section, | |||
2004 | if (!feat_ops[feat].process) | 2004 | if (!feat_ops[feat].process) |
2005 | return 0; | 2005 | return 0; |
2006 | 2006 | ||
2007 | return feat_ops[feat].process(section, ph, feat, fd); | 2007 | return feat_ops[feat].process(section, ph, feat, fd, data); |
2008 | } | 2008 | } |
2009 | 2009 | ||
2010 | static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, | 2010 | static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, |
@@ -2093,9 +2093,11 @@ static int read_attr(int fd, struct perf_header *ph, | |||
2093 | return ret <= 0 ? -1 : 0; | 2093 | return ret <= 0 ? -1 : 0; |
2094 | } | 2094 | } |
2095 | 2095 | ||
2096 | static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel) | 2096 | static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel, |
2097 | struct pevent *pevent) | ||
2097 | { | 2098 | { |
2098 | struct event_format *event = trace_find_event(evsel->attr.config); | 2099 | struct event_format *event = pevent_find_event(pevent, |
2100 | evsel->attr.config); | ||
2099 | char bf[128]; | 2101 | char bf[128]; |
2100 | 2102 | ||
2101 | if (event == NULL) | 2103 | if (event == NULL) |
@@ -2109,13 +2111,14 @@ static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel) | |||
2109 | return 0; | 2111 | return 0; |
2110 | } | 2112 | } |
2111 | 2113 | ||
2112 | static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist) | 2114 | static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist, |
2115 | struct pevent *pevent) | ||
2113 | { | 2116 | { |
2114 | struct perf_evsel *pos; | 2117 | struct perf_evsel *pos; |
2115 | 2118 | ||
2116 | list_for_each_entry(pos, &evlist->entries, node) { | 2119 | list_for_each_entry(pos, &evlist->entries, node) { |
2117 | if (pos->attr.type == PERF_TYPE_TRACEPOINT && | 2120 | if (pos->attr.type == PERF_TYPE_TRACEPOINT && |
2118 | perf_evsel__set_tracepoint_name(pos)) | 2121 | perf_evsel__set_tracepoint_name(pos, pevent)) |
2119 | return -1; | 2122 | return -1; |
2120 | } | 2123 | } |
2121 | 2124 | ||
@@ -2198,12 +2201,12 @@ int perf_session__read_header(struct perf_session *session, int fd) | |||
2198 | event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); | 2201 | event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); |
2199 | } | 2202 | } |
2200 | 2203 | ||
2201 | perf_header__process_sections(header, fd, NULL, | 2204 | perf_header__process_sections(header, fd, &session->pevent, |
2202 | perf_file_section__process); | 2205 | perf_file_section__process); |
2203 | 2206 | ||
2204 | lseek(fd, header->data_offset, SEEK_SET); | 2207 | lseek(fd, header->data_offset, SEEK_SET); |
2205 | 2208 | ||
2206 | if (perf_evlist__set_tracepoint_names(session->evlist)) | 2209 | if (perf_evlist__set_tracepoint_names(session->evlist, session->pevent)) |
2207 | goto out_delete_evlist; | 2210 | goto out_delete_evlist; |
2208 | 2211 | ||
2209 | header->frozen = 1; | 2212 | header->frozen = 1; |
@@ -2419,8 +2422,8 @@ int perf_event__process_tracing_data(union perf_event *event, | |||
2419 | lseek(session->fd, offset + sizeof(struct tracing_data_event), | 2422 | lseek(session->fd, offset + sizeof(struct tracing_data_event), |
2420 | SEEK_SET); | 2423 | SEEK_SET); |
2421 | 2424 | ||
2422 | size_read = trace_report(session->fd, session->repipe); | 2425 | size_read = trace_report(session->fd, &session->pevent, |
2423 | 2426 | session->repipe); | |
2424 | padding = ALIGN(size_read, sizeof(u64)) - size_read; | 2427 | padding = ALIGN(size_read, sizeof(u64)) - size_read; |
2425 | 2428 | ||
2426 | if (read(session->fd, buf, padding) < 0) | 2429 | if (read(session->fd, buf, padding) < 0) |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 34bb556d6219..0b096c27a419 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -47,6 +47,7 @@ enum hist_column { | |||
47 | HISTC_SYMBOL_TO, | 47 | HISTC_SYMBOL_TO, |
48 | HISTC_DSO_FROM, | 48 | HISTC_DSO_FROM, |
49 | HISTC_DSO_TO, | 49 | HISTC_DSO_TO, |
50 | HISTC_SRCLINE, | ||
50 | HISTC_NR_COLS, /* Last entry */ | 51 | HISTC_NR_COLS, /* Last entry */ |
51 | }; | 52 | }; |
52 | 53 | ||
diff --git a/tools/perf/util/include/linux/kernel.h b/tools/perf/util/include/linux/kernel.h index 1eb804fd3fbf..b6842c1d02a8 100644 --- a/tools/perf/util/include/linux/kernel.h +++ b/tools/perf/util/include/linux/kernel.h | |||
@@ -108,4 +108,14 @@ int eprintf(int level, | |||
108 | #define pr_debug3(fmt, ...) pr_debugN(3, pr_fmt(fmt), ##__VA_ARGS__) | 108 | #define pr_debug3(fmt, ...) pr_debugN(3, pr_fmt(fmt), ##__VA_ARGS__) |
109 | #define pr_debug4(fmt, ...) pr_debugN(4, pr_fmt(fmt), ##__VA_ARGS__) | 109 | #define pr_debug4(fmt, ...) pr_debugN(4, pr_fmt(fmt), ##__VA_ARGS__) |
110 | 110 | ||
111 | /* | ||
112 | * This looks more complex than it should be. But we need to | ||
113 | * get the type for the ~ right in round_down (it needs to be | ||
114 | * as wide as the result!), and we want to evaluate the macro | ||
115 | * arguments just once each. | ||
116 | */ | ||
117 | #define __round_mask(x, y) ((__typeof__(x))((y)-1)) | ||
118 | #define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) | ||
119 | #define round_down(x, y) ((x) & ~__round_mask(x, y)) | ||
120 | |||
111 | #endif | 121 | #endif |
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 81371bad4ef0..c14c665d9a25 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h | |||
@@ -157,7 +157,7 @@ void machine__exit(struct machine *self); | |||
157 | void machine__delete(struct machine *self); | 157 | void machine__delete(struct machine *self); |
158 | 158 | ||
159 | int machine__resolve_callchain(struct machine *machine, | 159 | int machine__resolve_callchain(struct machine *machine, |
160 | struct perf_evsel *evsel, struct thread *thread, | 160 | struct thread *thread, |
161 | struct ip_callchain *chain, | 161 | struct ip_callchain *chain, |
162 | struct symbol **parent); | 162 | struct symbol **parent); |
163 | int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name, | 163 | int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name, |
diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c index 76b98e2a587d..1b997d2b89ce 100644 --- a/tools/perf/util/parse-events-test.c +++ b/tools/perf/util/parse-events-test.c | |||
@@ -181,6 +181,22 @@ static int test__checkevent_breakpoint_w(struct perf_evlist *evlist) | |||
181 | return 0; | 181 | return 0; |
182 | } | 182 | } |
183 | 183 | ||
184 | static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist) | ||
185 | { | ||
186 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
187 | struct perf_evsel, node); | ||
188 | |||
189 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
190 | TEST_ASSERT_VAL("wrong type", | ||
191 | PERF_TYPE_BREAKPOINT == evsel->attr.type); | ||
192 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | ||
193 | TEST_ASSERT_VAL("wrong bp_type", | ||
194 | (HW_BREAKPOINT_R|HW_BREAKPOINT_W) == evsel->attr.bp_type); | ||
195 | TEST_ASSERT_VAL("wrong bp_len", | ||
196 | HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); | ||
197 | return 0; | ||
198 | } | ||
199 | |||
184 | static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) | 200 | static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) |
185 | { | 201 | { |
186 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | 202 | struct perf_evsel *evsel = list_entry(evlist->entries.next, |
@@ -309,6 +325,8 @@ static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) | |||
309 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | 325 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); |
310 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | 326 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); |
311 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | 327 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); |
328 | TEST_ASSERT_VAL("wrong name", | ||
329 | !strcmp(perf_evsel__name(evsel), "mem:0x0:rw:u")); | ||
312 | 330 | ||
313 | return test__checkevent_breakpoint(evlist); | 331 | return test__checkevent_breakpoint(evlist); |
314 | } | 332 | } |
@@ -322,6 +340,8 @@ static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) | |||
322 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | 340 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); |
323 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | 341 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); |
324 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); | 342 | TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); |
343 | TEST_ASSERT_VAL("wrong name", | ||
344 | !strcmp(perf_evsel__name(evsel), "mem:0x0:x:k")); | ||
325 | 345 | ||
326 | return test__checkevent_breakpoint_x(evlist); | 346 | return test__checkevent_breakpoint_x(evlist); |
327 | } | 347 | } |
@@ -335,6 +355,8 @@ static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) | |||
335 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | 355 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); |
336 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); | 356 | TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); |
337 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | 357 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); |
358 | TEST_ASSERT_VAL("wrong name", | ||
359 | !strcmp(perf_evsel__name(evsel), "mem:0x0:r:hp")); | ||
338 | 360 | ||
339 | return test__checkevent_breakpoint_r(evlist); | 361 | return test__checkevent_breakpoint_r(evlist); |
340 | } | 362 | } |
@@ -348,10 +370,27 @@ static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) | |||
348 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); | 370 | TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); |
349 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | 371 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); |
350 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | 372 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); |
373 | TEST_ASSERT_VAL("wrong name", | ||
374 | !strcmp(perf_evsel__name(evsel), "mem:0x0:w:up")); | ||
351 | 375 | ||
352 | return test__checkevent_breakpoint_w(evlist); | 376 | return test__checkevent_breakpoint_w(evlist); |
353 | } | 377 | } |
354 | 378 | ||
379 | static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist) | ||
380 | { | ||
381 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
382 | struct perf_evsel, node); | ||
383 | |||
384 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
385 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
386 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
387 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
388 | TEST_ASSERT_VAL("wrong name", | ||
389 | !strcmp(perf_evsel__name(evsel), "mem:0x0:rw:kp")); | ||
390 | |||
391 | return test__checkevent_breakpoint_rw(evlist); | ||
392 | } | ||
393 | |||
355 | static int test__checkevent_pmu(struct perf_evlist *evlist) | 394 | static int test__checkevent_pmu(struct perf_evlist *evlist) |
356 | { | 395 | { |
357 | 396 | ||
@@ -413,19 +452,63 @@ static int test__checkevent_pmu_name(struct perf_evlist *evlist) | |||
413 | { | 452 | { |
414 | struct perf_evsel *evsel; | 453 | struct perf_evsel *evsel; |
415 | 454 | ||
416 | /* cpu/config=1,name=krava1/u */ | 455 | /* cpu/config=1,name=krava/u */ |
417 | evsel = list_entry(evlist->entries.next, struct perf_evsel, node); | 456 | evsel = list_entry(evlist->entries.next, struct perf_evsel, node); |
418 | TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); | 457 | TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); |
419 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | 458 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); |
420 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); | 459 | TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); |
421 | TEST_ASSERT_VAL("wrong name", !strcmp(evsel->name, "krava")); | 460 | TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava")); |
422 | 461 | ||
423 | /* cpu/config=2/" */ | 462 | /* cpu/config=2/u" */ |
424 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); | 463 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); |
425 | TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); | 464 | TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); |
426 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); | 465 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); |
427 | TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); | 466 | TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); |
428 | TEST_ASSERT_VAL("wrong name", !strcmp(evsel->name, "raw 0x2")); | 467 | TEST_ASSERT_VAL("wrong name", |
468 | !strcmp(perf_evsel__name(evsel), "raw 0x2:u")); | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | static int test__checkterms_simple(struct list_head *terms) | ||
474 | { | ||
475 | struct parse_events__term *term; | ||
476 | |||
477 | /* config=10 */ | ||
478 | term = list_entry(terms->next, struct parse_events__term, list); | ||
479 | TEST_ASSERT_VAL("wrong type term", | ||
480 | term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG); | ||
481 | TEST_ASSERT_VAL("wrong type val", | ||
482 | term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); | ||
483 | TEST_ASSERT_VAL("wrong val", term->val.num == 10); | ||
484 | TEST_ASSERT_VAL("wrong config", !term->config); | ||
485 | |||
486 | /* config1 */ | ||
487 | term = list_entry(term->list.next, struct parse_events__term, list); | ||
488 | TEST_ASSERT_VAL("wrong type term", | ||
489 | term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG1); | ||
490 | TEST_ASSERT_VAL("wrong type val", | ||
491 | term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); | ||
492 | TEST_ASSERT_VAL("wrong val", term->val.num == 1); | ||
493 | TEST_ASSERT_VAL("wrong config", !term->config); | ||
494 | |||
495 | /* config2=3 */ | ||
496 | term = list_entry(term->list.next, struct parse_events__term, list); | ||
497 | TEST_ASSERT_VAL("wrong type term", | ||
498 | term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG2); | ||
499 | TEST_ASSERT_VAL("wrong type val", | ||
500 | term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); | ||
501 | TEST_ASSERT_VAL("wrong val", term->val.num == 3); | ||
502 | TEST_ASSERT_VAL("wrong config", !term->config); | ||
503 | |||
504 | /* umask=1*/ | ||
505 | term = list_entry(term->list.next, struct parse_events__term, list); | ||
506 | TEST_ASSERT_VAL("wrong type term", | ||
507 | term->type_term == PARSE_EVENTS__TERM_TYPE_USER); | ||
508 | TEST_ASSERT_VAL("wrong type val", | ||
509 | term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); | ||
510 | TEST_ASSERT_VAL("wrong val", term->val.num == 1); | ||
511 | TEST_ASSERT_VAL("wrong config", !strcmp(term->config, "umask")); | ||
429 | 512 | ||
430 | return 0; | 513 | return 0; |
431 | } | 514 | } |
@@ -541,10 +624,16 @@ static struct test__event_st test__events[] = { | |||
541 | .name = "instructions:H", | 624 | .name = "instructions:H", |
542 | .check = test__checkevent_exclude_guest_modifier, | 625 | .check = test__checkevent_exclude_guest_modifier, |
543 | }, | 626 | }, |
627 | [26] = { | ||
628 | .name = "mem:0:rw", | ||
629 | .check = test__checkevent_breakpoint_rw, | ||
630 | }, | ||
631 | [27] = { | ||
632 | .name = "mem:0:rw:kp", | ||
633 | .check = test__checkevent_breakpoint_rw_modifier, | ||
634 | }, | ||
544 | }; | 635 | }; |
545 | 636 | ||
546 | #define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st)) | ||
547 | |||
548 | static struct test__event_st test__events_pmu[] = { | 637 | static struct test__event_st test__events_pmu[] = { |
549 | [0] = { | 638 | [0] = { |
550 | .name = "cpu/config=10,config1,config2=3,period=1000/u", | 639 | .name = "cpu/config=10,config1,config2=3,period=1000/u", |
@@ -556,10 +645,23 @@ static struct test__event_st test__events_pmu[] = { | |||
556 | }, | 645 | }, |
557 | }; | 646 | }; |
558 | 647 | ||
559 | #define TEST__EVENTS_PMU_CNT (sizeof(test__events_pmu) / \ | 648 | struct test__term { |
560 | sizeof(struct test__event_st)) | 649 | const char *str; |
650 | __u32 type; | ||
651 | int (*check)(struct list_head *terms); | ||
652 | }; | ||
653 | |||
654 | static struct test__term test__terms[] = { | ||
655 | [0] = { | ||
656 | .str = "config=10,config1,config2=3,umask=1", | ||
657 | .check = test__checkterms_simple, | ||
658 | }, | ||
659 | }; | ||
660 | |||
661 | #define TEST__TERMS_CNT (sizeof(test__terms) / \ | ||
662 | sizeof(struct test__term)) | ||
561 | 663 | ||
562 | static int test(struct test__event_st *e) | 664 | static int test_event(struct test__event_st *e) |
563 | { | 665 | { |
564 | struct perf_evlist *evlist; | 666 | struct perf_evlist *evlist; |
565 | int ret; | 667 | int ret; |
@@ -590,7 +692,48 @@ static int test_events(struct test__event_st *events, unsigned cnt) | |||
590 | struct test__event_st *e = &events[i]; | 692 | struct test__event_st *e = &events[i]; |
591 | 693 | ||
592 | pr_debug("running test %d '%s'\n", i, e->name); | 694 | pr_debug("running test %d '%s'\n", i, e->name); |
593 | ret = test(e); | 695 | ret = test_event(e); |
696 | if (ret) | ||
697 | break; | ||
698 | } | ||
699 | |||
700 | return ret; | ||
701 | } | ||
702 | |||
703 | static int test_term(struct test__term *t) | ||
704 | { | ||
705 | struct list_head *terms; | ||
706 | int ret; | ||
707 | |||
708 | terms = malloc(sizeof(*terms)); | ||
709 | if (!terms) | ||
710 | return -ENOMEM; | ||
711 | |||
712 | INIT_LIST_HEAD(terms); | ||
713 | |||
714 | ret = parse_events_terms(terms, t->str); | ||
715 | if (ret) { | ||
716 | pr_debug("failed to parse terms '%s', err %d\n", | ||
717 | t->str , ret); | ||
718 | return ret; | ||
719 | } | ||
720 | |||
721 | ret = t->check(terms); | ||
722 | parse_events__free_terms(terms); | ||
723 | |||
724 | return ret; | ||
725 | } | ||
726 | |||
727 | static int test_terms(struct test__term *terms, unsigned cnt) | ||
728 | { | ||
729 | int ret = 0; | ||
730 | unsigned i; | ||
731 | |||
732 | for (i = 0; i < cnt; i++) { | ||
733 | struct test__term *t = &terms[i]; | ||
734 | |||
735 | pr_debug("running test %d '%s'\n", i, t->str); | ||
736 | ret = test_term(t); | ||
594 | if (ret) | 737 | if (ret) |
595 | break; | 738 | break; |
596 | } | 739 | } |
@@ -617,9 +760,17 @@ int parse_events__test(void) | |||
617 | { | 760 | { |
618 | int ret; | 761 | int ret; |
619 | 762 | ||
620 | ret = test_events(test__events, TEST__EVENTS_CNT); | 763 | #define TEST_EVENTS(tests) \ |
621 | if (!ret && test_pmu()) | 764 | do { \ |
622 | ret = test_events(test__events_pmu, TEST__EVENTS_PMU_CNT); | 765 | ret = test_events(tests, ARRAY_SIZE(tests)); \ |
766 | if (ret) \ | ||
767 | return ret; \ | ||
768 | } while (0) | ||
623 | 769 | ||
624 | return ret; | 770 | TEST_EVENTS(test__events); |
771 | |||
772 | if (test_pmu()) | ||
773 | TEST_EVENTS(test__events_pmu); | ||
774 | |||
775 | return test_terms(test__terms, ARRAY_SIZE(test__terms)); | ||
625 | } | 776 | } |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 05dbc8b3c767..1aa721d7c10f 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -11,14 +11,14 @@ | |||
11 | #include "cache.h" | 11 | #include "cache.h" |
12 | #include "header.h" | 12 | #include "header.h" |
13 | #include "debugfs.h" | 13 | #include "debugfs.h" |
14 | #include "parse-events-bison.h" | ||
15 | #define YY_EXTRA_TYPE int | ||
14 | #include "parse-events-flex.h" | 16 | #include "parse-events-flex.h" |
15 | #include "pmu.h" | 17 | #include "pmu.h" |
16 | 18 | ||
17 | #define MAX_NAME_LEN 100 | 19 | #define MAX_NAME_LEN 100 |
18 | 20 | ||
19 | struct event_symbol { | 21 | struct event_symbol { |
20 | u8 type; | ||
21 | u64 config; | ||
22 | const char *symbol; | 22 | const char *symbol; |
23 | const char *alias; | 23 | const char *alias; |
24 | }; | 24 | }; |
@@ -26,32 +26,88 @@ struct event_symbol { | |||
26 | #ifdef PARSER_DEBUG | 26 | #ifdef PARSER_DEBUG |
27 | extern int parse_events_debug; | 27 | extern int parse_events_debug; |
28 | #endif | 28 | #endif |
29 | int parse_events_parse(struct list_head *list, int *idx); | 29 | int parse_events_parse(void *data, void *scanner); |
30 | 30 | ||
31 | #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x | 31 | static struct event_symbol event_symbols_hw[PERF_COUNT_HW_MAX] = { |
32 | #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x | 32 | [PERF_COUNT_HW_CPU_CYCLES] = { |
33 | 33 | .symbol = "cpu-cycles", | |
34 | static struct event_symbol event_symbols[] = { | 34 | .alias = "cycles", |
35 | { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, | 35 | }, |
36 | { CHW(STALLED_CYCLES_FRONTEND), "stalled-cycles-frontend", "idle-cycles-frontend" }, | 36 | [PERF_COUNT_HW_INSTRUCTIONS] = { |
37 | { CHW(STALLED_CYCLES_BACKEND), "stalled-cycles-backend", "idle-cycles-backend" }, | 37 | .symbol = "instructions", |
38 | { CHW(INSTRUCTIONS), "instructions", "" }, | 38 | .alias = "", |
39 | { CHW(CACHE_REFERENCES), "cache-references", "" }, | 39 | }, |
40 | { CHW(CACHE_MISSES), "cache-misses", "" }, | 40 | [PERF_COUNT_HW_CACHE_REFERENCES] = { |
41 | { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, | 41 | .symbol = "cache-references", |
42 | { CHW(BRANCH_MISSES), "branch-misses", "" }, | 42 | .alias = "", |
43 | { CHW(BUS_CYCLES), "bus-cycles", "" }, | 43 | }, |
44 | { CHW(REF_CPU_CYCLES), "ref-cycles", "" }, | 44 | [PERF_COUNT_HW_CACHE_MISSES] = { |
45 | 45 | .symbol = "cache-misses", | |
46 | { CSW(CPU_CLOCK), "cpu-clock", "" }, | 46 | .alias = "", |
47 | { CSW(TASK_CLOCK), "task-clock", "" }, | 47 | }, |
48 | { CSW(PAGE_FAULTS), "page-faults", "faults" }, | 48 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { |
49 | { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, | 49 | .symbol = "branch-instructions", |
50 | { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, | 50 | .alias = "branches", |
51 | { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, | 51 | }, |
52 | { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, | 52 | [PERF_COUNT_HW_BRANCH_MISSES] = { |
53 | { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" }, | 53 | .symbol = "branch-misses", |
54 | { CSW(EMULATION_FAULTS), "emulation-faults", "" }, | 54 | .alias = "", |
55 | }, | ||
56 | [PERF_COUNT_HW_BUS_CYCLES] = { | ||
57 | .symbol = "bus-cycles", | ||
58 | .alias = "", | ||
59 | }, | ||
60 | [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = { | ||
61 | .symbol = "stalled-cycles-frontend", | ||
62 | .alias = "idle-cycles-frontend", | ||
63 | }, | ||
64 | [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = { | ||
65 | .symbol = "stalled-cycles-backend", | ||
66 | .alias = "idle-cycles-backend", | ||
67 | }, | ||
68 | [PERF_COUNT_HW_REF_CPU_CYCLES] = { | ||
69 | .symbol = "ref-cycles", | ||
70 | .alias = "", | ||
71 | }, | ||
72 | }; | ||
73 | |||
74 | static struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = { | ||
75 | [PERF_COUNT_SW_CPU_CLOCK] = { | ||
76 | .symbol = "cpu-clock", | ||
77 | .alias = "", | ||
78 | }, | ||
79 | [PERF_COUNT_SW_TASK_CLOCK] = { | ||
80 | .symbol = "task-clock", | ||
81 | .alias = "", | ||
82 | }, | ||
83 | [PERF_COUNT_SW_PAGE_FAULTS] = { | ||
84 | .symbol = "page-faults", | ||
85 | .alias = "faults", | ||
86 | }, | ||
87 | [PERF_COUNT_SW_CONTEXT_SWITCHES] = { | ||
88 | .symbol = "context-switches", | ||
89 | .alias = "cs", | ||
90 | }, | ||
91 | [PERF_COUNT_SW_CPU_MIGRATIONS] = { | ||
92 | .symbol = "cpu-migrations", | ||
93 | .alias = "migrations", | ||
94 | }, | ||
95 | [PERF_COUNT_SW_PAGE_FAULTS_MIN] = { | ||
96 | .symbol = "minor-faults", | ||
97 | .alias = "", | ||
98 | }, | ||
99 | [PERF_COUNT_SW_PAGE_FAULTS_MAJ] = { | ||
100 | .symbol = "major-faults", | ||
101 | .alias = "", | ||
102 | }, | ||
103 | [PERF_COUNT_SW_ALIGNMENT_FAULTS] = { | ||
104 | .symbol = "alignment-faults", | ||
105 | .alias = "", | ||
106 | }, | ||
107 | [PERF_COUNT_SW_EMULATION_FAULTS] = { | ||
108 | .symbol = "emulation-faults", | ||
109 | .alias = "", | ||
110 | }, | ||
55 | }; | 111 | }; |
56 | 112 | ||
57 | #define __PERF_EVENT_FIELD(config, name) \ | 113 | #define __PERF_EVENT_FIELD(config, name) \ |
@@ -62,63 +118,6 @@ static struct event_symbol event_symbols[] = { | |||
62 | #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) | 118 | #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) |
63 | #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) | 119 | #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) |
64 | 120 | ||
65 | static const char *sw_event_names[PERF_COUNT_SW_MAX] = { | ||
66 | "cpu-clock", | ||
67 | "task-clock", | ||
68 | "page-faults", | ||
69 | "context-switches", | ||
70 | "CPU-migrations", | ||
71 | "minor-faults", | ||
72 | "major-faults", | ||
73 | "alignment-faults", | ||
74 | "emulation-faults", | ||
75 | }; | ||
76 | |||
77 | #define MAX_ALIASES 8 | ||
78 | |||
79 | static const char *hw_cache[PERF_COUNT_HW_CACHE_MAX][MAX_ALIASES] = { | ||
80 | { "L1-dcache", "l1-d", "l1d", "L1-data", }, | ||
81 | { "L1-icache", "l1-i", "l1i", "L1-instruction", }, | ||
82 | { "LLC", "L2", }, | ||
83 | { "dTLB", "d-tlb", "Data-TLB", }, | ||
84 | { "iTLB", "i-tlb", "Instruction-TLB", }, | ||
85 | { "branch", "branches", "bpu", "btb", "bpc", }, | ||
86 | { "node", }, | ||
87 | }; | ||
88 | |||
89 | static const char *hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX][MAX_ALIASES] = { | ||
90 | { "load", "loads", "read", }, | ||
91 | { "store", "stores", "write", }, | ||
92 | { "prefetch", "prefetches", "speculative-read", "speculative-load", }, | ||
93 | }; | ||
94 | |||
95 | static const char *hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] | ||
96 | [MAX_ALIASES] = { | ||
97 | { "refs", "Reference", "ops", "access", }, | ||
98 | { "misses", "miss", }, | ||
99 | }; | ||
100 | |||
101 | #define C(x) PERF_COUNT_HW_CACHE_##x | ||
102 | #define CACHE_READ (1 << C(OP_READ)) | ||
103 | #define CACHE_WRITE (1 << C(OP_WRITE)) | ||
104 | #define CACHE_PREFETCH (1 << C(OP_PREFETCH)) | ||
105 | #define COP(x) (1 << x) | ||
106 | |||
107 | /* | ||
108 | * cache operartion stat | ||
109 | * L1I : Read and prefetch only | ||
110 | * ITLB and BPU : Read-only | ||
111 | */ | ||
112 | static unsigned long hw_cache_stat[C(MAX)] = { | ||
113 | [C(L1D)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), | ||
114 | [C(L1I)] = (CACHE_READ | CACHE_PREFETCH), | ||
115 | [C(LL)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), | ||
116 | [C(DTLB)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), | ||
117 | [C(ITLB)] = (CACHE_READ), | ||
118 | [C(BPU)] = (CACHE_READ), | ||
119 | [C(NODE)] = (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH), | ||
120 | }; | ||
121 | |||
122 | #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ | 121 | #define for_each_subsystem(sys_dir, sys_dirent, sys_next) \ |
123 | while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ | 122 | while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ |
124 | if (sys_dirent.d_type == DT_DIR && \ | 123 | if (sys_dirent.d_type == DT_DIR && \ |
@@ -218,48 +217,6 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config) | |||
218 | return NULL; | 217 | return NULL; |
219 | } | 218 | } |
220 | 219 | ||
221 | #define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1) | ||
222 | static const char *tracepoint_id_to_name(u64 config) | ||
223 | { | ||
224 | static char buf[TP_PATH_LEN]; | ||
225 | struct tracepoint_path *path; | ||
226 | |||
227 | path = tracepoint_id_to_path(config); | ||
228 | if (path) { | ||
229 | snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name); | ||
230 | free(path->name); | ||
231 | free(path->system); | ||
232 | free(path); | ||
233 | } else | ||
234 | snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown"); | ||
235 | |||
236 | return buf; | ||
237 | } | ||
238 | |||
239 | static int is_cache_op_valid(u8 cache_type, u8 cache_op) | ||
240 | { | ||
241 | if (hw_cache_stat[cache_type] & COP(cache_op)) | ||
242 | return 1; /* valid */ | ||
243 | else | ||
244 | return 0; /* invalid */ | ||
245 | } | ||
246 | |||
247 | static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result) | ||
248 | { | ||
249 | static char name[50]; | ||
250 | |||
251 | if (cache_result) { | ||
252 | sprintf(name, "%s-%s-%s", hw_cache[cache_type][0], | ||
253 | hw_cache_op[cache_op][0], | ||
254 | hw_cache_result[cache_result][0]); | ||
255 | } else { | ||
256 | sprintf(name, "%s-%s", hw_cache[cache_type][0], | ||
257 | hw_cache_op[cache_op][1]); | ||
258 | } | ||
259 | |||
260 | return name; | ||
261 | } | ||
262 | |||
263 | const char *event_type(int type) | 220 | const char *event_type(int type) |
264 | { | 221 | { |
265 | switch (type) { | 222 | switch (type) { |
@@ -282,76 +239,6 @@ const char *event_type(int type) | |||
282 | return "unknown"; | 239 | return "unknown"; |
283 | } | 240 | } |
284 | 241 | ||
285 | const char *event_name(struct perf_evsel *evsel) | ||
286 | { | ||
287 | u64 config = evsel->attr.config; | ||
288 | int type = evsel->attr.type; | ||
289 | |||
290 | if (type == PERF_TYPE_RAW || type == PERF_TYPE_HARDWARE) { | ||
291 | /* | ||
292 | * XXX minimal fix, see comment on perf_evsen__name, this static buffer | ||
293 | * will go away together with event_name in the next devel cycle. | ||
294 | */ | ||
295 | static char bf[128]; | ||
296 | perf_evsel__name(evsel, bf, sizeof(bf)); | ||
297 | return bf; | ||
298 | } | ||
299 | |||
300 | if (evsel->name) | ||
301 | return evsel->name; | ||
302 | |||
303 | return __event_name(type, config); | ||
304 | } | ||
305 | |||
306 | const char *__event_name(int type, u64 config) | ||
307 | { | ||
308 | static char buf[32]; | ||
309 | |||
310 | if (type == PERF_TYPE_RAW) { | ||
311 | sprintf(buf, "raw 0x%" PRIx64, config); | ||
312 | return buf; | ||
313 | } | ||
314 | |||
315 | switch (type) { | ||
316 | case PERF_TYPE_HARDWARE: | ||
317 | return __perf_evsel__hw_name(config); | ||
318 | |||
319 | case PERF_TYPE_HW_CACHE: { | ||
320 | u8 cache_type, cache_op, cache_result; | ||
321 | |||
322 | cache_type = (config >> 0) & 0xff; | ||
323 | if (cache_type > PERF_COUNT_HW_CACHE_MAX) | ||
324 | return "unknown-ext-hardware-cache-type"; | ||
325 | |||
326 | cache_op = (config >> 8) & 0xff; | ||
327 | if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX) | ||
328 | return "unknown-ext-hardware-cache-op"; | ||
329 | |||
330 | cache_result = (config >> 16) & 0xff; | ||
331 | if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX) | ||
332 | return "unknown-ext-hardware-cache-result"; | ||
333 | |||
334 | if (!is_cache_op_valid(cache_type, cache_op)) | ||
335 | return "invalid-cache"; | ||
336 | |||
337 | return event_cache_name(cache_type, cache_op, cache_result); | ||
338 | } | ||
339 | |||
340 | case PERF_TYPE_SOFTWARE: | ||
341 | if (config < PERF_COUNT_SW_MAX && sw_event_names[config]) | ||
342 | return sw_event_names[config]; | ||
343 | return "unknown-software"; | ||
344 | |||
345 | case PERF_TYPE_TRACEPOINT: | ||
346 | return tracepoint_id_to_name(config); | ||
347 | |||
348 | default: | ||
349 | break; | ||
350 | } | ||
351 | |||
352 | return "unknown"; | ||
353 | } | ||
354 | |||
355 | static int add_event(struct list_head **_list, int *idx, | 242 | static int add_event(struct list_head **_list, int *idx, |
356 | struct perf_event_attr *attr, char *name) | 243 | struct perf_event_attr *attr, char *name) |
357 | { | 244 | { |
@@ -373,19 +260,20 @@ static int add_event(struct list_head **_list, int *idx, | |||
373 | return -ENOMEM; | 260 | return -ENOMEM; |
374 | } | 261 | } |
375 | 262 | ||
376 | evsel->name = strdup(name); | 263 | if (name) |
264 | evsel->name = strdup(name); | ||
377 | list_add_tail(&evsel->node, list); | 265 | list_add_tail(&evsel->node, list); |
378 | *_list = list; | 266 | *_list = list; |
379 | return 0; | 267 | return 0; |
380 | } | 268 | } |
381 | 269 | ||
382 | static int parse_aliases(char *str, const char *names[][MAX_ALIASES], int size) | 270 | static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) |
383 | { | 271 | { |
384 | int i, j; | 272 | int i, j; |
385 | int n, longest = -1; | 273 | int n, longest = -1; |
386 | 274 | ||
387 | for (i = 0; i < size; i++) { | 275 | for (i = 0; i < size; i++) { |
388 | for (j = 0; j < MAX_ALIASES && names[i][j]; j++) { | 276 | for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) { |
389 | n = strlen(names[i][j]); | 277 | n = strlen(names[i][j]); |
390 | if (n > longest && !strncasecmp(str, names[i][j], n)) | 278 | if (n > longest && !strncasecmp(str, names[i][j], n)) |
391 | longest = n; | 279 | longest = n; |
@@ -410,7 +298,7 @@ int parse_events_add_cache(struct list_head **list, int *idx, | |||
410 | * No fallback - if we cannot get a clear cache type | 298 | * No fallback - if we cannot get a clear cache type |
411 | * then bail out: | 299 | * then bail out: |
412 | */ | 300 | */ |
413 | cache_type = parse_aliases(type, hw_cache, | 301 | cache_type = parse_aliases(type, perf_evsel__hw_cache, |
414 | PERF_COUNT_HW_CACHE_MAX); | 302 | PERF_COUNT_HW_CACHE_MAX); |
415 | if (cache_type == -1) | 303 | if (cache_type == -1) |
416 | return -EINVAL; | 304 | return -EINVAL; |
@@ -423,18 +311,18 @@ int parse_events_add_cache(struct list_head **list, int *idx, | |||
423 | snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str); | 311 | snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str); |
424 | 312 | ||
425 | if (cache_op == -1) { | 313 | if (cache_op == -1) { |
426 | cache_op = parse_aliases(str, hw_cache_op, | 314 | cache_op = parse_aliases(str, perf_evsel__hw_cache_op, |
427 | PERF_COUNT_HW_CACHE_OP_MAX); | 315 | PERF_COUNT_HW_CACHE_OP_MAX); |
428 | if (cache_op >= 0) { | 316 | if (cache_op >= 0) { |
429 | if (!is_cache_op_valid(cache_type, cache_op)) | 317 | if (!perf_evsel__is_cache_op_valid(cache_type, cache_op)) |
430 | return -EINVAL; | 318 | return -EINVAL; |
431 | continue; | 319 | continue; |
432 | } | 320 | } |
433 | } | 321 | } |
434 | 322 | ||
435 | if (cache_result == -1) { | 323 | if (cache_result == -1) { |
436 | cache_result = parse_aliases(str, hw_cache_result, | 324 | cache_result = parse_aliases(str, perf_evsel__hw_cache_result, |
437 | PERF_COUNT_HW_CACHE_RESULT_MAX); | 325 | PERF_COUNT_HW_CACHE_RESULT_MAX); |
438 | if (cache_result >= 0) | 326 | if (cache_result >= 0) |
439 | continue; | 327 | continue; |
440 | } | 328 | } |
@@ -549,21 +437,31 @@ parse_breakpoint_type(const char *type, struct perf_event_attr *attr) | |||
549 | if (!type || !type[i]) | 437 | if (!type || !type[i]) |
550 | break; | 438 | break; |
551 | 439 | ||
440 | #define CHECK_SET_TYPE(bit) \ | ||
441 | do { \ | ||
442 | if (attr->bp_type & bit) \ | ||
443 | return -EINVAL; \ | ||
444 | else \ | ||
445 | attr->bp_type |= bit; \ | ||
446 | } while (0) | ||
447 | |||
552 | switch (type[i]) { | 448 | switch (type[i]) { |
553 | case 'r': | 449 | case 'r': |
554 | attr->bp_type |= HW_BREAKPOINT_R; | 450 | CHECK_SET_TYPE(HW_BREAKPOINT_R); |
555 | break; | 451 | break; |
556 | case 'w': | 452 | case 'w': |
557 | attr->bp_type |= HW_BREAKPOINT_W; | 453 | CHECK_SET_TYPE(HW_BREAKPOINT_W); |
558 | break; | 454 | break; |
559 | case 'x': | 455 | case 'x': |
560 | attr->bp_type |= HW_BREAKPOINT_X; | 456 | CHECK_SET_TYPE(HW_BREAKPOINT_X); |
561 | break; | 457 | break; |
562 | default: | 458 | default: |
563 | return -EINVAL; | 459 | return -EINVAL; |
564 | } | 460 | } |
565 | } | 461 | } |
566 | 462 | ||
463 | #undef CHECK_SET_TYPE | ||
464 | |||
567 | if (!attr->bp_type) /* Default */ | 465 | if (!attr->bp_type) /* Default */ |
568 | attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; | 466 | attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; |
569 | 467 | ||
@@ -574,7 +472,6 @@ int parse_events_add_breakpoint(struct list_head **list, int *idx, | |||
574 | void *ptr, char *type) | 472 | void *ptr, char *type) |
575 | { | 473 | { |
576 | struct perf_event_attr attr; | 474 | struct perf_event_attr attr; |
577 | char name[MAX_NAME_LEN]; | ||
578 | 475 | ||
579 | memset(&attr, 0, sizeof(attr)); | 476 | memset(&attr, 0, sizeof(attr)); |
580 | attr.bp_addr = (unsigned long) ptr; | 477 | attr.bp_addr = (unsigned long) ptr; |
@@ -593,8 +490,7 @@ int parse_events_add_breakpoint(struct list_head **list, int *idx, | |||
593 | 490 | ||
594 | attr.type = PERF_TYPE_BREAKPOINT; | 491 | attr.type = PERF_TYPE_BREAKPOINT; |
595 | 492 | ||
596 | snprintf(name, MAX_NAME_LEN, "mem:%p:%s", ptr, type ? type : "rw"); | 493 | return add_event(list, idx, &attr, NULL); |
597 | return add_event(list, idx, &attr, name); | ||
598 | } | 494 | } |
599 | 495 | ||
600 | static int config_term(struct perf_event_attr *attr, | 496 | static int config_term(struct perf_event_attr *attr, |
@@ -666,8 +562,7 @@ int parse_events_add_numeric(struct list_head **list, int *idx, | |||
666 | config_attr(&attr, head_config, 1)) | 562 | config_attr(&attr, head_config, 1)) |
667 | return -EINVAL; | 563 | return -EINVAL; |
668 | 564 | ||
669 | return add_event(list, idx, &attr, | 565 | return add_event(list, idx, &attr, NULL); |
670 | (char *) __event_name(type, config)); | ||
671 | } | 566 | } |
672 | 567 | ||
673 | static int parse_events__is_name_term(struct parse_events__term *term) | 568 | static int parse_events__is_name_term(struct parse_events__term *term) |
@@ -675,8 +570,7 @@ static int parse_events__is_name_term(struct parse_events__term *term) | |||
675 | return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME; | 570 | return term->type_term == PARSE_EVENTS__TERM_TYPE_NAME; |
676 | } | 571 | } |
677 | 572 | ||
678 | static char *pmu_event_name(struct perf_event_attr *attr, | 573 | static char *pmu_event_name(struct list_head *head_terms) |
679 | struct list_head *head_terms) | ||
680 | { | 574 | { |
681 | struct parse_events__term *term; | 575 | struct parse_events__term *term; |
682 | 576 | ||
@@ -684,7 +578,7 @@ static char *pmu_event_name(struct perf_event_attr *attr, | |||
684 | if (parse_events__is_name_term(term)) | 578 | if (parse_events__is_name_term(term)) |
685 | return term->val.str; | 579 | return term->val.str; |
686 | 580 | ||
687 | return (char *) __event_name(PERF_TYPE_RAW, attr->config); | 581 | return NULL; |
688 | } | 582 | } |
689 | 583 | ||
690 | int parse_events_add_pmu(struct list_head **list, int *idx, | 584 | int parse_events_add_pmu(struct list_head **list, int *idx, |
@@ -699,6 +593,9 @@ int parse_events_add_pmu(struct list_head **list, int *idx, | |||
699 | 593 | ||
700 | memset(&attr, 0, sizeof(attr)); | 594 | memset(&attr, 0, sizeof(attr)); |
701 | 595 | ||
596 | if (perf_pmu__check_alias(pmu, head_config)) | ||
597 | return -EINVAL; | ||
598 | |||
702 | /* | 599 | /* |
703 | * Configure hardcoded terms first, no need to check | 600 | * Configure hardcoded terms first, no need to check |
704 | * return value when called with fail == 0 ;) | 601 | * return value when called with fail == 0 ;) |
@@ -709,7 +606,7 @@ int parse_events_add_pmu(struct list_head **list, int *idx, | |||
709 | return -EINVAL; | 606 | return -EINVAL; |
710 | 607 | ||
711 | return add_event(list, idx, &attr, | 608 | return add_event(list, idx, &attr, |
712 | pmu_event_name(&attr, head_config)); | 609 | pmu_event_name(head_config)); |
713 | } | 610 | } |
714 | 611 | ||
715 | void parse_events_update_lists(struct list_head *list_event, | 612 | void parse_events_update_lists(struct list_head *list_event, |
@@ -787,27 +684,62 @@ int parse_events_modifier(struct list_head *list, char *str) | |||
787 | return 0; | 684 | return 0; |
788 | } | 685 | } |
789 | 686 | ||
790 | int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) | 687 | static int parse_events__scanner(const char *str, void *data, int start_token) |
791 | { | 688 | { |
792 | LIST_HEAD(list); | ||
793 | LIST_HEAD(list_tmp); | ||
794 | YY_BUFFER_STATE buffer; | 689 | YY_BUFFER_STATE buffer; |
795 | int ret, idx = evlist->nr_entries; | 690 | void *scanner; |
691 | int ret; | ||
692 | |||
693 | ret = parse_events_lex_init_extra(start_token, &scanner); | ||
694 | if (ret) | ||
695 | return ret; | ||
796 | 696 | ||
797 | buffer = parse_events__scan_string(str); | 697 | buffer = parse_events__scan_string(str, scanner); |
798 | 698 | ||
799 | #ifdef PARSER_DEBUG | 699 | #ifdef PARSER_DEBUG |
800 | parse_events_debug = 1; | 700 | parse_events_debug = 1; |
801 | #endif | 701 | #endif |
802 | ret = parse_events_parse(&list, &idx); | 702 | ret = parse_events_parse(data, scanner); |
803 | 703 | ||
804 | parse_events__flush_buffer(buffer); | 704 | parse_events__flush_buffer(buffer, scanner); |
805 | parse_events__delete_buffer(buffer); | 705 | parse_events__delete_buffer(buffer, scanner); |
806 | parse_events_lex_destroy(); | 706 | parse_events_lex_destroy(scanner); |
707 | return ret; | ||
708 | } | ||
709 | |||
710 | /* | ||
711 | * parse event config string, return a list of event terms. | ||
712 | */ | ||
713 | int parse_events_terms(struct list_head *terms, const char *str) | ||
714 | { | ||
715 | struct parse_events_data__terms data = { | ||
716 | .terms = NULL, | ||
717 | }; | ||
718 | int ret; | ||
807 | 719 | ||
720 | ret = parse_events__scanner(str, &data, PE_START_TERMS); | ||
808 | if (!ret) { | 721 | if (!ret) { |
809 | int entries = idx - evlist->nr_entries; | 722 | list_splice(data.terms, terms); |
810 | perf_evlist__splice_list_tail(evlist, &list, entries); | 723 | free(data.terms); |
724 | return 0; | ||
725 | } | ||
726 | |||
727 | parse_events__free_terms(data.terms); | ||
728 | return ret; | ||
729 | } | ||
730 | |||
731 | int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) | ||
732 | { | ||
733 | struct parse_events_data__events data = { | ||
734 | .list = LIST_HEAD_INIT(data.list), | ||
735 | .idx = evlist->nr_entries, | ||
736 | }; | ||
737 | int ret; | ||
738 | |||
739 | ret = parse_events__scanner(str, &data, PE_START_EVENTS); | ||
740 | if (!ret) { | ||
741 | int entries = data.idx - evlist->nr_entries; | ||
742 | perf_evlist__splice_list_tail(evlist, &data.list, entries); | ||
811 | return 0; | 743 | return 0; |
812 | } | 744 | } |
813 | 745 | ||
@@ -946,16 +878,13 @@ int is_valid_tracepoint(const char *event_string) | |||
946 | return 0; | 878 | return 0; |
947 | } | 879 | } |
948 | 880 | ||
949 | void print_events_type(u8 type) | 881 | static void __print_events_type(u8 type, struct event_symbol *syms, |
882 | unsigned max) | ||
950 | { | 883 | { |
951 | struct event_symbol *syms = event_symbols; | ||
952 | unsigned int i; | ||
953 | char name[64]; | 884 | char name[64]; |
885 | unsigned i; | ||
954 | 886 | ||
955 | for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { | 887 | for (i = 0; i < max ; i++, syms++) { |
956 | if (type != syms->type) | ||
957 | continue; | ||
958 | |||
959 | if (strlen(syms->alias)) | 888 | if (strlen(syms->alias)) |
960 | snprintf(name, sizeof(name), "%s OR %s", | 889 | snprintf(name, sizeof(name), "%s OR %s", |
961 | syms->symbol, syms->alias); | 890 | syms->symbol, syms->alias); |
@@ -967,19 +896,28 @@ void print_events_type(u8 type) | |||
967 | } | 896 | } |
968 | } | 897 | } |
969 | 898 | ||
899 | void print_events_type(u8 type) | ||
900 | { | ||
901 | if (type == PERF_TYPE_SOFTWARE) | ||
902 | __print_events_type(type, event_symbols_sw, PERF_COUNT_SW_MAX); | ||
903 | else | ||
904 | __print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX); | ||
905 | } | ||
906 | |||
970 | int print_hwcache_events(const char *event_glob) | 907 | int print_hwcache_events(const char *event_glob) |
971 | { | 908 | { |
972 | unsigned int type, op, i, printed = 0; | 909 | unsigned int type, op, i, printed = 0; |
910 | char name[64]; | ||
973 | 911 | ||
974 | for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { | 912 | for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { |
975 | for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { | 913 | for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { |
976 | /* skip invalid cache type */ | 914 | /* skip invalid cache type */ |
977 | if (!is_cache_op_valid(type, op)) | 915 | if (!perf_evsel__is_cache_op_valid(type, op)) |
978 | continue; | 916 | continue; |
979 | 917 | ||
980 | for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { | 918 | for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { |
981 | char *name = event_cache_name(type, op, i); | 919 | __perf_evsel__hw_cache_type_op_res_name(type, op, i, |
982 | 920 | name, sizeof(name)); | |
983 | if (event_glob != NULL && !strglobmatch(name, event_glob)) | 921 | if (event_glob != NULL && !strglobmatch(name, event_glob)) |
984 | continue; | 922 | continue; |
985 | 923 | ||
@@ -993,26 +931,13 @@ int print_hwcache_events(const char *event_glob) | |||
993 | return printed; | 931 | return printed; |
994 | } | 932 | } |
995 | 933 | ||
996 | /* | 934 | static void print_symbol_events(const char *event_glob, unsigned type, |
997 | * Print the help text for the event symbols: | 935 | struct event_symbol *syms, unsigned max) |
998 | */ | ||
999 | void print_events(const char *event_glob) | ||
1000 | { | 936 | { |
1001 | unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0; | 937 | unsigned i, printed = 0; |
1002 | struct event_symbol *syms = event_symbols; | ||
1003 | char name[MAX_NAME_LEN]; | 938 | char name[MAX_NAME_LEN]; |
1004 | 939 | ||
1005 | printf("\n"); | 940 | for (i = 0; i < max; i++, syms++) { |
1006 | printf("List of pre-defined events (to be used in -e):\n"); | ||
1007 | |||
1008 | for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) { | ||
1009 | type = syms->type; | ||
1010 | |||
1011 | if (type != prev_type && printed) { | ||
1012 | printf("\n"); | ||
1013 | printed = 0; | ||
1014 | ntypes_printed++; | ||
1015 | } | ||
1016 | 941 | ||
1017 | if (event_glob != NULL && | 942 | if (event_glob != NULL && |
1018 | !(strglobmatch(syms->symbol, event_glob) || | 943 | !(strglobmatch(syms->symbol, event_glob) || |
@@ -1023,17 +948,31 @@ void print_events(const char *event_glob) | |||
1023 | snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); | 948 | snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); |
1024 | else | 949 | else |
1025 | strncpy(name, syms->symbol, MAX_NAME_LEN); | 950 | strncpy(name, syms->symbol, MAX_NAME_LEN); |
1026 | printf(" %-50s [%s]\n", name, | ||
1027 | event_type_descriptors[type]); | ||
1028 | 951 | ||
1029 | prev_type = type; | 952 | printf(" %-50s [%s]\n", name, event_type_descriptors[type]); |
1030 | ++printed; | 953 | |
954 | printed++; | ||
1031 | } | 955 | } |
1032 | 956 | ||
1033 | if (ntypes_printed) { | 957 | if (printed) |
1034 | printed = 0; | ||
1035 | printf("\n"); | 958 | printf("\n"); |
1036 | } | 959 | } |
960 | |||
961 | /* | ||
962 | * Print the help text for the event symbols: | ||
963 | */ | ||
964 | void print_events(const char *event_glob) | ||
965 | { | ||
966 | |||
967 | printf("\n"); | ||
968 | printf("List of pre-defined events (to be used in -e):\n"); | ||
969 | |||
970 | print_symbol_events(event_glob, PERF_TYPE_HARDWARE, | ||
971 | event_symbols_hw, PERF_COUNT_HW_MAX); | ||
972 | |||
973 | print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, | ||
974 | event_symbols_sw, PERF_COUNT_SW_MAX); | ||
975 | |||
1037 | print_hwcache_events(event_glob); | 976 | print_hwcache_events(event_glob); |
1038 | 977 | ||
1039 | if (event_glob != NULL) | 978 | if (event_glob != NULL) |
@@ -1106,6 +1045,13 @@ int parse_events__term_str(struct parse_events__term **term, | |||
1106 | config, str, 0); | 1045 | config, str, 0); |
1107 | } | 1046 | } |
1108 | 1047 | ||
1048 | int parse_events__term_clone(struct parse_events__term **new, | ||
1049 | struct parse_events__term *term) | ||
1050 | { | ||
1051 | return new_term(new, term->type_val, term->type_term, term->config, | ||
1052 | term->val.str, term->val.num); | ||
1053 | } | ||
1054 | |||
1109 | void parse_events__free_terms(struct list_head *terms) | 1055 | void parse_events__free_terms(struct list_head *terms) |
1110 | { | 1056 | { |
1111 | struct parse_events__term *term, *h; | 1057 | struct parse_events__term *term, *h; |
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 8cac57ab4ee6..ee9c218a193c 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
@@ -26,13 +26,12 @@ extern struct tracepoint_path *tracepoint_id_to_path(u64 config); | |||
26 | extern bool have_tracepoints(struct list_head *evlist); | 26 | extern bool have_tracepoints(struct list_head *evlist); |
27 | 27 | ||
28 | const char *event_type(int type); | 28 | const char *event_type(int type); |
29 | const char *event_name(struct perf_evsel *event); | ||
30 | extern const char *__event_name(int type, u64 config); | ||
31 | 29 | ||
32 | extern int parse_events_option(const struct option *opt, const char *str, | 30 | extern int parse_events_option(const struct option *opt, const char *str, |
33 | int unset); | 31 | int unset); |
34 | extern int parse_events(struct perf_evlist *evlist, const char *str, | 32 | extern int parse_events(struct perf_evlist *evlist, const char *str, |
35 | int unset); | 33 | int unset); |
34 | extern int parse_events_terms(struct list_head *terms, const char *str); | ||
36 | extern int parse_filter(const struct option *opt, const char *str, int unset); | 35 | extern int parse_filter(const struct option *opt, const char *str, int unset); |
37 | 36 | ||
38 | #define EVENTS_HELP_MAX (128*1024) | 37 | #define EVENTS_HELP_MAX (128*1024) |
@@ -63,11 +62,22 @@ struct parse_events__term { | |||
63 | struct list_head list; | 62 | struct list_head list; |
64 | }; | 63 | }; |
65 | 64 | ||
65 | struct parse_events_data__events { | ||
66 | struct list_head list; | ||
67 | int idx; | ||
68 | }; | ||
69 | |||
70 | struct parse_events_data__terms { | ||
71 | struct list_head *terms; | ||
72 | }; | ||
73 | |||
66 | int parse_events__is_hardcoded_term(struct parse_events__term *term); | 74 | int parse_events__is_hardcoded_term(struct parse_events__term *term); |
67 | int parse_events__term_num(struct parse_events__term **_term, | 75 | int parse_events__term_num(struct parse_events__term **_term, |
68 | int type_term, char *config, long num); | 76 | int type_term, char *config, long num); |
69 | int parse_events__term_str(struct parse_events__term **_term, | 77 | int parse_events__term_str(struct parse_events__term **_term, |
70 | int type_term, char *config, char *str); | 78 | int type_term, char *config, char *str); |
79 | int parse_events__term_clone(struct parse_events__term **new, | ||
80 | struct parse_events__term *term); | ||
71 | void parse_events__free_terms(struct list_head *terms); | 81 | void parse_events__free_terms(struct list_head *terms); |
72 | int parse_events_modifier(struct list_head *list, char *str); | 82 | int parse_events_modifier(struct list_head *list, char *str); |
73 | int parse_events_add_tracepoint(struct list_head **list, int *idx, | 83 | int parse_events_add_tracepoint(struct list_head **list, int *idx, |
@@ -83,8 +93,7 @@ int parse_events_add_pmu(struct list_head **list, int *idx, | |||
83 | char *pmu , struct list_head *head_config); | 93 | char *pmu , struct list_head *head_config); |
84 | void parse_events_update_lists(struct list_head *list_event, | 94 | void parse_events_update_lists(struct list_head *list_event, |
85 | struct list_head *list_all); | 95 | struct list_head *list_all); |
86 | void parse_events_error(struct list_head *list_all, | 96 | void parse_events_error(void *data, void *scanner, char const *msg); |
87 | int *idx, char const *msg); | ||
88 | int parse_events__test(void); | 97 | int parse_events__test(void); |
89 | 98 | ||
90 | void print_events(const char *event_glob); | 99 | void print_events(const char *event_glob); |
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 618a8e788399..384ca74c6b22 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l | |||
@@ -1,4 +1,6 @@ | |||
1 | 1 | ||
2 | %option reentrant | ||
3 | %option bison-bridge | ||
2 | %option prefix="parse_events_" | 4 | %option prefix="parse_events_" |
3 | %option stack | 5 | %option stack |
4 | 6 | ||
@@ -8,7 +10,10 @@ | |||
8 | #include "parse-events-bison.h" | 10 | #include "parse-events-bison.h" |
9 | #include "parse-events.h" | 11 | #include "parse-events.h" |
10 | 12 | ||
11 | static int __value(char *str, int base, int token) | 13 | char *parse_events_get_text(yyscan_t yyscanner); |
14 | YYSTYPE *parse_events_get_lval(yyscan_t yyscanner); | ||
15 | |||
16 | static int __value(YYSTYPE *yylval, char *str, int base, int token) | ||
12 | { | 17 | { |
13 | long num; | 18 | long num; |
14 | 19 | ||
@@ -17,35 +22,48 @@ static int __value(char *str, int base, int token) | |||
17 | if (errno) | 22 | if (errno) |
18 | return PE_ERROR; | 23 | return PE_ERROR; |
19 | 24 | ||
20 | parse_events_lval.num = num; | 25 | yylval->num = num; |
21 | return token; | 26 | return token; |
22 | } | 27 | } |
23 | 28 | ||
24 | static int value(int base) | 29 | static int value(yyscan_t scanner, int base) |
25 | { | 30 | { |
26 | return __value(parse_events_text, base, PE_VALUE); | 31 | YYSTYPE *yylval = parse_events_get_lval(scanner); |
32 | char *text = parse_events_get_text(scanner); | ||
33 | |||
34 | return __value(yylval, text, base, PE_VALUE); | ||
27 | } | 35 | } |
28 | 36 | ||
29 | static int raw(void) | 37 | static int raw(yyscan_t scanner) |
30 | { | 38 | { |
31 | return __value(parse_events_text + 1, 16, PE_RAW); | 39 | YYSTYPE *yylval = parse_events_get_lval(scanner); |
40 | char *text = parse_events_get_text(scanner); | ||
41 | |||
42 | return __value(yylval, text + 1, 16, PE_RAW); | ||
32 | } | 43 | } |
33 | 44 | ||
34 | static int str(int token) | 45 | static int str(yyscan_t scanner, int token) |
35 | { | 46 | { |
36 | parse_events_lval.str = strdup(parse_events_text); | 47 | YYSTYPE *yylval = parse_events_get_lval(scanner); |
48 | char *text = parse_events_get_text(scanner); | ||
49 | |||
50 | yylval->str = strdup(text); | ||
37 | return token; | 51 | return token; |
38 | } | 52 | } |
39 | 53 | ||
40 | static int sym(int type, int config) | 54 | static int sym(yyscan_t scanner, int type, int config) |
41 | { | 55 | { |
42 | parse_events_lval.num = (type << 16) + config; | 56 | YYSTYPE *yylval = parse_events_get_lval(scanner); |
43 | return PE_VALUE_SYM; | 57 | |
58 | yylval->num = (type << 16) + config; | ||
59 | return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW; | ||
44 | } | 60 | } |
45 | 61 | ||
46 | static int term(int type) | 62 | static int term(yyscan_t scanner, int type) |
47 | { | 63 | { |
48 | parse_events_lval.num = type; | 64 | YYSTYPE *yylval = parse_events_get_lval(scanner); |
65 | |||
66 | yylval->num = type; | ||
49 | return PE_TERM; | 67 | return PE_TERM; |
50 | } | 68 | } |
51 | 69 | ||
@@ -58,28 +76,41 @@ num_hex 0x[a-fA-F0-9]+ | |||
58 | num_raw_hex [a-fA-F0-9]+ | 76 | num_raw_hex [a-fA-F0-9]+ |
59 | name [a-zA-Z_*?][a-zA-Z0-9_*?]* | 77 | name [a-zA-Z_*?][a-zA-Z0-9_*?]* |
60 | modifier_event [ukhpGH]{1,8} | 78 | modifier_event [ukhpGH]{1,8} |
61 | modifier_bp [rwx] | 79 | modifier_bp [rwx]{1,3} |
62 | 80 | ||
63 | %% | 81 | %% |
64 | cpu-cycles|cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); } | 82 | |
65 | stalled-cycles-frontend|idle-cycles-frontend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } | 83 | %{ |
66 | stalled-cycles-backend|idle-cycles-backend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } | 84 | { |
67 | instructions { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); } | 85 | int start_token; |
68 | cache-references { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); } | 86 | |
69 | cache-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); } | 87 | start_token = (int) parse_events_get_extra(yyscanner); |
70 | branch-instructions|branches { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } | 88 | if (start_token) { |
71 | branch-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); } | 89 | parse_events_set_extra(NULL, yyscanner); |
72 | bus-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); } | 90 | return start_token; |
73 | ref-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); } | 91 | } |
74 | cpu-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); } | 92 | } |
75 | task-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); } | 93 | %} |
76 | page-faults|faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); } | 94 | |
77 | minor-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); } | 95 | cpu-cycles|cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); } |
78 | major-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); } | 96 | stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } |
79 | context-switches|cs { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); } | 97 | stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } |
80 | cpu-migrations|migrations { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); } | 98 | instructions { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); } |
81 | alignment-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); } | 99 | cache-references { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); } |
82 | emulation-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } | 100 | cache-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); } |
101 | branch-instructions|branches { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } | ||
102 | branch-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); } | ||
103 | bus-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); } | ||
104 | ref-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); } | ||
105 | cpu-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); } | ||
106 | task-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); } | ||
107 | page-faults|faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); } | ||
108 | minor-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); } | ||
109 | major-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); } | ||
110 | context-switches|cs { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); } | ||
111 | cpu-migrations|migrations { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); } | ||
112 | alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); } | ||
113 | emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } | ||
83 | 114 | ||
84 | L1-dcache|l1-d|l1d|L1-data | | 115 | L1-dcache|l1-d|l1d|L1-data | |
85 | L1-icache|l1-i|l1i|L1-instruction | | 116 | L1-icache|l1-i|l1i|L1-instruction | |
@@ -87,14 +118,14 @@ LLC|L2 | | |||
87 | dTLB|d-tlb|Data-TLB | | 118 | dTLB|d-tlb|Data-TLB | |
88 | iTLB|i-tlb|Instruction-TLB | | 119 | iTLB|i-tlb|Instruction-TLB | |
89 | branch|branches|bpu|btb|bpc | | 120 | branch|branches|bpu|btb|bpc | |
90 | node { return str(PE_NAME_CACHE_TYPE); } | 121 | node { return str(yyscanner, PE_NAME_CACHE_TYPE); } |
91 | 122 | ||
92 | load|loads|read | | 123 | load|loads|read | |
93 | store|stores|write | | 124 | store|stores|write | |
94 | prefetch|prefetches | | 125 | prefetch|prefetches | |
95 | speculative-read|speculative-load | | 126 | speculative-read|speculative-load | |
96 | refs|Reference|ops|access | | 127 | refs|Reference|ops|access | |
97 | misses|miss { return str(PE_NAME_CACHE_OP_RESULT); } | 128 | misses|miss { return str(yyscanner, PE_NAME_CACHE_OP_RESULT); } |
98 | 129 | ||
99 | /* | 130 | /* |
100 | * These are event config hardcoded term names to be specified | 131 | * These are event config hardcoded term names to be specified |
@@ -102,38 +133,39 @@ misses|miss { return str(PE_NAME_CACHE_OP_RESULT); } | |||
102 | * so we can put them here directly. In case the we have a conflict | 133 | * so we can put them here directly. In case the we have a conflict |
103 | * in future, this needs to go into '//' condition block. | 134 | * in future, this needs to go into '//' condition block. |
104 | */ | 135 | */ |
105 | config { return term(PARSE_EVENTS__TERM_TYPE_CONFIG); } | 136 | config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); } |
106 | config1 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG1); } | 137 | config1 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); } |
107 | config2 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG2); } | 138 | config2 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); } |
108 | name { return term(PARSE_EVENTS__TERM_TYPE_NAME); } | 139 | name { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); } |
109 | period { return term(PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); } | 140 | period { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); } |
110 | branch_type { return term(PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); } | 141 | branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); } |
111 | 142 | ||
112 | mem: { BEGIN(mem); return PE_PREFIX_MEM; } | 143 | mem: { BEGIN(mem); return PE_PREFIX_MEM; } |
113 | r{num_raw_hex} { return raw(); } | 144 | r{num_raw_hex} { return raw(yyscanner); } |
114 | {num_dec} { return value(10); } | 145 | {num_dec} { return value(yyscanner, 10); } |
115 | {num_hex} { return value(16); } | 146 | {num_hex} { return value(yyscanner, 16); } |
116 | 147 | ||
117 | {modifier_event} { return str(PE_MODIFIER_EVENT); } | 148 | {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } |
118 | {name} { return str(PE_NAME); } | 149 | {name} { return str(yyscanner, PE_NAME); } |
119 | "/" { return '/'; } | 150 | "/" { return '/'; } |
120 | - { return '-'; } | 151 | - { return '-'; } |
121 | , { return ','; } | 152 | , { return ','; } |
122 | : { return ':'; } | 153 | : { return ':'; } |
123 | = { return '='; } | 154 | = { return '='; } |
155 | \n { } | ||
124 | 156 | ||
125 | <mem>{ | 157 | <mem>{ |
126 | {modifier_bp} { return str(PE_MODIFIER_BP); } | 158 | {modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); } |
127 | : { return ':'; } | 159 | : { return ':'; } |
128 | {num_dec} { return value(10); } | 160 | {num_dec} { return value(yyscanner, 10); } |
129 | {num_hex} { return value(16); } | 161 | {num_hex} { return value(yyscanner, 16); } |
130 | /* | 162 | /* |
131 | * We need to separate 'mem:' scanner part, in order to get specific | 163 | * We need to separate 'mem:' scanner part, in order to get specific |
132 | * modifier bits parsed out. Otherwise we would need to handle PE_NAME | 164 | * modifier bits parsed out. Otherwise we would need to handle PE_NAME |
133 | * and we'd need to parse it manually. During the escape from <mem> | 165 | * and we'd need to parse it manually. During the escape from <mem> |
134 | * state we need to put the escaping char back, so we dont miss it. | 166 | * state we need to put the escaping char back, so we dont miss it. |
135 | */ | 167 | */ |
136 | . { unput(*parse_events_text); BEGIN(INITIAL); } | 168 | . { unput(*yytext); BEGIN(INITIAL); } |
137 | /* | 169 | /* |
138 | * We destroy the scanner after reaching EOF, | 170 | * We destroy the scanner after reaching EOF, |
139 | * but anyway just to be sure get back to INIT state. | 171 | * but anyway just to be sure get back to INIT state. |
@@ -143,7 +175,7 @@ r{num_raw_hex} { return raw(); } | |||
143 | 175 | ||
144 | %% | 176 | %% |
145 | 177 | ||
146 | int parse_events_wrap(void) | 178 | int parse_events_wrap(void *scanner __used) |
147 | { | 179 | { |
148 | return 1; | 180 | return 1; |
149 | } | 181 | } |
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 362cc59332ae..2bc5fbff2b5d 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y | |||
@@ -1,7 +1,8 @@ | |||
1 | 1 | %pure-parser | |
2 | %name-prefix "parse_events_" | 2 | %name-prefix "parse_events_" |
3 | %parse-param {struct list_head *list_all} | 3 | %parse-param {void *_data} |
4 | %parse-param {int *idx} | 4 | %parse-param {void *scanner} |
5 | %lex-param {void* scanner} | ||
5 | 6 | ||
6 | %{ | 7 | %{ |
7 | 8 | ||
@@ -12,8 +13,9 @@ | |||
12 | #include "types.h" | 13 | #include "types.h" |
13 | #include "util.h" | 14 | #include "util.h" |
14 | #include "parse-events.h" | 15 | #include "parse-events.h" |
16 | #include "parse-events-bison.h" | ||
15 | 17 | ||
16 | extern int parse_events_lex (void); | 18 | extern int parse_events_lex (YYSTYPE* lvalp, void* scanner); |
17 | 19 | ||
18 | #define ABORT_ON(val) \ | 20 | #define ABORT_ON(val) \ |
19 | do { \ | 21 | do { \ |
@@ -23,14 +25,16 @@ do { \ | |||
23 | 25 | ||
24 | %} | 26 | %} |
25 | 27 | ||
26 | %token PE_VALUE PE_VALUE_SYM PE_RAW PE_TERM | 28 | %token PE_START_EVENTS PE_START_TERMS |
29 | %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM | ||
27 | %token PE_NAME | 30 | %token PE_NAME |
28 | %token PE_MODIFIER_EVENT PE_MODIFIER_BP | 31 | %token PE_MODIFIER_EVENT PE_MODIFIER_BP |
29 | %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT | 32 | %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT |
30 | %token PE_PREFIX_MEM PE_PREFIX_RAW | 33 | %token PE_PREFIX_MEM PE_PREFIX_RAW |
31 | %token PE_ERROR | 34 | %token PE_ERROR |
32 | %type <num> PE_VALUE | 35 | %type <num> PE_VALUE |
33 | %type <num> PE_VALUE_SYM | 36 | %type <num> PE_VALUE_SYM_HW |
37 | %type <num> PE_VALUE_SYM_SW | ||
34 | %type <num> PE_RAW | 38 | %type <num> PE_RAW |
35 | %type <num> PE_TERM | 39 | %type <num> PE_TERM |
36 | %type <str> PE_NAME | 40 | %type <str> PE_NAME |
@@ -38,6 +42,7 @@ do { \ | |||
38 | %type <str> PE_NAME_CACHE_OP_RESULT | 42 | %type <str> PE_NAME_CACHE_OP_RESULT |
39 | %type <str> PE_MODIFIER_EVENT | 43 | %type <str> PE_MODIFIER_EVENT |
40 | %type <str> PE_MODIFIER_BP | 44 | %type <str> PE_MODIFIER_BP |
45 | %type <num> value_sym | ||
41 | %type <head> event_config | 46 | %type <head> event_config |
42 | %type <term> event_term | 47 | %type <term> event_term |
43 | %type <head> event_pmu | 48 | %type <head> event_pmu |
@@ -58,24 +63,33 @@ do { \ | |||
58 | } | 63 | } |
59 | %% | 64 | %% |
60 | 65 | ||
66 | start: | ||
67 | PE_START_EVENTS events | ||
68 | | | ||
69 | PE_START_TERMS terms | ||
70 | |||
61 | events: | 71 | events: |
62 | events ',' event | event | 72 | events ',' event | event |
63 | 73 | ||
64 | event: | 74 | event: |
65 | event_def PE_MODIFIER_EVENT | 75 | event_def PE_MODIFIER_EVENT |
66 | { | 76 | { |
77 | struct parse_events_data__events *data = _data; | ||
78 | |||
67 | /* | 79 | /* |
68 | * Apply modifier on all events added by single event definition | 80 | * Apply modifier on all events added by single event definition |
69 | * (there could be more events added for multiple tracepoint | 81 | * (there could be more events added for multiple tracepoint |
70 | * definitions via '*?'. | 82 | * definitions via '*?'. |
71 | */ | 83 | */ |
72 | ABORT_ON(parse_events_modifier($1, $2)); | 84 | ABORT_ON(parse_events_modifier($1, $2)); |
73 | parse_events_update_lists($1, list_all); | 85 | parse_events_update_lists($1, &data->list); |
74 | } | 86 | } |
75 | | | 87 | | |
76 | event_def | 88 | event_def |
77 | { | 89 | { |
78 | parse_events_update_lists($1, list_all); | 90 | struct parse_events_data__events *data = _data; |
91 | |||
92 | parse_events_update_lists($1, &data->list); | ||
79 | } | 93 | } |
80 | 94 | ||
81 | event_def: event_pmu | | 95 | event_def: event_pmu | |
@@ -89,104 +103,131 @@ event_def: event_pmu | | |||
89 | event_pmu: | 103 | event_pmu: |
90 | PE_NAME '/' event_config '/' | 104 | PE_NAME '/' event_config '/' |
91 | { | 105 | { |
106 | struct parse_events_data__events *data = _data; | ||
92 | struct list_head *list = NULL; | 107 | struct list_head *list = NULL; |
93 | 108 | ||
94 | ABORT_ON(parse_events_add_pmu(&list, idx, $1, $3)); | 109 | ABORT_ON(parse_events_add_pmu(&list, &data->idx, $1, $3)); |
95 | parse_events__free_terms($3); | 110 | parse_events__free_terms($3); |
96 | $$ = list; | 111 | $$ = list; |
97 | } | 112 | } |
98 | 113 | ||
114 | value_sym: | ||
115 | PE_VALUE_SYM_HW | ||
116 | | | ||
117 | PE_VALUE_SYM_SW | ||
118 | |||
99 | event_legacy_symbol: | 119 | event_legacy_symbol: |
100 | PE_VALUE_SYM '/' event_config '/' | 120 | value_sym '/' event_config '/' |
101 | { | 121 | { |
122 | struct parse_events_data__events *data = _data; | ||
102 | struct list_head *list = NULL; | 123 | struct list_head *list = NULL; |
103 | int type = $1 >> 16; | 124 | int type = $1 >> 16; |
104 | int config = $1 & 255; | 125 | int config = $1 & 255; |
105 | 126 | ||
106 | ABORT_ON(parse_events_add_numeric(&list, idx, type, config, $3)); | 127 | ABORT_ON(parse_events_add_numeric(&list, &data->idx, |
128 | type, config, $3)); | ||
107 | parse_events__free_terms($3); | 129 | parse_events__free_terms($3); |
108 | $$ = list; | 130 | $$ = list; |
109 | } | 131 | } |
110 | | | 132 | | |
111 | PE_VALUE_SYM sep_slash_dc | 133 | value_sym sep_slash_dc |
112 | { | 134 | { |
135 | struct parse_events_data__events *data = _data; | ||
113 | struct list_head *list = NULL; | 136 | struct list_head *list = NULL; |
114 | int type = $1 >> 16; | 137 | int type = $1 >> 16; |
115 | int config = $1 & 255; | 138 | int config = $1 & 255; |
116 | 139 | ||
117 | ABORT_ON(parse_events_add_numeric(&list, idx, type, config, NULL)); | 140 | ABORT_ON(parse_events_add_numeric(&list, &data->idx, |
141 | type, config, NULL)); | ||
118 | $$ = list; | 142 | $$ = list; |
119 | } | 143 | } |
120 | 144 | ||
121 | event_legacy_cache: | 145 | event_legacy_cache: |
122 | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT | 146 | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT |
123 | { | 147 | { |
148 | struct parse_events_data__events *data = _data; | ||
124 | struct list_head *list = NULL; | 149 | struct list_head *list = NULL; |
125 | 150 | ||
126 | ABORT_ON(parse_events_add_cache(&list, idx, $1, $3, $5)); | 151 | ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, $5)); |
127 | $$ = list; | 152 | $$ = list; |
128 | } | 153 | } |
129 | | | 154 | | |
130 | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT | 155 | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT |
131 | { | 156 | { |
157 | struct parse_events_data__events *data = _data; | ||
132 | struct list_head *list = NULL; | 158 | struct list_head *list = NULL; |
133 | 159 | ||
134 | ABORT_ON(parse_events_add_cache(&list, idx, $1, $3, NULL)); | 160 | ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, NULL)); |
135 | $$ = list; | 161 | $$ = list; |
136 | } | 162 | } |
137 | | | 163 | | |
138 | PE_NAME_CACHE_TYPE | 164 | PE_NAME_CACHE_TYPE |
139 | { | 165 | { |
166 | struct parse_events_data__events *data = _data; | ||
140 | struct list_head *list = NULL; | 167 | struct list_head *list = NULL; |
141 | 168 | ||
142 | ABORT_ON(parse_events_add_cache(&list, idx, $1, NULL, NULL)); | 169 | ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, NULL, NULL)); |
143 | $$ = list; | 170 | $$ = list; |
144 | } | 171 | } |
145 | 172 | ||
146 | event_legacy_mem: | 173 | event_legacy_mem: |
147 | PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc | 174 | PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc |
148 | { | 175 | { |
176 | struct parse_events_data__events *data = _data; | ||
149 | struct list_head *list = NULL; | 177 | struct list_head *list = NULL; |
150 | 178 | ||
151 | ABORT_ON(parse_events_add_breakpoint(&list, idx, (void *) $2, $4)); | 179 | ABORT_ON(parse_events_add_breakpoint(&list, &data->idx, |
180 | (void *) $2, $4)); | ||
152 | $$ = list; | 181 | $$ = list; |
153 | } | 182 | } |
154 | | | 183 | | |
155 | PE_PREFIX_MEM PE_VALUE sep_dc | 184 | PE_PREFIX_MEM PE_VALUE sep_dc |
156 | { | 185 | { |
186 | struct parse_events_data__events *data = _data; | ||
157 | struct list_head *list = NULL; | 187 | struct list_head *list = NULL; |
158 | 188 | ||
159 | ABORT_ON(parse_events_add_breakpoint(&list, idx, (void *) $2, NULL)); | 189 | ABORT_ON(parse_events_add_breakpoint(&list, &data->idx, |
190 | (void *) $2, NULL)); | ||
160 | $$ = list; | 191 | $$ = list; |
161 | } | 192 | } |
162 | 193 | ||
163 | event_legacy_tracepoint: | 194 | event_legacy_tracepoint: |
164 | PE_NAME ':' PE_NAME | 195 | PE_NAME ':' PE_NAME |
165 | { | 196 | { |
197 | struct parse_events_data__events *data = _data; | ||
166 | struct list_head *list = NULL; | 198 | struct list_head *list = NULL; |
167 | 199 | ||
168 | ABORT_ON(parse_events_add_tracepoint(&list, idx, $1, $3)); | 200 | ABORT_ON(parse_events_add_tracepoint(&list, &data->idx, $1, $3)); |
169 | $$ = list; | 201 | $$ = list; |
170 | } | 202 | } |
171 | 203 | ||
172 | event_legacy_numeric: | 204 | event_legacy_numeric: |
173 | PE_VALUE ':' PE_VALUE | 205 | PE_VALUE ':' PE_VALUE |
174 | { | 206 | { |
207 | struct parse_events_data__events *data = _data; | ||
175 | struct list_head *list = NULL; | 208 | struct list_head *list = NULL; |
176 | 209 | ||
177 | ABORT_ON(parse_events_add_numeric(&list, idx, $1, $3, NULL)); | 210 | ABORT_ON(parse_events_add_numeric(&list, &data->idx, $1, $3, NULL)); |
178 | $$ = list; | 211 | $$ = list; |
179 | } | 212 | } |
180 | 213 | ||
181 | event_legacy_raw: | 214 | event_legacy_raw: |
182 | PE_RAW | 215 | PE_RAW |
183 | { | 216 | { |
217 | struct parse_events_data__events *data = _data; | ||
184 | struct list_head *list = NULL; | 218 | struct list_head *list = NULL; |
185 | 219 | ||
186 | ABORT_ON(parse_events_add_numeric(&list, idx, PERF_TYPE_RAW, $1, NULL)); | 220 | ABORT_ON(parse_events_add_numeric(&list, &data->idx, |
221 | PERF_TYPE_RAW, $1, NULL)); | ||
187 | $$ = list; | 222 | $$ = list; |
188 | } | 223 | } |
189 | 224 | ||
225 | terms: event_config | ||
226 | { | ||
227 | struct parse_events_data__terms *data = _data; | ||
228 | data->terms = $1; | ||
229 | } | ||
230 | |||
190 | event_config: | 231 | event_config: |
191 | event_config ',' event_term | 232 | event_config ',' event_term |
192 | { | 233 | { |
@@ -267,8 +308,7 @@ sep_slash_dc: '/' | ':' | | |||
267 | 308 | ||
268 | %% | 309 | %% |
269 | 310 | ||
270 | void parse_events_error(struct list_head *list_all __used, | 311 | void parse_events_error(void *data __used, void *scanner __used, |
271 | int *idx __used, | ||
272 | char const *msg __used) | 312 | char const *msg __used) |
273 | { | 313 | { |
274 | } | 314 | } |
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index a119a5371699..67715a42cd6d 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
@@ -72,7 +72,7 @@ static int pmu_format(char *name, struct list_head *format) | |||
72 | "%s/bus/event_source/devices/%s/format", sysfs, name); | 72 | "%s/bus/event_source/devices/%s/format", sysfs, name); |
73 | 73 | ||
74 | if (stat(path, &st) < 0) | 74 | if (stat(path, &st) < 0) |
75 | return -1; | 75 | return 0; /* no error if format does not exist */ |
76 | 76 | ||
77 | if (pmu_format_parse(path, format)) | 77 | if (pmu_format_parse(path, format)) |
78 | return -1; | 78 | return -1; |
@@ -80,6 +80,114 @@ static int pmu_format(char *name, struct list_head *format) | |||
80 | return 0; | 80 | return 0; |
81 | } | 81 | } |
82 | 82 | ||
83 | static int perf_pmu__new_alias(struct list_head *list, char *name, FILE *file) | ||
84 | { | ||
85 | struct perf_pmu__alias *alias; | ||
86 | char buf[256]; | ||
87 | int ret; | ||
88 | |||
89 | ret = fread(buf, 1, sizeof(buf), file); | ||
90 | if (ret == 0) | ||
91 | return -EINVAL; | ||
92 | buf[ret] = 0; | ||
93 | |||
94 | alias = malloc(sizeof(*alias)); | ||
95 | if (!alias) | ||
96 | return -ENOMEM; | ||
97 | |||
98 | INIT_LIST_HEAD(&alias->terms); | ||
99 | ret = parse_events_terms(&alias->terms, buf); | ||
100 | if (ret) { | ||
101 | free(alias); | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | alias->name = strdup(name); | ||
106 | list_add_tail(&alias->list, list); | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Process all the sysfs attributes located under the directory | ||
112 | * specified in 'dir' parameter. | ||
113 | */ | ||
114 | static int pmu_aliases_parse(char *dir, struct list_head *head) | ||
115 | { | ||
116 | struct dirent *evt_ent; | ||
117 | DIR *event_dir; | ||
118 | int ret = 0; | ||
119 | |||
120 | event_dir = opendir(dir); | ||
121 | if (!event_dir) | ||
122 | return -EINVAL; | ||
123 | |||
124 | while (!ret && (evt_ent = readdir(event_dir))) { | ||
125 | char path[PATH_MAX]; | ||
126 | char *name = evt_ent->d_name; | ||
127 | FILE *file; | ||
128 | |||
129 | if (!strcmp(name, ".") || !strcmp(name, "..")) | ||
130 | continue; | ||
131 | |||
132 | snprintf(path, PATH_MAX, "%s/%s", dir, name); | ||
133 | |||
134 | ret = -EINVAL; | ||
135 | file = fopen(path, "r"); | ||
136 | if (!file) | ||
137 | break; | ||
138 | ret = perf_pmu__new_alias(head, name, file); | ||
139 | fclose(file); | ||
140 | } | ||
141 | |||
142 | closedir(event_dir); | ||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * Reading the pmu event aliases definition, which should be located at: | ||
148 | * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes. | ||
149 | */ | ||
150 | static int pmu_aliases(char *name, struct list_head *head) | ||
151 | { | ||
152 | struct stat st; | ||
153 | char path[PATH_MAX]; | ||
154 | const char *sysfs; | ||
155 | |||
156 | sysfs = sysfs_find_mountpoint(); | ||
157 | if (!sysfs) | ||
158 | return -1; | ||
159 | |||
160 | snprintf(path, PATH_MAX, | ||
161 | "%s/bus/event_source/devices/%s/events", sysfs, name); | ||
162 | |||
163 | if (stat(path, &st) < 0) | ||
164 | return -1; | ||
165 | |||
166 | if (pmu_aliases_parse(path, head)) | ||
167 | return -1; | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static int pmu_alias_terms(struct perf_pmu__alias *alias, | ||
173 | struct list_head *terms) | ||
174 | { | ||
175 | struct parse_events__term *term, *clone; | ||
176 | LIST_HEAD(list); | ||
177 | int ret; | ||
178 | |||
179 | list_for_each_entry(term, &alias->terms, list) { | ||
180 | ret = parse_events__term_clone(&clone, term); | ||
181 | if (ret) { | ||
182 | parse_events__free_terms(&list); | ||
183 | return ret; | ||
184 | } | ||
185 | list_add_tail(&clone->list, &list); | ||
186 | } | ||
187 | list_splice(&list, terms); | ||
188 | return 0; | ||
189 | } | ||
190 | |||
83 | /* | 191 | /* |
84 | * Reading/parsing the default pmu type value, which should be | 192 | * Reading/parsing the default pmu type value, which should be |
85 | * located at: | 193 | * located at: |
@@ -118,6 +226,7 @@ static struct perf_pmu *pmu_lookup(char *name) | |||
118 | { | 226 | { |
119 | struct perf_pmu *pmu; | 227 | struct perf_pmu *pmu; |
120 | LIST_HEAD(format); | 228 | LIST_HEAD(format); |
229 | LIST_HEAD(aliases); | ||
121 | __u32 type; | 230 | __u32 type; |
122 | 231 | ||
123 | /* | 232 | /* |
@@ -135,10 +244,15 @@ static struct perf_pmu *pmu_lookup(char *name) | |||
135 | if (!pmu) | 244 | if (!pmu) |
136 | return NULL; | 245 | return NULL; |
137 | 246 | ||
247 | pmu_aliases(name, &aliases); | ||
248 | |||
138 | INIT_LIST_HEAD(&pmu->format); | 249 | INIT_LIST_HEAD(&pmu->format); |
250 | INIT_LIST_HEAD(&pmu->aliases); | ||
139 | list_splice(&format, &pmu->format); | 251 | list_splice(&format, &pmu->format); |
252 | list_splice(&aliases, &pmu->aliases); | ||
140 | pmu->name = strdup(name); | 253 | pmu->name = strdup(name); |
141 | pmu->type = type; | 254 | pmu->type = type; |
255 | list_add_tail(&pmu->list, &pmus); | ||
142 | return pmu; | 256 | return pmu; |
143 | } | 257 | } |
144 | 258 | ||
@@ -279,6 +393,59 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, | |||
279 | return pmu_config(&pmu->format, attr, head_terms); | 393 | return pmu_config(&pmu->format, attr, head_terms); |
280 | } | 394 | } |
281 | 395 | ||
396 | static struct perf_pmu__alias *pmu_find_alias(struct perf_pmu *pmu, | ||
397 | struct parse_events__term *term) | ||
398 | { | ||
399 | struct perf_pmu__alias *alias; | ||
400 | char *name; | ||
401 | |||
402 | if (parse_events__is_hardcoded_term(term)) | ||
403 | return NULL; | ||
404 | |||
405 | if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { | ||
406 | if (term->val.num != 1) | ||
407 | return NULL; | ||
408 | if (pmu_find_format(&pmu->format, term->config)) | ||
409 | return NULL; | ||
410 | name = term->config; | ||
411 | } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { | ||
412 | if (strcasecmp(term->config, "event")) | ||
413 | return NULL; | ||
414 | name = term->val.str; | ||
415 | } else { | ||
416 | return NULL; | ||
417 | } | ||
418 | |||
419 | list_for_each_entry(alias, &pmu->aliases, list) { | ||
420 | if (!strcasecmp(alias->name, name)) | ||
421 | return alias; | ||
422 | } | ||
423 | return NULL; | ||
424 | } | ||
425 | |||
426 | /* | ||
427 | * Find alias in the terms list and replace it with the terms | ||
428 | * defined for the alias | ||
429 | */ | ||
430 | int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms) | ||
431 | { | ||
432 | struct parse_events__term *term, *h; | ||
433 | struct perf_pmu__alias *alias; | ||
434 | int ret; | ||
435 | |||
436 | list_for_each_entry_safe(term, h, head_terms, list) { | ||
437 | alias = pmu_find_alias(pmu, term); | ||
438 | if (!alias) | ||
439 | continue; | ||
440 | ret = pmu_alias_terms(alias, &term->list); | ||
441 | if (ret) | ||
442 | return ret; | ||
443 | list_del(&term->list); | ||
444 | free(term); | ||
445 | } | ||
446 | return 0; | ||
447 | } | ||
448 | |||
282 | int perf_pmu__new_format(struct list_head *list, char *name, | 449 | int perf_pmu__new_format(struct list_head *list, char *name, |
283 | int config, unsigned long *bits) | 450 | int config, unsigned long *bits) |
284 | { | 451 | { |
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 68c0db965e1f..535f2c5258ab 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h | |||
@@ -19,17 +19,26 @@ struct perf_pmu__format { | |||
19 | struct list_head list; | 19 | struct list_head list; |
20 | }; | 20 | }; |
21 | 21 | ||
22 | struct perf_pmu__alias { | ||
23 | char *name; | ||
24 | struct list_head terms; | ||
25 | struct list_head list; | ||
26 | }; | ||
27 | |||
22 | struct perf_pmu { | 28 | struct perf_pmu { |
23 | char *name; | 29 | char *name; |
24 | __u32 type; | 30 | __u32 type; |
25 | struct list_head format; | 31 | struct list_head format; |
32 | struct list_head aliases; | ||
26 | struct list_head list; | 33 | struct list_head list; |
27 | }; | 34 | }; |
28 | 35 | ||
29 | struct perf_pmu *perf_pmu__find(char *name); | 36 | struct perf_pmu *perf_pmu__find(char *name); |
30 | int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, | 37 | int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, |
31 | struct list_head *head_terms); | 38 | struct list_head *head_terms); |
32 | 39 | int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms); | |
40 | struct list_head *perf_pmu__alias(struct perf_pmu *pmu, | ||
41 | struct list_head *head_terms); | ||
33 | int perf_pmu_wrap(void); | 42 | int perf_pmu_wrap(void); |
34 | void perf_pmu_error(struct list_head *list, char *name, char const *msg); | 43 | void perf_pmu_error(struct list_head *list, char *name, char const *msg); |
35 | 44 | ||
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index 4c1b3d72a1d2..02dfa19a467f 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c | |||
@@ -209,6 +209,10 @@ static void define_event_symbols(struct event_format *event, | |||
209 | define_symbolic_values(args->symbol.symbols, ev_name, | 209 | define_symbolic_values(args->symbol.symbols, ev_name, |
210 | cur_field_name); | 210 | cur_field_name); |
211 | break; | 211 | break; |
212 | case PRINT_HEX: | ||
213 | define_event_symbols(event, ev_name, args->hex.field); | ||
214 | define_event_symbols(event, ev_name, args->hex.size); | ||
215 | break; | ||
212 | case PRINT_BSTRING: | 216 | case PRINT_BSTRING: |
213 | case PRINT_DYNAMIC_ARRAY: | 217 | case PRINT_DYNAMIC_ARRAY: |
214 | case PRINT_STRING: | 218 | case PRINT_STRING: |
@@ -233,7 +237,8 @@ static void define_event_symbols(struct event_format *event, | |||
233 | define_event_symbols(event, ev_name, args->next); | 237 | define_event_symbols(event, ev_name, args->next); |
234 | } | 238 | } |
235 | 239 | ||
236 | static inline struct event_format *find_cache_event(int type) | 240 | static inline |
241 | struct event_format *find_cache_event(struct pevent *pevent, int type) | ||
237 | { | 242 | { |
238 | static char ev_name[256]; | 243 | static char ev_name[256]; |
239 | struct event_format *event; | 244 | struct event_format *event; |
@@ -241,7 +246,7 @@ static inline struct event_format *find_cache_event(int type) | |||
241 | if (events[type]) | 246 | if (events[type]) |
242 | return events[type]; | 247 | return events[type]; |
243 | 248 | ||
244 | events[type] = event = trace_find_event(type); | 249 | events[type] = event = pevent_find_event(pevent, type); |
245 | if (!event) | 250 | if (!event) |
246 | return NULL; | 251 | return NULL; |
247 | 252 | ||
@@ -252,7 +257,8 @@ static inline struct event_format *find_cache_event(int type) | |||
252 | return event; | 257 | return event; |
253 | } | 258 | } |
254 | 259 | ||
255 | static void perl_process_tracepoint(union perf_event *pevent __unused, | 260 | static void perl_process_tracepoint(union perf_event *perf_event __unused, |
261 | struct pevent *pevent, | ||
256 | struct perf_sample *sample, | 262 | struct perf_sample *sample, |
257 | struct perf_evsel *evsel, | 263 | struct perf_evsel *evsel, |
258 | struct machine *machine __unused, | 264 | struct machine *machine __unused, |
@@ -275,13 +281,13 @@ static void perl_process_tracepoint(union perf_event *pevent __unused, | |||
275 | if (evsel->attr.type != PERF_TYPE_TRACEPOINT) | 281 | if (evsel->attr.type != PERF_TYPE_TRACEPOINT) |
276 | return; | 282 | return; |
277 | 283 | ||
278 | type = trace_parse_common_type(data); | 284 | type = trace_parse_common_type(pevent, data); |
279 | 285 | ||
280 | event = find_cache_event(type); | 286 | event = find_cache_event(pevent, type); |
281 | if (!event) | 287 | if (!event) |
282 | die("ug! no event found for type %d", type); | 288 | die("ug! no event found for type %d", type); |
283 | 289 | ||
284 | pid = trace_parse_common_pid(data); | 290 | pid = trace_parse_common_pid(pevent, data); |
285 | 291 | ||
286 | sprintf(handler, "%s::%s", event->system, event->name); | 292 | sprintf(handler, "%s::%s", event->system, event->name); |
287 | 293 | ||
@@ -314,7 +320,8 @@ static void perl_process_tracepoint(union perf_event *pevent __unused, | |||
314 | offset = field->offset; | 320 | offset = field->offset; |
315 | XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0))); | 321 | XPUSHs(sv_2mortal(newSVpv((char *)data + offset, 0))); |
316 | } else { /* FIELD_IS_NUMERIC */ | 322 | } else { /* FIELD_IS_NUMERIC */ |
317 | val = read_size(data + field->offset, field->size); | 323 | val = read_size(pevent, data + field->offset, |
324 | field->size); | ||
318 | if (field->flags & FIELD_IS_SIGNED) { | 325 | if (field->flags & FIELD_IS_SIGNED) { |
319 | XPUSHs(sv_2mortal(newSViv(val))); | 326 | XPUSHs(sv_2mortal(newSViv(val))); |
320 | } else { | 327 | } else { |
@@ -368,14 +375,15 @@ static void perl_process_event_generic(union perf_event *pevent __unused, | |||
368 | LEAVE; | 375 | LEAVE; |
369 | } | 376 | } |
370 | 377 | ||
371 | static void perl_process_event(union perf_event *pevent, | 378 | static void perl_process_event(union perf_event *event, |
379 | struct pevent *pevent, | ||
372 | struct perf_sample *sample, | 380 | struct perf_sample *sample, |
373 | struct perf_evsel *evsel, | 381 | struct perf_evsel *evsel, |
374 | struct machine *machine, | 382 | struct machine *machine, |
375 | struct thread *thread) | 383 | struct thread *thread) |
376 | { | 384 | { |
377 | perl_process_tracepoint(pevent, sample, evsel, machine, thread); | 385 | perl_process_tracepoint(event, pevent, sample, evsel, machine, thread); |
378 | perl_process_event_generic(pevent, sample, evsel, machine, thread); | 386 | perl_process_event_generic(event, sample, evsel, machine, thread); |
379 | } | 387 | } |
380 | 388 | ||
381 | static void run_start_sub(void) | 389 | static void run_start_sub(void) |
@@ -448,7 +456,7 @@ static int perl_stop_script(void) | |||
448 | return 0; | 456 | return 0; |
449 | } | 457 | } |
450 | 458 | ||
451 | static int perl_generate_script(const char *outfile) | 459 | static int perl_generate_script(struct pevent *pevent, const char *outfile) |
452 | { | 460 | { |
453 | struct event_format *event = NULL; | 461 | struct event_format *event = NULL; |
454 | struct format_field *f; | 462 | struct format_field *f; |
@@ -495,7 +503,7 @@ static int perl_generate_script(const char *outfile) | |||
495 | fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n"); | 503 | fprintf(ofp, "sub trace_begin\n{\n\t# optional\n}\n\n"); |
496 | fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n"); | 504 | fprintf(ofp, "sub trace_end\n{\n\t# optional\n}\n\n"); |
497 | 505 | ||
498 | while ((event = trace_find_next_event(event))) { | 506 | while ((event = trace_find_next_event(pevent, event))) { |
499 | fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name); | 507 | fprintf(ofp, "sub %s::%s\n{\n", event->system, event->name); |
500 | fprintf(ofp, "\tmy ("); | 508 | fprintf(ofp, "\tmy ("); |
501 | 509 | ||
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index acb9795286c4..ce4d1b0c3862 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c | |||
@@ -166,6 +166,10 @@ static void define_event_symbols(struct event_format *event, | |||
166 | define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name, | 166 | define_values(PRINT_SYMBOL, args->symbol.symbols, ev_name, |
167 | cur_field_name); | 167 | cur_field_name); |
168 | break; | 168 | break; |
169 | case PRINT_HEX: | ||
170 | define_event_symbols(event, ev_name, args->hex.field); | ||
171 | define_event_symbols(event, ev_name, args->hex.size); | ||
172 | break; | ||
169 | case PRINT_STRING: | 173 | case PRINT_STRING: |
170 | break; | 174 | break; |
171 | case PRINT_TYPE: | 175 | case PRINT_TYPE: |
@@ -190,7 +194,8 @@ static void define_event_symbols(struct event_format *event, | |||
190 | define_event_symbols(event, ev_name, args->next); | 194 | define_event_symbols(event, ev_name, args->next); |
191 | } | 195 | } |
192 | 196 | ||
193 | static inline struct event_format *find_cache_event(int type) | 197 | static inline |
198 | struct event_format *find_cache_event(struct pevent *pevent, int type) | ||
194 | { | 199 | { |
195 | static char ev_name[256]; | 200 | static char ev_name[256]; |
196 | struct event_format *event; | 201 | struct event_format *event; |
@@ -198,7 +203,7 @@ static inline struct event_format *find_cache_event(int type) | |||
198 | if (events[type]) | 203 | if (events[type]) |
199 | return events[type]; | 204 | return events[type]; |
200 | 205 | ||
201 | events[type] = event = trace_find_event(type); | 206 | events[type] = event = pevent_find_event(pevent, type); |
202 | if (!event) | 207 | if (!event) |
203 | return NULL; | 208 | return NULL; |
204 | 209 | ||
@@ -209,7 +214,8 @@ static inline struct event_format *find_cache_event(int type) | |||
209 | return event; | 214 | return event; |
210 | } | 215 | } |
211 | 216 | ||
212 | static void python_process_event(union perf_event *pevent __unused, | 217 | static void python_process_event(union perf_event *perf_event __unused, |
218 | struct pevent *pevent, | ||
213 | struct perf_sample *sample, | 219 | struct perf_sample *sample, |
214 | struct perf_evsel *evsel __unused, | 220 | struct perf_evsel *evsel __unused, |
215 | struct machine *machine __unused, | 221 | struct machine *machine __unused, |
@@ -233,13 +239,13 @@ static void python_process_event(union perf_event *pevent __unused, | |||
233 | if (!t) | 239 | if (!t) |
234 | Py_FatalError("couldn't create Python tuple"); | 240 | Py_FatalError("couldn't create Python tuple"); |
235 | 241 | ||
236 | type = trace_parse_common_type(data); | 242 | type = trace_parse_common_type(pevent, data); |
237 | 243 | ||
238 | event = find_cache_event(type); | 244 | event = find_cache_event(pevent, type); |
239 | if (!event) | 245 | if (!event) |
240 | die("ug! no event found for type %d", type); | 246 | die("ug! no event found for type %d", type); |
241 | 247 | ||
242 | pid = trace_parse_common_pid(data); | 248 | pid = trace_parse_common_pid(pevent, data); |
243 | 249 | ||
244 | sprintf(handler_name, "%s__%s", event->system, event->name); | 250 | sprintf(handler_name, "%s__%s", event->system, event->name); |
245 | 251 | ||
@@ -284,7 +290,8 @@ static void python_process_event(union perf_event *pevent __unused, | |||
284 | offset = field->offset; | 290 | offset = field->offset; |
285 | obj = PyString_FromString((char *)data + offset); | 291 | obj = PyString_FromString((char *)data + offset); |
286 | } else { /* FIELD_IS_NUMERIC */ | 292 | } else { /* FIELD_IS_NUMERIC */ |
287 | val = read_size(data + field->offset, field->size); | 293 | val = read_size(pevent, data + field->offset, |
294 | field->size); | ||
288 | if (field->flags & FIELD_IS_SIGNED) { | 295 | if (field->flags & FIELD_IS_SIGNED) { |
289 | if ((long long)val >= LONG_MIN && | 296 | if ((long long)val >= LONG_MIN && |
290 | (long long)val <= LONG_MAX) | 297 | (long long)val <= LONG_MAX) |
@@ -438,7 +445,7 @@ out: | |||
438 | return err; | 445 | return err; |
439 | } | 446 | } |
440 | 447 | ||
441 | static int python_generate_script(const char *outfile) | 448 | static int python_generate_script(struct pevent *pevent, const char *outfile) |
442 | { | 449 | { |
443 | struct event_format *event = NULL; | 450 | struct event_format *event = NULL; |
444 | struct format_field *f; | 451 | struct format_field *f; |
@@ -487,7 +494,7 @@ static int python_generate_script(const char *outfile) | |||
487 | fprintf(ofp, "def trace_end():\n"); | 494 | fprintf(ofp, "def trace_end():\n"); |
488 | fprintf(ofp, "\tprint \"in trace_end\"\n\n"); | 495 | fprintf(ofp, "\tprint \"in trace_end\"\n\n"); |
489 | 496 | ||
490 | while ((event = trace_find_next_event(event))) { | 497 | while ((event = trace_find_next_event(pevent, event))) { |
491 | fprintf(ofp, "def %s__%s(", event->system, event->name); | 498 | fprintf(ofp, "def %s__%s(", event->system, event->name); |
492 | fprintf(ofp, "event_name, "); | 499 | fprintf(ofp, "event_name, "); |
493 | fprintf(ofp, "context, "); | 500 | fprintf(ofp, "context, "); |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 56142d0fb8d7..8e485592ca20 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include "sort.h" | 14 | #include "sort.h" |
15 | #include "util.h" | 15 | #include "util.h" |
16 | #include "cpumap.h" | 16 | #include "cpumap.h" |
17 | #include "event-parse.h" | ||
17 | 18 | ||
18 | static int perf_session__open(struct perf_session *self, bool force) | 19 | static int perf_session__open(struct perf_session *self, bool force) |
19 | { | 20 | { |
@@ -289,7 +290,6 @@ struct branch_info *machine__resolve_bstack(struct machine *self, | |||
289 | } | 290 | } |
290 | 291 | ||
291 | int machine__resolve_callchain(struct machine *self, | 292 | int machine__resolve_callchain(struct machine *self, |
292 | struct perf_evsel *evsel __used, | ||
293 | struct thread *thread, | 293 | struct thread *thread, |
294 | struct ip_callchain *chain, | 294 | struct ip_callchain *chain, |
295 | struct symbol **parent) | 295 | struct symbol **parent) |
@@ -1449,7 +1449,7 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) | |||
1449 | ret += hists__fprintf_nr_events(&session->hists, fp); | 1449 | ret += hists__fprintf_nr_events(&session->hists, fp); |
1450 | 1450 | ||
1451 | list_for_each_entry(pos, &session->evlist->entries, node) { | 1451 | list_for_each_entry(pos, &session->evlist->entries, node) { |
1452 | ret += fprintf(fp, "%s stats:\n", event_name(pos)); | 1452 | ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); |
1453 | ret += hists__fprintf_nr_events(&pos->hists, fp); | 1453 | ret += hists__fprintf_nr_events(&pos->hists, fp); |
1454 | } | 1454 | } |
1455 | 1455 | ||
@@ -1490,8 +1490,8 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | |||
1490 | } | 1490 | } |
1491 | 1491 | ||
1492 | void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, | 1492 | void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, |
1493 | struct machine *machine, struct perf_evsel *evsel, | 1493 | struct machine *machine, int print_sym, |
1494 | int print_sym, int print_dso, int print_symoffset) | 1494 | int print_dso, int print_symoffset) |
1495 | { | 1495 | { |
1496 | struct addr_location al; | 1496 | struct addr_location al; |
1497 | struct callchain_cursor_node *node; | 1497 | struct callchain_cursor_node *node; |
@@ -1505,7 +1505,7 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, | |||
1505 | 1505 | ||
1506 | if (symbol_conf.use_callchain && sample->callchain) { | 1506 | if (symbol_conf.use_callchain && sample->callchain) { |
1507 | 1507 | ||
1508 | if (machine__resolve_callchain(machine, evsel, al.thread, | 1508 | if (machine__resolve_callchain(machine, al.thread, |
1509 | sample->callchain, NULL) != 0) { | 1509 | sample->callchain, NULL) != 0) { |
1510 | if (verbose) | 1510 | if (verbose) |
1511 | error("Failed to resolve callchain. Skipping\n"); | 1511 | error("Failed to resolve callchain. Skipping\n"); |
@@ -1611,3 +1611,58 @@ void perf_session__fprintf_info(struct perf_session *session, FILE *fp, | |||
1611 | perf_header__fprintf_info(session, fp, full); | 1611 | perf_header__fprintf_info(session, fp, full); |
1612 | fprintf(fp, "# ========\n#\n"); | 1612 | fprintf(fp, "# ========\n#\n"); |
1613 | } | 1613 | } |
1614 | |||
1615 | |||
1616 | int __perf_session__set_tracepoints_handlers(struct perf_session *session, | ||
1617 | const struct perf_evsel_str_handler *assocs, | ||
1618 | size_t nr_assocs) | ||
1619 | { | ||
1620 | struct perf_evlist *evlist = session->evlist; | ||
1621 | struct event_format *format; | ||
1622 | struct perf_evsel *evsel; | ||
1623 | char *tracepoint, *name; | ||
1624 | size_t i; | ||
1625 | int err; | ||
1626 | |||
1627 | for (i = 0; i < nr_assocs; i++) { | ||
1628 | err = -ENOMEM; | ||
1629 | tracepoint = strdup(assocs[i].name); | ||
1630 | if (tracepoint == NULL) | ||
1631 | goto out; | ||
1632 | |||
1633 | err = -ENOENT; | ||
1634 | name = strchr(tracepoint, ':'); | ||
1635 | if (name == NULL) | ||
1636 | goto out_free; | ||
1637 | |||
1638 | *name++ = '\0'; | ||
1639 | format = pevent_find_event_by_name(session->pevent, | ||
1640 | tracepoint, name); | ||
1641 | if (format == NULL) { | ||
1642 | /* | ||
1643 | * Adding a handler for an event not in the session, | ||
1644 | * just ignore it. | ||
1645 | */ | ||
1646 | goto next; | ||
1647 | } | ||
1648 | |||
1649 | evsel = perf_evlist__find_tracepoint_by_id(evlist, format->id); | ||
1650 | if (evsel == NULL) | ||
1651 | goto next; | ||
1652 | |||
1653 | err = -EEXIST; | ||
1654 | if (evsel->handler.func != NULL) | ||
1655 | goto out_free; | ||
1656 | evsel->handler.func = assocs[i].handler; | ||
1657 | next: | ||
1658 | free(tracepoint); | ||
1659 | } | ||
1660 | |||
1661 | err = 0; | ||
1662 | out: | ||
1663 | return err; | ||
1664 | |||
1665 | out_free: | ||
1666 | free(tracepoint); | ||
1667 | goto out; | ||
1668 | } | ||
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 0c702e3f0a36..7c435bde6eb0 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -33,6 +33,7 @@ struct perf_session { | |||
33 | struct machine host_machine; | 33 | struct machine host_machine; |
34 | struct rb_root machines; | 34 | struct rb_root machines; |
35 | struct perf_evlist *evlist; | 35 | struct perf_evlist *evlist; |
36 | struct pevent *pevent; | ||
36 | /* | 37 | /* |
37 | * FIXME: Need to split this up further, we need global | 38 | * FIXME: Need to split this up further, we need global |
38 | * stats + per event stats. 'perf diff' also needs | 39 | * stats + per event stats. 'perf diff' also needs |
@@ -151,11 +152,20 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | |||
151 | unsigned int type); | 152 | unsigned int type); |
152 | 153 | ||
153 | void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, | 154 | void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, |
154 | struct machine *machine, struct perf_evsel *evsel, | 155 | struct machine *machine, int print_sym, |
155 | int print_sym, int print_dso, int print_symoffset); | 156 | int print_dso, int print_symoffset); |
156 | 157 | ||
157 | int perf_session__cpu_bitmap(struct perf_session *session, | 158 | int perf_session__cpu_bitmap(struct perf_session *session, |
158 | const char *cpu_list, unsigned long *cpu_bitmap); | 159 | const char *cpu_list, unsigned long *cpu_bitmap); |
159 | 160 | ||
160 | void perf_session__fprintf_info(struct perf_session *s, FILE *fp, bool full); | 161 | void perf_session__fprintf_info(struct perf_session *s, FILE *fp, bool full); |
162 | |||
163 | struct perf_evsel_str_handler; | ||
164 | |||
165 | int __perf_session__set_tracepoints_handlers(struct perf_session *session, | ||
166 | const struct perf_evsel_str_handler *assocs, | ||
167 | size_t nr_assocs); | ||
168 | |||
169 | #define perf_session__set_tracepoints_handlers(session, array) \ | ||
170 | __perf_session__set_tracepoints_handlers(session, array, ARRAY_SIZE(array)) | ||
161 | #endif /* __PERF_SESSION_H */ | 171 | #endif /* __PERF_SESSION_H */ |
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index a27237430c5f..0f5a0a496bc4 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
@@ -241,6 +241,54 @@ struct sort_entry sort_sym = { | |||
241 | .se_width_idx = HISTC_SYMBOL, | 241 | .se_width_idx = HISTC_SYMBOL, |
242 | }; | 242 | }; |
243 | 243 | ||
244 | /* --sort srcline */ | ||
245 | |||
246 | static int64_t | ||
247 | sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right) | ||
248 | { | ||
249 | return (int64_t)(right->ip - left->ip); | ||
250 | } | ||
251 | |||
252 | static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf, | ||
253 | size_t size, unsigned int width __used) | ||
254 | { | ||
255 | FILE *fp; | ||
256 | char cmd[PATH_MAX + 2], *path = self->srcline, *nl; | ||
257 | size_t line_len; | ||
258 | |||
259 | if (path != NULL) | ||
260 | goto out_path; | ||
261 | |||
262 | snprintf(cmd, sizeof(cmd), "addr2line -e %s %016" PRIx64, | ||
263 | self->ms.map->dso->long_name, self->ip); | ||
264 | fp = popen(cmd, "r"); | ||
265 | if (!fp) | ||
266 | goto out_ip; | ||
267 | |||
268 | if (getline(&path, &line_len, fp) < 0 || !line_len) | ||
269 | goto out_ip; | ||
270 | fclose(fp); | ||
271 | self->srcline = strdup(path); | ||
272 | if (self->srcline == NULL) | ||
273 | goto out_ip; | ||
274 | |||
275 | nl = strchr(self->srcline, '\n'); | ||
276 | if (nl != NULL) | ||
277 | *nl = '\0'; | ||
278 | path = self->srcline; | ||
279 | out_path: | ||
280 | return repsep_snprintf(bf, size, "%s", path); | ||
281 | out_ip: | ||
282 | return repsep_snprintf(bf, size, "%-#*llx", BITS_PER_LONG / 4, self->ip); | ||
283 | } | ||
284 | |||
285 | struct sort_entry sort_srcline = { | ||
286 | .se_header = "Source:Line", | ||
287 | .se_cmp = sort__srcline_cmp, | ||
288 | .se_snprintf = hist_entry__srcline_snprintf, | ||
289 | .se_width_idx = HISTC_SRCLINE, | ||
290 | }; | ||
291 | |||
244 | /* --sort parent */ | 292 | /* --sort parent */ |
245 | 293 | ||
246 | static int64_t | 294 | static int64_t |
@@ -439,6 +487,7 @@ static struct sort_dimension sort_dimensions[] = { | |||
439 | DIM(SORT_PARENT, "parent", sort_parent), | 487 | DIM(SORT_PARENT, "parent", sort_parent), |
440 | DIM(SORT_CPU, "cpu", sort_cpu), | 488 | DIM(SORT_CPU, "cpu", sort_cpu), |
441 | DIM(SORT_MISPREDICT, "mispredict", sort_mispredict), | 489 | DIM(SORT_MISPREDICT, "mispredict", sort_mispredict), |
490 | DIM(SORT_SRCLINE, "srcline", sort_srcline), | ||
442 | }; | 491 | }; |
443 | 492 | ||
444 | int sort_dimension__add(const char *tok) | 493 | int sort_dimension__add(const char *tok) |
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 472aa5a63a58..e724b26acd51 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
@@ -71,6 +71,7 @@ struct hist_entry { | |||
71 | char level; | 71 | char level; |
72 | bool used; | 72 | bool used; |
73 | u8 filtered; | 73 | u8 filtered; |
74 | char *srcline; | ||
74 | struct symbol *parent; | 75 | struct symbol *parent; |
75 | union { | 76 | union { |
76 | unsigned long position; | 77 | unsigned long position; |
@@ -93,6 +94,7 @@ enum sort_type { | |||
93 | SORT_SYM_FROM, | 94 | SORT_SYM_FROM, |
94 | SORT_SYM_TO, | 95 | SORT_SYM_TO, |
95 | SORT_MISPREDICT, | 96 | SORT_MISPREDICT, |
97 | SORT_SRCLINE, | ||
96 | }; | 98 | }; |
97 | 99 | ||
98 | /* | 100 | /* |
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index d5836382ff2c..199bc4d8905d 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c | |||
@@ -313,3 +313,25 @@ int strtailcmp(const char *s1, const char *s2) | |||
313 | return 0; | 313 | return 0; |
314 | } | 314 | } |
315 | 315 | ||
316 | /** | ||
317 | * rtrim - Removes trailing whitespace from @s. | ||
318 | * @s: The string to be stripped. | ||
319 | * | ||
320 | * Note that the first trailing whitespace is replaced with a %NUL-terminator | ||
321 | * in the given string @s. Returns @s. | ||
322 | */ | ||
323 | char *rtrim(char *s) | ||
324 | { | ||
325 | size_t size = strlen(s); | ||
326 | char *end; | ||
327 | |||
328 | if (!size) | ||
329 | return s; | ||
330 | |||
331 | end = s + size - 1; | ||
332 | while (end >= s && isspace(*end)) | ||
333 | end--; | ||
334 | *(end + 1) = '\0'; | ||
335 | |||
336 | return s; | ||
337 | } | ||
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 3e2e5ea0f03f..50958bbeb26a 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -1478,14 +1478,31 @@ static int elf_read_build_id(Elf *elf, void *bf, size_t size) | |||
1478 | goto out; | 1478 | goto out; |
1479 | } | 1479 | } |
1480 | 1480 | ||
1481 | sec = elf_section_by_name(elf, &ehdr, &shdr, | 1481 | /* |
1482 | ".note.gnu.build-id", NULL); | 1482 | * Check following sections for notes: |
1483 | if (sec == NULL) { | 1483 | * '.note.gnu.build-id' |
1484 | * '.notes' | ||
1485 | * '.note' (VDSO specific) | ||
1486 | */ | ||
1487 | do { | ||
1488 | sec = elf_section_by_name(elf, &ehdr, &shdr, | ||
1489 | ".note.gnu.build-id", NULL); | ||
1490 | if (sec) | ||
1491 | break; | ||
1492 | |||
1484 | sec = elf_section_by_name(elf, &ehdr, &shdr, | 1493 | sec = elf_section_by_name(elf, &ehdr, &shdr, |
1485 | ".notes", NULL); | 1494 | ".notes", NULL); |
1486 | if (sec == NULL) | 1495 | if (sec) |
1487 | goto out; | 1496 | break; |
1488 | } | 1497 | |
1498 | sec = elf_section_by_name(elf, &ehdr, &shdr, | ||
1499 | ".note", NULL); | ||
1500 | if (sec) | ||
1501 | break; | ||
1502 | |||
1503 | return err; | ||
1504 | |||
1505 | } while (0); | ||
1489 | 1506 | ||
1490 | data = elf_getdata(sec, NULL); | 1507 | data = elf_getdata(sec, NULL); |
1491 | if (data == NULL) | 1508 | if (data == NULL) |
@@ -1590,11 +1607,62 @@ out: | |||
1590 | return err; | 1607 | return err; |
1591 | } | 1608 | } |
1592 | 1609 | ||
1610 | static int filename__read_debuglink(const char *filename, | ||
1611 | char *debuglink, size_t size) | ||
1612 | { | ||
1613 | int fd, err = -1; | ||
1614 | Elf *elf; | ||
1615 | GElf_Ehdr ehdr; | ||
1616 | GElf_Shdr shdr; | ||
1617 | Elf_Data *data; | ||
1618 | Elf_Scn *sec; | ||
1619 | Elf_Kind ek; | ||
1620 | |||
1621 | fd = open(filename, O_RDONLY); | ||
1622 | if (fd < 0) | ||
1623 | goto out; | ||
1624 | |||
1625 | elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); | ||
1626 | if (elf == NULL) { | ||
1627 | pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename); | ||
1628 | goto out_close; | ||
1629 | } | ||
1630 | |||
1631 | ek = elf_kind(elf); | ||
1632 | if (ek != ELF_K_ELF) | ||
1633 | goto out_close; | ||
1634 | |||
1635 | if (gelf_getehdr(elf, &ehdr) == NULL) { | ||
1636 | pr_err("%s: cannot get elf header.\n", __func__); | ||
1637 | goto out_close; | ||
1638 | } | ||
1639 | |||
1640 | sec = elf_section_by_name(elf, &ehdr, &shdr, | ||
1641 | ".gnu_debuglink", NULL); | ||
1642 | if (sec == NULL) | ||
1643 | goto out_close; | ||
1644 | |||
1645 | data = elf_getdata(sec, NULL); | ||
1646 | if (data == NULL) | ||
1647 | goto out_close; | ||
1648 | |||
1649 | /* the start of this section is a zero-terminated string */ | ||
1650 | strncpy(debuglink, data->d_buf, size); | ||
1651 | |||
1652 | elf_end(elf); | ||
1653 | |||
1654 | out_close: | ||
1655 | close(fd); | ||
1656 | out: | ||
1657 | return err; | ||
1658 | } | ||
1659 | |||
1593 | char dso__symtab_origin(const struct dso *dso) | 1660 | char dso__symtab_origin(const struct dso *dso) |
1594 | { | 1661 | { |
1595 | static const char origin[] = { | 1662 | static const char origin[] = { |
1596 | [SYMTAB__KALLSYMS] = 'k', | 1663 | [SYMTAB__KALLSYMS] = 'k', |
1597 | [SYMTAB__JAVA_JIT] = 'j', | 1664 | [SYMTAB__JAVA_JIT] = 'j', |
1665 | [SYMTAB__DEBUGLINK] = 'l', | ||
1598 | [SYMTAB__BUILD_ID_CACHE] = 'B', | 1666 | [SYMTAB__BUILD_ID_CACHE] = 'B', |
1599 | [SYMTAB__FEDORA_DEBUGINFO] = 'f', | 1667 | [SYMTAB__FEDORA_DEBUGINFO] = 'f', |
1600 | [SYMTAB__UBUNTU_DEBUGINFO] = 'u', | 1668 | [SYMTAB__UBUNTU_DEBUGINFO] = 'u', |
@@ -1662,10 +1730,22 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) | |||
1662 | */ | 1730 | */ |
1663 | want_symtab = 1; | 1731 | want_symtab = 1; |
1664 | restart: | 1732 | restart: |
1665 | for (dso->symtab_type = SYMTAB__BUILD_ID_CACHE; | 1733 | for (dso->symtab_type = SYMTAB__DEBUGLINK; |
1666 | dso->symtab_type != SYMTAB__NOT_FOUND; | 1734 | dso->symtab_type != SYMTAB__NOT_FOUND; |
1667 | dso->symtab_type++) { | 1735 | dso->symtab_type++) { |
1668 | switch (dso->symtab_type) { | 1736 | switch (dso->symtab_type) { |
1737 | case SYMTAB__DEBUGLINK: { | ||
1738 | char *debuglink; | ||
1739 | strncpy(name, dso->long_name, size); | ||
1740 | debuglink = name + dso->long_name_len; | ||
1741 | while (debuglink != name && *debuglink != '/') | ||
1742 | debuglink--; | ||
1743 | if (*debuglink == '/') | ||
1744 | debuglink++; | ||
1745 | filename__read_debuglink(dso->long_name, debuglink, | ||
1746 | size - (debuglink - name)); | ||
1747 | } | ||
1748 | break; | ||
1669 | case SYMTAB__BUILD_ID_CACHE: | 1749 | case SYMTAB__BUILD_ID_CACHE: |
1670 | /* skip the locally configured cache if a symfs is given */ | 1750 | /* skip the locally configured cache if a symfs is given */ |
1671 | if (symbol_conf.symfs[0] || | 1751 | if (symbol_conf.symfs[0] || |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index af0752b1aca1..a884b99017f0 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -257,6 +257,7 @@ enum symtab_type { | |||
257 | SYMTAB__KALLSYMS = 0, | 257 | SYMTAB__KALLSYMS = 0, |
258 | SYMTAB__GUEST_KALLSYMS, | 258 | SYMTAB__GUEST_KALLSYMS, |
259 | SYMTAB__JAVA_JIT, | 259 | SYMTAB__JAVA_JIT, |
260 | SYMTAB__DEBUGLINK, | ||
260 | SYMTAB__BUILD_ID_CACHE, | 261 | SYMTAB__BUILD_ID_CACHE, |
261 | SYMTAB__FEDORA_DEBUGINFO, | 262 | SYMTAB__FEDORA_DEBUGINFO, |
262 | SYMTAB__UBUNTU_DEBUGINFO, | 263 | SYMTAB__UBUNTU_DEBUGINFO, |
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index abe0e8e95068..7eeebcee291c 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c | |||
@@ -65,7 +65,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) | |||
65 | top->freq ? "Hz" : ""); | 65 | top->freq ? "Hz" : ""); |
66 | } | 66 | } |
67 | 67 | ||
68 | ret += SNPRINTF(bf + ret, size - ret, "%s", event_name(top->sym_evsel)); | 68 | ret += SNPRINTF(bf + ret, size - ret, "%s", perf_evsel__name(top->sym_evsel)); |
69 | 69 | ||
70 | ret += SNPRINTF(bf + ret, size - ret, "], "); | 70 | ret += SNPRINTF(bf + ret, size - ret, "], "); |
71 | 71 | ||
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index 5dd3b5ec8411..0715c843c2e7 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c | |||
@@ -32,29 +32,25 @@ int header_page_size_size; | |||
32 | int header_page_ts_size; | 32 | int header_page_ts_size; |
33 | int header_page_data_offset; | 33 | int header_page_data_offset; |
34 | 34 | ||
35 | struct pevent *perf_pevent; | ||
36 | static struct pevent *pevent; | ||
37 | |||
38 | bool latency_format; | 35 | bool latency_format; |
39 | 36 | ||
40 | int read_trace_init(int file_bigendian, int host_bigendian) | 37 | struct pevent *read_trace_init(int file_bigendian, int host_bigendian) |
41 | { | 38 | { |
42 | if (pevent) | 39 | struct pevent *pevent = pevent_alloc(); |
43 | return 0; | ||
44 | |||
45 | perf_pevent = pevent_alloc(); | ||
46 | pevent = perf_pevent; | ||
47 | 40 | ||
48 | pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT); | 41 | if (pevent != NULL) { |
49 | pevent_set_file_bigendian(pevent, file_bigendian); | 42 | pevent_set_flag(pevent, PEVENT_NSEC_OUTPUT); |
50 | pevent_set_host_bigendian(pevent, host_bigendian); | 43 | pevent_set_file_bigendian(pevent, file_bigendian); |
44 | pevent_set_host_bigendian(pevent, host_bigendian); | ||
45 | } | ||
51 | 46 | ||
52 | return 0; | 47 | return pevent; |
53 | } | 48 | } |
54 | 49 | ||
55 | static int get_common_field(struct scripting_context *context, | 50 | static int get_common_field(struct scripting_context *context, |
56 | int *offset, int *size, const char *type) | 51 | int *offset, int *size, const char *type) |
57 | { | 52 | { |
53 | struct pevent *pevent = context->pevent; | ||
58 | struct event_format *event; | 54 | struct event_format *event; |
59 | struct format_field *field; | 55 | struct format_field *field; |
60 | 56 | ||
@@ -150,7 +146,7 @@ void *raw_field_ptr(struct event_format *event, const char *name, void *data) | |||
150 | return data + field->offset; | 146 | return data + field->offset; |
151 | } | 147 | } |
152 | 148 | ||
153 | int trace_parse_common_type(void *data) | 149 | int trace_parse_common_type(struct pevent *pevent, void *data) |
154 | { | 150 | { |
155 | struct pevent_record record; | 151 | struct pevent_record record; |
156 | 152 | ||
@@ -158,7 +154,7 @@ int trace_parse_common_type(void *data) | |||
158 | return pevent_data_type(pevent, &record); | 154 | return pevent_data_type(pevent, &record); |
159 | } | 155 | } |
160 | 156 | ||
161 | int trace_parse_common_pid(void *data) | 157 | int trace_parse_common_pid(struct pevent *pevent, void *data) |
162 | { | 158 | { |
163 | struct pevent_record record; | 159 | struct pevent_record record; |
164 | 160 | ||
@@ -166,27 +162,21 @@ int trace_parse_common_pid(void *data) | |||
166 | return pevent_data_pid(pevent, &record); | 162 | return pevent_data_pid(pevent, &record); |
167 | } | 163 | } |
168 | 164 | ||
169 | unsigned long long read_size(void *ptr, int size) | 165 | unsigned long long read_size(struct pevent *pevent, void *ptr, int size) |
170 | { | 166 | { |
171 | return pevent_read_number(pevent, ptr, size); | 167 | return pevent_read_number(pevent, ptr, size); |
172 | } | 168 | } |
173 | 169 | ||
174 | struct event_format *trace_find_event(int type) | 170 | void print_trace_event(struct pevent *pevent, int cpu, void *data, int size) |
175 | { | ||
176 | return pevent_find_event(pevent, type); | ||
177 | } | ||
178 | |||
179 | |||
180 | void print_trace_event(int cpu, void *data, int size) | ||
181 | { | 171 | { |
182 | struct event_format *event; | 172 | struct event_format *event; |
183 | struct pevent_record record; | 173 | struct pevent_record record; |
184 | struct trace_seq s; | 174 | struct trace_seq s; |
185 | int type; | 175 | int type; |
186 | 176 | ||
187 | type = trace_parse_common_type(data); | 177 | type = trace_parse_common_type(pevent, data); |
188 | 178 | ||
189 | event = trace_find_event(type); | 179 | event = pevent_find_event(pevent, type); |
190 | if (!event) { | 180 | if (!event) { |
191 | warning("ug! no event found for type %d", type); | 181 | warning("ug! no event found for type %d", type); |
192 | return; | 182 | return; |
@@ -202,8 +192,8 @@ void print_trace_event(int cpu, void *data, int size) | |||
202 | trace_seq_do_printf(&s); | 192 | trace_seq_do_printf(&s); |
203 | } | 193 | } |
204 | 194 | ||
205 | void print_event(int cpu, void *data, int size, unsigned long long nsecs, | 195 | void print_event(struct pevent *pevent, int cpu, void *data, int size, |
206 | char *comm) | 196 | unsigned long long nsecs, char *comm) |
207 | { | 197 | { |
208 | struct pevent_record record; | 198 | struct pevent_record record; |
209 | struct trace_seq s; | 199 | struct trace_seq s; |
@@ -226,7 +216,8 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs, | |||
226 | printf("\n"); | 216 | printf("\n"); |
227 | } | 217 | } |
228 | 218 | ||
229 | void parse_proc_kallsyms(char *file, unsigned int size __unused) | 219 | void parse_proc_kallsyms(struct pevent *pevent, |
220 | char *file, unsigned int size __unused) | ||
230 | { | 221 | { |
231 | unsigned long long addr; | 222 | unsigned long long addr; |
232 | char *func; | 223 | char *func; |
@@ -257,7 +248,8 @@ void parse_proc_kallsyms(char *file, unsigned int size __unused) | |||
257 | } | 248 | } |
258 | } | 249 | } |
259 | 250 | ||
260 | void parse_ftrace_printk(char *file, unsigned int size __unused) | 251 | void parse_ftrace_printk(struct pevent *pevent, |
252 | char *file, unsigned int size __unused) | ||
261 | { | 253 | { |
262 | unsigned long long addr; | 254 | unsigned long long addr; |
263 | char *printk; | 255 | char *printk; |
@@ -281,17 +273,19 @@ void parse_ftrace_printk(char *file, unsigned int size __unused) | |||
281 | } | 273 | } |
282 | } | 274 | } |
283 | 275 | ||
284 | int parse_ftrace_file(char *buf, unsigned long size) | 276 | int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size) |
285 | { | 277 | { |
286 | return pevent_parse_event(pevent, buf, size, "ftrace"); | 278 | return pevent_parse_event(pevent, buf, size, "ftrace"); |
287 | } | 279 | } |
288 | 280 | ||
289 | int parse_event_file(char *buf, unsigned long size, char *sys) | 281 | int parse_event_file(struct pevent *pevent, |
282 | char *buf, unsigned long size, char *sys) | ||
290 | { | 283 | { |
291 | return pevent_parse_event(pevent, buf, size, sys); | 284 | return pevent_parse_event(pevent, buf, size, sys); |
292 | } | 285 | } |
293 | 286 | ||
294 | struct event_format *trace_find_next_event(struct event_format *event) | 287 | struct event_format *trace_find_next_event(struct pevent *pevent, |
288 | struct event_format *event) | ||
295 | { | 289 | { |
296 | static int idx; | 290 | static int idx; |
297 | 291 | ||
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c index f097e0dd6c5c..719ed74a8565 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c | |||
@@ -114,20 +114,20 @@ static void skip(int size) | |||
114 | }; | 114 | }; |
115 | } | 115 | } |
116 | 116 | ||
117 | static unsigned int read4(void) | 117 | static unsigned int read4(struct pevent *pevent) |
118 | { | 118 | { |
119 | unsigned int data; | 119 | unsigned int data; |
120 | 120 | ||
121 | read_or_die(&data, 4); | 121 | read_or_die(&data, 4); |
122 | return __data2host4(perf_pevent, data); | 122 | return __data2host4(pevent, data); |
123 | } | 123 | } |
124 | 124 | ||
125 | static unsigned long long read8(void) | 125 | static unsigned long long read8(struct pevent *pevent) |
126 | { | 126 | { |
127 | unsigned long long data; | 127 | unsigned long long data; |
128 | 128 | ||
129 | read_or_die(&data, 8); | 129 | read_or_die(&data, 8); |
130 | return __data2host8(perf_pevent, data); | 130 | return __data2host8(pevent, data); |
131 | } | 131 | } |
132 | 132 | ||
133 | static char *read_string(void) | 133 | static char *read_string(void) |
@@ -168,12 +168,12 @@ static char *read_string(void) | |||
168 | return str; | 168 | return str; |
169 | } | 169 | } |
170 | 170 | ||
171 | static void read_proc_kallsyms(void) | 171 | static void read_proc_kallsyms(struct pevent *pevent) |
172 | { | 172 | { |
173 | unsigned int size; | 173 | unsigned int size; |
174 | char *buf; | 174 | char *buf; |
175 | 175 | ||
176 | size = read4(); | 176 | size = read4(pevent); |
177 | if (!size) | 177 | if (!size) |
178 | return; | 178 | return; |
179 | 179 | ||
@@ -181,29 +181,29 @@ static void read_proc_kallsyms(void) | |||
181 | read_or_die(buf, size); | 181 | read_or_die(buf, size); |
182 | buf[size] = '\0'; | 182 | buf[size] = '\0'; |
183 | 183 | ||
184 | parse_proc_kallsyms(buf, size); | 184 | parse_proc_kallsyms(pevent, buf, size); |
185 | 185 | ||
186 | free(buf); | 186 | free(buf); |
187 | } | 187 | } |
188 | 188 | ||
189 | static void read_ftrace_printk(void) | 189 | static void read_ftrace_printk(struct pevent *pevent) |
190 | { | 190 | { |
191 | unsigned int size; | 191 | unsigned int size; |
192 | char *buf; | 192 | char *buf; |
193 | 193 | ||
194 | size = read4(); | 194 | size = read4(pevent); |
195 | if (!size) | 195 | if (!size) |
196 | return; | 196 | return; |
197 | 197 | ||
198 | buf = malloc_or_die(size); | 198 | buf = malloc_or_die(size); |
199 | read_or_die(buf, size); | 199 | read_or_die(buf, size); |
200 | 200 | ||
201 | parse_ftrace_printk(buf, size); | 201 | parse_ftrace_printk(pevent, buf, size); |
202 | 202 | ||
203 | free(buf); | 203 | free(buf); |
204 | } | 204 | } |
205 | 205 | ||
206 | static void read_header_files(void) | 206 | static void read_header_files(struct pevent *pevent) |
207 | { | 207 | { |
208 | unsigned long long size; | 208 | unsigned long long size; |
209 | char *header_event; | 209 | char *header_event; |
@@ -214,7 +214,7 @@ static void read_header_files(void) | |||
214 | if (memcmp(buf, "header_page", 12) != 0) | 214 | if (memcmp(buf, "header_page", 12) != 0) |
215 | die("did not read header page"); | 215 | die("did not read header page"); |
216 | 216 | ||
217 | size = read8(); | 217 | size = read8(pevent); |
218 | skip(size); | 218 | skip(size); |
219 | 219 | ||
220 | /* | 220 | /* |
@@ -227,47 +227,48 @@ static void read_header_files(void) | |||
227 | if (memcmp(buf, "header_event", 13) != 0) | 227 | if (memcmp(buf, "header_event", 13) != 0) |
228 | die("did not read header event"); | 228 | die("did not read header event"); |
229 | 229 | ||
230 | size = read8(); | 230 | size = read8(pevent); |
231 | header_event = malloc_or_die(size); | 231 | header_event = malloc_or_die(size); |
232 | read_or_die(header_event, size); | 232 | read_or_die(header_event, size); |
233 | free(header_event); | 233 | free(header_event); |
234 | } | 234 | } |
235 | 235 | ||
236 | static void read_ftrace_file(unsigned long long size) | 236 | static void read_ftrace_file(struct pevent *pevent, unsigned long long size) |
237 | { | 237 | { |
238 | char *buf; | 238 | char *buf; |
239 | 239 | ||
240 | buf = malloc_or_die(size); | 240 | buf = malloc_or_die(size); |
241 | read_or_die(buf, size); | 241 | read_or_die(buf, size); |
242 | parse_ftrace_file(buf, size); | 242 | parse_ftrace_file(pevent, buf, size); |
243 | free(buf); | 243 | free(buf); |
244 | } | 244 | } |
245 | 245 | ||
246 | static void read_event_file(char *sys, unsigned long long size) | 246 | static void read_event_file(struct pevent *pevent, char *sys, |
247 | unsigned long long size) | ||
247 | { | 248 | { |
248 | char *buf; | 249 | char *buf; |
249 | 250 | ||
250 | buf = malloc_or_die(size); | 251 | buf = malloc_or_die(size); |
251 | read_or_die(buf, size); | 252 | read_or_die(buf, size); |
252 | parse_event_file(buf, size, sys); | 253 | parse_event_file(pevent, buf, size, sys); |
253 | free(buf); | 254 | free(buf); |
254 | } | 255 | } |
255 | 256 | ||
256 | static void read_ftrace_files(void) | 257 | static void read_ftrace_files(struct pevent *pevent) |
257 | { | 258 | { |
258 | unsigned long long size; | 259 | unsigned long long size; |
259 | int count; | 260 | int count; |
260 | int i; | 261 | int i; |
261 | 262 | ||
262 | count = read4(); | 263 | count = read4(pevent); |
263 | 264 | ||
264 | for (i = 0; i < count; i++) { | 265 | for (i = 0; i < count; i++) { |
265 | size = read8(); | 266 | size = read8(pevent); |
266 | read_ftrace_file(size); | 267 | read_ftrace_file(pevent, size); |
267 | } | 268 | } |
268 | } | 269 | } |
269 | 270 | ||
270 | static void read_event_files(void) | 271 | static void read_event_files(struct pevent *pevent) |
271 | { | 272 | { |
272 | unsigned long long size; | 273 | unsigned long long size; |
273 | char *sys; | 274 | char *sys; |
@@ -275,15 +276,15 @@ static void read_event_files(void) | |||
275 | int count; | 276 | int count; |
276 | int i,x; | 277 | int i,x; |
277 | 278 | ||
278 | systems = read4(); | 279 | systems = read4(pevent); |
279 | 280 | ||
280 | for (i = 0; i < systems; i++) { | 281 | for (i = 0; i < systems; i++) { |
281 | sys = read_string(); | 282 | sys = read_string(); |
282 | 283 | ||
283 | count = read4(); | 284 | count = read4(pevent); |
284 | for (x=0; x < count; x++) { | 285 | for (x=0; x < count; x++) { |
285 | size = read8(); | 286 | size = read8(pevent); |
286 | read_event_file(sys, size); | 287 | read_event_file(pevent, sys, size); |
287 | } | 288 | } |
288 | } | 289 | } |
289 | } | 290 | } |
@@ -377,7 +378,7 @@ static int calc_index(void *ptr, int cpu) | |||
377 | return (unsigned long)ptr - (unsigned long)cpu_data[cpu].page; | 378 | return (unsigned long)ptr - (unsigned long)cpu_data[cpu].page; |
378 | } | 379 | } |
379 | 380 | ||
380 | struct pevent_record *trace_peek_data(int cpu) | 381 | struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu) |
381 | { | 382 | { |
382 | struct pevent_record *data; | 383 | struct pevent_record *data; |
383 | void *page = cpu_data[cpu].page; | 384 | void *page = cpu_data[cpu].page; |
@@ -399,15 +400,15 @@ struct pevent_record *trace_peek_data(int cpu) | |||
399 | /* FIXME: handle header page */ | 400 | /* FIXME: handle header page */ |
400 | if (header_page_ts_size != 8) | 401 | if (header_page_ts_size != 8) |
401 | die("expected a long long type for timestamp"); | 402 | die("expected a long long type for timestamp"); |
402 | cpu_data[cpu].timestamp = data2host8(perf_pevent, ptr); | 403 | cpu_data[cpu].timestamp = data2host8(pevent, ptr); |
403 | ptr += 8; | 404 | ptr += 8; |
404 | switch (header_page_size_size) { | 405 | switch (header_page_size_size) { |
405 | case 4: | 406 | case 4: |
406 | cpu_data[cpu].page_size = data2host4(perf_pevent, ptr); | 407 | cpu_data[cpu].page_size = data2host4(pevent, ptr); |
407 | ptr += 4; | 408 | ptr += 4; |
408 | break; | 409 | break; |
409 | case 8: | 410 | case 8: |
410 | cpu_data[cpu].page_size = data2host8(perf_pevent, ptr); | 411 | cpu_data[cpu].page_size = data2host8(pevent, ptr); |
411 | ptr += 8; | 412 | ptr += 8; |
412 | break; | 413 | break; |
413 | default: | 414 | default: |
@@ -421,10 +422,10 @@ read_again: | |||
421 | 422 | ||
422 | if (idx >= cpu_data[cpu].page_size) { | 423 | if (idx >= cpu_data[cpu].page_size) { |
423 | get_next_page(cpu); | 424 | get_next_page(cpu); |
424 | return trace_peek_data(cpu); | 425 | return trace_peek_data(pevent, cpu); |
425 | } | 426 | } |
426 | 427 | ||
427 | type_len_ts = data2host4(perf_pevent, ptr); | 428 | type_len_ts = data2host4(pevent, ptr); |
428 | ptr += 4; | 429 | ptr += 4; |
429 | 430 | ||
430 | type_len = type_len4host(type_len_ts); | 431 | type_len = type_len4host(type_len_ts); |
@@ -434,14 +435,14 @@ read_again: | |||
434 | case RINGBUF_TYPE_PADDING: | 435 | case RINGBUF_TYPE_PADDING: |
435 | if (!delta) | 436 | if (!delta) |
436 | die("error, hit unexpected end of page"); | 437 | die("error, hit unexpected end of page"); |
437 | length = data2host4(perf_pevent, ptr); | 438 | length = data2host4(pevent, ptr); |
438 | ptr += 4; | 439 | ptr += 4; |
439 | length *= 4; | 440 | length *= 4; |
440 | ptr += length; | 441 | ptr += length; |
441 | goto read_again; | 442 | goto read_again; |
442 | 443 | ||
443 | case RINGBUF_TYPE_TIME_EXTEND: | 444 | case RINGBUF_TYPE_TIME_EXTEND: |
444 | extend = data2host4(perf_pevent, ptr); | 445 | extend = data2host4(pevent, ptr); |
445 | ptr += 4; | 446 | ptr += 4; |
446 | extend <<= TS_SHIFT; | 447 | extend <<= TS_SHIFT; |
447 | extend += delta; | 448 | extend += delta; |
@@ -452,7 +453,7 @@ read_again: | |||
452 | ptr += 12; | 453 | ptr += 12; |
453 | break; | 454 | break; |
454 | case 0: | 455 | case 0: |
455 | length = data2host4(perf_pevent, ptr); | 456 | length = data2host4(pevent, ptr); |
456 | ptr += 4; | 457 | ptr += 4; |
457 | die("here! length=%d", length); | 458 | die("here! length=%d", length); |
458 | break; | 459 | break; |
@@ -477,17 +478,17 @@ read_again: | |||
477 | return data; | 478 | return data; |
478 | } | 479 | } |
479 | 480 | ||
480 | struct pevent_record *trace_read_data(int cpu) | 481 | struct pevent_record *trace_read_data(struct pevent *pevent, int cpu) |
481 | { | 482 | { |
482 | struct pevent_record *data; | 483 | struct pevent_record *data; |
483 | 484 | ||
484 | data = trace_peek_data(cpu); | 485 | data = trace_peek_data(pevent, cpu); |
485 | cpu_data[cpu].next = NULL; | 486 | cpu_data[cpu].next = NULL; |
486 | 487 | ||
487 | return data; | 488 | return data; |
488 | } | 489 | } |
489 | 490 | ||
490 | ssize_t trace_report(int fd, bool __repipe) | 491 | ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe) |
491 | { | 492 | { |
492 | char buf[BUFSIZ]; | 493 | char buf[BUFSIZ]; |
493 | char test[] = { 23, 8, 68 }; | 494 | char test[] = { 23, 8, 68 }; |
@@ -519,30 +520,32 @@ ssize_t trace_report(int fd, bool __repipe) | |||
519 | file_bigendian = buf[0]; | 520 | file_bigendian = buf[0]; |
520 | host_bigendian = bigendian(); | 521 | host_bigendian = bigendian(); |
521 | 522 | ||
522 | read_trace_init(file_bigendian, host_bigendian); | 523 | *ppevent = read_trace_init(file_bigendian, host_bigendian); |
524 | if (*ppevent == NULL) | ||
525 | die("read_trace_init failed"); | ||
523 | 526 | ||
524 | read_or_die(buf, 1); | 527 | read_or_die(buf, 1); |
525 | long_size = buf[0]; | 528 | long_size = buf[0]; |
526 | 529 | ||
527 | page_size = read4(); | 530 | page_size = read4(*ppevent); |
528 | 531 | ||
529 | read_header_files(); | 532 | read_header_files(*ppevent); |
530 | 533 | ||
531 | read_ftrace_files(); | 534 | read_ftrace_files(*ppevent); |
532 | read_event_files(); | 535 | read_event_files(*ppevent); |
533 | read_proc_kallsyms(); | 536 | read_proc_kallsyms(*ppevent); |
534 | read_ftrace_printk(); | 537 | read_ftrace_printk(*ppevent); |
535 | 538 | ||
536 | size = calc_data_size - 1; | 539 | size = calc_data_size - 1; |
537 | calc_data_size = 0; | 540 | calc_data_size = 0; |
538 | repipe = false; | 541 | repipe = false; |
539 | 542 | ||
540 | if (show_funcs) { | 543 | if (show_funcs) { |
541 | pevent_print_funcs(perf_pevent); | 544 | pevent_print_funcs(*ppevent); |
542 | return size; | 545 | return size; |
543 | } | 546 | } |
544 | if (show_printk) { | 547 | if (show_printk) { |
545 | pevent_print_printk(perf_pevent); | 548 | pevent_print_printk(*ppevent); |
546 | return size; | 549 | return size; |
547 | } | 550 | } |
548 | 551 | ||
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 18ae6c1831d3..474aa7a7df43 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c | |||
@@ -36,6 +36,7 @@ static int stop_script_unsupported(void) | |||
36 | } | 36 | } |
37 | 37 | ||
38 | static void process_event_unsupported(union perf_event *event __unused, | 38 | static void process_event_unsupported(union perf_event *event __unused, |
39 | struct pevent *pevent __unused, | ||
39 | struct perf_sample *sample __unused, | 40 | struct perf_sample *sample __unused, |
40 | struct perf_evsel *evsel __unused, | 41 | struct perf_evsel *evsel __unused, |
41 | struct machine *machine __unused, | 42 | struct machine *machine __unused, |
@@ -61,7 +62,8 @@ static int python_start_script_unsupported(const char *script __unused, | |||
61 | return -1; | 62 | return -1; |
62 | } | 63 | } |
63 | 64 | ||
64 | static int python_generate_script_unsupported(const char *outfile __unused) | 65 | static int python_generate_script_unsupported(struct pevent *pevent __unused, |
66 | const char *outfile __unused) | ||
65 | { | 67 | { |
66 | print_python_unsupported_msg(); | 68 | print_python_unsupported_msg(); |
67 | 69 | ||
@@ -122,7 +124,8 @@ static int perl_start_script_unsupported(const char *script __unused, | |||
122 | return -1; | 124 | return -1; |
123 | } | 125 | } |
124 | 126 | ||
125 | static int perl_generate_script_unsupported(const char *outfile __unused) | 127 | static int perl_generate_script_unsupported(struct pevent *pevent __unused, |
128 | const char *outfile __unused) | ||
126 | { | 129 | { |
127 | print_perl_unsupported_msg(); | 130 | print_perl_unsupported_msg(); |
128 | 131 | ||
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 639852ac1117..8fef1d6687b7 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h | |||
@@ -8,6 +8,7 @@ | |||
8 | struct machine; | 8 | struct machine; |
9 | struct perf_sample; | 9 | struct perf_sample; |
10 | union perf_event; | 10 | union perf_event; |
11 | struct perf_tool; | ||
11 | struct thread; | 12 | struct thread; |
12 | 13 | ||
13 | extern int header_page_size_size; | 14 | extern int header_page_size_size; |
@@ -29,35 +30,36 @@ enum { | |||
29 | 30 | ||
30 | int bigendian(void); | 31 | int bigendian(void); |
31 | 32 | ||
32 | int read_trace_init(int file_bigendian, int host_bigendian); | 33 | struct pevent *read_trace_init(int file_bigendian, int host_bigendian); |
33 | void print_trace_event(int cpu, void *data, int size); | 34 | void print_trace_event(struct pevent *pevent, int cpu, void *data, int size); |
34 | 35 | ||
35 | void print_event(int cpu, void *data, int size, unsigned long long nsecs, | 36 | void print_event(struct pevent *pevent, int cpu, void *data, int size, |
36 | char *comm); | 37 | unsigned long long nsecs, char *comm); |
37 | 38 | ||
38 | int parse_ftrace_file(char *buf, unsigned long size); | 39 | int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size); |
39 | int parse_event_file(char *buf, unsigned long size, char *sys); | 40 | int parse_event_file(struct pevent *pevent, |
41 | char *buf, unsigned long size, char *sys); | ||
40 | 42 | ||
41 | struct pevent_record *trace_peek_data(int cpu); | 43 | struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu); |
42 | struct event_format *trace_find_event(int type); | ||
43 | 44 | ||
44 | unsigned long long | 45 | unsigned long long |
45 | raw_field_value(struct event_format *event, const char *name, void *data); | 46 | raw_field_value(struct event_format *event, const char *name, void *data); |
46 | void *raw_field_ptr(struct event_format *event, const char *name, void *data); | 47 | void *raw_field_ptr(struct event_format *event, const char *name, void *data); |
47 | 48 | ||
48 | void parse_proc_kallsyms(char *file, unsigned int size __unused); | 49 | void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size); |
49 | void parse_ftrace_printk(char *file, unsigned int size __unused); | 50 | void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size); |
50 | 51 | ||
51 | ssize_t trace_report(int fd, bool repipe); | 52 | ssize_t trace_report(int fd, struct pevent **pevent, bool repipe); |
52 | 53 | ||
53 | int trace_parse_common_type(void *data); | 54 | int trace_parse_common_type(struct pevent *pevent, void *data); |
54 | int trace_parse_common_pid(void *data); | 55 | int trace_parse_common_pid(struct pevent *pevent, void *data); |
55 | 56 | ||
56 | struct event_format *trace_find_next_event(struct event_format *event); | 57 | struct event_format *trace_find_next_event(struct pevent *pevent, |
57 | unsigned long long read_size(void *ptr, int size); | 58 | struct event_format *event); |
59 | unsigned long long read_size(struct pevent *pevent, void *ptr, int size); | ||
58 | unsigned long long eval_flag(const char *flag); | 60 | unsigned long long eval_flag(const char *flag); |
59 | 61 | ||
60 | struct pevent_record *trace_read_data(int cpu); | 62 | struct pevent_record *trace_read_data(struct pevent *pevent, int cpu); |
61 | int read_tracing_data(int fd, struct list_head *pattrs); | 63 | int read_tracing_data(int fd, struct list_head *pattrs); |
62 | 64 | ||
63 | struct tracing_data { | 65 | struct tracing_data { |
@@ -77,11 +79,12 @@ struct scripting_ops { | |||
77 | int (*start_script) (const char *script, int argc, const char **argv); | 79 | int (*start_script) (const char *script, int argc, const char **argv); |
78 | int (*stop_script) (void); | 80 | int (*stop_script) (void); |
79 | void (*process_event) (union perf_event *event, | 81 | void (*process_event) (union perf_event *event, |
82 | struct pevent *pevent, | ||
80 | struct perf_sample *sample, | 83 | struct perf_sample *sample, |
81 | struct perf_evsel *evsel, | 84 | struct perf_evsel *evsel, |
82 | struct machine *machine, | 85 | struct machine *machine, |
83 | struct thread *thread); | 86 | struct thread *thread); |
84 | int (*generate_script) (const char *outfile); | 87 | int (*generate_script) (struct pevent *pevent, const char *outfile); |
85 | }; | 88 | }; |
86 | 89 | ||
87 | int script_spec_register(const char *spec, struct scripting_ops *ops); | 90 | int script_spec_register(const char *spec, struct scripting_ops *ops); |
@@ -90,6 +93,7 @@ void setup_perl_scripting(void); | |||
90 | void setup_python_scripting(void); | 93 | void setup_python_scripting(void); |
91 | 94 | ||
92 | struct scripting_context { | 95 | struct scripting_context { |
96 | struct pevent *pevent; | ||
93 | void *event_data; | 97 | void *event_data; |
94 | }; | 98 | }; |
95 | 99 | ||
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 2daaedb83d84..b13c7331eaf8 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -264,4 +264,6 @@ bool is_power_of_2(unsigned long n) | |||
264 | 264 | ||
265 | size_t hex_width(u64 v); | 265 | size_t hex_width(u64 v); |
266 | 266 | ||
267 | char *rtrim(char *s); | ||
268 | |||
267 | #endif | 269 | #endif |