aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/parisc/Kconfig2
-rw-r--r--arch/parisc/Makefile21
-rw-r--r--arch/parisc/include/asm/hardirq.h9
-rw-r--r--arch/parisc/include/asm/processor.h3
-rw-r--r--arch/parisc/kernel/entry.S155
-rw-r--r--arch/parisc/kernel/irq.c101
-rw-r--r--arch/parisc/mm/init.c4
7 files changed, 194 insertions, 101 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index cad060f288cf..6507dabdd5dd 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -245,7 +245,7 @@ config SMP
245 245
246config IRQSTACKS 246config IRQSTACKS
247 bool "Use separate kernel stacks when processing interrupts" 247 bool "Use separate kernel stacks when processing interrupts"
248 default n 248 default y
249 help 249 help
250 If you say Y here the kernel will use separate kernel stacks 250 If you say Y here the kernel will use separate kernel stacks
251 for handling hard and soft interrupts. This can help avoid 251 for handling hard and soft interrupts. This can help avoid
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 2f967cc6649e..197690068f88 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -23,24 +23,21 @@ NM = sh $(srctree)/arch/parisc/nm
23CHECKFLAGS += -D__hppa__=1 23CHECKFLAGS += -D__hppa__=1
24LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) 24LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
25 25
26MACHINE := $(shell uname -m)
27NATIVE := $(if $(filter parisc%,$(MACHINE)),1,0)
28
29ifdef CONFIG_64BIT 26ifdef CONFIG_64BIT
30UTS_MACHINE := parisc64 27UTS_MACHINE := parisc64
31CHECKFLAGS += -D__LP64__=1 -m64 28CHECKFLAGS += -D__LP64__=1 -m64
32WIDTH := 64 29CC_ARCHES = hppa64
33else # 32-bit 30else # 32-bit
34WIDTH := 31CC_ARCHES = hppa hppa2.0 hppa1.1
35endif 32endif
36 33
37# attempt to help out folks who are cross-compiling 34ifneq ($(SUBARCH),$(UTS_MACHINE))
38ifeq ($(NATIVE),1) 35 ifeq ($(CROSS_COMPILE),)
39CROSS_COMPILE := hppa$(WIDTH)-linux- 36 CC_SUFFIXES = linux linux-gnu unknown-linux-gnu
40else 37 CROSS_COMPILE := $(call cc-cross-prefix, \
41 ifeq ($(CROSS_COMPILE),) 38 $(foreach a,$(CC_ARCHES), \
42 CROSS_COMPILE := hppa$(WIDTH)-linux-gnu- 39 $(foreach s,$(CC_SUFFIXES),$(a)-$(s)-)))
43 endif 40 endif
44endif 41endif
45 42
46OBJCOPY_FLAGS =-O binary -R .note -R .comment -S 43OBJCOPY_FLAGS =-O binary -R .note -R .comment -S
diff --git a/arch/parisc/include/asm/hardirq.h b/arch/parisc/include/asm/hardirq.h
index 12373c4dabab..c19f7138ba48 100644
--- a/arch/parisc/include/asm/hardirq.h
+++ b/arch/parisc/include/asm/hardirq.h
@@ -11,10 +11,18 @@
11#include <linux/threads.h> 11#include <linux/threads.h>
12#include <linux/irq.h> 12#include <linux/irq.h>
13 13
14#ifdef CONFIG_IRQSTACKS
15#define __ARCH_HAS_DO_SOFTIRQ
16#endif
17
14typedef struct { 18typedef struct {
15 unsigned int __softirq_pending; 19 unsigned int __softirq_pending;
16#ifdef CONFIG_DEBUG_STACKOVERFLOW 20#ifdef CONFIG_DEBUG_STACKOVERFLOW
17 unsigned int kernel_stack_usage; 21 unsigned int kernel_stack_usage;
22#ifdef CONFIG_IRQSTACKS
23 unsigned int irq_stack_usage;
24 unsigned int irq_stack_counter;
25#endif
18#endif 26#endif
19#ifdef CONFIG_SMP 27#ifdef CONFIG_SMP
20 unsigned int irq_resched_count; 28 unsigned int irq_resched_count;
@@ -28,6 +36,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
28#define __ARCH_IRQ_STAT 36#define __ARCH_IRQ_STAT
29#define __IRQ_STAT(cpu, member) (irq_stat[cpu].member) 37#define __IRQ_STAT(cpu, member) (irq_stat[cpu].member)
30#define inc_irq_stat(member) this_cpu_inc(irq_stat.member) 38#define inc_irq_stat(member) this_cpu_inc(irq_stat.member)
39#define __inc_irq_stat(member) __this_cpu_inc(irq_stat.member)
31#define local_softirq_pending() this_cpu_read(irq_stat.__softirq_pending) 40#define local_softirq_pending() this_cpu_read(irq_stat.__softirq_pending)
32 41
33#define __ARCH_SET_SOFTIRQ_PENDING 42#define __ARCH_SET_SOFTIRQ_PENDING
diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h
index 064015547d1e..cfbc43929cf6 100644
--- a/arch/parisc/include/asm/processor.h
+++ b/arch/parisc/include/asm/processor.h
@@ -63,10 +63,13 @@
63 */ 63 */
64#ifdef __KERNEL__ 64#ifdef __KERNEL__
65 65
66#include <linux/spinlock_types.h>
67
66#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */ 68#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */
67 69
68union irq_stack_union { 70union irq_stack_union {
69 unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)]; 71 unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
72 raw_spinlock_t lock;
70}; 73};
71 74
72DECLARE_PER_CPU(union irq_stack_union, irq_stack_union); 75DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 4bb96ad9b0b1..ae27cb6ce19a 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -452,9 +452,41 @@
452 L2_ptep \pgd,\pte,\index,\va,\fault 452 L2_ptep \pgd,\pte,\index,\va,\fault
453 .endm 453 .endm
454 454
455 /* Acquire pa_dbit_lock lock. */
456 .macro dbit_lock spc,tmp,tmp1
457#ifdef CONFIG_SMP
458 cmpib,COND(=),n 0,\spc,2f
459 load32 PA(pa_dbit_lock),\tmp
4601: LDCW 0(\tmp),\tmp1
461 cmpib,COND(=) 0,\tmp1,1b
462 nop
4632:
464#endif
465 .endm
466
467 /* Release pa_dbit_lock lock without reloading lock address. */
468 .macro dbit_unlock0 spc,tmp
469#ifdef CONFIG_SMP
470 or,COND(=) %r0,\spc,%r0
471 stw \spc,0(\tmp)
472#endif
473 .endm
474
475 /* Release pa_dbit_lock lock. */
476 .macro dbit_unlock1 spc,tmp
477#ifdef CONFIG_SMP
478 load32 PA(pa_dbit_lock),\tmp
479 dbit_unlock0 \spc,\tmp
480#endif
481 .endm
482
455 /* Set the _PAGE_ACCESSED bit of the PTE. Be clever and 483 /* Set the _PAGE_ACCESSED bit of the PTE. Be clever and
456 * don't needlessly dirty the cache line if it was already set */ 484 * don't needlessly dirty the cache line if it was already set */
457 .macro update_ptep ptep,pte,tmp,tmp1 485 .macro update_ptep spc,ptep,pte,tmp,tmp1
486#ifdef CONFIG_SMP
487 or,COND(=) %r0,\spc,%r0
488 LDREG 0(\ptep),\pte
489#endif
458 ldi _PAGE_ACCESSED,\tmp1 490 ldi _PAGE_ACCESSED,\tmp1
459 or \tmp1,\pte,\tmp 491 or \tmp1,\pte,\tmp
460 and,COND(<>) \tmp1,\pte,%r0 492 and,COND(<>) \tmp1,\pte,%r0
@@ -463,7 +495,11 @@
463 495
464 /* Set the dirty bit (and accessed bit). No need to be 496 /* Set the dirty bit (and accessed bit). No need to be
465 * clever, this is only used from the dirty fault */ 497 * clever, this is only used from the dirty fault */
466 .macro update_dirty ptep,pte,tmp 498 .macro update_dirty spc,ptep,pte,tmp
499#ifdef CONFIG_SMP
500 or,COND(=) %r0,\spc,%r0
501 LDREG 0(\ptep),\pte
502#endif
467 ldi _PAGE_ACCESSED|_PAGE_DIRTY,\tmp 503 ldi _PAGE_ACCESSED|_PAGE_DIRTY,\tmp
468 or \tmp,\pte,\pte 504 or \tmp,\pte,\pte
469 STREG \pte,0(\ptep) 505 STREG \pte,0(\ptep)
@@ -1111,11 +1147,13 @@ dtlb_miss_20w:
1111 1147
1112 L3_ptep ptp,pte,t0,va,dtlb_check_alias_20w 1148 L3_ptep ptp,pte,t0,va,dtlb_check_alias_20w
1113 1149
1114 update_ptep ptp,pte,t0,t1 1150 dbit_lock spc,t0,t1
1151 update_ptep spc,ptp,pte,t0,t1
1115 1152
1116 make_insert_tlb spc,pte,prot 1153 make_insert_tlb spc,pte,prot
1117 1154
1118 idtlbt pte,prot 1155 idtlbt pte,prot
1156 dbit_unlock1 spc,t0
1119 1157
1120 rfir 1158 rfir
1121 nop 1159 nop
@@ -1135,11 +1173,13 @@ nadtlb_miss_20w:
1135 1173
1136 L3_ptep ptp,pte,t0,va,nadtlb_check_alias_20w 1174 L3_ptep ptp,pte,t0,va,nadtlb_check_alias_20w
1137 1175
1138 update_ptep ptp,pte,t0,t1 1176 dbit_lock spc,t0,t1
1177 update_ptep spc,ptp,pte,t0,t1
1139 1178
1140 make_insert_tlb spc,pte,prot 1179 make_insert_tlb spc,pte,prot
1141 1180
1142 idtlbt pte,prot 1181 idtlbt pte,prot
1182 dbit_unlock1 spc,t0
1143 1183
1144 rfir 1184 rfir
1145 nop 1185 nop
@@ -1161,7 +1201,8 @@ dtlb_miss_11:
1161 1201
1162 L2_ptep ptp,pte,t0,va,dtlb_check_alias_11 1202 L2_ptep ptp,pte,t0,va,dtlb_check_alias_11
1163 1203
1164 update_ptep ptp,pte,t0,t1 1204 dbit_lock spc,t0,t1
1205 update_ptep spc,ptp,pte,t0,t1
1165 1206
1166 make_insert_tlb_11 spc,pte,prot 1207 make_insert_tlb_11 spc,pte,prot
1167 1208
@@ -1172,6 +1213,7 @@ dtlb_miss_11:
1172 idtlbp prot,(%sr1,va) 1213 idtlbp prot,(%sr1,va)
1173 1214
1174 mtsp t0, %sr1 /* Restore sr1 */ 1215 mtsp t0, %sr1 /* Restore sr1 */
1216 dbit_unlock1 spc,t0
1175 1217
1176 rfir 1218 rfir
1177 nop 1219 nop
@@ -1192,7 +1234,8 @@ nadtlb_miss_11:
1192 1234
1193 L2_ptep ptp,pte,t0,va,nadtlb_check_alias_11 1235 L2_ptep ptp,pte,t0,va,nadtlb_check_alias_11
1194 1236
1195 update_ptep ptp,pte,t0,t1 1237 dbit_lock spc,t0,t1
1238 update_ptep spc,ptp,pte,t0,t1
1196 1239
1197 make_insert_tlb_11 spc,pte,prot 1240 make_insert_tlb_11 spc,pte,prot
1198 1241
@@ -1204,6 +1247,7 @@ nadtlb_miss_11:
1204 idtlbp prot,(%sr1,va) 1247 idtlbp prot,(%sr1,va)
1205 1248
1206 mtsp t0, %sr1 /* Restore sr1 */ 1249 mtsp t0, %sr1 /* Restore sr1 */
1250 dbit_unlock1 spc,t0
1207 1251
1208 rfir 1252 rfir
1209 nop 1253 nop
@@ -1224,13 +1268,15 @@ dtlb_miss_20:
1224 1268
1225 L2_ptep ptp,pte,t0,va,dtlb_check_alias_20 1269 L2_ptep ptp,pte,t0,va,dtlb_check_alias_20
1226 1270
1227 update_ptep ptp,pte,t0,t1 1271 dbit_lock spc,t0,t1
1272 update_ptep spc,ptp,pte,t0,t1
1228 1273
1229 make_insert_tlb spc,pte,prot 1274 make_insert_tlb spc,pte,prot
1230 1275
1231 f_extend pte,t0 1276 f_extend pte,t0
1232 1277
1233 idtlbt pte,prot 1278 idtlbt pte,prot
1279 dbit_unlock1 spc,t0
1234 1280
1235 rfir 1281 rfir
1236 nop 1282 nop
@@ -1250,13 +1296,15 @@ nadtlb_miss_20:
1250 1296
1251 L2_ptep ptp,pte,t0,va,nadtlb_check_alias_20 1297 L2_ptep ptp,pte,t0,va,nadtlb_check_alias_20
1252 1298
1253 update_ptep ptp,pte,t0,t1 1299 dbit_lock spc,t0,t1
1300 update_ptep spc,ptp,pte,t0,t1
1254 1301
1255 make_insert_tlb spc,pte,prot 1302 make_insert_tlb spc,pte,prot
1256 1303
1257 f_extend pte,t0 1304 f_extend pte,t0
1258 1305
1259 idtlbt pte,prot 1306 idtlbt pte,prot
1307 dbit_unlock1 spc,t0
1260 1308
1261 rfir 1309 rfir
1262 nop 1310 nop
@@ -1357,11 +1405,13 @@ itlb_miss_20w:
1357 1405
1358 L3_ptep ptp,pte,t0,va,itlb_fault 1406 L3_ptep ptp,pte,t0,va,itlb_fault
1359 1407
1360 update_ptep ptp,pte,t0,t1 1408 dbit_lock spc,t0,t1
1409 update_ptep spc,ptp,pte,t0,t1
1361 1410
1362 make_insert_tlb spc,pte,prot 1411 make_insert_tlb spc,pte,prot
1363 1412
1364 iitlbt pte,prot 1413 iitlbt pte,prot
1414 dbit_unlock1 spc,t0
1365 1415
1366 rfir 1416 rfir
1367 nop 1417 nop
@@ -1379,11 +1429,13 @@ naitlb_miss_20w:
1379 1429
1380 L3_ptep ptp,pte,t0,va,naitlb_check_alias_20w 1430 L3_ptep ptp,pte,t0,va,naitlb_check_alias_20w
1381 1431
1382 update_ptep ptp,pte,t0,t1 1432 dbit_lock spc,t0,t1
1433 update_ptep spc,ptp,pte,t0,t1
1383 1434
1384 make_insert_tlb spc,pte,prot 1435 make_insert_tlb spc,pte,prot
1385 1436
1386 iitlbt pte,prot 1437 iitlbt pte,prot
1438 dbit_unlock1 spc,t0
1387 1439
1388 rfir 1440 rfir
1389 nop 1441 nop
@@ -1405,7 +1457,8 @@ itlb_miss_11:
1405 1457
1406 L2_ptep ptp,pte,t0,va,itlb_fault 1458 L2_ptep ptp,pte,t0,va,itlb_fault
1407 1459
1408 update_ptep ptp,pte,t0,t1 1460 dbit_lock spc,t0,t1
1461 update_ptep spc,ptp,pte,t0,t1
1409 1462
1410 make_insert_tlb_11 spc,pte,prot 1463 make_insert_tlb_11 spc,pte,prot
1411 1464
@@ -1416,6 +1469,7 @@ itlb_miss_11:
1416 iitlbp prot,(%sr1,va) 1469 iitlbp prot,(%sr1,va)
1417 1470
1418 mtsp t0, %sr1 /* Restore sr1 */ 1471 mtsp t0, %sr1 /* Restore sr1 */
1472 dbit_unlock1 spc,t0
1419 1473
1420 rfir 1474 rfir
1421 nop 1475 nop
@@ -1427,7 +1481,8 @@ naitlb_miss_11:
1427 1481
1428 L2_ptep ptp,pte,t0,va,naitlb_check_alias_11 1482 L2_ptep ptp,pte,t0,va,naitlb_check_alias_11
1429 1483
1430 update_ptep ptp,pte,t0,t1 1484 dbit_lock spc,t0,t1
1485 update_ptep spc,ptp,pte,t0,t1
1431 1486
1432 make_insert_tlb_11 spc,pte,prot 1487 make_insert_tlb_11 spc,pte,prot
1433 1488
@@ -1438,6 +1493,7 @@ naitlb_miss_11:
1438 iitlbp prot,(%sr1,va) 1493 iitlbp prot,(%sr1,va)
1439 1494
1440 mtsp t0, %sr1 /* Restore sr1 */ 1495 mtsp t0, %sr1 /* Restore sr1 */
1496 dbit_unlock1 spc,t0
1441 1497
1442 rfir 1498 rfir
1443 nop 1499 nop
@@ -1459,13 +1515,15 @@ itlb_miss_20:
1459 1515
1460 L2_ptep ptp,pte,t0,va,itlb_fault 1516 L2_ptep ptp,pte,t0,va,itlb_fault
1461 1517
1462 update_ptep ptp,pte,t0,t1 1518 dbit_lock spc,t0,t1
1519 update_ptep spc,ptp,pte,t0,t1
1463 1520
1464 make_insert_tlb spc,pte,prot 1521 make_insert_tlb spc,pte,prot
1465 1522
1466 f_extend pte,t0 1523 f_extend pte,t0
1467 1524
1468 iitlbt pte,prot 1525 iitlbt pte,prot
1526 dbit_unlock1 spc,t0
1469 1527
1470 rfir 1528 rfir
1471 nop 1529 nop
@@ -1477,13 +1535,15 @@ naitlb_miss_20:
1477 1535
1478 L2_ptep ptp,pte,t0,va,naitlb_check_alias_20 1536 L2_ptep ptp,pte,t0,va,naitlb_check_alias_20
1479 1537
1480 update_ptep ptp,pte,t0,t1 1538 dbit_lock spc,t0,t1
1539 update_ptep spc,ptp,pte,t0,t1
1481 1540
1482 make_insert_tlb spc,pte,prot 1541 make_insert_tlb spc,pte,prot
1483 1542
1484 f_extend pte,t0 1543 f_extend pte,t0
1485 1544
1486 iitlbt pte,prot 1545 iitlbt pte,prot
1546 dbit_unlock1 spc,t0
1487 1547
1488 rfir 1548 rfir
1489 nop 1549 nop
@@ -1507,29 +1567,13 @@ dbit_trap_20w:
1507 1567
1508 L3_ptep ptp,pte,t0,va,dbit_fault 1568 L3_ptep ptp,pte,t0,va,dbit_fault
1509 1569
1510#ifdef CONFIG_SMP 1570 dbit_lock spc,t0,t1
1511 cmpib,COND(=),n 0,spc,dbit_nolock_20w 1571 update_dirty spc,ptp,pte,t1
1512 load32 PA(pa_dbit_lock),t0
1513
1514dbit_spin_20w:
1515 LDCW 0(t0),t1
1516 cmpib,COND(=) 0,t1,dbit_spin_20w
1517 nop
1518
1519dbit_nolock_20w:
1520#endif
1521 update_dirty ptp,pte,t1
1522 1572
1523 make_insert_tlb spc,pte,prot 1573 make_insert_tlb spc,pte,prot
1524 1574
1525 idtlbt pte,prot 1575 idtlbt pte,prot
1526#ifdef CONFIG_SMP 1576 dbit_unlock0 spc,t0
1527 cmpib,COND(=),n 0,spc,dbit_nounlock_20w
1528 ldi 1,t1
1529 stw t1,0(t0)
1530
1531dbit_nounlock_20w:
1532#endif
1533 1577
1534 rfir 1578 rfir
1535 nop 1579 nop
@@ -1543,18 +1587,8 @@ dbit_trap_11:
1543 1587
1544 L2_ptep ptp,pte,t0,va,dbit_fault 1588 L2_ptep ptp,pte,t0,va,dbit_fault
1545 1589
1546#ifdef CONFIG_SMP 1590 dbit_lock spc,t0,t1
1547 cmpib,COND(=),n 0,spc,dbit_nolock_11 1591 update_dirty spc,ptp,pte,t1
1548 load32 PA(pa_dbit_lock),t0
1549
1550dbit_spin_11:
1551 LDCW 0(t0),t1
1552 cmpib,= 0,t1,dbit_spin_11
1553 nop
1554
1555dbit_nolock_11:
1556#endif
1557 update_dirty ptp,pte,t1
1558 1592
1559 make_insert_tlb_11 spc,pte,prot 1593 make_insert_tlb_11 spc,pte,prot
1560 1594
@@ -1565,13 +1599,7 @@ dbit_nolock_11:
1565 idtlbp prot,(%sr1,va) 1599 idtlbp prot,(%sr1,va)
1566 1600
1567 mtsp t1, %sr1 /* Restore sr1 */ 1601 mtsp t1, %sr1 /* Restore sr1 */
1568#ifdef CONFIG_SMP 1602 dbit_unlock0 spc,t0
1569 cmpib,COND(=),n 0,spc,dbit_nounlock_11
1570 ldi 1,t1
1571 stw t1,0(t0)
1572
1573dbit_nounlock_11:
1574#endif
1575 1603
1576 rfir 1604 rfir
1577 nop 1605 nop
@@ -1583,32 +1611,15 @@ dbit_trap_20:
1583 1611
1584 L2_ptep ptp,pte,t0,va,dbit_fault 1612 L2_ptep ptp,pte,t0,va,dbit_fault
1585 1613
1586#ifdef CONFIG_SMP 1614 dbit_lock spc,t0,t1
1587 cmpib,COND(=),n 0,spc,dbit_nolock_20 1615 update_dirty spc,ptp,pte,t1
1588 load32 PA(pa_dbit_lock),t0
1589
1590dbit_spin_20:
1591 LDCW 0(t0),t1
1592 cmpib,= 0,t1,dbit_spin_20
1593 nop
1594
1595dbit_nolock_20:
1596#endif
1597 update_dirty ptp,pte,t1
1598 1616
1599 make_insert_tlb spc,pte,prot 1617 make_insert_tlb spc,pte,prot
1600 1618
1601 f_extend pte,t1 1619 f_extend pte,t1
1602 1620
1603 idtlbt pte,prot 1621 idtlbt pte,prot
1604 1622 dbit_unlock0 spc,t0
1605#ifdef CONFIG_SMP
1606 cmpib,COND(=),n 0,spc,dbit_nounlock_20
1607 ldi 1,t1
1608 stw t1,0(t0)
1609
1610dbit_nounlock_20:
1611#endif
1612 1623
1613 rfir 1624 rfir
1614 nop 1625 nop
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index e255db0bb761..55237a70e197 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -166,22 +166,32 @@ int arch_show_interrupts(struct seq_file *p, int prec)
166 seq_printf(p, "%*s: ", prec, "STK"); 166 seq_printf(p, "%*s: ", prec, "STK");
167 for_each_online_cpu(j) 167 for_each_online_cpu(j)
168 seq_printf(p, "%10u ", irq_stats(j)->kernel_stack_usage); 168 seq_printf(p, "%10u ", irq_stats(j)->kernel_stack_usage);
169 seq_printf(p, " Kernel stack usage\n"); 169 seq_puts(p, " Kernel stack usage\n");
170# ifdef CONFIG_IRQSTACKS
171 seq_printf(p, "%*s: ", prec, "IST");
172 for_each_online_cpu(j)
173 seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage);
174 seq_puts(p, " Interrupt stack usage\n");
175 seq_printf(p, "%*s: ", prec, "ISC");
176 for_each_online_cpu(j)
177 seq_printf(p, "%10u ", irq_stats(j)->irq_stack_counter);
178 seq_puts(p, " Interrupt stack usage counter\n");
179# endif
170#endif 180#endif
171#ifdef CONFIG_SMP 181#ifdef CONFIG_SMP
172 seq_printf(p, "%*s: ", prec, "RES"); 182 seq_printf(p, "%*s: ", prec, "RES");
173 for_each_online_cpu(j) 183 for_each_online_cpu(j)
174 seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count); 184 seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
175 seq_printf(p, " Rescheduling interrupts\n"); 185 seq_puts(p, " Rescheduling interrupts\n");
176 seq_printf(p, "%*s: ", prec, "CAL"); 186 seq_printf(p, "%*s: ", prec, "CAL");
177 for_each_online_cpu(j) 187 for_each_online_cpu(j)
178 seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); 188 seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
179 seq_printf(p, " Function call interrupts\n"); 189 seq_puts(p, " Function call interrupts\n");
180#endif 190#endif
181 seq_printf(p, "%*s: ", prec, "TLB"); 191 seq_printf(p, "%*s: ", prec, "TLB");
182 for_each_online_cpu(j) 192 for_each_online_cpu(j)
183 seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count); 193 seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
184 seq_printf(p, " TLB shootdowns\n"); 194 seq_puts(p, " TLB shootdowns\n");
185 return 0; 195 return 0;
186} 196}
187 197
@@ -378,6 +388,7 @@ static inline void stack_overflow_check(struct pt_regs *regs)
378 unsigned long sp = regs->gr[30]; 388 unsigned long sp = regs->gr[30];
379 unsigned long stack_usage; 389 unsigned long stack_usage;
380 unsigned int *last_usage; 390 unsigned int *last_usage;
391 int cpu = smp_processor_id();
381 392
382 /* if sr7 != 0, we interrupted a userspace process which we do not want 393 /* if sr7 != 0, we interrupted a userspace process which we do not want
383 * to check for stack overflow. We will only check the kernel stack. */ 394 * to check for stack overflow. We will only check the kernel stack. */
@@ -386,7 +397,31 @@ static inline void stack_overflow_check(struct pt_regs *regs)
386 397
387 /* calculate kernel stack usage */ 398 /* calculate kernel stack usage */
388 stack_usage = sp - stack_start; 399 stack_usage = sp - stack_start;
389 last_usage = &per_cpu(irq_stat.kernel_stack_usage, smp_processor_id()); 400#ifdef CONFIG_IRQSTACKS
401 if (likely(stack_usage <= THREAD_SIZE))
402 goto check_kernel_stack; /* found kernel stack */
403
404 /* check irq stack usage */
405 stack_start = (unsigned long) &per_cpu(irq_stack_union, cpu).stack;
406 stack_usage = sp - stack_start;
407
408 last_usage = &per_cpu(irq_stat.irq_stack_usage, cpu);
409 if (unlikely(stack_usage > *last_usage))
410 *last_usage = stack_usage;
411
412 if (likely(stack_usage < (IRQ_STACK_SIZE - STACK_MARGIN)))
413 return;
414
415 pr_emerg("stackcheck: %s will most likely overflow irq stack "
416 "(sp:%lx, stk bottom-top:%lx-%lx)\n",
417 current->comm, sp, stack_start, stack_start + IRQ_STACK_SIZE);
418 goto panic_check;
419
420check_kernel_stack:
421#endif
422
423 /* check kernel stack usage */
424 last_usage = &per_cpu(irq_stat.kernel_stack_usage, cpu);
390 425
391 if (unlikely(stack_usage > *last_usage)) 426 if (unlikely(stack_usage > *last_usage))
392 *last_usage = stack_usage; 427 *last_usage = stack_usage;
@@ -398,31 +433,69 @@ static inline void stack_overflow_check(struct pt_regs *regs)
398 "(sp:%lx, stk bottom-top:%lx-%lx)\n", 433 "(sp:%lx, stk bottom-top:%lx-%lx)\n",
399 current->comm, sp, stack_start, stack_start + THREAD_SIZE); 434 current->comm, sp, stack_start, stack_start + THREAD_SIZE);
400 435
436#ifdef CONFIG_IRQSTACKS
437panic_check:
438#endif
401 if (sysctl_panic_on_stackoverflow) 439 if (sysctl_panic_on_stackoverflow)
402 panic("low stack detected by irq handler - check messages\n"); 440 panic("low stack detected by irq handler - check messages\n");
403#endif 441#endif
404} 442}
405 443
406#ifdef CONFIG_IRQSTACKS 444#ifdef CONFIG_IRQSTACKS
407DEFINE_PER_CPU(union irq_stack_union, irq_stack_union); 445DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = {
446 .lock = __RAW_SPIN_LOCK_UNLOCKED((irq_stack_union).lock)
447 };
408 448
409static void execute_on_irq_stack(void *func, unsigned long param1) 449static void execute_on_irq_stack(void *func, unsigned long param1)
410{ 450{
411 unsigned long *irq_stack_start; 451 union irq_stack_union *union_ptr;
412 unsigned long irq_stack; 452 unsigned long irq_stack;
413 int cpu = smp_processor_id(); 453 raw_spinlock_t *irq_stack_in_use;
414 454
415 irq_stack_start = &per_cpu(irq_stack_union, cpu).stack[0]; 455 union_ptr = &per_cpu(irq_stack_union, smp_processor_id());
416 irq_stack = (unsigned long) irq_stack_start; 456 irq_stack = (unsigned long) &union_ptr->stack;
417 irq_stack = ALIGN(irq_stack, 16); /* align for stack frame usage */ 457 irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.lock),
458 64); /* align for stack frame usage */
418 459
419 BUG_ON(*irq_stack_start); /* report bug if we were called recursive. */ 460 /* We may be called recursive. If we are already using the irq stack,
420 *irq_stack_start = 1; 461 * just continue to use it. Use spinlocks to serialize
462 * the irq stack usage.
463 */
464 irq_stack_in_use = &union_ptr->lock;
465 if (!raw_spin_trylock(irq_stack_in_use)) {
466 void (*direct_call)(unsigned long p1) = func;
467
468 /* We are using the IRQ stack already.
469 * Do direct call on current stack. */
470 direct_call(param1);
471 return;
472 }
421 473
422 /* This is where we switch to the IRQ stack. */ 474 /* This is where we switch to the IRQ stack. */
423 call_on_stack(param1, func, irq_stack); 475 call_on_stack(param1, func, irq_stack);
424 476
425 *irq_stack_start = 0; 477 __inc_irq_stat(irq_stack_counter);
478
479 /* free up irq stack usage. */
480 do_raw_spin_unlock(irq_stack_in_use);
481}
482
483asmlinkage void do_softirq(void)
484{
485 __u32 pending;
486 unsigned long flags;
487
488 if (in_interrupt())
489 return;
490
491 local_irq_save(flags);
492
493 pending = local_softirq_pending();
494
495 if (pending)
496 execute_on_irq_stack(__do_softirq, 0);
497
498 local_irq_restore(flags);
426} 499}
427#endif /* CONFIG_IRQSTACKS */ 500#endif /* CONFIG_IRQSTACKS */
428 501
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index ce939ac8622b..1c965642068b 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -1069,7 +1069,7 @@ void flush_tlb_all(void)
1069{ 1069{
1070 int do_recycle; 1070 int do_recycle;
1071 1071
1072 inc_irq_stat(irq_tlb_count); 1072 __inc_irq_stat(irq_tlb_count);
1073 do_recycle = 0; 1073 do_recycle = 0;
1074 spin_lock(&sid_lock); 1074 spin_lock(&sid_lock);
1075 if (dirty_space_ids > RECYCLE_THRESHOLD) { 1075 if (dirty_space_ids > RECYCLE_THRESHOLD) {
@@ -1090,7 +1090,7 @@ void flush_tlb_all(void)
1090#else 1090#else
1091void flush_tlb_all(void) 1091void flush_tlb_all(void)
1092{ 1092{
1093 inc_irq_stat(irq_tlb_count); 1093 __inc_irq_stat(irq_tlb_count);
1094 spin_lock(&sid_lock); 1094 spin_lock(&sid_lock);
1095 flush_tlb_all_local(NULL); 1095 flush_tlb_all_local(NULL);
1096 recycle_sids(); 1096 recycle_sids();