提交 65ac56c4 编写于 作者: J Junhao He 提交者: Zheng Zengkai

coresight: etm4x: Workaround CPU hung bug on HiSilicon ETM

driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5EZY2

------------------------------------------------------------------

In FIFO mode, when the state of sink buffer is full, the sink device will
continuously backpressures the ETM, so that the ETM cannot switch to the
idle state. In this case, the WFx instruction cannot be executed because
the CPU detects that the ETM is not in the idle state which that will
cause CPU hung.
We workaround this issue on HiSilicon ETM by setting bit 13 of TRCAUXCTLR
which is used to indicate that the ETM is in the idle state.

The call trace is shown below:
 rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
 rcu: 	10-...0: (1 ticks this GP) idle=5b6/1/0x4000000000000000 softirq=12309/12318 fqs=114196
 	(detected by 67, t=330041 jiffies, g=309253, q=453663)
 Task dump for CPU 10:
 task:ksoftirqd/10    state:R  running task     stack:    0 pid:   64 ppid:     2 flags:0x0000000a
 Call trace:
  __switch_to+0xbc/0xfc
 irqtime_account_irq+0x58/0xc4
 __do_softirq+0x6c/0x358
 run_ksoftirqd+0x68/0x90
 smpboot_thread_fn+0x15c/0x1a0
 kthread+0x108/0x13c
 ret_from_fork+0x10/0x18
watchdog: BUG: soft lockup - CPU#35 stuck for 22s! [bash:133345]
...
Call trace:
 smp_call_function_single+0x178/0x190
 etm4_disable_sysfs+0x74/0xfc [coresight_etm4x]
 etm4_disable+0x6c/0x70 [coresight_etm4x]
 coresight_disable_source+0x7c/0xa0 [coresight]
 coresight_disable+0x6c/0x13c [coresight]
 enable_source_store+0x88/0xa0 [coresight]
 dev_attr_store+0x20/0x34
 sysfs_kf_write+0x4c/0x5c
 kernfs_fop_write_iter+0x130/0x1c0
 new_sync_write+0xec/0x18c
 vfs_write+0x214/0x2ac
 ksys_write+0x70/0xfc
 __arm64_sys_write+0x24/0x30
 el0_svc_common.constprop.0+0x7c/0x1bc
 do_el0_svc+0x2c/0x94
 el0_svc+0x20/0x30
 el0_sync_handler+0xb0/0xb4
 el0_sync+0x160/0x180
Signed-off-by: NQi Liu <liuqi115@huawei.com>
Signed-off-by: NJunhao He <hejunhao3@huawei.com>
Reviewed-by: NJay Fang <f.fangjian@huawei.com>
Acked-by: NXie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 9ed56e23
......@@ -116,8 +116,10 @@ struct etm4_enable_arg {
#define HISI_HIP08_CORE_COMMIT_LVL_1 0b01
#define HISI_HIP08_CORE_COMMIT_REG sys_reg(3, 1, 15, 2, 5)
#define HISI_HIP08_AUXCTRL_CHICKEN_BIT BIT(13)
struct etm4_arch_features {
void (*arch_callback)(bool enable);
void (*arch_callback)(void *info);
};
static bool etm4_hisi_match_pid(unsigned int id)
......@@ -125,8 +127,9 @@ static bool etm4_hisi_match_pid(unsigned int id)
return (id & ETM4_AMBA_MASK) == HISI_HIP08_AMBA_ID;
}
static void etm4_hisi_config_core_commit(bool enable)
static void etm4_hisi_config_core_commit(void *info)
{
bool enable = *(bool *)info;
u8 commit = enable ? HISI_HIP08_CORE_COMMIT_LVL_1 :
HISI_HIP08_CORE_COMMIT_FULL;
u64 val;
......@@ -143,48 +146,67 @@ static void etm4_hisi_config_core_commit(bool enable)
write_sysreg_s(val, HISI_HIP08_CORE_COMMIT_REG);
}
static void etm4_hisi_config_auxctrlr(void *info)
{
struct etmv4_drvdata *drvdata = info;
/* Switch the ETM to idle state */
writel_relaxed(HISI_HIP08_AUXCTRL_CHICKEN_BIT, drvdata->base + TRCAUXCTLR);
}
static struct etm4_arch_features etm4_features[] = {
[ETM4_IMPDEF_HISI_CORE_COMMIT] = {
.arch_callback = etm4_hisi_config_core_commit,
},
[ETM4_IMPDEF_HISI_SET_AUXCTRLR] = {
.arch_callback = etm4_hisi_config_auxctrlr,
},
{},
};
static void etm4_enable_arch_specific(struct etmv4_drvdata *drvdata)
{
struct etm4_arch_features *ftr;
bool enable = true;
int bit;
for_each_set_bit(bit, drvdata->arch_features, ETM4_IMPDEF_FEATURE_MAX) {
ftr = &etm4_features[bit];
if (ftr->arch_callback)
ftr->arch_callback(true);
if (bit == ETM4_IMPDEF_HISI_CORE_COMMIT && ftr->arch_callback)
ftr->arch_callback(&enable);
if (bit == ETM4_IMPDEF_HISI_SET_AUXCTRLR && ftr->arch_callback)
ftr->arch_callback(drvdata);
}
}
static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
{
struct etm4_arch_features *ftr;
bool enable = false;
int bit;
for_each_set_bit(bit, drvdata->arch_features, ETM4_IMPDEF_FEATURE_MAX) {
ftr = &etm4_features[bit];
if (ftr->arch_callback)
ftr->arch_callback(false);
if (bit == ETM4_IMPDEF_HISI_CORE_COMMIT && ftr->arch_callback)
ftr->arch_callback(&enable);
}
}
static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
unsigned int id)
{
if (etm4_hisi_match_pid(id))
if (etm4_hisi_match_pid(id)) {
set_bit(ETM4_IMPDEF_HISI_CORE_COMMIT, drvdata->arch_features);
set_bit(ETM4_IMPDEF_HISI_SET_AUXCTRLR, drvdata->arch_features);
}
}
#else
static void etm4_enable_arch_specific(struct etmv4_drvdata *drvdata)
{
writel_relaxed(0x0, drvdata->base + TRCAUXCTLR);
}
static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
......@@ -223,7 +245,6 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
writel_relaxed(config->pe_sel, drvdata->base + TRCPROCSELR);
writel_relaxed(config->cfg, drvdata->base + TRCCONFIGR);
/* nothing specific implemented */
writel_relaxed(0x0, drvdata->base + TRCAUXCTLR);
writel_relaxed(config->eventctrl0, drvdata->base + TRCEVENTCTL0R);
writel_relaxed(config->eventctrl1, drvdata->base + TRCEVENTCTL1R);
if (drvdata->stallctl)
......
......@@ -206,6 +206,7 @@
enum etm_impdef_type {
ETM4_IMPDEF_HISI_CORE_COMMIT,
ETM4_IMPDEF_HISI_SET_AUXCTRLR,
ETM4_IMPDEF_FEATURE_MAX,
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册