diff mbox series

[v5,1/4] lib: sbi: Optimize sbi_tlb

Message ID 20230411045621.60331-2-wxjstz@126.com
State Accepted
Headers show
Series Miscellaneous about sbi_tlb and sbi_ipi | expand

Commit Message

Xiang W April 11, 2023, 4:56 a.m. UTC
Originally, the process and sync of sbi_tlb need to wait for each other.
Evasion by atomic addition and subtraction.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Tested-by: Anup Patel <anup@brainfault.org>
---
 lib/sbi/sbi_tlb.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

Comments

Anup Patel April 13, 2023, 9:14 a.m. UTC | #1
On Tue, Apr 11, 2023 at 10:27 AM Xiang W <wxjstz@126.com> wrote:
>
> Originally, the process and sync of sbi_tlb need to wait for each other.
> Evasion by atomic addition and subtraction.
>
> Signed-off-by: Xiang W <wxjstz@126.com>
> Reviewed-by: Anup Patel <anup@brainfault.org>
> Tested-by: Anup Patel <anup@brainfault.org>

Applied this patch to the riscv/opensbi repo.

Thanks,
Anup

> ---
>  lib/sbi/sbi_tlb.c | 21 +++++++++++----------
>  1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/lib/sbi/sbi_tlb.c b/lib/sbi/sbi_tlb.c
> index 4c142ea..d950c45 100644
> --- a/lib/sbi/sbi_tlb.c
> +++ b/lib/sbi/sbi_tlb.c
> @@ -215,7 +215,7 @@ static void tlb_entry_process(struct sbi_tlb_info *tinfo)
>  {
>         u32 rhartid;
>         struct sbi_scratch *rscratch = NULL;
> -       unsigned long *rtlb_sync = NULL;
> +       atomic_t *rtlb_sync = NULL;
>
>         tinfo->local_fn(tinfo);
>
> @@ -225,7 +225,7 @@ static void tlb_entry_process(struct sbi_tlb_info *tinfo)
>                         continue;
>
>                 rtlb_sync = sbi_scratch_offset_ptr(rscratch, tlb_sync_off);
> -               while (atomic_raw_xchg_ulong(rtlb_sync, 1)) ;
> +               atomic_sub_return(rtlb_sync, 1);
>         }
>  }
>
> @@ -257,10 +257,10 @@ static void tlb_process(struct sbi_scratch *scratch)
>
>  static void tlb_sync(struct sbi_scratch *scratch)
>  {
> -       unsigned long *tlb_sync =
> +       atomic_t *tlb_sync =
>                         sbi_scratch_offset_ptr(scratch, tlb_sync_off);
>
> -       while (!atomic_raw_xchg_ulong(tlb_sync, 0)) {
> +       while (atomic_read(tlb_sync) > 0) {
>                 /*
>                  * While we are waiting for remote hart to set the sync,
>                  * consume fifo requests to avoid deadlock.
> @@ -343,6 +343,7 @@ static int tlb_update(struct sbi_scratch *scratch,
>                           u32 remote_hartid, void *data)
>  {
>         int ret;
> +       atomic_t *tlb_sync;
>         struct sbi_fifo *tlb_fifo_r;
>         struct sbi_tlb_info *tinfo = data;
>         u32 curr_hartid = current_hartid();
> @@ -369,11 +370,8 @@ static int tlb_update(struct sbi_scratch *scratch,
>         tlb_fifo_r = sbi_scratch_offset_ptr(remote_scratch, tlb_fifo_off);
>
>         ret = sbi_fifo_inplace_update(tlb_fifo_r, data, tlb_update_cb);
> -       if (ret != SBI_FIFO_UNCHANGED) {
> -               return 1;
> -       }
>
> -       while (sbi_fifo_enqueue(tlb_fifo_r, data) < 0) {
> +       while (ret == SBI_FIFO_UNCHANGED && sbi_fifo_enqueue(tlb_fifo_r, data) < 0) {
>                 /**
>                  * For now, Busy loop until there is space in the fifo.
>                  * There may be case where target hart is also
> @@ -387,6 +385,9 @@ static int tlb_update(struct sbi_scratch *scratch,
>                             curr_hartid, remote_hartid);
>         }
>
> +       tlb_sync = sbi_scratch_offset_ptr(scratch, tlb_sync_off);
> +       atomic_add_return(tlb_sync, 1);
> +
>         return 0;
>  }
>
> @@ -413,7 +414,7 @@ int sbi_tlb_init(struct sbi_scratch *scratch, bool cold_boot)
>  {
>         int ret;
>         void *tlb_mem;
> -       unsigned long *tlb_sync;
> +       atomic_t *tlb_sync;
>         struct sbi_fifo *tlb_q;
>         const struct sbi_platform *plat = sbi_platform_ptr(scratch);
>
> @@ -455,7 +456,7 @@ int sbi_tlb_init(struct sbi_scratch *scratch, bool cold_boot)
>         tlb_q = sbi_scratch_offset_ptr(scratch, tlb_fifo_off);
>         tlb_mem = sbi_scratch_offset_ptr(scratch, tlb_fifo_mem_off);
>
> -       *tlb_sync = 0;
> +       ATOMIC_INIT(tlb_sync, 0);
>
>         sbi_fifo_init(tlb_q, tlb_mem,
>                       SBI_TLB_FIFO_NUM_ENTRIES, SBI_TLB_INFO_SIZE);
> --
> 2.39.2
>
diff mbox series

Patch

diff --git a/lib/sbi/sbi_tlb.c b/lib/sbi/sbi_tlb.c
index 4c142ea..d950c45 100644
--- a/lib/sbi/sbi_tlb.c
+++ b/lib/sbi/sbi_tlb.c
@@ -215,7 +215,7 @@  static void tlb_entry_process(struct sbi_tlb_info *tinfo)
 {
 	u32 rhartid;
 	struct sbi_scratch *rscratch = NULL;
-	unsigned long *rtlb_sync = NULL;
+	atomic_t *rtlb_sync = NULL;
 
 	tinfo->local_fn(tinfo);
 
@@ -225,7 +225,7 @@  static void tlb_entry_process(struct sbi_tlb_info *tinfo)
 			continue;
 
 		rtlb_sync = sbi_scratch_offset_ptr(rscratch, tlb_sync_off);
-		while (atomic_raw_xchg_ulong(rtlb_sync, 1)) ;
+		atomic_sub_return(rtlb_sync, 1);
 	}
 }
 
@@ -257,10 +257,10 @@  static void tlb_process(struct sbi_scratch *scratch)
 
 static void tlb_sync(struct sbi_scratch *scratch)
 {
-	unsigned long *tlb_sync =
+	atomic_t *tlb_sync =
 			sbi_scratch_offset_ptr(scratch, tlb_sync_off);
 
-	while (!atomic_raw_xchg_ulong(tlb_sync, 0)) {
+	while (atomic_read(tlb_sync) > 0) {
 		/*
 		 * While we are waiting for remote hart to set the sync,
 		 * consume fifo requests to avoid deadlock.
@@ -343,6 +343,7 @@  static int tlb_update(struct sbi_scratch *scratch,
 			  u32 remote_hartid, void *data)
 {
 	int ret;
+	atomic_t *tlb_sync;
 	struct sbi_fifo *tlb_fifo_r;
 	struct sbi_tlb_info *tinfo = data;
 	u32 curr_hartid = current_hartid();
@@ -369,11 +370,8 @@  static int tlb_update(struct sbi_scratch *scratch,
 	tlb_fifo_r = sbi_scratch_offset_ptr(remote_scratch, tlb_fifo_off);
 
 	ret = sbi_fifo_inplace_update(tlb_fifo_r, data, tlb_update_cb);
-	if (ret != SBI_FIFO_UNCHANGED) {
-		return 1;
-	}
 
-	while (sbi_fifo_enqueue(tlb_fifo_r, data) < 0) {
+	while (ret == SBI_FIFO_UNCHANGED && sbi_fifo_enqueue(tlb_fifo_r, data) < 0) {
 		/**
 		 * For now, Busy loop until there is space in the fifo.
 		 * There may be case where target hart is also
@@ -387,6 +385,9 @@  static int tlb_update(struct sbi_scratch *scratch,
 			    curr_hartid, remote_hartid);
 	}
 
+	tlb_sync = sbi_scratch_offset_ptr(scratch, tlb_sync_off);
+	atomic_add_return(tlb_sync, 1);
+
 	return 0;
 }
 
@@ -413,7 +414,7 @@  int sbi_tlb_init(struct sbi_scratch *scratch, bool cold_boot)
 {
 	int ret;
 	void *tlb_mem;
-	unsigned long *tlb_sync;
+	atomic_t *tlb_sync;
 	struct sbi_fifo *tlb_q;
 	const struct sbi_platform *plat = sbi_platform_ptr(scratch);
 
@@ -455,7 +456,7 @@  int sbi_tlb_init(struct sbi_scratch *scratch, bool cold_boot)
 	tlb_q = sbi_scratch_offset_ptr(scratch, tlb_fifo_off);
 	tlb_mem = sbi_scratch_offset_ptr(scratch, tlb_fifo_mem_off);
 
-	*tlb_sync = 0;
+	ATOMIC_INIT(tlb_sync, 0);
 
 	sbi_fifo_init(tlb_q, tlb_mem,
 		      SBI_TLB_FIFO_NUM_ENTRIES, SBI_TLB_INFO_SIZE);