This patch series has patches for POWER DSCR fixes, improvements,
in code documentaion, kernel support user documentation and selftest based
test cases. It has got five test cases which are derived from Anton's DSCR
test bucket which can be listed as follows.
(1) http://ozlabs.org/~anton/junkcode/dscr_default_test.c
(2) http://ozlabs.org/~anton/junkcode/dscr_explicit_test.c
(3) http://ozlabs.org/~anton/junkcode/dscr_inherit_exec_test.c
(4) http://ozlabs.org/~anton/junkcode/dscr_inherit_test.c
(5) http://ozlabs.org/~anton/junkcode/user_dscr_test.c
NOTE1: Anton's original inherit exec test expected the child to have system
default DSCR value instead of the inherited DSCR value from it's parent.
But looks like thats not the case when we execute the test, it always
inherits it's parent's DSCR value over the exec call as well. So I have
changed the test program assuming its correct to have the inherited DSCR
value in the fork/execed child program. Please let me know if thats not
correct and I am missing something there.
Changes in V4:
- Restoring the system DSCR default value in test cases before exiting
- Removed new-line from all the perror() calls
- Some minor cosmetic changes to the test cases
- Added Anton's SOB to the above mentioned five derived test cases
Changes in V3:
-------------
- Minor changes to last couple of sysfs test cases
- Added .gitignore file for the new test directory
Changes in V2: (https://lkml.org/lkml/2015/1/13/148)
-------------
- Updated the thread struct DSCR value inside mtspr facility exception path
- Modified the in code documentation to follow the kernel-doc format
- Added seven selftest based DSCR related test cases under powerpc
Original V1:
------------
- Posted here at https://patchwork.ozlabs.org/patch/418583/
Anshuman Khandual (13):
powerpc: Fix handling of DSCR related facility unavailable exception
powerpc, process: Remove the unused extern dscr_default
powerpc, offset: Change PACA_DSCR to PACA_DSCR_DEFAULT
powerpc, dscr: Added some in-code documentation
documentation, powerpc: Add documentation for DSCR support
selftests, powerpc: Add test for system wide DSCR default
selftests, powerpc: Add test for explicitly changing DSCR value
selftests, powerpc: Add test for DSCR SPR numbers
selftests, powerpc: Add test for DSCR value inheritence across fork
selftests, powerpc: Add test for DSCR inheritence across fork & exec
selftests, powerpc: Add test for all DSCR sysfs interfaces
selftests, powerpc: Add thread based stress test for DSCR sysfs interfaces
selftests, powerpc: Add gitignore file for the new DSCR tests
Documentation/powerpc/00-INDEX | 2 +
Documentation/powerpc/dscr.txt | 83 +++++++++++++
arch/powerpc/include/asm/processor.h | 9 ++
arch/powerpc/kernel/asm-offsets.c | 2 +-
arch/powerpc/kernel/entry_64.S | 2 +-
arch/powerpc/kernel/process.c | 1 -
arch/powerpc/kernel/sysfs.c | 38 ++++++
arch/powerpc/kernel/tm.S | 4 +-
arch/powerpc/kernel/traps.c | 45 +++++++-
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 +-
tools/testing/selftests/powerpc/Makefile | 2 +-
tools/testing/selftests/powerpc/dscr/.gitignore | 7 ++
tools/testing/selftests/powerpc/dscr/Makefile | 19 +++
tools/testing/selftests/powerpc/dscr/dscr.h | 120 +++++++++++++++++++
.../selftests/powerpc/dscr/dscr_default_test.c | 128 +++++++++++++++++++++
.../selftests/powerpc/dscr/dscr_explicit_test.c | 72 ++++++++++++
.../powerpc/dscr/dscr_inherit_exec_test.c | 118 +++++++++++++++++++
.../selftests/powerpc/dscr/dscr_inherit_test.c | 96 ++++++++++++++++
.../selftests/powerpc/dscr/dscr_sysfs_test.c | 98 ++++++++++++++++
.../powerpc/dscr/dscr_sysfs_thread_test.c | 123 ++++++++++++++++++++
.../selftests/powerpc/dscr/dscr_user_test.c | 62 ++++++++++
21 files changed, 1021 insertions(+), 12 deletions(-)
create mode 100644 Documentation/powerpc/dscr.txt
create mode 100644 tools/testing/selftests/powerpc/dscr/.gitignore
create mode 100644 tools/testing/selftests/powerpc/dscr/Makefile
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr.h
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_default_test.c
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_user_test.c
--
1.9.3
The process context switch code no longer uses dscr_default variable
from the sysfs.c file. The variable became unused when we started
storing the CPU specific DSCR value in the PACA structure instead.
This patch just removes this extern declaration. It was originally
added by the following commit.
efcac658: powerpc: Per process DSCR + some fixes (try#4)
Signed-off-by: Anshuman Khandual <redacted>
---
arch/powerpc/kernel/process.c | 1 -
1 file changed, 1 deletion(-)
This patch adds a test case for the system wide DSCR default
value, which when changed through it's sysfs interface must
be visible to all threads reading DSCR either through the
privilege state SPR or the problem state SPR. The DSCR value
change should be immediate as well.
Acked-by: Shuah Khan <redacted>
Signed-off-by: Anshuman Khandual <redacted>
Signed-off-by: Anton Blanchard <redacted>
---
tools/testing/selftests/powerpc/Makefile | 2 +-
tools/testing/selftests/powerpc/dscr/Makefile | 17 +++
tools/testing/selftests/powerpc/dscr/dscr.h | 120 +++++++++++++++++++
.../selftests/powerpc/dscr/dscr_default_test.c | 128 +++++++++++++++++++++
4 files changed, 266 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/dscr/Makefile
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr.h
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_default_test.c
@@ -0,0 +1,128 @@+/*+*POWERDataStreamControlRegister(DSCR)defaulttest+*+*ThistestmodifiesthesystemwidedefaultDSCRthrough+*it'ssysfsinterfaceandthenverifiesthatallthreads+*seethecorrectchangedDSCRvalueimmediately.+*+*Copyright(C)2012AntonBlanchard<anton@au.ibm.com>,IBM+*Copyright(C)2015AnshumanKhandual<khandual@linux.vnet.ibm.com>,IBM+*+*Thisprogramisfreesoftware;youcanredistributeitand/or+*modifyitunderthetermsoftheGNUGeneralPublicLicense+*aspublishedbytheFreeSoftwareFoundation;eitherversion+*2oftheLicense,or(atyouroption)anylaterversion.+*/+#include"dscr.h"++staticunsignedlongdscr;/* System DSCR default */+staticunsignedlongsequence;+staticunsignedlongresult[THREADS];++staticvoid*do_test(void*in)+{+unsignedlongthread=(unsignedlong)in;+unsignedlongi;++for(i=0;i<COUNT;i++){+unsignedlongd,cur_dscr,cur_dscr_usr;+unsignedlongs1,s2;++s1=ACCESS_ONCE(sequence);+if(s1&1)+continue;+rmb();++d=dscr;+cur_dscr=get_dscr();+cur_dscr_usr=get_dscr_usr();++rmb();+s2=sequence;++if(s1!=s2)+continue;++if(cur_dscr!=d){+fprintf(stderr,"thread %ld kernel DSCR should be %ld "+"but is %ld\n",thread,d,cur_dscr);+result[thread]=1;+pthread_exit(&result[thread]);+}++if(cur_dscr_usr!=d){+fprintf(stderr,"thread %ld user DSCR should be %ld "+"but is %ld\n",thread,d,cur_dscr_usr);+result[thread]=1;+pthread_exit(&result[thread]);+}+}+result[thread]=0;+pthread_exit(&result[thread]);+}++intdscr_default(void)+{+pthread_tthreads[THREADS];+unsignedlongi,*status[THREADS];+unsignedlongorig_dscr_default;++orig_dscr_default=get_default_dscr();++/* Initial DSCR default */+dscr=1;+set_default_dscr(dscr);++/* Spawn all testing threads */+for(i=0;i<THREADS;i++){+if(pthread_create(&threads[i],NULL,do_test,(void*)i)){+perror("pthread_create() failed");+gotofail;+}+}++srand(getpid());++/* Keep changing the DSCR default */+for(i=0;i<COUNT;i++){+doubleret=uniform_deviate(rand());++if(ret<0.0001){+sequence++;+wmb();++dscr++;+if(dscr>DSCR_MAX)+dscr=0;++set_default_dscr(dscr);++wmb();+sequence++;+}+}++/* Individual testing thread exit status */+for(i=0;i<THREADS;i++){+if(pthread_join(threads[i],(void**)&(status[i]))){+perror("pthread_join() failed");+gotofail;+}++if(*status[i]){+printf("%ldth thread failed to join with %ld status\n",+i,*status[i]);+gotofail;+}+}+set_default_dscr(orig_dscr_default);+return0;+fail:+set_default_dscr(orig_dscr_default);+return1;+}++intmain(intargc,char*argv[])+{+returntest_harness(dscr_default,"dscr_default_test");+}
This patch adds a new documentation file explaining the DSCR
support on powerpc platforms. This explains DSCR related data
structure, code paths and also available user interfaces. Any
further functional changes to the DSCR support in the kernel
should definitely update the documentation here.
Signed-off-by: Anshuman Khandual <redacted>
---
Documentation/powerpc/00-INDEX | 2 +
Documentation/powerpc/dscr.txt | 83 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+)
create mode 100644 Documentation/powerpc/dscr.txt
@@ -30,3 +30,5 @@ ptrace.txt - Information on the ptrace interfaces for hardware debug registers. transactional_memory.txt - Overview of the Power8 transactional memory support.+dscr.txt+ - Overview DSCR (Data Stream Control Register) support.
@@ -0,0 +1,83 @@+ DSCR (Data Stream Control Register)+ ================================================++DSCR register in powerpc allows user to have some control of prefetch of data+stream in the processor. Please refer to the ISA documents or related manual+for more detailed information regarding how to use this DSCR to attain this+control of the pefetches . This document here provides an overview of kernel+support for DSCR, related kernel objects, it's functionalities and exported+user interface.++(A) Data Structures:++ (1) thread_struct:+ dscr /* Thread DSCR value */+ dscr_inherit /* Thread has changed default DSCR */++ (2) PACA:+ dscr_default /* per-CPU DSCR default value */++ (3) sysfs.c:+ dscr_default /* System DSCR default value */++(B) Scheduler Changes:++ Scheduler will write the per-CPU DSCR default which is stored in the+ CPU's PACA value into the register if the thread has dscr_inherit value+ cleared which means that it has not changed the default DSCR till now.+ If the dscr_inherit value is set which means that it has changed the+ default DSCR value, scheduler will write the changed value which will+ now be contained in thread struct's dscr into the register instead of+ the per-CPU default PACA based DSCR value.++ NOTE: Please note here that the system wide global DSCR value never+ gets used directly in the scheduler process context switch at all.++(C) SYSFS Interface:++ Global DSCR default: /sys/devices/system/cpu/dscr_default+ CPU specific DSCR default: /sys/devices/system/cpu/cpuN/dscr++ Changing the global DSCR default in the sysfs will change all the CPU+ specific DSCR defaults immediately in their PACA structures. Again if+ the current process has the dscr_inherit clear, it also writes the new+ value into every CPU's DSCR register right away and updates the current+ thread's DSCR value as well.++ Changing the CPU specif DSCR default value in the sysfs does exactly+ the same thing as above but unlike the global one above, it just changes+ stuff for that particular CPU instead for all the CPUs on the system.++(D) User Space Instructions:++ The DSCR register can be accessed in the user space using any of these+ two SPR numbers available for that purpose.++ (1) Problem state SPR: 0x03 (Un-privileged, POWER8 only)+ (2) Privileged state SPR: 0x11 (Privileged)++ Accessing DSCR through privileged SPR number (0x11) from user space+ works, as it is emulated following an illegal instruction exception+ inside the kernel. Both mfspr and mtspr instructions are emulated.++ Accessing DSCR through user level SPR (0x03) from user space will first+ create a facility unavailable exception. Inside this exception handler+ all mfspr isntruction based read attempts will get emulated and returned+ where as the first mtspr instruction based write attempts will enable+ the DSCR facility for the next time around (both for read and write) by+ setting DSCR facility in the FSCR register.++(E) Specifics about 'dscr_inherit':++ The thread struct element 'dscr_inherit' represents whether the thread+ in question has attempted and changed the DSCR itself using any of the+ following methods. This element signifies whether the thread wants to+ use the CPU default DSCR value or its own changed DSCR value in the+ kernel.++ (1) mtspr instruction (SPR number 0x03)+ (2) mtspr instruction (SPR number 0x11)+ (3) ptrace interface (Explicitly set user DSCR value)++ Any child of the process created after this event in the process inherits+ this same behaviour as well.
This patch adds a test case to verify that the changed DSCR value
inside any process would be inherited to it's child across the fork
and exec system call.
Acked-by: Shuah Khan <redacted>
Signed-off-by: Anshuman Khandual <redacted>
Signed-off-by: Anton Blanchard <redacted>
---
tools/testing/selftests/powerpc/dscr/Makefile | 2 +-
.../powerpc/dscr/dscr_inherit_exec_test.c | 118 +++++++++++++++++++++
2 files changed, 119 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_inherit_exec_test.c
This patch adds a test which verifies that the DSCR privilege and
problem state SPR read & write accesses while making sure that the
results are always the same irrespective of which SPR number is
being used.
Acked-by: Shuah Khan <redacted>
Signed-off-by: Anshuman Khandual <redacted>
Signed-off-by: Anton Blanchard <redacted>
---
tools/testing/selftests/powerpc/dscr/Makefile | 2 +-
.../selftests/powerpc/dscr/dscr_user_test.c | 62 ++++++++++++++++++++++
2 files changed, 63 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_user_test.c
@@ -0,0 +1,62 @@+/*+*POWERDataStreamControlRegister(DSCR)SPRtest+*+*ThistestmodifiestheDSCRvaluethroughboththeSPRnumber+*basedmtsprinstructionandthenmakessurethatthesameis+*reflectedthroughmfsprinstructionusingeitheroftheSPR+*numbers.+*+*WhenusingtheprivilegestateSPR,theinstructionssuchas+*mfsprormtsprarepriviledgedandthekernelemulatesthem+*forus.InstructionsusingproblemstateSPRcanbeexuecuted+*directlywithoutanyemulationiftheHWsupportsthem.Else+*theyalsogetemulatedbythekernel.+*+*Copyright(C)2013AntonBlanchard<anton@au.ibm.com>,IBM+*Copyright(C)2015AnshumanKhandual<khandual@linux.vnet.ibm.com>,IBM+*+*Thisprogramisfreesoftware;youcanredistributeitand/or+*modifyitunderthetermsoftheGNUGeneralPublicLicense+*aspublishedbytheFreeSoftwareFoundation;eitherversion+*2oftheLicense,or(atyouroption)anylaterversion.+*/+#include"dscr.h"++staticintcheck_dscr(char*str)+{+unsignedlongcur_dscr,cur_dscr_usr;++cur_dscr=get_dscr();+cur_dscr_usr=get_dscr_usr();+if(cur_dscr!=cur_dscr_usr){+printf("%s set, kernel get %lx != user get %lx\n",+str,cur_dscr,cur_dscr_usr);+return1;+}+return0;+}++intdscr_user(void)+{+inti;++check_dscr("");++for(i=0;i<COUNT;i++){+set_dscr(i);+if(check_dscr("kernel"))+return1;+}++for(i=0;i<COUNT;i++){+set_dscr_usr(i);+if(check_dscr("user"))+return1;+}+return0;+}++intmain(intargc,char*argv[])+{+returntest_harness(dscr_user,"dscr_user_test");+}
PACA_DSCR offset macro tracks dscr_default element in the paca
structure. Better change the name of this macro to match that
of the data element it tracks. Makes the code more readable.
Signed-off-by: Anshuman Khandual <redacted>
---
arch/powerpc/kernel/asm-offsets.c | 2 +-
arch/powerpc/kernel/entry_64.S | 2 +-
arch/powerpc/kernel/tm.S | 4 ++--
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
Currently DSCR (Data Stream Control Register) can be accessed with
mfspr or mtspr instructions inside a thread via two different SPR
numbers. One being the user accessible problem state SPR number 0x03
and the other being the privilege state SPR number 0x11. All access
through the privilege state SPR number get emulated through illegal
instruction exception. Any access through the problem state SPR number
raises one facility unavailable exception which sets the thread based
dscr_inherit bit and enables DSCR facility through FSCR register thus
allowing direct access to DSCR without going through this exception in
the future. We set the thread.dscr_inherit bit whether the access was
with mfspr or mtspr instruction which is neither correct nor does it
match the behaviour through the instruction emulation code path driven
from privilege state SPR number. User currently observes two different
kind of behaviour when accessing the DSCR through these two SPR numbers.
This problem can be observed through these two test cases by replacing
the privilege state SPR number with the problem state SPR number.
(1) http://ozlabs.org/~anton/junkcode/dscr_default_test.c
(2) http://ozlabs.org/~anton/junkcode/dscr_explicit_test.c
This patch fixes the problem by making sure that the behaviour visible
to the user remains the same irrespective of which SPR number is being
used. Inside facility unavailable exception, we check whether it was
cuased by a mfspr or a mtspr isntrucction. In case of mfspr instruction,
just emulate the instruction. In case of mtspr instruction, set the
thread based dscr_inherit bit and also enable the facility through FSCR.
All user SPR based mfspr instruction will be emulated till one user SPR
based mtspr has been executed.
Signed-off-by: Anshuman Khandual <redacted>
---
arch/powerpc/kernel/traps.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 40 insertions(+), 5 deletions(-)
@@ -1388,12 +1389,46 @@ void facility_unavailable_exception(struct pt_regs *regs)status=value>>56;if(status==FSCR_DSCR_LG){-/* User is acessing the DSCR. Set the inherit bit and allow-*theusertosetitdirectlyinfuturebysettingviathe-*FSCRDSCRbit.WealwaysleaveHFSCRDSCRset.+/*+*UserisaccessingtheDSCRregisterusingtheproblem+*stateonlySPRnumber(0x03)eitherthroughamfspror+*amtsprinstruction.Ifitisawriteattemptthrough+*amtspr,thenwesettheinheritbit.Thisalsoallows+*theusertowriteorreadtheregisterdirectlyinthe+*futurebysettingviatheFSCRDSCRbit.Butincaseit+*isareadDSCRattemptthroughamfsprinstruction,we+*justemulatetheinstructioninstead.Thiscodepathwill+*alwaysemulateallthemfsprinstructionstilltheuser+*hasattemptedatleastonemtsprinstruction.Thiswayit+*preservesthesamebehaviourwhentheuserisaccessing+*theDSCRthroughprivilegelevelonlySPRnumber(0x11)+*whichisemulatedthroughillegalinstructionexception.+*WealwaysleaveHFSCRDSCRset.*/-current->thread.dscr_inherit=1;-mtspr(SPRN_FSCR,value|FSCR_DSCR);+if(get_user(instword,(u32__user*)(regs->nip))){+pr_err("Failed to fetch the user instruction\n");+return;+}++/* Write into DSCR (mtspr 0x03, RS) */+if((instword&PPC_INST_MTSPR_DSCR_USER_MASK)+==PPC_INST_MTSPR_DSCR_USER){+rd=(instword>>21)&0x1f;+current->thread.dscr=regs->gpr[rd];+current->thread.dscr_inherit=1;+mtspr(SPRN_FSCR,value|FSCR_DSCR);+}++/* Read from DSCR (mfspr RT, 0x03) */+if((instword&PPC_INST_MFSPR_DSCR_USER_MASK)+==PPC_INST_MFSPR_DSCR_USER){+if(emulate_instruction(regs)){+pr_err("DSCR based mfspr emulation failed\n");+return;+}+regs->nip+=4;+emulate_single_step(regs);+}return;}
This test continuously updates the system wide DSCR default value
in the sysfs interface and makes sure that the same is reflected
across all the sysfs interfaces for each individual CPUs present
on the system.
Acked-by: Shuah Khan <redacted>
Signed-off-by: Anshuman Khandual <redacted>
---
tools/testing/selftests/powerpc/dscr/Makefile | 3 +-
.../selftests/powerpc/dscr/dscr_sysfs_test.c | 98 ++++++++++++++++++++++
2 files changed, 100 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
This patch adds a test which modifies the DSCR using mtspr instruction
and verifies the change using mfspr instruction. It uses both the
privilege state SPR as well as the problem state SPR for the purpose.
Acked-by: Shuah Khan <redacted>
Signed-off-by: Anshuman Khandual <redacted>
Signed-off-by: Anton Blanchard <redacted>
---
tools/testing/selftests/powerpc/dscr/Makefile | 2 +-
.../selftests/powerpc/dscr/dscr_explicit_test.c | 72 ++++++++++++++++++++++
2 files changed, 73 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_explicit_test.c
@@ -0,0 +1,72 @@+/*+*POWERDataStreamControlRegister(DSCR)explicittest+*+*ThistestmodifiestheDSCRvalueusingmtsprinstructionand+*verifiesthechangewithmfsprinstruction.Itusesboththe+*privilegestateSPRandtheproblemstateSPRforthispurpose.+*+*WhenusingtheprivilegestateSPR,theinstructionssuchas+*mfsprormtsprarepriviledgedandthekernelemulatesthem+*forus.InstructionsusingproblemstateSPRcanbeexuecuted+*directlywithoutanyemulationiftheHWsupportsthem.Else+*theyalsogetemulatedbythekernel.+*+*Copyright(C)2012AntonBlanchard<anton@au.ibm.com>,IBM+*Copyright(C)2015AnshumanKhandual<khandual@linux.vnet.ibm.com>,IBM+*+*Thisprogramisfreesoftware;youcanredistributeitand/or+*modifyitunderthetermsoftheGNUGeneralPublicLicense+*aspublishedbytheFreeSoftwareFoundation;eitherversion+*2oftheLicense,or(atyouroption)anylaterversion.+*/+#include"dscr.h"++intdscr_explicit(void)+{+unsignedlongi,dscr=0;++srand(getpid());+set_dscr(dscr);++for(i=0;i<COUNT;i++){+unsignedlongcur_dscr,cur_dscr_usr;+doubleret=uniform_deviate(rand());++if(ret<0.001){+dscr++;+if(dscr>DSCR_MAX)+dscr=0;++set_dscr(dscr);+}++cur_dscr=get_dscr();+if(cur_dscr!=dscr){+fprintf(stderr,"Kernel DSCR should be %ld but "+"is %ld\n",dscr,cur_dscr);+return1;+}++ret=uniform_deviate(rand());+if(ret<0.001){+dscr++;+if(dscr>DSCR_MAX)+dscr=0;++set_dscr_usr(dscr);+}++cur_dscr_usr=get_dscr_usr();+if(cur_dscr_usr!=dscr){+fprintf(stderr,"User DSCR should be %ld but "+"is %ld\n",dscr,cur_dscr_usr);+return1;+}+}+return0;+}++intmain(intargc,char*argv[])+{+returntest_harness(dscr_explicit,"dscr_explicit_test");+}
This patch adds a test to verify that the changed DSCR value inside
any process would be inherited to it's child process across the fork
system call.
Acked-by: Shuah Khan <redacted>
Signed-off-by: Anshuman Khandual <redacted>
Signed-off-by: Anton Blanchard <redacted>
---
tools/testing/selftests/powerpc/dscr/Makefile | 3 +-
.../selftests/powerpc/dscr/dscr_inherit_test.c | 96 ++++++++++++++++++++++
2 files changed, 98 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_inherit_test.c
@@ -0,0 +1,96 @@+/*+*POWERDataStreamControlRegister(DSCR)forktest+*+*ThistestcasemodifiestheDSCRusingmtspr,forksandthen+*verifiesthatthechildprocesshasthecorrectchangedDSCR+*valueusingmfspr.+*+*WhenusingtheprivilegestateSPR,theinstructionssuchas+*mfsprormtsprarepriviledgedandthekernelemulatesthem+*forus.InstructionsusingproblemstateSPRcanbeexuecuted+*directlywithoutanyemulationiftheHWsupportsthem.Else+*theyalsogetemulatedbythekernel.+*+*Copyright(C)2012AntonBlanchard<anton@au.ibm.com>,IBM+*Copyright(C)2015AnshumanKhandual<khandual@linux.vnet.ibm.com>,IBM+*+*Thisprogramisfreesoftware;youcanredistributeitand/or+*modifyitunderthetermsoftheGNUGeneralPublicLicense+*aspublishedbytheFreeSoftwareFoundation;eitherversion+*2oftheLicense,or(atyouroption)anylaterversion.+*/+#include"dscr.h"++intdscr_inherit(void)+{+unsignedlongi,dscr=0;+pid_tpid;++srand(getpid());+set_dscr(dscr);++for(i=0;i<COUNT;i++){+unsignedlongcur_dscr,cur_dscr_usr;++dscr++;+if(dscr>DSCR_MAX)+dscr=0;++if(i%2==0)+set_dscr_usr(dscr);+else+set_dscr(dscr);++/*+*XXX:ForceacontextswitchoutsothatDSCR+*currentvalueiscopiedintothethreadstruct+*whichisrequiredforthechildtoinheritthe+*changedvalue.+*/+sleep(1);++pid=fork();+if(pid==-1){+perror("fork() failed");+exit(1);+}elseif(pid){+intstatus;++if(waitpid(pid,&status,0)==-1){+perror("waitpid() failed");+exit(1);+}++if(!WIFEXITED(status)){+fprintf(stderr,"Child didn't exit cleanly\n");+exit(1);+}++if(WEXITSTATUS(status)!=0){+fprintf(stderr,"Child didn't exit cleanly\n");+return1;+}+}else{+cur_dscr=get_dscr();+if(cur_dscr!=dscr){+fprintf(stderr,"Kernel DSCR should be %ld "+"but is %ld\n",dscr,cur_dscr);+exit(1);+}++cur_dscr_usr=get_dscr_usr();+if(cur_dscr_usr!=dscr){+fprintf(stderr,"User DSCR should be %ld "+"but is %ld\n",dscr,cur_dscr_usr);+exit(1);+}+exit(0);+}+}+return0;+}++intmain(intargc,char*argv[])+{+returntest_harness(dscr_inherit,"dscr_inherit_test");+}
This patch adds some in-code documentation to the DSCR related
code to make it more readable without having any functional
change to it.
Signed-off-by: Anshuman Khandual <redacted>
---
arch/powerpc/include/asm/processor.h | 9 +++++++++
arch/powerpc/kernel/sysfs.c | 38 ++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+)
This patch adds a test to update the system wide DSCR value repeatedly
and then verifies that any thread on any given CPU on the system must
be able to see the same DSCR value whether its is being read through
the problem state based SPR or the privilege state based SPR.
Acked-by: Shuah Khan <redacted>
Signed-off-by: Anshuman Khandual <redacted>
---
tools/testing/selftests/powerpc/dscr/Makefile | 2 +-
.../powerpc/dscr/dscr_sysfs_thread_test.c | 123 +++++++++++++++++++++
2 files changed, 124 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/dscr/dscr_sysfs_thread_test.c
@@ -0,0 +1,123 @@+/*+*POWERDataStreamControlRegister(DSCR)sysfsthreadtest+*+*ThistestupdatesthesystemwideDSCRdefaultvaluethrough+*sysfsinterfacewhichshouldthenupdatealltheCPUspecific+*DSCRdefaultvalueswhichmustalsobethenvisibletothreads+*executingonindividualCPUsonthesystem.+*+*Copyright(C)2015AnshumanKhandual<khandual@linux.vnet.ibm.com>,IBM+*+*Thisprogramisfreesoftware;youcanredistributeitand/or+*modifyitunderthetermsoftheGNUGeneralPublicLicense+*aspublishedbytheFreeSoftwareFoundation;eitherversion+*2oftheLicense,or(atyouroption)anylaterversion.+*/+#define _GNU_SOURCE+#include"dscr.h"++staticpthread_mutex_tlock;/* Pthread lock */+staticcpu_set_tcpuset;/* Thread cpu set */+staticinttarget;/* Thread target cpu */+staticunsignedlong*result;/* Thread exit status array */++#define NR_ONLN sysconf(_SC_NPROCESSORS_ONLN)++staticvoid*test_thread_dscr(void*in)+{+unsignedlongcur_dscr,cur_dscr_usr;+unsignedlongval=(unsignedlong)in;++pthread_mutex_lock(&lock);+target++;+if(target==NR_ONLN)+target=0;+CPU_ZERO(&cpuset);+CPU_SET(target,&cpuset);++if(sched_setaffinity(0,sizeof(cpuset),&cpuset)){+perror("sched_setaffinity() failed");+pthread_mutex_unlock(&lock);+result[target]=1;+pthread_exit(&result[target]);+}+pthread_mutex_unlock(&lock);++cur_dscr=get_dscr();+cur_dscr_usr=get_dscr_usr();++if(val!=cur_dscr){+printf("[cpu %d] Kernel DSCR should be %ld but is %ld\n",+sched_getcpu(),val,cur_dscr);+result[target]=1;+pthread_exit(&result[target]);+}++if(val!=cur_dscr_usr){+printf("[cpu %d] User DSCR should be %ld but is %ld\n",+sched_getcpu(),val,cur_dscr_usr);+result[target]=1;+pthread_exit(&result[target]);+}+result[target]=0;+pthread_exit(&result[target]);+}++staticintcheck_cpu_dscr_thread(unsignedlongval)+{+pthread_tthreads[NR_ONLN];+unsignedlong*status[NR_ONLN];+unsignedlongi;++for(i=0;i<NR_ONLN;i++){+if(pthread_create(&threads[i],NULL,+test_thread_dscr,(void*)val)){+perror("pthread_create() failed");+return1;+}+}++for(i=0;i<NR_ONLN;i++){+if(pthread_join(threads[i],(void**)&(status[i]))){+perror("pthread_join() failed");+return1;+}++if(*status[i]){+printf(" %ldth thread join failed with %ld\n",+i,*status[i]);+return1;+}+}+return0;+}++intdscr_sysfs_thread(void)+{+unsignedlongorig_dscr_default;+inti,j;++result=malloc(sizeof(unsignedlong)*NR_ONLN);+pthread_mutex_init(&lock,NULL);+target=0;+orig_dscr_default=get_default_dscr();+for(i=0;i<COUNT;i++){+for(j=0;j<DSCR_MAX;j++){+set_default_dscr(j);+if(check_cpu_dscr_thread(j))+gotofail;+}+}+free(result);+set_default_dscr(orig_dscr_default);+return0;+fail:+free(result);+set_default_dscr(orig_dscr_default);+return1;+}++intmain(intargc,char*argv[])+{+returntest_harness(dscr_sysfs_thread,"dscr_sysfs_thread_test");+}
The selftests still fail to build:
cc -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"v4.0-rc1-13631-gdfcba4b"' -I/home/buildbot/buildbot/slave/selftests-ppc64-gcc-ubuntu-be/build/tools/testing/selftests/powerpc -lpthread dscr_default_test.c ../harness.c -o dscr_default_test
In file included from dscr_default_test.c:16:0:
dscr.h: In function ‘get_default_dscr’:
dscr.h:93:6: error: ignoring return value of ‘read’, declared with attribute warn_unused_result [-Werror=unused-result]
read(fd, buf, sizeof(buf));
^
dscr.h: In function ‘set_default_dscr’:
dscr.h:112:7: error: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Werror=unused-result]
write(fd, buf, strlen(buf));
^
cc1: all warnings being treated as errors
make[1]: *** [dscr_default_test] Error 1
I'm happy for you to call perror() and exit(1) if either fail.
Please fix and resend.
cheers