mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
db7e007fd6
When using systemtap it was observed that our udelay implementation is rather suboptimal if being called from a kprobe handler installed by systemtap. The problem observed when a kprobe was installed on lock_acquired(). When the probe was hit the kprobe handler did call udelay, which set up an (internal) timer and reenabled interrupts (only the clock comparator interrupt) and waited for the interrupt. This is an optimization to avoid that the cpu is busy looping while waiting that enough time passes. The problem is that the interrupt handler still does call irq_enter()/irq_exit() which then again can lead to a deadlock, since some accounting functions may take locks as well. If one of these locks is the same, which caused lock_acquired() to be called, we have a nice deadlock. This patch reworks the udelay code for the interrupts disabled case to immediately leave the low level interrupt handler when the clock comparator interrupt happens. That way no C code is being called and the deadlock cannot happen anymore. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Reviewed-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
30 lines
670 B
C
30 lines
670 B
C
/*
|
|
* Copyright IBM Corp. 2014
|
|
*
|
|
* Author: Martin Schwidefsky <schwidefsky@de.ibm.com>
|
|
*/
|
|
|
|
#ifndef _S390_IDLE_H
|
|
#define _S390_IDLE_H
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/device.h>
|
|
#include <linux/seqlock.h>
|
|
|
|
struct s390_idle_data {
|
|
seqcount_t seqcount;
|
|
unsigned long long idle_count;
|
|
unsigned long long idle_time;
|
|
unsigned long long clock_idle_enter;
|
|
unsigned long long clock_idle_exit;
|
|
unsigned long long timer_idle_enter;
|
|
unsigned long long timer_idle_exit;
|
|
};
|
|
|
|
extern struct device_attribute dev_attr_idle_count;
|
|
extern struct device_attribute dev_attr_idle_time_us;
|
|
|
|
void psw_idle(struct s390_idle_data *, unsigned long);
|
|
|
|
#endif /* _S390_IDLE_H */
|