s390x: smp: Improve smp code and reset checks
v3 cover s390x: smp: Improve smp code and reset checks
Let's extend sigp reset testing and clean up the smp library as well.
GIT: https://github.com/frankjaa/kvm-unit-tests/tree/smp_cleanup
v3:
* Added patch to introduce cpu loop in cpu setup
* Added patch that removes cpu loops in favor of the previously introduced one
* Fixed inline assembly for fpc dirtying
* Moved cpu stop hunk from first into the second patch
* Reworked patch #4 commit message and added a comment when waiting for PU
v2:
* Added cpu stop to test_store_status()
* Added smp_cpu_destroy() to the end of smp.c main()
* New patch that prints cpu id on interrupt errors
* New patch that reworks cpu start in the smp library (needed for lpar)
* nullp is now an array
Janosch Frank (9):
s390x: smp: Cleanup smp.c
s390x: smp: Only use smp_cpu_setup once
s390x: Add cpu id to interrupt error prints
s390x: smp: Rework cpu start and active tracking
s390x: smp: Wait for cpu setup to finish
s390x: smp: Loop if secondary cpu returns into cpu setup again
s390x: smp: Remove unneeded cpu loops
s390x: smp: Test all CRs on initial reset
s390x: smp: Dirty fpc before initial reset test
lib/s390x/interrupt.c | 20 +++++------ lib/s390x/smp.c | 52 ++++++++++++++++----------- s390x/cstart64.S | 4 +++ s390x/smp.c | 82 +++++++++++++++++++++++++++---------------- 4 files changed, 97 insertions(+), 61 deletions(-)
Signature · 1 line
2.20.1
PATCH v3 1/9 s390x: smp: Cleanup smp.c
Let's remove a lot of badly formatted code by introducing the wait_for_flag() function.
Also let's remove some stray spaces.
--- s390x/smp.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-)
s390x/smp.c +23 -19
@@ -22,6 +22,13 @@static int testflag =0 ; +static void wait_for_flag (void ) +{ +while (!testflag) { +mb (); + } +} +static void cpu_loop (void ) {for (;;) {}
@@ -30,20 +37,17 @@ static void cpu_loop(void)static void test_func (void ) { testflag =1 ; -mb ();cpu_loop (); }static void test_start (void ) {struct psw psw; - psw.mask =extract_psw_mask (); + psw.mask =extract_psw_mask (); psw.addr = (unsigned long )test_func;smp_cpu_setup (1 , psw); -while (!testflag) { -mb (); - } +wait_for_flag ();report (1 ,"start" ); }
@@ -115,24 +119,24 @@ static void ecall(void) testflag =1 ;while (lc->ext_int_code !=0x1202 ) {mb (); }report (1 ,"ecall" ); - testflag=1 ; + testflag =1 ; }static void test_ecall (void ) {struct psw psw; - psw.mask =extract_psw_mask (); + psw.mask =extract_psw_mask (); psw.addr = (unsigned long )ecall;report_prefix_push ("ecall" ); - testflag=0 ; + testflag =0 ;smp_cpu_destroy (1 );smp_cpu_setup (1 , psw); -while (!testflag) {mb (); } - testflag=0 ; +wait_for_flag (); + testflag =0 ;sigp (1 ,SIGP_EXTERNAL_CALL ,0 ,NULL ); -while (!testflag) {mb ();} +wait_for_flag ();smp_cpu_stop (1 );report_prefix_pop (); }
@@ -147,7 +151,7 @@ static void emcall(void) mask =extract_psw_mask (); mask |=PSW_MASK_EXT ;load_psw_mask (mask); - testflag=1 ; + testflag =1 ;while (lc->ext_int_code !=0x1201 ) {mb (); }report (1 ,"ecall" ); testflag =1 ;
@@ -156,18 +160,18 @@ static void emcall(void)static void test_emcall (void ) {struct psw psw; - psw.mask =extract_psw_mask (); + psw.mask =extract_psw_mask (); psw.addr = (unsigned long )emcall;report_prefix_push ("emcall" ); - testflag=0 ; + testflag =0 ;smp_cpu_destroy (1 );smp_cpu_setup (1 , psw); -while (!testflag) {mb (); } - testflag=0 ; +wait_for_flag (); + testflag =0 ;sigp (1 ,SIGP_EMERGENCY_SIGNAL ,0 ,NULL ); -while (!testflag) {mb (); } +wait_for_flag ();smp_cpu_stop (1 );report_prefix_pop (); }
@@ -177,7 +181,7 @@ static void test_reset_initial(void)struct cpu_status *status =alloc_pages (0 );struct psw psw; - psw.mask =extract_psw_mask (); + psw.mask =extract_psw_mask (); psw.addr = (unsigned long )test_func;report_prefix_push ("reset initial" );
@@ -208,7 +212,7 @@ static void test_reset(void) {struct psw psw; - psw.mask =extract_psw_mask (); + psw.mask =extract_psw_mask (); psw.addr = (unsigned long )test_func;report_prefix_push ("cpu reset" );
Signature · 1 line
2.20.1
Re: [kvm-unit-tests PATCH v3 1/9] s390x: smp: Cleanup smp.c
Quoted 17 lines · Janosch Frank
Let's remove a lot of badly formatted code by introducing the
wait_for_flag()function.Also let's remove some stray spaces.
Signed-off-by Janosch Frank <[email protected]>Reviewed-by Thomas Huth <[email protected]>Reviewed-by Cornelia Huck <[email protected]>--- s390x/smp.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-)s390x/smp.c +0
-0
s390x/smp.c line 29
Quoted 8 lines
s390x/smp.c +5
-0@@ -22,6 +22,13 @@static int testflag =0 ; +static void wait_for_flag (void ) +{ +while (!testflag) { +mb (); + }
No need for the {}
Signature · 3 lines
Thanks, David / dhildenb
PATCH v3 2/9 s390x: smp: Only use smp_cpu_setup once
In reply to Janosch FrankLet's stop and start instead of using setup to run a function on a cpu.
--- s390x/smp.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
s390x/smp.c +14 -7
@@ -46,7 +46,7 @@ static void test_start(void) psw.mask =extract_psw_mask (); psw.addr = (unsigned long )test_func; -smp_cpu_setup (1 , psw); +smp_cpu_start (1 , psw);wait_for_flag ();report (1 ,"start" ); }
@@ -102,6 +102,7 @@ static void test_store_status(void)report (1 ,"status written" );free_pages (status,PAGE_SIZE *2 );report_prefix_pop (); +smp_cpu_stop (1 );report_prefix_pop (); }
@@ -130,9 +131,8 @@ static void test_ecall(void)report_prefix_push ("ecall" ); testflag =0 ; -smp_cpu_destroy (1 ); -smp_cpu_setup (1 , psw); +smp_cpu_start (1 , psw);wait_for_flag (); testflag =0 ;sigp (1 ,SIGP_EXTERNAL_CALL ,0 ,NULL );
@@ -165,9 +165,8 @@ static void test_emcall(void)report_prefix_push ("emcall" ); testflag =0 ; -smp_cpu_destroy (1 ); -smp_cpu_setup (1 , psw); +smp_cpu_start (1 , psw);wait_for_flag (); testflag =0 ;sigp (1 ,SIGP_EMERGENCY_SIGNAL ,0 ,NULL );
@@ -185,7 +184,7 @@ static void test_reset_initial(void) psw.addr = (unsigned long )test_func;report_prefix_push ("reset initial" ); -smp_cpu_setup (1 , psw); +smp_cpu_start (1 , psw);sigp_retry (1 ,SIGP_INITIAL_CPU_RESET ,0 ,NULL );sigp (1 ,SIGP_STORE_STATUS_AT_ADDRESS , (uintptr_t )status,NULL );
@@ -216,7 +215,7 @@ static void test_reset(void) psw.addr = (unsigned long )test_func;report_prefix_push ("cpu reset" ); -smp_cpu_setup (1 , psw); +smp_cpu_start (1 , psw);sigp_retry (1 ,SIGP_CPU_RESET ,0 ,NULL );report (smp_cpu_stopped (1 ),"cpu stopped" );
@@ -225,6 +224,7 @@ static void test_reset(void)int main (void ) { +struct psw psw;report_prefix_push ("smp" );if (smp_query_num_cpus () ==1 ) {
@@ -232,6 +232,12 @@ int main(void) goto done; } +/* Setting up the cpu to give it a stack and lowcore */ + psw.mask =extract_psw_mask (); + psw.addr = (unsigned long )cpu_loop; +smp_cpu_setup (1 , psw); +smp_cpu_stop (1 ); +test_start ();test_stop ();test_stop_store_status ();
@@ -240,6 +246,7 @@ int main(void)test_emcall ();test_reset ();test_reset_initial (); +smp_cpu_destroy (1 ); done:report_prefix_pop ();
Signature · 1 line
2.20.1
PATCH v3 3/9 s390x: Add cpu id to interrupt error prints
In reply to Janosch FrankIt's good to know which cpu broke the test.
--- lib/s390x/interrupt.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
lib/s390x/interrupt.c +10 -10
@@ -107,8 +107,8 @@ static void fixup_pgm_int(void)void handle_pgm_int (void ) {if (!pgm_int_expected) -report_abort ("Unexpected program interrupt: %d at %#lx, ilen %d\n" , - lc->pgm_int_code, lc->pgm_old_psw.addr, +report_abort ("Unexpected program interrupt: %d on cpu %d at %#lx, ilen %d\n" , + lc->pgm_int_code,stap (), lc->pgm_old_psw.addr, lc->pgm_int_id); pgm_int_expected = false;
@@ -119,8 +119,8 @@ void handle_ext_int(void) {if (!ext_int_expected && lc->ext_int_code !=EXT_IRQ_SERVICE_SIG ) { -report_abort ("Unexpected external call interrupt (code %#x): at %#lx" , - lc->ext_int_code, lc->ext_old_psw.addr); +report_abort ("Unexpected external call interrupt (code %#x): on cpu %d at %#lx" , +stap (), lc->ext_int_code, lc->ext_old_psw.addr);return ; }
@@ -137,18 +137,18 @@ void handle_ext_int(void)void handle_mcck_int (void ) { -report_abort ("Unexpected machine check interrupt: at %#lx" , - lc->mcck_old_psw.addr); +report_abort ("Unexpected machine check interrupt: on cpu %d at %#lx" , +stap (), lc->mcck_old_psw.addr); }void handle_io_int (void ) { -report_abort ("Unexpected io interrupt: at %#lx" , - lc->io_old_psw.addr); +report_abort ("Unexpected io interrupt: on cpu %d at %#lx" , +stap (), lc->io_old_psw.addr); }void handle_svc_int (void ) { -report_abort ("Unexpected supervisor call interrupt: at %#lx" , - lc->svc_old_psw.addr); +report_abort ("Unexpected supervisor call interrupt: on cpu %d at %#lx" , +stap (), lc->svc_old_psw.addr); }
Signature · 1 line
2.20.1
PATCH v3 4/9 s390x: smp: Rework cpu start and active tracking
In reply to Janosch FrankThe architecture specifies that processing sigp orders may be asynchronous, and this is indeed the case on some hypervisors, so we need to wait until the cpu runs before we return from the setup/start function.
As there was a lot of duplicate code, a common function for cpu restarts has been introduced.
--- lib/s390x/smp.c | 50 ++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 21 deletions(-)
lib/s390x/smp.c +29 -21
@@ -104,35 +104,46 @@ int smp_cpu_stop_store_status(uint16_t addr)return rc; } +static int smp_cpu_restart_nolock (uint16_t addr,struct psw *psw) +{ +int rc; +struct cpu *cpu =smp_cpu_from_addr (addr); + +if (!cpu) +return -1 ; +if (psw) { + cpu->lowcore->restart_new_psw.mask = psw->mask; + cpu->lowcore->restart_new_psw.addr = psw->addr; + } + rc =sigp (addr,SIGP_RESTART ,0 ,NULL ); +if (rc) +return rc; +/* +* The order has been accepted, but the actual restart may not +* have been performed yet, so wait until the cpu is running. +*/ +while (!smp_cpu_running (addr)) +mb (); + cpu->active = true; +return 0 ; +} +int smp_cpu_restart (uint16_t addr) { -int rc =-1 ; -struct cpu *cpu; +int rc;spin_lock (&lock); - cpu =smp_cpu_from_addr (addr); -if (cpu) { - rc =sigp (addr,SIGP_RESTART ,0 ,NULL ); - cpu->active = true; - } + rc =smp_cpu_restart_nolock (addr,NULL );spin_unlock (&lock);return rc; }int smp_cpu_start (uint16_t addr,struct psw psw) { -int rc =-1 ; -struct cpu *cpu; -struct lowcore *lc; +int rc;spin_lock (&lock); - cpu =smp_cpu_from_addr (addr); -if (cpu) { - lc = cpu->lowcore; - lc->restart_new_psw.mask = psw.mask; - lc->restart_new_psw.addr = psw.addr; - rc =sigp (addr,SIGP_RESTART ,0 ,NULL ); - } + rc =smp_cpu_restart_nolock (addr, &psw);spin_unlock (&lock);return rc; }
@@ -192,10 +203,7 @@ int smp_cpu_setup(uint16_t addr, struct psw psw) lc->sw_int_crs[0 ] =0x0000000000040000UL ;/* Start processing */ - rc =sigp_retry (cpu->addr,SIGP_RESTART ,0 ,NULL ); -if (!rc) - cpu->active = true; - +smp_cpu_restart_nolock (addr,NULL ); out:spin_unlock (&lock);return rc;
Signature · 1 line
2.20.1
Re: [kvm-unit-tests PATCH v3 4/9] s390x: smp: Rework cpu start and active tracking
Quoted 19 lines · Janosch Frank
The architecture specifies that processing sigp orders may be asynchronous, and this is indeed the case on some hypervisors, so we need to wait until the cpu runs before we return from the setup/start function.
As there was a lot of duplicate code, a common function for cpu restarts has been introduced.
Signed-off-by Janosch Frank <[email protected]>Reviewed-by Cornelia Huck <[email protected]>--- lib/s390x/smp.c | 50 ++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 21 deletions(-)lib/s390x/smp.c +0
-0
lib/s390x/smp.c int smp_cpu_stop_store_status(uint16_t addr) · line 110
Quoted 7 lines
lib/s390x/smp.c +4
-0@@ -104,35 +104,46 @@ int smp_cpu_stop_store_status(uint16_t addr)return rc; } +static int smp_cpu_restart_nolock (uint16_t addr,struct psw *psw) +{ +int rc; +struct cpu *cpu =smp_cpu_from_addr (addr);
I'd exchange these two (reverse christmas tree)
lib/s390x/smp.c int smp_cpu_stop_store_status(uint16_t addr) · line 113
Quoted 3 lines
lib/s390x/smp.c +3
-0+ +if (!cpu) +return -1 ;
-EINVAL?
lib/s390x/smp.c int smp_cpu_stop_store_status(uint16_t addr) · line 117
Quoted 4 lines
lib/s390x/smp.c +4
-0+if (psw) { + cpu->lowcore->restart_new_psw.mask = psw->mask; + cpu->lowcore->restart_new_psw.addr = psw->addr; + }
Does this make sense to have optional? (the other CPU will execute random crap if not set, won't it?)
lib/s390x/smp.c int smp_cpu_stop_store_status(uint16_t addr) · line 126
Quoted 9 lines
lib/s390x/smp.c +9
-0+ rc =sigp (addr,SIGP_RESTART ,0 ,NULL ); +if (rc) +return rc; +/* +* The order has been accepted, but the actual restart may not +* have been performed yet, so wait until the cpu is running. +*/ +while (!smp_cpu_running (addr)) +mb ();
Should you make sure to stop the CPU before issuing the restart? Otherwise you will get false positives if it is still running (but hasn't processed the RESTART yet)
Signature · 3 lines
Thanks, David / dhildenb
Re: [kvm-unit-tests PATCH v3 4/9] s390x: smp: Rework cpu start and active tracking
Quoted 1 line · David Hildenbrand
On 17.01.20 11:46, Janosch Frank wrote:
[...]
Quoted 5 lines
lib/s390x/smp.c int smp_cpu_stop_store_status(uint16_t addr) · line 113
Quoted 3 lines
lib/s390x/smp.c +3
-0+ +if (!cpu) +return -1 ;
-EINVAL?
-ENOERRNOHEADERINKVMUNITTESTS ;-)
Thomas
Re: [kvm-unit-tests PATCH v3 4/9] s390x: smp: Rework cpu start and active tracking
Quoted 11 lines · Thomas Huth
Quoted 1 line · David Hildenbrand
On 17.01.20 11:46, Janosch Frank wrote:
[...]
Quoted 5 lines
lib/s390x/smp.c int smp_cpu_stop_store_status(uint16_t addr) · line 113
Quoted 3 lines
lib/s390x/smp.c +3
-0+ +if (!cpu) +return -1 ;
-EINVAL?
-ENOERRNOHEADERINKVMUNITTESTS;-)
-EDAMMIT :)
Signature · 3 lines
Thanks, David / dhildenb
Re: [kvm-unit-tests PATCH v3 4/9] s390x: smp: Rework cpu start and active tracking
In reply to David HildenbrandQuoted 23 lines · David Hildenbrand
Quoted 22 lines · Janosch Frank
The architecture specifies that processing sigp orders may be asynchronous, and this is indeed the case on some hypervisors, so we need to wait until the cpu runs before we return from the setup/start function.
As there was a lot of duplicate code, a common function for cpu restarts has been introduced.
Signed-off-by Janosch Frank <[email protected]>Reviewed-by Cornelia Huck <[email protected]>--- lib/s390x/smp.c | 50 ++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 21 deletions(-)lib/s390x/smp.c +0
-0@@ -104,35 +104,46 @@ int smp_cpu_stop_store_status(uint16_t addr)return rc; }
Quoted 6 lines
lib/s390x/smp.c int smp_cpu_stop_store_status(uint16_t addr) · line 110
Quoted 4 lines
lib/s390x/smp.c +4
-0+static int smp_cpu_restart_nolock (uint16_t addr,struct psw *psw) +{ +int rc; +struct cpu *cpu =smp_cpu_from_addr (addr);I'd exchange these two (reverse christmas tree)
Christmas is over
Quoted 7 lines
lib/s390x/smp.c int smp_cpu_stop_store_status(uint16_t addr) · line 113
Quoted 4 lines
lib/s390x/smp.c +3
-0+ +if (!cpu) +return -1 ;
-EINVAL?
Quoted 7 lines
lib/s390x/smp.c int smp_cpu_stop_store_status(uint16_t addr) · line 117
Quoted 4 lines
lib/s390x/smp.c +4
-0+if (psw) { + cpu->lowcore->restart_new_psw.mask = psw->mask; + cpu->lowcore->restart_new_psw.addr = psw->addr; + }Does this make sense to have optional? (the other CPU will execute random crap if not set, won't it?)
Well, I have restarts in the smp test and I don't want to always pass a psw if I know what the last restart psw was.
Simply restarting into test_func or wait_for_flag is certainly no problem.
Quoted 14 lines
lib/s390x/smp.c int smp_cpu_stop_store_status(uint16_t addr) · line 126
Quoted 10 lines
lib/s390x/smp.c +9
-0+ rc =sigp (addr,SIGP_RESTART ,0 ,NULL ); +if (rc) +return rc; +/* +* The order has been accepted, but the actual restart may not +* have been performed yet, so wait until the cpu is running. +*/ +while (!smp_cpu_running (addr)) +mb ();Should you make sure to stop the CPU before issuing the restart? Otherwise you will get false positives if it is still running (but hasn't processed the RESTART yet)
Good point
Re: [kvm-unit-tests PATCH v3 4/9] s390x: smp: Rework cpu start and active tracking
Quoted 5 lines
Well, I have restarts in the smp test and I don't want to always pass a psw if I know what the last restart psw was.
Simply restarting intotest_funcorwait_for_flagis certainly no problem.Quoted 1 line
Makes sense.
Quoted 16 lines
Quoted 5 lines
Quoted 5 lines
lib/s390x/smp.c +5
-0+ rc =sigp (addr,SIGP_RESTART ,0 ,NULL ); +if (rc) +return rc; +/* +* The order has been accepted, but the actual restart may not Quoted 8 lines
lib/s390x/smp.c int smp_cpu_stop_store_status(uint16_t addr) · line 126
Quoted 4 lines
lib/s390x/smp.c +4
-0+* have been performed yet, so wait until the cpu is running. +*/ +while (!smp_cpu_running (addr)) +mb ();Should you make sure to stop the CPU before issuing the restart? Otherwise you will get false positives if it is still running (but hasn't processed the RESTART yet)
Good point
Signature · 3 lines
Thanks, David / dhildenb
PATCH v3 5/9 s390x: smp: Wait for cpu setup to finish
In reply to Janosch FrankWe store the user provided psw address into restart new, so a psw restart does not lead us through setup again.
Also we wait on smp_cpu_setup() until the cpu has finished setup before returning. This is necessary for z/VM and LPAR where sigp is asynchronous.
--- lib/s390x/smp.c | 2 ++ s390x/cstart64.S | 2 ++ 2 files changed, 4 insertions(+)
lib/s390x/smp.c +2 -0
@@ -204,6 +204,8 @@ int smp_cpu_setup(uint16_t addr, struct psw psw)/* Start processing */ smp_cpu_restart_nolock (addr,NULL ); +/* Wait until the cpu has finished setup and started the provided psw */ +while (lc->restart_new_psw.addr != psw.addr) {mb (); } out:spin_unlock (&lock);return rc;
s390x/cstart64.S +2 -0
@@ -159,6 +159,8 @@ smp_cpu_setup_state: xgr %r1, %r1 lmg %r0, %r15, GEN_LC_SW_INT_GRS lctlg %c0, %c0, GEN_LC_SW_INT_CRS + /* We should only go once through cpu setup and not for every restart */ + stg %r14, GEN_LC_RESTART_NEW_PSW + 8 br %r14 pgm_int:
Signature · 1 line
2.20.1
Re: [kvm-unit-tests PATCH v3 5/9] s390x: smp: Wait for cpu setup to finish
Quoted 7 lines · On Fri, 17 Jan 2020 05:46:36 -0500 Janosch Frank <[email protected]> wrote:
We store the user provided psw address into restart new, so a psw restart does not lead us through setup again.
Also we wait on
smp_cpu_setup()until the cpu has finished setup before returning. This is necessary for z/VM and LPAR where sigp is asynchronous.
Quoted 6 lines
Signed-off-by Janosch Frank <[email protected]>Reviewed-by David Hildenbrand <[email protected]>--- lib/s390x/smp.c | 2 ++ s390x/cstart64.S | 2 ++ 2 files changed, 4 insertions(+)
Re: [kvm-unit-tests PATCH v3 5/9] s390x: smp: Wait for cpu setup to finish
In reply to Janosch FrankQuoted 19 lines · Janosch Frank
We store the user provided psw address into restart new, so a psw restart does not lead us through setup again.
Also we wait on
smp_cpu_setup()until the cpu has finished setup before returning. This is necessary for z/VM and LPAR where sigp is asynchronous.Signed-off-by Janosch Frank <[email protected]>Reviewed-by David Hildenbrand <[email protected]>--- lib/s390x/smp.c | 2 ++ s390x/cstart64.S | 2 ++ 2 files changed, 4 insertions(+)lib/s390x/smp.c +0
-0
lib/s390x/smp.c int smp_cpu_setup(uint16_t addr, struct psw psw) · line 208
Quoted 5 lines
lib/s390x/smp.c +2
-0@@ -204,6 +204,8 @@ int smp_cpu_setup(uint16_t addr, struct psw psw)/* Start processing */ smp_cpu_restart_nolock (addr,NULL ); +/* Wait until the cpu has finished setup and started the provided psw */ +while (lc->restart_new_psw.addr != psw.addr) {mb (); }
while (lc->restart_new_psw.addr != psw.addr)
mb();
Signature · 3 lines
Thanks, David / dhildenb
PATCH v3 6/9 s390x: smp: Loop if secondary cpu returns into cpu setup again
In reply to Janosch FrankUp to now a secondary cpu could have returned from the function it was executing and ending up somewhere in cstart64.S. This was mostly circumvented by an endless loop in the function that it executed.
Let's add a loop to the end of the cpu setup, so we don't have to rely on added loops in the tests.
--- s390x/cstart64.S | 2 ++ 1 file changed, 2 insertions(+)
s390x/cstart64.S +2 -0
@@ -162,6 +162,8 @@ smp_cpu_setup_state: /* We should only go once through cpu setup and not for every restart */ stg %r14, GEN_LC_RESTART_NEW_PSW + 8 br %r14 + /* If the function returns, just loop here */ +0: j 0 pgm_int: SAVE_REGS
Signature · 1 line
2.20.1
Re: [kvm-unit-tests PATCH v3 6/9] s390x: smp: Loop if secondary cpu returns into cpu setup again
Quoted 17 lines · On Fri, 17 Jan 2020 05:46:37 -0500 Janosch Frank <[email protected]> wrote:
Up to now a secondary cpu could have returned from the function it was executing and ending up somewhere in
cstart64.S. This was mostly circumvented by an endless loop in the function that it executed.Let's add a loop to the end of the cpu setup, so we don't have to rely on added loops in the tests.
Signed-off-by Janosch Frank <[email protected]>--- s390x/cstart64.S | 2 ++ 1 file changed, 2 insertions(+)s390x/cstart64.S +0
-0
s390x/cstart64.S smp_cpu_setup_state: · line 166
Quoted 5 lines
s390x/cstart64.S +2
-0@@ -162,6 +162,8 @@ smp_cpu_setup_state: /* We should only go once through cpu setup and not for every restart */ stg %r14, GEN_LC_RESTART_NEW_PSW + 8 br %r14 + /* If the function returns, just loop here */ +0: j 0
Would it make sense to e.g. load a disabled wait psw instead? Or does that mess things up elsewhere?
Quoted 3 lines
s390x/cstart64.S +0
-0pgm_int: SAVE_REGS
Re: [kvm-unit-tests PATCH v3 6/9] s390x: smp: Loop if secondary cpu returns into cpu setup again
Quoted 15 lines · Cornelia Huck
Quoted 12 lines · On Fri, 17 Jan 2020 05:46:37 -0500 Janosch Frank <[email protected]> wrote:
Up to now a secondary cpu could have returned from the function it was executing and ending up somewhere in
cstart64.S. This was mostly circumvented by an endless loop in the function that it executed.Let's add a loop to the end of the cpu setup, so we don't have to rely on added loops in the tests.
Signed-off-by Janosch Frank <[email protected]>--- s390x/cstart64.S | 2 ++ 1 file changed, 2 insertions(+)
Quoted 13 lines
s390x/cstart64.S smp_cpu_setup_state: · line 166
Quoted 10 lines
s390x/cstart64.S +2
-0@@ -162,6 +162,8 @@ smp_cpu_setup_state: /* We should only go once through cpu setup and not for every restart */ stg %r14, GEN_LC_RESTART_NEW_PSW + 8 br %r14 + /* If the function returns, just loop here */ +0: j 0Would it make sense to e.g. load a disabled wait psw instead? Or does that mess things up elsewhere?
I think we can keep it like that for now (simpler than loading a PSW). Overall, I don't care about burning CPU cycles here :)
Signature · 3 lines
Thanks, David / dhildenb
PATCH v3 7/9 s390x: smp: Remove unneeded cpu loops
In reply to Janosch FrankNow that we have a loop which is executed after we return from the main function of a secondary cpu, we can remove the surplus loops.
--- s390x/smp.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
s390x/smp.c +1 -7
@@ -29,15 +29,9 @@ static void wait_for_flag(void) } } -static void cpu_loop (void ) -{ -for (;;) {} -} -static void test_func (void ) { testflag =1 ; -cpu_loop (); }static void test_start (void )
@@ -234,7 +228,7 @@ int main(void)/* Setting up the cpu to give it a stack and lowcore */ psw.mask =extract_psw_mask (); - psw.addr = (unsigned long )cpu_loop; + psw.addr = (unsigned long )test_func;smp_cpu_setup (1 , psw);smp_cpu_stop (1 );
Signature · 1 line
2.20.1
Re: [kvm-unit-tests PATCH v3 7/9] s390x: smp: Remove unneeded cpu loops
Quoted 29 lines · On Fri, 17 Jan 2020 05:46:38 -0500 Janosch Frank <[email protected]> wrote:
Now that we have a loop which is executed after we return from the main function of a secondary cpu, we can remove the surplus loops.
Signed-off-by Janosch Frank <[email protected]>--- s390x/smp.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)s390x/smp.c +0
-6@@ -29,15 +29,9 @@ static void wait_for_flag(void) } } -static void cpu_loop (void ) -{ -for (;;) {} -} -static void test_func (void ) { testflag =1 ; -cpu_loop (); }static void test_start (void )
s390x/smp.c int main(void) · line 231
Quoted 5 lines
s390x/smp.c +1
-1@@ -234,7 +228,7 @@ int main(void)/* Setting up the cpu to give it a stack and lowcore */ psw.mask =extract_psw_mask (); - psw.addr = (unsigned long )cpu_loop; + psw.addr = (unsigned long )test_func;
Before, you did not set testflag here... intended change?
Quoted 3 lines
s390x/smp.c +0
-0smp_cpu_setup (1 , psw);smp_cpu_stop (1 );
Re: [kvm-unit-tests PATCH v3 7/9] s390x: smp: Remove unneeded cpu loops
Quoted 33 lines · Cornelia Huck
Quoted 30 lines · On Fri, 17 Jan 2020 05:46:38 -0500 Janosch Frank <[email protected]> wrote:
Now that we have a loop which is executed after we return from the main function of a secondary cpu, we can remove the surplus loops.
Signed-off-by Janosch Frank <[email protected]>--- s390x/smp.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)s390x/smp.c +0
-6@@ -29,15 +29,9 @@ static void wait_for_flag(void) } } -static void cpu_loop (void ) -{ -for (;;) {} -} -static void test_func (void ) { testflag =1 ; -cpu_loop (); }static void test_start (void )@@ -234,7 +228,7 @@ int main(void)
Quoted 6 lines
s390x/smp.c int main(void) · line 231
Quoted 4 lines
s390x/smp.c +1
-1/* Setting up the cpu to give it a stack and lowcore */ psw.mask =extract_psw_mask (); - psw.addr = (unsigned long )cpu_loop; + psw.addr = (unsigned long )test_func;Before, you did not set testflag here... intended change?
Yes
It is set to 0 before the first test, so it shouldn't matter.
Quoted 5 lines
Quoted 4 lines
s390x/smp.c +0
-0smp_cpu_setup (1 , psw);smp_cpu_stop (1 );
Re: [kvm-unit-tests PATCH v3 7/9] s390x: smp: Remove unneeded cpu loops
Quoted 41 lines · On Mon, 20 Jan 2020 15:41:52 +0100 Janosch Frank <[email protected]> wrote:
Quoted 33 lines · Cornelia Huck
Quoted 30 lines · On Fri, 17 Jan 2020 05:46:38 -0500 Janosch Frank <[email protected]> wrote:
Now that we have a loop which is executed after we return from the main function of a secondary cpu, we can remove the surplus loops.
Signed-off-by Janosch Frank <[email protected]>--- s390x/smp.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)s390x/smp.c +0
-6@@ -29,15 +29,9 @@ static void wait_for_flag(void) } } -static void cpu_loop (void ) -{ -for (;;) {} -} -static void test_func (void ) { testflag =1 ; -cpu_loop (); }static void test_start (void )@@ -234,7 +228,7 @@ int main(void)Quoted 6 lines
s390x/smp.c int main(void) · line 231
Quoted 4 lines
s390x/smp.c +1
-1/* Setting up the cpu to give it a stack and lowcore */ psw.mask =extract_psw_mask (); - psw.addr = (unsigned long )cpu_loop; + psw.addr = (unsigned long )test_func;Before, you did not set testflag here... intended change?
Quoted 2 lines
Yes
It is set to 0 before the first test, so it shouldn't matter.
Hm... I got a bit lost in all those changes, so I checked your branch on github, and I don't see it being set to 0 before test_start() is called?
Quoted 8 lines
Quoted 6 lines
Quoted 5 lines
s390x/smp.c +0
-0smp_cpu_setup (1 , psw);smp_cpu_stop (1 );
Re: [kvm-unit-tests PATCH v3 7/9] s390x: smp: Remove unneeded cpu loops
Quoted 44 lines · Cornelia Huck
Quoted 41 lines · On Mon, 20 Jan 2020 15:41:52 +0100 Janosch Frank <[email protected]> wrote:
Quoted 39 lines · Cornelia Huck
Quoted 29 lines · On Fri, 17 Jan 2020 05:46:38 -0500 Janosch Frank <[email protected]> wrote:
Now that we have a loop which is executed after we return from the main function of a secondary cpu, we can remove the surplus loops.
Signed-off-by Janosch Frank <[email protected]>--- s390x/smp.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)s390x/smp.c +0
-6@@ -29,15 +29,9 @@ static void wait_for_flag(void) } } -static void cpu_loop (void ) -{ -for (;;) {} -} -static void test_func (void ) { testflag =1 ; -cpu_loop (); }static void test_start (void )s390x/smp.c int main(void) · line 231
Quoted 5 lines
s390x/smp.c +1
-1@@ -234,7 +228,7 @@ int main(void)/* Setting up the cpu to give it a stack and lowcore */ psw.mask =extract_psw_mask (); - psw.addr = (unsigned long )cpu_loop; + psw.addr = (unsigned long )test_func;Before, you did not set testflag here... intended change?
Quoted 6 lines
Quoted 2 lines
Yes
It is set to 0 before the first test, so it shouldn't matter.Hm... I got a bit lost in all those changes, so I checked your branch on github, and I don't see it being set to 0 before
test_start()is called?
Well, that's because test_start doesn't care about the flag. ecall and emcall are the first users, and they set it to 0 before using it.
Quoted 10 lines
Quoted 9 lines
Quoted 7 lines
Quoted 6 lines
s390x/smp.c +0
-0smp_cpu_setup (1 , psw);smp_cpu_stop (1 );
Re: [kvm-unit-tests PATCH v3 7/9] s390x: smp: Remove unneeded cpu loops
Quoted 45 lines · On Tue, 21 Jan 2020 13:46:51 +0100 Janosch Frank <[email protected]> wrote:
Quoted 44 lines · Cornelia Huck
Quoted 41 lines · On Mon, 20 Jan 2020 15:41:52 +0100 Janosch Frank <[email protected]> wrote:
Quoted 39 lines · Cornelia Huck
Quoted 29 lines · On Fri, 17 Jan 2020 05:46:38 -0500 Janosch Frank <[email protected]> wrote:
Now that we have a loop which is executed after we return from the main function of a secondary cpu, we can remove the surplus loops.
Signed-off-by Janosch Frank <[email protected]>--- s390x/smp.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)s390x/smp.c +0
-6@@ -29,15 +29,9 @@ static void wait_for_flag(void) } } -static void cpu_loop (void ) -{ -for (;;) {} -} -static void test_func (void ) { testflag =1 ; -cpu_loop (); }static void test_start (void )s390x/smp.c int main(void) · line 231
Quoted 5 lines
s390x/smp.c +1
-1@@ -234,7 +228,7 @@ int main(void)/* Setting up the cpu to give it a stack and lowcore */ psw.mask =extract_psw_mask (); - psw.addr = (unsigned long )cpu_loop; + psw.addr = (unsigned long )test_func;Before, you did not set testflag here... intended change?
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
Yes
It is set to 0 before the first test, so it shouldn't matter.Hm... I got a bit lost in all those changes, so I checked your branch on github, and I don't see it being set to 0 before
test_start()is called?Well, that's because
test_startdoesn't care about the flag.
But I see a wait_for_flag() in there? What am I missing?
Quoted 14 lines
ecall and emcall are the first users, and they set it to 0 before using it.
Quoted 10 lines
Quoted 9 lines
Quoted 7 lines
Quoted 6 lines
s390x/smp.c +0
-0smp_cpu_setup (1 , psw);smp_cpu_stop (1 );
Re: [kvm-unit-tests PATCH v3 7/9] s390x: smp: Remove unneeded cpu loops
Quoted 51 lines · Cornelia Huck
Quoted 48 lines · On Tue, 21 Jan 2020 13:46:51 +0100 Janosch Frank <[email protected]> wrote:
Quoted 47 lines · Cornelia Huck
Quoted 43 lines · On Mon, 20 Jan 2020 15:41:52 +0100 Janosch Frank <[email protected]> wrote:
Quoted 33 lines · Cornelia Huck
Quoted 30 lines · On Fri, 17 Jan 2020 05:46:38 -0500 Janosch Frank <[email protected]> wrote:
Now that we have a loop which is executed after we return from the main function of a secondary cpu, we can remove the surplus loops.
Signed-off-by Janosch Frank <[email protected]>--- s390x/smp.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)s390x/smp.c +0
-6@@ -29,15 +29,9 @@ static void wait_for_flag(void) } } -static void cpu_loop (void ) -{ -for (;;) {} -} -static void test_func (void ) { testflag =1 ; -cpu_loop (); }static void test_start (void )@@ -234,7 +228,7 @@ int main(void)Quoted 6 lines
s390x/smp.c int main(void) · line 231
Quoted 4 lines
s390x/smp.c +1
-1/* Setting up the cpu to give it a stack and lowcore */ psw.mask =extract_psw_mask (); - psw.addr = (unsigned long )cpu_loop; + psw.addr = (unsigned long )test_func;Before, you did not set testflag here... intended change?
Yes
It is set to 0 before the first test, so it shouldn't matter.
Quoted 9 lines
Quoted 5 lines
Quoted 3 lines
Hm... I got a bit lost in all those changes, so I checked your branch on github, and I don't see it being set to 0 before
test_start()is called?Well, that's because
test_startdoesn't care about the flag.But I see a
wait_for_flag()in there? What am I missing?Quoted 1 line
ecall and emcall are the first users, and they set it to 0 before using it.
Well, cpu #1 will update tesflag to 1 in ecall() and emcall()
Quoted 14 lines
Quoted 13 lines
Quoted 11 lines
Quoted 10 lines
Quoted 8 lines
Quoted 7 lines
s390x/smp.c +0
-0smp_cpu_setup (1 , psw);smp_cpu_stop (1 );
PATCH v3 8/9 s390x: smp: Test all CRs on initial reset
In reply to Janosch FrankAll CRs are set to 0 and CRs 0 and 14 are set to pre-defined values, so we also need to test 1-13 and 15 for 0.
And while we're at it, let's also set some values to cr 1, 7 and 13, so we can actually be sure that they will be zeroed.
--- s390x/smp.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
s390x/smp.c +17 -1
@@ -169,16 +169,30 @@ static void test_emcall(void)report_prefix_pop (); } +/* Used to dirty registers of cpu #1 before it is reset */ +static void test_func_initial (void ) +{ +lctlg (1 ,0x42000UL ); +lctlg (7 ,0x43000UL ); +lctlg (13 ,0x44000UL ); +mb (); + testflag =1 ; +} +static void test_reset_initial (void ) {struct cpu_status *status =alloc_pages (0 ); +uint64_t nullp[12 ] = {};struct psw psw; psw.mask =extract_psw_mask (); - psw.addr = (unsigned long )test_func; + psw.addr = (unsigned long )test_func_initial;report_prefix_push ("reset initial" ); + testflag =0 ; +mb ();smp_cpu_start (1 , psw); +wait_for_flag ();sigp_retry (1 ,SIGP_INITIAL_CPU_RESET ,0 ,NULL );sigp (1 ,SIGP_STORE_STATUS_AT_ADDRESS , (uintptr_t )status,NULL );
@@ -189,6 +203,8 @@ static void test_reset_initial(void)report (!status->fpc,"fpc" );report (!status->cputm,"cpu timer" );report (!status->todpr,"todpr" ); +report (!memcmp (&status->crs[1 ], nullp,sizeof (status->crs[1 ]) *12 ),"cr1-13 == 0" ); +report (status->crs[15 ] ==0 ,"cr15 == 0" );report_prefix_pop ();report_prefix_push ("initialized" );
Signature · 1 line
2.20.1
Re: [kvm-unit-tests PATCH v3 8/9] s390x: smp: Test all CRs on initial reset
Quoted 10 lines · On Fri, 17 Jan 2020 05:46:39 -0500 Janosch Frank <[email protected]> wrote:
All CRs are set to 0 and CRs 0 and 14 are set to pre-defined values, so we also need to test 1-13 and 15 for 0.
And while we're at it, let's also set some values to cr 1, 7 and 13, so we can actually be sure that they will be zeroed.
Signed-off-by Janosch Frank <[email protected]>--- s390x/smp.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
Re: [kvm-unit-tests PATCH v3 8/9] s390x: smp: Test all CRs on initial reset
In reply to Janosch FrankQuoted 32 lines · Janosch Frank
All CRs are set to 0 and CRs 0 and 14 are set to pre-defined values, so we also need to test 1-13 and 15 for 0.
And while we're at it, let's also set some values to cr 1, 7 and 13, so we can actually be sure that they will be zeroed.
Signed-off-by Janosch Frank <[email protected]>--- s390x/smp.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)s390x/smp.c +10
-0@@ -169,16 +169,30 @@ static void test_emcall(void)report_prefix_pop (); } +/* Used to dirty registers of cpu #1 before it is reset */ +static void test_func_initial (void ) +{ +lctlg (1 ,0x42000UL ); +lctlg (7 ,0x43000UL ); +lctlg (13 ,0x44000UL ); +mb (); + testflag =1 ; +} +static void test_reset_initial (void ) {struct cpu_status *status =alloc_pages (0 );
s390x/smp.c static void test_emcall(void) · line 193
Quoted 10 lines
s390x/smp.c +4
-1+uint64_t nullp[12 ] = {};struct psw psw; psw.mask =extract_psw_mask (); - psw.addr = (unsigned long )test_func; + psw.addr = (unsigned long )test_func_initial;report_prefix_push ("reset initial" ); + testflag =0 ; +mb ();
maybe use a set_flag() function like
mb();
testflag = val;mb();
and use it everywhere you set the flag? (e.g., in test_func_initial())
Apart from that
Quoted 15 lines
s390x/smp.c +3
-0smp_cpu_start (1 , psw); +wait_for_flag ();sigp_retry (1 ,SIGP_INITIAL_CPU_RESET ,0 ,NULL );sigp (1 ,SIGP_STORE_STATUS_AT_ADDRESS , (uintptr_t )status,NULL );@@ -189,6 +203,8 @@ static void test_reset_initial(void)report (!status->fpc,"fpc" );report (!status->cputm,"cpu timer" );report (!status->todpr,"todpr" ); +report (!memcmp (&status->crs[1 ], nullp,sizeof (status->crs[1 ]) *12 ),"cr1-13 == 0" ); +report (status->crs[15 ] ==0 ,"cr15 == 0" );report_prefix_pop ();report_prefix_push ("initialized" );
Signature · 3 lines
Thanks, David / dhildenb
Re: [kvm-unit-tests PATCH v3 8/9] s390x: smp: Test all CRs on initial reset
Quoted 46 lines · David Hildenbrand
Quoted 32 lines · Janosch Frank
All CRs are set to 0 and CRs 0 and 14 are set to pre-defined values, so we also need to test 1-13 and 15 for 0.
And while we're at it, let's also set some values to cr 1, 7 and 13, so we can actually be sure that they will be zeroed.
Signed-off-by Janosch Frank <[email protected]>--- s390x/smp.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)s390x/smp.c +10
-0@@ -169,16 +169,30 @@ static void test_emcall(void)report_prefix_pop (); } +/* Used to dirty registers of cpu #1 before it is reset */ +static void test_func_initial (void ) +{ +lctlg (1 ,0x42000UL ); +lctlg (7 ,0x43000UL ); +lctlg (13 ,0x44000UL ); +mb (); + testflag =1 ; +} +static void test_reset_initial (void ) {struct cpu_status *status =alloc_pages (0 );s390x/smp.c static void test_emcall(void) · line 193
Quoted 10 lines
s390x/smp.c +4
-1+uint64_t nullp[12 ] = {};struct psw psw; psw.mask =extract_psw_mask (); - psw.addr = (unsigned long )test_func; + psw.addr = (unsigned long )test_func_initial;report_prefix_push ("reset initial" ); + testflag =0 ; +mb ();maybe use a
set_flag()function like
Quoted 5 lines
mb();
testflag = val;mb();and use it everywhere you set the flag? (e.g., in
test_func_initial())
Hmm, so basically a set_test_flag() function in a new patch :) Ok, I'll have a look.
Quoted 22 lines
Apart from that
Reviewed-by David Hildenbrand <[email protected]>Quoted 15 lines
s390x/smp.c +3
-0smp_cpu_start (1 , psw); +wait_for_flag ();sigp_retry (1 ,SIGP_INITIAL_CPU_RESET ,0 ,NULL );sigp (1 ,SIGP_STORE_STATUS_AT_ADDRESS , (uintptr_t )status,NULL );@@ -189,6 +203,8 @@ static void test_reset_initial(void)report (!status->fpc,"fpc" );report (!status->cputm,"cpu timer" );report (!status->todpr,"todpr" ); +report (!memcmp (&status->crs[1 ], nullp,sizeof (status->crs[1 ]) *12 ),"cr1-13 == 0" ); +report (status->crs[15 ] ==0 ,"cr15 == 0" );report_prefix_pop ();report_prefix_push ("initialized" );
Re: [kvm-unit-tests PATCH v3 8/9] s390x: smp: Test all CRs on initial reset
Quoted 47 lines · Janosch Frank
Quoted 46 lines · David Hildenbrand
Quoted 32 lines · Janosch Frank
All CRs are set to 0 and CRs 0 and 14 are set to pre-defined values, so we also need to test 1-13 and 15 for 0.
And while we're at it, let's also set some values to cr 1, 7 and 13, so we can actually be sure that they will be zeroed.
Signed-off-by Janosch Frank <[email protected]>--- s390x/smp.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)s390x/smp.c +10
-0@@ -169,16 +169,30 @@ static void test_emcall(void)report_prefix_pop (); } +/* Used to dirty registers of cpu #1 before it is reset */ +static void test_func_initial (void ) +{ +lctlg (1 ,0x42000UL ); +lctlg (7 ,0x43000UL ); +lctlg (13 ,0x44000UL ); +mb (); + testflag =1 ; +} +static void test_reset_initial (void ) {struct cpu_status *status =alloc_pages (0 );s390x/smp.c static void test_emcall(void) · line 193
Quoted 10 lines
s390x/smp.c +4
-1+uint64_t nullp[12 ] = {};struct psw psw; psw.mask =extract_psw_mask (); - psw.addr = (unsigned long )test_func; + psw.addr = (unsigned long )test_func_initial;report_prefix_push ("reset initial" ); + testflag =0 ; +mb ();maybe use a
set_flag()function like
Quoted 8 lines
Quoted 5 lines
mb();
testflag = val;mb();and use it everywhere you set the flag? (e.g., in
test_func_initial())Hmm, so basically a
set_test_flag()function in a new patch :) Ok, I'll have a look.
Sorry that this patch set keeps exploding :)
Signature · 3 lines
Thanks, David / dhildenb
PATCH v3 9/9 s390x: smp: Dirty fpc before initial reset test
In reply to Janosch FrankLet's dirty the fpc, before we test if the initial reset sets it to 0.
--- s390x/smp.c | 1 + 1 file changed, 1 insertion(+)
s390x/smp.c +1 -0
@@ -172,6 +172,7 @@ static void test_emcall(void)/* Used to dirty registers of cpu #1 before it is reset */ static void test_func_initial (void ) { + asmvolatile ("sfpc %0" ::"d" (0x11 ));lctlg (1 ,0x42000UL );lctlg (7 ,0x43000UL );lctlg (13 ,0x44000UL );
Signature · 1 line
2.20.1