forked from luck/tmp_suning_uos_patched
kcsan: Fix misreporting if concurrent races on same address
If there are at least 4 threads racing on the same address, it can happen that one of the readers may observe another matching reader in other_info. To avoid locking up, we have to consume 'other_info' regardless, but skip the report. See the added comment for more details. Signed-off-by: Marco Elver <elver@google.com> Signed-off-by: Paul E. McKenney <paulmck@kernel.org> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
80d4c47752
commit
3a5b45e503
|
@ -422,6 +422,44 @@ static bool prepare_report(unsigned long *flags, const volatile void *ptr,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
access_type |= other_info.access_type;
|
||||||
|
if ((access_type & KCSAN_ACCESS_WRITE) == 0) {
|
||||||
|
/*
|
||||||
|
* While the address matches, this is not the other_info
|
||||||
|
* from the thread that consumed our watchpoint, since
|
||||||
|
* neither this nor the access in other_info is a write.
|
||||||
|
* It is invalid to continue with the report, since we
|
||||||
|
* only have information about reads.
|
||||||
|
*
|
||||||
|
* This can happen due to concurrent races on the same
|
||||||
|
* address, with at least 4 threads. To avoid locking up
|
||||||
|
* other_info and all other threads, we have to consume
|
||||||
|
* it regardless.
|
||||||
|
*
|
||||||
|
* A concrete case to illustrate why we might lock up if
|
||||||
|
* we do not consume other_info:
|
||||||
|
*
|
||||||
|
* We have 4 threads, all accessing the same address
|
||||||
|
* (or matching address ranges). Assume the following
|
||||||
|
* watcher and watchpoint consumer pairs:
|
||||||
|
* write1-read1, read2-write2. The first to populate
|
||||||
|
* other_info is write2, however, write1 consumes it,
|
||||||
|
* resulting in a report of write1-write2. This report
|
||||||
|
* is valid, however, now read1 populates other_info;
|
||||||
|
* read2-read1 is an invalid conflict, yet, no other
|
||||||
|
* conflicting access is left. Therefore, we must
|
||||||
|
* consume read1's other_info.
|
||||||
|
*
|
||||||
|
* Since this case is assumed to be rare, it is
|
||||||
|
* reasonable to omit this report: one of the other
|
||||||
|
* reports includes information about the same shared
|
||||||
|
* data, and at this point the likelihood that we
|
||||||
|
* re-report the same race again is high.
|
||||||
|
*/
|
||||||
|
release_report(flags, KCSAN_REPORT_RACE_SIGNAL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Matching & usable access in other_info: keep other_info_lock
|
* Matching & usable access in other_info: keep other_info_lock
|
||||||
* locked, as this thread consumes it to print the full report;
|
* locked, as this thread consumes it to print the full report;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user