diff options
author | Stewart Smith <stewart@linux.vnet.ibm.com> | 2018-03-28 13:44:52 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2018-04-03 03:29:44 -0500 |
commit | 36f6c25c731446d2dafa1be3b412c387259f47bd (patch) | |
tree | 63dfc1aac855fd5827633503f72c9c9d92643cfc /core | |
parent | 0a1d25fbae1a4d4697214f8befdf65b2e1fef3a6 (diff) | |
download | skiboot-36f6c25c731446d2dafa1be3b412c387259f47bd.zip skiboot-36f6c25c731446d2dafa1be3b412c387259f47bd.tar.gz skiboot-36f6c25c731446d2dafa1be3b412c387259f47bd.tar.bz2 |
core/lock.c: ensure valid start value for lock spin duration warning
The previous fix in a8e6cc3f4 only addressed half of the problem, as
we could also get an invalid value for start, causing us to fail
in a weird way.
This was caught by the testcases.OpTestHMIHandling.HMI_TFMR_ERRORS
test in op-test-framework.
You'd get to this part of the test and get the erroneous lock
spinning warnings:
PATH=/usr/local/sbin:$PATH putscom -c 00000000 0x2b010a84 0003080000000000
0000080000000000
[ 790.140976993,4] WARNING: Lock has been spinning for 790275ms
[ 790.140976993,4] WARNING: Lock has been spinning for 790275ms
[ 790.140976918,4] WARNING: Lock has been spinning for 790275ms
This patch checks the validity of timebase before setting start,
and only checks the lock timeout if we got a valid start value.
Fixes: a8e6cc3f47525f86ef1d69d69a477b6264d0f8ee
Fixes: 84186ef0944c9413262f0974ddab3fb1343ccfe8
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Reviewed-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Tested-by: Pridhiviraj Paidipeddi <ppaidipe@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core')
-rw-r--r-- | core/lock.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/core/lock.c b/core/lock.c index 620d26b..4ae3a21 100644 --- a/core/lock.c +++ b/core/lock.c @@ -206,7 +206,7 @@ bool try_lock_caller(struct lock *l, const char *owner) void lock_caller(struct lock *l, const char *owner) { bool timeout_warn = false; - unsigned long start; + unsigned long start = 0; if (bust_locks) return; @@ -218,7 +218,13 @@ void lock_caller(struct lock *l, const char *owner) add_lock_request(l); #ifdef DEBUG_LOCKS - start = tb_to_msecs(mftb()); + /* + * Ensure that we get a valid start value + * as we may be handling TFMR errors and taking + * a lock to do so, so timebase could be garbage + */ + if( (mfspr(SPR_TFMR) & SPR_TFMR_TB_VALID)) + start = tb_to_msecs(mftb()); #endif for (;;) { @@ -229,7 +235,7 @@ void lock_caller(struct lock *l, const char *owner) barrier(); smt_medium(); - if (!timeout_warn) + if (start && !timeout_warn) timeout_warn = lock_timeout(start); } |