loongarch.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: maobibo <maobibo@loongson.cn>
To: Huacai Chen <chenhuacai@loongson.cn>,
	Arnd Bergmann <arnd@arndb.de>,
	Huacai Chen <chenhuacai@kernel.org>
Cc: loongarch@lists.linux.dev, linux-arch@vger.kernel.org,
	Xuefeng Li <lixuefeng@loongson.cn>, Guo Ren <guoren@kernel.org>,
	Xuerui Wang <kernel@xen0n.name>,
	Jiaxun Yang <jiaxun.yang@flygoat.com>,
	linux-kernel@vger.kernel.org, loongson-kernel@lists.loongnix.cn
Subject: Re: [PATCH] LoongArch: Add irq_work support via self IPIs
Date: Thu, 16 May 2024 20:23:18 +0800	[thread overview]
Message-ID: <b1182755-ec71-2add-ad69-72da85cdbb19@loongson.cn> (raw)
In-Reply-To: <20240514073232.3694867-1-chenhuacai@loongson.cn>



On 2024/5/14 下午3:32, Huacai Chen wrote:
> Add irq_work support for LoongArch via self IPIs. This make it possible
> to run works in hardware interrupt context, which is a prerequisite for
> NOHZ_FULL.
> 
> Implement:
>   - arch_irq_work_raise()
>   - arch_irq_work_has_interrupt()
> 
> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> ---
>   arch/loongarch/include/asm/hardirq.h  |  3 ++-
>   arch/loongarch/include/asm/irq_work.h | 10 ++++++++++
>   arch/loongarch/include/asm/smp.h      |  2 ++
>   arch/loongarch/kernel/paravirt.c      |  6 ++++++
>   arch/loongarch/kernel/smp.c           | 14 ++++++++++++++
>   5 files changed, 34 insertions(+), 1 deletion(-)
>   create mode 100644 arch/loongarch/include/asm/irq_work.h
> 
> diff --git a/arch/loongarch/include/asm/hardirq.h b/arch/loongarch/include/asm/hardirq.h
> index d41138abcf26..1d7feb719515 100644
> --- a/arch/loongarch/include/asm/hardirq.h
> +++ b/arch/loongarch/include/asm/hardirq.h
> @@ -12,11 +12,12 @@
>   extern void ack_bad_irq(unsigned int irq);
>   #define ack_bad_irq ack_bad_irq
>   
> -#define NR_IPI	2
> +#define NR_IPI	3
>   
>   enum ipi_msg_type {
>   	IPI_RESCHEDULE,
>   	IPI_CALL_FUNCTION,
> +	IPI_IRQ_WORK,
>   };
>   
>   typedef struct {
> diff --git a/arch/loongarch/include/asm/irq_work.h b/arch/loongarch/include/asm/irq_work.h
> new file mode 100644
> index 000000000000..d63076e9160d
> --- /dev/null
> +++ b/arch/loongarch/include/asm/irq_work.h
> @@ -0,0 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _ASM_LOONGARCH_IRQ_WORK_H
> +#define _ASM_LOONGARCH_IRQ_WORK_H
> +
> +static inline bool arch_irq_work_has_interrupt(void)
> +{
> +	return IS_ENABLED(CONFIG_SMP);
> +}
> +
> +#endif /* _ASM_LOONGARCH_IRQ_WORK_H */
> diff --git a/arch/loongarch/include/asm/smp.h b/arch/loongarch/include/asm/smp.h
> index 278700cfee88..50db503f44e3 100644
> --- a/arch/loongarch/include/asm/smp.h
> +++ b/arch/loongarch/include/asm/smp.h
> @@ -69,9 +69,11 @@ extern int __cpu_logical_map[NR_CPUS];
>   #define ACTION_BOOT_CPU	0
>   #define ACTION_RESCHEDULE	1
>   #define ACTION_CALL_FUNCTION	2
> +#define ACTION_IRQ_WORK		3
>   #define SMP_BOOT_CPU		BIT(ACTION_BOOT_CPU)
>   #define SMP_RESCHEDULE		BIT(ACTION_RESCHEDULE)
>   #define SMP_CALL_FUNCTION	BIT(ACTION_CALL_FUNCTION)
> +#define SMP_IRQ_WORK		BIT(ACTION_IRQ_WORK)
>   
>   struct secondary_data {
>   	unsigned long stack;
> diff --git a/arch/loongarch/kernel/paravirt.c b/arch/loongarch/kernel/paravirt.c
> index 1633ed4f692f..4272d2447445 100644
> --- a/arch/loongarch/kernel/paravirt.c
> +++ b/arch/loongarch/kernel/paravirt.c
> @@ -2,6 +2,7 @@
>   #include <linux/export.h>
>   #include <linux/types.h>
>   #include <linux/interrupt.h>
> +#include <linux/irq_work.h>
>   #include <linux/jump_label.h>
>   #include <linux/kvm_para.h>
>   #include <linux/static_call.h>
> @@ -97,6 +98,11 @@ static irqreturn_t pv_ipi_interrupt(int irq, void *dev)
>   		info->ipi_irqs[IPI_CALL_FUNCTION]++;
>   	}
>   
> +	if (action & SMP_IRQ_WORK) {
> +		irq_work_run();
> +		info->ipi_irqs[IPI_IRQ_WORK]++;
> +	}
> +
Would you mind adding common api so that pv ipi handler and hw ipi 
handler can call it both? The coming avec MSI interrupt driver has the 
same requirement for ipi.

void do_ipi_demux(unsigned int action)
{
         irq_cpustat_t *info;

         info = this_cpu_ptr(&irq_stat);
         if (action & SMP_RESCHEDULE) {
                 scheduler_ipi();
                 info->ipi_irqs[IPI_RESCHEDULE]++;
         }

         if (action & SMP_CALL_FUNCTION) {
                 generic_smp_call_function_interrupt();
                 info->ipi_irqs[IPI_CALL_FUNCTION]++;
         }

  	if (action & SMP_IRQ_WORK) {
  		irq_work_run();
  		info->ipi_irqs[IPI_IRQ_WORK]++;
}

Regards
Bibo Mao
>   	return IRQ_HANDLED;
>   }
>   
> diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c
> index 0dfe2388ef41..7366de776f6e 100644
> --- a/arch/loongarch/kernel/smp.c
> +++ b/arch/loongarch/kernel/smp.c
> @@ -13,6 +13,7 @@
>   #include <linux/cpumask.h>
>   #include <linux/init.h>
>   #include <linux/interrupt.h>
> +#include <linux/irq_work.h>
>   #include <linux/profile.h>
>   #include <linux/seq_file.h>
>   #include <linux/smp.h>
> @@ -70,6 +71,7 @@ static DEFINE_PER_CPU(int, cpu_state);
>   static const char *ipi_types[NR_IPI] __tracepoint_string = {
>   	[IPI_RESCHEDULE] = "Rescheduling interrupts",
>   	[IPI_CALL_FUNCTION] = "Function call interrupts",
> +	[IPI_IRQ_WORK] = "IRQ work interrupts",
>   };
>   
>   void show_ipi_list(struct seq_file *p, int prec)
> @@ -217,6 +219,13 @@ void arch_smp_send_reschedule(int cpu)
>   }
>   EXPORT_SYMBOL_GPL(arch_smp_send_reschedule);
>   
> +#ifdef CONFIG_IRQ_WORK
> +void arch_irq_work_raise(void)
> +{
> +	mp_ops.send_ipi_single(smp_processor_id(), ACTION_IRQ_WORK);
> +}
> +#endif
> +
>   static irqreturn_t loongson_ipi_interrupt(int irq, void *dev)
>   {
>   	unsigned int action;
> @@ -234,6 +243,11 @@ static irqreturn_t loongson_ipi_interrupt(int irq, void *dev)
>   		per_cpu(irq_stat, cpu).ipi_irqs[IPI_CALL_FUNCTION]++;
>   	}
>   
> +	if (action & SMP_IRQ_WORK) {
> +		irq_work_run();
> +		per_cpu(irq_stat, cpu).ipi_irqs[IPI_IRQ_WORK]++;
> +	}
> +
>   	return IRQ_HANDLED;
>   }
>   
> 


  parent reply	other threads:[~2024-05-16 12:23 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-14  7:32 [PATCH] LoongArch: Add irq_work support via self IPIs Huacai Chen
2024-05-14 10:11 ` Guo Ren
2024-05-14 11:14   ` Huacai Chen
2024-05-15  3:21     ` Guo Ren
2024-05-15  4:02       ` Huacai Chen
2024-05-16 12:23 ` maobibo [this message]
2024-05-17  7:37   ` Huacai Chen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b1182755-ec71-2add-ad69-72da85cdbb19@loongson.cn \
    --to=maobibo@loongson.cn \
    --cc=arnd@arndb.de \
    --cc=chenhuacai@kernel.org \
    --cc=chenhuacai@loongson.cn \
    --cc=guoren@kernel.org \
    --cc=jiaxun.yang@flygoat.com \
    --cc=kernel@xen0n.name \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lixuefeng@loongson.cn \
    --cc=loongarch@lists.linux.dev \
    --cc=loongson-kernel@lists.loongnix.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).