[PATCH] Re: New interrupt code in 2.1.80 breaks HiSax

MOLNAR Ingo (mingo@chiara.csoma.elte.hu)
Wed, 21 Jan 1998 19:24:59 +0100 (CET)


On 21 Jan 1998, Andi Kleen wrote:

> It seems the new interrupt code in 2.1.80 breaks HiSax's Teles3 driver.

the problem is that kstat.interrupts has changed in an incompatible way.
Here is a proposed patch to clean those issues up. kstat.interrupts is
changed to kstat.irqs to catch unconverted code. (looks like the warning
message in 2.1.80 wasnt enough ;) Also, a 'kstat_irqs()' function is
provided which calculates per-irq-source statistics, transparently wether
SMP is enabled or not.

cpu_logical_map is changed to __cpu_logical_map, and cpu_logical_map() is
now an inline function which is an identity mapping on UP, and the SMP
mapping on SMP.

all these changes have one common goal: to remove #ifdef SMP from the main
code, and to streamline/simplify kstat.irqs usage.

i've tested the patch on SMP, UP compiles. The patch is (supposed to be)
orthogonal to the previous patches i've sent.

now, if Linus likes these changes, the ISDN code should use kstat_irqs()
to safely detect the number of IRQs during initialization.

-- mingo

--- linux/fs/proc/.array.c.orig Tue Jan 27 06:38:26 1998
+++ linux/fs/proc/array.c Tue Jan 27 07:02:34 1998
@@ -221,20 +221,14 @@

static int get_kstat(char * buffer)
{
- int i, j, len;
+ int i, len;
unsigned sum = 0;
extern unsigned long total_forks;
unsigned long ticks;

ticks = jiffies * smp_num_cpus;
-#ifndef __SMP__
for (i = 0 ; i < NR_IRQS ; i++)
- sum += kstat.interrupts[0][i];
-#else
- for (j = 0 ; j < smp_num_cpus ; j++)
- for (i = 0 ; i < NR_IRQS ; i++)
- sum += kstat.interrupts[cpu_logical_map[j]][i];
-#endif
+ sum += kstat_irqs(i);

#ifdef __SMP__
len = sprintf(buffer,
@@ -246,12 +240,12 @@
for (i = 0 ; i < smp_num_cpus; i++)
len += sprintf(buffer + len, "cpu%d %u %u %u %lu\n",
i,
- kstat.per_cpu_user[cpu_logical_map[i]],
- kstat.per_cpu_nice[cpu_logical_map[i]],
- kstat.per_cpu_system[cpu_logical_map[i]],
- jiffies - ( kstat.per_cpu_user[cpu_logical_map[i]] \
- + kstat.per_cpu_nice[cpu_logical_map[i]] \
- + kstat.per_cpu_system[cpu_logical_map[i]]));
+ kstat.per_cpu_user[cpu_logical_map(i)],
+ kstat.per_cpu_nice[cpu_logical_map(i)],
+ kstat.per_cpu_system[cpu_logical_map(i)],
+ jiffies - ( kstat.per_cpu_user[cpu_logical_map(i)] \
+ + kstat.per_cpu_nice[cpu_logical_map(i)] \
+ + kstat.per_cpu_system[cpu_logical_map(i)]));
len += sprintf(buffer + len,
"disk %u %u %u %u\n"
"disk_rio %u %u %u %u\n"
@@ -292,17 +286,8 @@
kstat.pswpin,
kstat.pswpout,
sum);
- for (i = 0 ; i < NR_IRQS ; i++) {
-#ifndef __SMP__
- len += sprintf(buffer + len, " %u", kstat.interrupts[0][i]);
-#else
- int sum=0;
-
- for (j = 0 ; j < smp_num_cpus ; j++)
- sum += kstat.interrupts[cpu_logical_map[j]][i];
- len += sprintf(buffer + len, " %u", sum);
-#endif
- }
+ for (i = 0 ; i < NR_IRQS ; i++)
+ len += sprintf(buffer + len, " %u", kstat_irqs(i));
len += sprintf(buffer + len,
"\nctxt %u\n"
"btime %lu\n"
@@ -1147,8 +1132,8 @@
for (i = 0 ; i < smp_num_cpus; i++)
len += sprintf(buffer + len, "cpu%d %lu %lu\n",
i,
- tsk->per_cpu_utime[cpu_logical_map[i]],
- tsk->per_cpu_stime[cpu_logical_map[i]]);
+ tsk->per_cpu_utime[cpu_logical_map(i)],
+ tsk->per_cpu_stime[cpu_logical_map(i)]);

return len;
}
--- linux/include/asm-i386/.smp.h.orig Tue Jan 27 06:44:23 1998
+++ linux/include/asm-i386/smp.h Tue Jan 27 07:01:10 1998
@@ -159,7 +159,6 @@
extern unsigned char boot_cpu_id;
extern unsigned long cpu_present_map;
extern volatile int cpu_number_map[NR_CPUS];
-extern volatile int cpu_logical_map[NR_CPUS];
extern volatile unsigned long smp_invalidate_needed;
extern void smp_flush_tlb(void);
extern volatile unsigned long kernel_flag, kernel_counter;
@@ -171,6 +170,11 @@
extern void smp_invalidate_rcv(void); /* Process an NMI */
extern void smp_local_timer_interrupt(struct pt_regs * regs);
extern void setup_APIC_clock (void);
+extern volatile int __cpu_logical_map[NR_CPUS];
+extern inline int cpu_logical_map(int cpu)
+{
+ return __cpu_logical_map[cpu];
+}


/*
@@ -235,5 +239,10 @@
#define SMP_FROM_INT 1
#define SMP_FROM_SYSCALL 2

+#else
+extern static inline int cpu_logical_map(int cpu)
+{
+ return cpu;
+}
#endif
#endif
--- linux/drivers/scsi/.BusLogic.c.orig Tue Jan 27 07:15:31 1998
+++ linux/drivers/scsi/BusLogic.c Tue Jan 27 07:16:29 1998
@@ -2338,15 +2338,11 @@
Issue the Test Command Complete Interrupt commands.
*/

- InitialInterruptCount = 0;
- for (i=0; i<NR_CPUS; i++)
- InitialInterruptCount += kstat.interrupts[i][HostAdapter->IRQ_Channel];
+ InitialInterruptCount = kstat_irqs(HostAdapter->IRQ_Channel);
for (i = 0; i < TestCount; i++)
BusLogic_Command(HostAdapter, BusLogic_TestCommandCompleteInterrupt,
NULL, 0, NULL, 0);
- FinalInterruptCount = 0;
- for (i=0; i<NR_CPUS; i++)
- FinalInterruptCount += kstat.interrupts[i][HostAdapter->IRQ_Channel];
+ FinalInterruptCount = kstat_irqs(HostAdapter->IRQ_Channel);
/*
Verify that BusLogic_InterruptHandler was called at least TestCount
times. Shared IRQ Channels could cause more than TestCount interrupts to
--- linux/arch/i386/kernel/.smp.c.orig Tue Jan 27 04:51:48 1998
+++ linux/arch/i386/kernel/smp.c Tue Jan 27 06:51:01 1998
@@ -115,7 +115,7 @@
int smp_num_cpus = 1; /* Total count of live CPU's */
int smp_threads_ready=0; /* Set when the idlers are all forked */
volatile int cpu_number_map[NR_CPUS]; /* which CPU maps to which logical number */
-volatile int cpu_logical_map[NR_CPUS]; /* which logical number maps to which CPU */
+volatile int __cpu_logical_map[NR_CPUS]; /* which logical number maps to which CPU */
volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; /* We always use 0 the rest is ready for parallel delivery */
volatile unsigned long smp_invalidate_needed; /* Used for the invalidate map that's also checked in the spinlock */
volatile unsigned long kstack_ptr; /* Stack vector for booting CPU's */
@@ -526,7 +526,7 @@
* set some other information about it.
*/
nlong = boot_cpu_id<<24; /* Dummy 'self' for bootup */
- cpu_logical_map[0] = boot_cpu_id;
+ __cpu_logical_map[0] = boot_cpu_id;
global_irq_holder = boot_cpu_id;
current->processor = boot_cpu_id;

@@ -717,7 +717,7 @@
panic("No idle process for CPU %d", i);

idle->processor = i;
- cpu_logical_map[cpucount] = i;
+ __cpu_logical_map[cpucount] = i;
cpu_number_map[i] = cpucount;

/* start_eip had better be page-aligned! */
@@ -861,7 +861,7 @@
/* number CPUs logically, starting from 1 (BSP is 0) */
#if 0
cpu_number_map[i] = cpucount;
- cpu_logical_map[cpucount] = i;
+ __cpu_logical_map[cpucount] = i;
#endif
printk("OK.\n");
printk("CPU%d: ", i);
--- linux/arch/i386/kernel/.irq.c.orig Tue Jan 27 04:53:16 1998
+++ linux/arch/i386/kernel/irq.c Tue Jan 27 07:07:42 1998
@@ -355,13 +357,7 @@
if (!action)
continue;
p += sprintf(p, "%3d: ",i);
-#ifndef __SMP__
- p += sprintf(p, "%10u ", kstat.interrupts[0][i]);
-#else
- for (j=0; j<smp_num_cpus; j++)
- p += sprintf(p, "%10u ",
- kstat.interrupts[cpu_logical_map[j]][i]);
-#endif
+ p += sprintf(p, "%10u ", kstat_irqs(i));
if (IO_APIC_IRQ(i))
p += sprintf(p, " IO-APIC ");
else
@@ -596,7 +592,7 @@
while (test_bit(0,&global_irq_lock)) mb();
#endif

- kstat.interrupts[cpu][irq]++;
+ kstat.irqs[cpu][irq]++;
status = 0;
action = *(irq + irq_action);

@@ -897,7 +893,7 @@
/*
* save current irq counts
*/
- memcpy(probe_irqs,kstat.interrupts,NR_CPUS*NR_IRQS*sizeof(int));
+ memcpy(probe_irqs,kstat.irqs,NR_CPUS*NR_IRQS*sizeof(int));

/*
* first, enable any unassigned irqs
@@ -922,7 +918,7 @@
*/
for (i=0; i<NR_IRQS; i++)
for (j=0; j<NR_CPUS; j++)
- if (kstat.interrupts[j][i] != probe_irqs[j][i])
+ if (kstat.irqs[j][i] != probe_irqs[j][i])
irqs &= ~(i<<1);

return irqs;
@@ -935,7 +931,7 @@
for (i=0; i<NR_IRQS; i++) {
int sum = 0;
for (j=0; j<NR_CPUS; j++) {
- sum += kstat.interrupts[j][i];
+ sum += kstat.irqs[j][i];
sum -= probe_irqs[j][i];
}
if (sum && (irqs & (i<<1))) {