Skip to content

Commit

Permalink
csky: Add arch_show_interrupts for IPI interrupts
Browse files Browse the repository at this point in the history
Here is the result:

 cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3
 15:       1348       1299        952       1076  C-SKY SMP Intc  15  IPI Interrupt
 16:       1203       1825       1598       1307  C-SKY SMP Intc  16  csky_mp_timer
 43:        292          0          0          0  C-SKY SMP Intc  43  ttyS0
 57:        106          0          0          0  C-SKY SMP Intc  57  virtio0
IPI0:         0          0          0          0  Empty interrupts
IPI1:        19         41         45         27  Rescheduling interrupts
IPI2:      1330       1259        908       1050  Function call interrupts
IPI3:         0          0          0          0  Irq work interrupts

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Cc: Arnd Bergmann <arnd@arndb.de>
  • Loading branch information
Guo Ren committed Jul 31, 2020
1 parent 2c81b07 commit e6169c4
Showing 1 changed file with 41 additions and 8 deletions.
49 changes: 41 additions & 8 deletions arch/csky/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/irq_work.h>
#include <linux/irqdomain.h>
#include <linux/of.h>
#include <linux/seq_file.h>
#include <linux/sched/task_stack.h>
#include <linux/sched/mm.h>
#include <linux/sched/hotplug.h>
Expand All @@ -27,11 +28,6 @@
#include <abi/fpu.h>
#endif

struct ipi_data_struct {
unsigned long bits ____cacheline_aligned;
};
static DEFINE_PER_CPU(struct ipi_data_struct, ipi_data);

enum ipi_message_type {
IPI_EMPTY,
IPI_RESCHEDULE,
Expand All @@ -40,23 +36,37 @@ enum ipi_message_type {
IPI_MAX
};

struct ipi_data_struct {
unsigned long bits ____cacheline_aligned;
unsigned long stats[IPI_MAX] ____cacheline_aligned;
};
static DEFINE_PER_CPU(struct ipi_data_struct, ipi_data);

static irqreturn_t handle_ipi(int irq, void *dev)
{
unsigned long *stats = this_cpu_ptr(&ipi_data)->stats;

while (true) {
unsigned long ops;

ops = xchg(&this_cpu_ptr(&ipi_data)->bits, 0);
if (ops == 0)
return IRQ_HANDLED;

if (ops & (1 << IPI_RESCHEDULE))
if (ops & (1 << IPI_RESCHEDULE)) {
stats[IPI_RESCHEDULE]++;
scheduler_ipi();
}

if (ops & (1 << IPI_CALL_FUNC))
if (ops & (1 << IPI_CALL_FUNC)) {
stats[IPI_CALL_FUNC]++;
generic_smp_call_function_interrupt();
}

if (ops & (1 << IPI_IRQ_WORK))
if (ops & (1 << IPI_IRQ_WORK)) {
stats[IPI_IRQ_WORK]++;
irq_work_run();
}

BUG_ON((ops >> IPI_MAX) != 0);
}
Expand Down Expand Up @@ -88,6 +98,29 @@ send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation)
send_arch_ipi(to_whom);
}

static const char * const ipi_names[] = {
[IPI_EMPTY] = "Empty interrupts",
[IPI_RESCHEDULE] = "Rescheduling interrupts",
[IPI_CALL_FUNC] = "Function call interrupts",
[IPI_IRQ_WORK] = "Irq work interrupts",
};

int arch_show_interrupts(struct seq_file *p, int prec)
{
unsigned int cpu, i;

for (i = 0; i < IPI_MAX; i++) {
seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
prec >= 4 ? " " : "");
for_each_online_cpu(cpu)
seq_printf(p, "%10lu ",
per_cpu_ptr(&ipi_data, cpu)->stats[i]);
seq_printf(p, " %s\n", ipi_names[i]);
}

return 0;
}

void arch_send_call_function_ipi_mask(struct cpumask *mask)
{
send_ipi_message(mask, IPI_CALL_FUNC);
Expand Down

0 comments on commit e6169c4

Please sign in to comment.