Skip to content

Commit

Permalink
riscv: add option to wait for ack from secondary harts in smp functions
Browse files Browse the repository at this point in the history
Add a wait option to smp_call_function() to wait for the secondary harts
to acknowledge the call-function request. The request is considered to
be acknowledged once each secondary hart has cleared the corresponding
IPI.

As part of the call-function request, the secondary harts invalidate the
instruction cache after clearing the IPI. This adds a delay between
acknowledgment (clear IPI) and fulfillment (call function) of the
request. We want to use the acknowledgment to be able to judge when the
request has been completed. Remove the delay by clearing the IPI after
cache invalidation and just before calling the function from the
request.

Signed-off-by: Lukas Auer <[email protected]>
Reviewed-by: Rick Chen <[email protected]>
Tested-by: Rick Chen <[email protected]>
Reviewed-by: Anup Patel <[email protected]>
  • Loading branch information
lukasauer authored and Andes committed Dec 10, 2019
1 parent 8b3e97b commit 90ae281
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 13 deletions.
2 changes: 2 additions & 0 deletions arch/riscv/cpu/start.S
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ spl_secondary_hart_stack_gd_setup:
la a0, secondary_hart_relocate
mv a1, s0
mv a2, s0
mv a3, zero
jal smp_call_function

/* hang if relocation of secondary harts has failed */
Expand Down Expand Up @@ -337,6 +338,7 @@ relocate_secondary_harts:

mv a1, s2
mv a2, s3
mv a3, zero
jal smp_call_function

/* hang if relocation of secondary harts has failed */
Expand Down
3 changes: 2 additions & 1 deletion arch/riscv/include/asm/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ void handle_ipi(ulong hart);
* @addr: Address of function
* @arg0: First argument of function
* @arg1: Second argument of function
* @wait: Wait for harts to acknowledge request
* @return 0 if OK, -ve on error
*/
int smp_call_function(ulong addr, ulong arg0, ulong arg1);
int smp_call_function(ulong addr, ulong arg0, ulong arg1, int wait);

#endif
2 changes: 1 addition & 1 deletion arch/riscv/lib/bootm.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
#ifdef CONFIG_SMP
ret = smp_call_function(images->ep,
(ulong)images->ft_addr, 0);
(ulong)images->ft_addr, 0, 0);
if (ret)
hang();
#endif
Expand Down
31 changes: 22 additions & 9 deletions arch/riscv/lib/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ extern int riscv_clear_ipi(int hart);
*/
extern int riscv_get_ipi(int hart, int *pending);

static int send_ipi_many(struct ipi_data *ipi)
static int send_ipi_many(struct ipi_data *ipi, int wait)
{
ofnode node, cpus;
u32 reg;
int ret;
int ret, pending;

cpus = ofnode_path("/cpus");
if (!ofnode_valid(cpus)) {
Expand Down Expand Up @@ -91,6 +91,15 @@ static int send_ipi_many(struct ipi_data *ipi)
pr_err("Cannot send IPI to hart %d\n", reg);
return ret;
}

if (wait) {
pending = 1;
while (pending) {
ret = riscv_get_ipi(reg, &pending);
if (ret)
return ret;
}
}
}

return 0;
Expand All @@ -104,21 +113,25 @@ void handle_ipi(ulong hart)
if (hart >= CONFIG_NR_CPUS)
return;

__smp_mb();

smp_function = (void (*)(ulong, ulong, ulong))gd->arch.ipi[hart].addr;
invalidate_icache_all();

/*
* Clear the IPI to acknowledge the request before jumping to the
* requested function.
*/
ret = riscv_clear_ipi(hart);
if (ret) {
pr_err("Cannot clear IPI of hart %ld\n", hart);
return;
}

__smp_mb();

smp_function = (void (*)(ulong, ulong, ulong))gd->arch.ipi[hart].addr;
invalidate_icache_all();

smp_function(hart, gd->arch.ipi[hart].arg0, gd->arch.ipi[hart].arg1);
}

int smp_call_function(ulong addr, ulong arg0, ulong arg1)
int smp_call_function(ulong addr, ulong arg0, ulong arg1, int wait)
{
int ret = 0;
struct ipi_data ipi;
Expand All @@ -127,7 +140,7 @@ int smp_call_function(ulong addr, ulong arg0, ulong arg1)
ipi.arg0 = arg0;
ipi.arg1 = arg1;

ret = send_ipi_many(&ipi);
ret = send_ipi_many(&ipi, wait);

return ret;
}
2 changes: 1 addition & 1 deletion arch/riscv/lib/spl.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)

debug("image entry point: 0x%lX\n", spl_image->entry_point);
#ifdef CONFIG_SMP
ret = smp_call_function(spl_image->entry_point, (ulong)fdt_blob, 0);
ret = smp_call_function(spl_image->entry_point, (ulong)fdt_blob, 0, 0);
if (ret)
hang();
#endif
Expand Down
2 changes: 1 addition & 1 deletion common/spl/spl_opensbi.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void spl_invoke_opensbi(struct spl_image_info *spl_image)
#ifdef CONFIG_SMP
ret = smp_call_function((ulong)spl_image->entry_point,
(ulong)spl_image->fdt_addr,
(ulong)&opensbi_info);
(ulong)&opensbi_info, 0);
if (ret)
hang();
#endif
Expand Down

0 comments on commit 90ae281

Please sign in to comment.