提交 16073a19 编写于 作者: Y Yipeng Zou 提交者: Yongqiang Liu

genirq: introduce CONFIG_GENERIC_PENDING_IRQ_FIX_KABI

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6BO2R
CVE: NA

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

Since CONFIG_GENERIC_PENDING_IRQ has been introduced for gic-v3-its,
there has some kabi changed(irq_desc->pending_mask).

Introduce CONFIG_GENERIC_PENDING_IRQ_FIX_KABI to fix it.

The main way is to use an static array(irq_pending_mask) to replace
pending_mask in irq_desc.
Signed-off-by: NYipeng Zou <zouyipeng@huawei.com>
Reviewed-by: NLiao Chang <liaochang1@huawei.com>
Reviewed-by: NZhang Jianhua <chris.zjh@huawei.com>
Signed-off-by: NYongqiang Liu <liuyongqiang13@huawei.com>
上级 6ea55196
...@@ -77,7 +77,8 @@ struct irq_desc { ...@@ -77,7 +77,8 @@ struct irq_desc {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
const struct cpumask *affinity_hint; const struct cpumask *affinity_hint;
struct irq_affinity_notify *affinity_notify; struct irq_affinity_notify *affinity_notify;
#ifdef CONFIG_GENERIC_PENDING_IRQ #if defined(CONFIG_GENERIC_PENDING_IRQ) && \
!defined(CONFIG_GENERIC_PENDING_IRQ_FIX_KABI)
cpumask_var_t pending_mask; cpumask_var_t pending_mask;
#endif #endif
#endif #endif
......
...@@ -138,6 +138,12 @@ config GENERIC_IRQ_DEBUGFS ...@@ -138,6 +138,12 @@ config GENERIC_IRQ_DEBUGFS
If you don't know what to do here, say N. If you don't know what to do here, say N.
# Support for delayed migration from interrupt context without kabi modification
config GENERIC_PENDING_IRQ_FIX_KABI
bool "Support for delayed migration from interrupt context without kabi modification "
depends on GENERIC_PENDING_IRQ
default n
endmenu endmenu
config GENERIC_IRQ_MULTI_HANDLER config GENERIC_IRQ_MULTI_HANDLER
......
...@@ -39,7 +39,7 @@ static void irq_debug_show_masks(struct seq_file *m, struct irq_desc *desc) ...@@ -39,7 +39,7 @@ static void irq_debug_show_masks(struct seq_file *m, struct irq_desc *desc)
seq_printf(m, "effectiv: %*pbl\n", cpumask_pr_args(msk)); seq_printf(m, "effectiv: %*pbl\n", cpumask_pr_args(msk));
#endif #endif
#ifdef CONFIG_GENERIC_PENDING_IRQ #ifdef CONFIG_GENERIC_PENDING_IRQ
msk = desc->pending_mask; msk = irq_desc_get_pending_mask(desc);
seq_printf(m, "pending: %*pbl\n", cpumask_pr_args(msk)); seq_printf(m, "pending: %*pbl\n", cpumask_pr_args(msk));
#endif #endif
} }
......
...@@ -410,6 +410,7 @@ static inline bool irq_move_pending(struct irq_data *data) ...@@ -410,6 +410,7 @@ static inline bool irq_move_pending(struct irq_data *data)
{ {
return irqd_is_setaffinity_pending(data); return irqd_is_setaffinity_pending(data);
} }
#ifndef CONFIG_GENERIC_PENDING_IRQ_FIX_KABI
static inline void static inline void
irq_copy_pending(struct irq_desc *desc, const struct cpumask *mask) irq_copy_pending(struct irq_desc *desc, const struct cpumask *mask)
{ {
...@@ -424,6 +425,24 @@ static inline struct cpumask *irq_desc_get_pending_mask(struct irq_desc *desc) ...@@ -424,6 +425,24 @@ static inline struct cpumask *irq_desc_get_pending_mask(struct irq_desc *desc)
{ {
return desc->pending_mask; return desc->pending_mask;
} }
#else
extern struct cpumask irq_pending_mask[IRQ_BITMAP_BITS];
static inline void
irq_copy_pending(struct irq_desc *desc, const struct cpumask *mask)
{
cpumask_copy(&irq_pending_mask[irq_desc_get_irq(desc)], mask);
}
static inline void
irq_get_pending(struct cpumask *mask, struct irq_desc *desc)
{
cpumask_copy(mask, &irq_pending_mask[irq_desc_get_irq(desc)]);
}
static inline struct cpumask *irq_desc_get_pending_mask(struct irq_desc *desc)
{
return &irq_pending_mask[irq_desc_get_irq(desc)];
}
#endif
static inline bool handle_enforce_irqctx(struct irq_data *data) static inline bool handle_enforce_irqctx(struct irq_data *data)
{ {
return irqd_is_handle_enforce_irqctx(data); return irqd_is_handle_enforce_irqctx(data);
......
...@@ -66,7 +66,8 @@ static int alloc_masks(struct irq_desc *desc, int node) ...@@ -66,7 +66,8 @@ static int alloc_masks(struct irq_desc *desc, int node)
} }
#endif #endif
#ifdef CONFIG_GENERIC_PENDING_IRQ #if defined(CONFIG_GENERIC_PENDING_IRQ) && \
!defined(CONFIG_GENERIC_PENDING_IRQ_FIX_KABI)
if (!zalloc_cpumask_var_node(&desc->pending_mask, GFP_KERNEL, node)) { if (!zalloc_cpumask_var_node(&desc->pending_mask, GFP_KERNEL, node)) {
#ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
free_cpumask_var(desc->irq_common_data.effective_affinity); free_cpumask_var(desc->irq_common_data.effective_affinity);
...@@ -86,7 +87,7 @@ static void desc_smp_init(struct irq_desc *desc, int node, ...@@ -86,7 +87,7 @@ static void desc_smp_init(struct irq_desc *desc, int node,
cpumask_copy(desc->irq_common_data.affinity, affinity); cpumask_copy(desc->irq_common_data.affinity, affinity);
#ifdef CONFIG_GENERIC_PENDING_IRQ #ifdef CONFIG_GENERIC_PENDING_IRQ
cpumask_clear(desc->pending_mask); cpumask_clear(irq_desc_get_pending_mask(desc));
#endif #endif
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
desc->irq_common_data.node = node; desc->irq_common_data.node = node;
...@@ -361,7 +362,8 @@ static void delete_irq_desc(unsigned int irq) ...@@ -361,7 +362,8 @@ static void delete_irq_desc(unsigned int irq)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static void free_masks(struct irq_desc *desc) static void free_masks(struct irq_desc *desc)
{ {
#ifdef CONFIG_GENERIC_PENDING_IRQ #if defined(CONFIG_GENERIC_PENDING_IRQ) && \
!defined(CONFIG_GENERIC_PENDING_IRQ_FIX_KABI)
free_cpumask_var(desc->pending_mask); free_cpumask_var(desc->pending_mask);
#endif #endif
free_cpumask_var(desc->irq_common_data.affinity); free_cpumask_var(desc->irq_common_data.affinity);
......
...@@ -23,6 +23,12 @@ ...@@ -23,6 +23,12 @@
#include "internals.h" #include "internals.h"
#ifdef CONFIG_GENERIC_PENDING_IRQ_FIX_KABI
struct cpumask irq_pending_mask[IRQ_BITMAP_BITS] = {
[0 ... IRQ_BITMAP_BITS - 1] = { CPU_BITS_NONE }
};
#endif
#ifdef CONFIG_IRQ_FORCED_THREADING #ifdef CONFIG_IRQ_FORCED_THREADING
__read_mostly bool force_irqthreads; __read_mostly bool force_irqthreads;
EXPORT_SYMBOL_GPL(force_irqthreads); EXPORT_SYMBOL_GPL(force_irqthreads);
......
...@@ -26,7 +26,8 @@ bool irq_fixup_move_pending(struct irq_desc *desc, bool force_clear) ...@@ -26,7 +26,8 @@ bool irq_fixup_move_pending(struct irq_desc *desc, bool force_clear)
* The outgoing CPU might be the last online target in a pending * The outgoing CPU might be the last online target in a pending
* interrupt move. If that's the case clear the pending move bit. * interrupt move. If that's the case clear the pending move bit.
*/ */
if (cpumask_any_and(desc->pending_mask, cpu_online_mask) >= nr_cpu_ids) { if (cpumask_any_and(irq_desc_get_pending_mask(desc),
cpu_online_mask) >= nr_cpu_ids) {
irqd_clr_move_pending(data); irqd_clr_move_pending(data);
return false; return false;
} }
...@@ -54,7 +55,7 @@ void irq_move_masked_irq(struct irq_data *idata) ...@@ -54,7 +55,7 @@ void irq_move_masked_irq(struct irq_data *idata)
return; return;
} }
if (unlikely(cpumask_empty(desc->pending_mask))) if (unlikely(cpumask_empty(irq_desc_get_pending_mask(desc))))
return; return;
if (!chip->irq_set_affinity) if (!chip->irq_set_affinity)
...@@ -74,10 +75,12 @@ void irq_move_masked_irq(struct irq_data *idata) ...@@ -74,10 +75,12 @@ void irq_move_masked_irq(struct irq_data *idata)
* For correct operation this depends on the caller * For correct operation this depends on the caller
* masking the irqs. * masking the irqs.
*/ */
if (cpumask_any_and(desc->pending_mask, cpu_online_mask) < nr_cpu_ids) { if (cpumask_any_and(irq_desc_get_pending_mask(desc),
cpu_online_mask) < nr_cpu_ids) {
int ret; int ret;
ret = irq_do_set_affinity(data, desc->pending_mask, false); ret = irq_do_set_affinity(data, irq_desc_get_pending_mask(desc),
false);
/* /*
* If the there is a cleanup pending in the underlying * If the there is a cleanup pending in the underlying
* vector management, reschedule the move for the next * vector management, reschedule the move for the next
...@@ -88,7 +91,7 @@ void irq_move_masked_irq(struct irq_data *idata) ...@@ -88,7 +91,7 @@ void irq_move_masked_irq(struct irq_data *idata)
return; return;
} }
} }
cpumask_clear(desc->pending_mask); cpumask_clear(irq_desc_get_pending_mask(desc));
} }
void __irq_move_irq(struct irq_data *idata) void __irq_move_irq(struct irq_data *idata)
......
...@@ -54,7 +54,7 @@ static int show_irq_affinity(int type, struct seq_file *m) ...@@ -54,7 +54,7 @@ static int show_irq_affinity(int type, struct seq_file *m)
mask = desc->irq_common_data.affinity; mask = desc->irq_common_data.affinity;
#ifdef CONFIG_GENERIC_PENDING_IRQ #ifdef CONFIG_GENERIC_PENDING_IRQ
if (irqd_is_setaffinity_pending(&desc->irq_data)) if (irqd_is_setaffinity_pending(&desc->irq_data))
mask = desc->pending_mask; mask = irq_desc_get_pending_mask(desc);
#endif #endif
break; break;
case EFFECTIVE: case EFFECTIVE:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册