Skip to content

Commit

Permalink
acpm: dump delta of kernel irq counts when ipc timeout
Browse files Browse the repository at this point in the history
Bug: 249004528
Change-Id: I01bffc2c7505fb76696f87f713c97c63f3b2b51d
Signed-off-by: Redick_Lin <[email protected]>
  • Loading branch information
Redick_Lin authored and TreeHugger Robot committed Oct 31, 2022
1 parent 3920886 commit 827e0fb
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
66 changes: 65 additions & 1 deletion drivers/soc/google/acpm/acpm_ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/workqueue.h>
#include <linux/debugfs.h>
#include <linux/bitmap.h>
#include <linux/kernel_stat.h>
#include <soc/google/exynos-debug.h>
#include <soc/google/debug-snapshot.h>

Expand All @@ -42,6 +43,7 @@ static struct acpm_ipc_info *acpm_ipc;
static struct workqueue_struct *update_log_wq;
static struct acpm_debug_info *acpm_debug;
static bool is_acpm_stop_log;
static struct cpu_irq_info *irq_info;

static struct acpm_framework *acpm_initdata;
static void __iomem *acpm_srambase;
Expand Down Expand Up @@ -574,6 +576,65 @@ int acpm_ipc_send_data_sync(unsigned int channel_id, struct ipc_config *cfg)
}
EXPORT_SYMBOL_GPL(acpm_ipc_send_data_sync);

#ifndef arch_irq_stat
#define arch_irq_stat() 0
#endif

extern int nr_irqs;

static void cpu_irq_info_dump(u32 retry)
{
int i, cpu;
u64 sum = 0;

for_each_possible_cpu(cpu)
sum += kstat_cpu_irqs_sum(cpu);

sum += arch_irq_stat();

if (retry == 5)
pr_info("<Dump delta of irq counts>\n");

for_each_irq_nr(i) {
struct irq_data *data;
struct irq_desc *desc;
unsigned int irq_stat = 0, delta;
const char *name;

data = irq_get_irq_data(i);
if (!data)
continue;

desc = irq_data_to_desc(data);
if (!desc)
continue;

for_each_possible_cpu(cpu)
irq_stat += *per_cpu_ptr(desc->kstat_irqs, cpu);

if (!irq_stat)
continue;

if (desc->action && desc->action->name)
name = desc->action->name;
else
name = "???";

if (retry == 1) {
irq_info[i].irq_num = i;
irq_info[i].hwirq_num = desc->irq_data.hwirq;
irq_info[i].irq_stat = irq_stat;
irq_info[i].name = name;
} else if (retry == 5) {
delta = irq_stat - irq_info[i].irq_stat;
if (delta > 0) {
pr_info("irq-%-4d(hwirq-%-3d) delta of irqs: %8u %s\n",
i, (int)desc->irq_data.hwirq, delta, name);
}
}
}
}

int __acpm_ipc_send_data(unsigned int channel_id, struct ipc_config *cfg, bool w_mode)
{
volatile unsigned int tx_front, tx_rear, rx_front;
Expand Down Expand Up @@ -702,6 +763,7 @@ int __acpm_ipc_send_data(unsigned int channel_id, struct ipc_config *cfg, bool w
__raw_readl(acpm_ipc->intr + INTMR1),
__raw_readl(acpm_ipc->intr + INTMSR1));

cpu_irq_info_dump(retry_cnt);
++retry_cnt;

goto retry;
Expand Down Expand Up @@ -731,7 +793,6 @@ int __acpm_ipc_send_data(unsigned int channel_id, struct ipc_config *cfg, bool w
pr_err("%s Timeout error! now = %llu timeout = %llu ch:%u s:%u bitmap:%lx\n",
__func__, now, timeout, channel->id, seq_num,
channel->bitmap_seqnum[0]);

acpm_ramdump();
dump_stack();
dbg_snapshot_do_dpm_policy(acpm_ipc->panic_action, "acpm_ipc timeout");
Expand Down Expand Up @@ -1019,6 +1080,9 @@ int acpm_ipc_probe(struct platform_device *pdev)
}

ret = plugins_init(node);

irq_info = kcalloc(nr_irqs, sizeof(struct cpu_irq_info), GFP_KERNEL);

dev_info(&pdev->dev, "acpm_ipc probe done.\n");
return ret;
}
Expand Down
7 changes: 7 additions & 0 deletions drivers/soc/google/acpm/acpm_ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ struct acpm_debug_info {
spinlock_t lock; /* generic spin-lock for debug */
};

struct cpu_irq_info {
const char *name;
int irq_num;
unsigned long hwirq_num;
unsigned int irq_stat;
};

#define LOG_ID_SHIFT (28)
#define LOG_IS_RAW_SHIFT (27)
#define LOG_IS_ERR_SHIFT (26)
Expand Down

0 comments on commit 827e0fb

Please sign in to comment.