msm: mdss: handle race condition in pingpong done counter
Current mechanism to count number of synchronized ping pong transfers
can have a race condition in case ping pong done happens as in
following simplified code sequence:
Thread 0 | Thread 1
-------------------------|----------------------------
1) | wait_event(w, !ctx->koff_cnt &&
| !sctx->koff_cnt)
| /* ctx->koff_cnt == 1 */
| /* sctx->koff_cnt == 1 */
2) ctx->koff_cnt-- |
| /* ctx->koff_cnt == 0 */
3) if (!sctx->koff_cnt) |
4) pp_done_cnt++ |
5) sctx->koff_cnt-- |
| /* sctx->koff_cnt == 0 */
| /* wait_event unblocks, transfer done */
6) | ctx->koff_cnt++ /* new transfer */
7) | sctx->koff_cnt++
8) if (!ctx->koff_cnt) |
9) pp_done_cnt++ |
By decrementing koff_cnt at #5, we are signaling that transfer has
completed for both ctx and sctx, unblocking Thread 1 which can go
ahead and trigger next transfer before we increment pp_done_cnt. By
checking the status of ctx->koff_cnt before #5, we can safely allow
Thread 1 to go forward but still maintain proper count of pp_done_cnt.
CRs-Fixed: 966529
Change-Id: I59e7798b5cc5bc28ff56551a0a009503019d32a9
Signed-off-by:
Adrian Salido-Moreno <adrianm@codeaurora.org>
Loading
Please register or sign in to comment