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.
Unified · Split
| @@ -422,6 +422,44 @@ retry: · 421 unmodified lines | ||
| 422 | 422 | return false; |
| 423 | 423 | } |
| 424 | 424 | |
| 425 | + access_type |= other_info.access_type; | |
| 426 | + if ((access_type & KCSAN_ACCESS_WRITE) == 0) { | |
| 427 | + /* | |
| 428 | + * While the address matches, this is not the other_info | |
| 429 | + * from the thread that consumed our watchpoint, since | |
| 430 | + * neither this nor the access in other_info is a write. | |
| 431 | + * It is invalid to continue with the report, since we | |
| 432 | + * only have information about reads. | |
| 433 | + * | |
| 434 | + * This can happen due to concurrent races on the same | |
| 435 | + * address, with at least 4 threads. To avoid locking up | |
| 436 | + * other_info and all other threads, we have to consume | |
| 437 | + * it regardless. | |
| 438 | + * | |
| 439 | + * A concrete case to illustrate why we might lock up if | |
| 440 | + * we do not consume other_info: | |
| 441 | + * | |
| 442 | + * We have 4 threads, all accessing the same address | |
| 443 | + * (or matching address ranges). Assume the following | |
| 444 | + * watcher and watchpoint consumer pairs: | |
| 445 | + * write1-read1, read2-write2. The first to populate | |
| 446 | + * other_info is write2, however, write1 consumes it, | |
| 447 | + * resulting in a report of write1-write2. This report | |
| 448 | + * is valid, however, now read1 populates other_info; | |
| 449 | + * read2-read1 is an invalid conflict, yet, no other | |
| 450 | + * conflicting access is left. Therefore, we must | |
| 451 | + * consume read1's other_info. | |
| 452 | + * | |
| 453 | + * Since this case is assumed to be rare, it is | |
| 454 | + * reasonable to omit this report: one of the other | |
| 455 | + * reports includes information about the same shared | |
| 456 | + * data, and at this point the likelihood that we | |
| 457 | + * re-report the same race again is high. | |
| 458 | + */ | |
| 459 | + release_report(flags, KCSAN_REPORT_RACE_SIGNAL); | |
| 460 | + return false; | |
| 461 | + } | |
| 462 | + | |
| 425 | 463 | /* |
| 426 | 464 | * Matching & usable access in other_info: keep other_info_lock |
| 427 | 465 | * locked, as this thread consumes it to print the full report; |