When doing dirty card refinement, if an STS suspension request is active then processing a card buffer is aborted and the remainder of the buffer is pushed on the DCQS paused list. It's not just G1ConcurrentRefineThreads that check the STS state there, Java threads do too.
When coming out of a safepoint, Java threads are activated before the STS suspension request is cleared. So a Java thread could be activated, enqueue a buffer, decide it needed to do some refinement work so obtain a buffer from the queue, notice the STS suspension request, and pause the buffer until after the *next* safepoint. And of course that could keep happening until the STS suspension request finally gets cleared.
I haven't found anything that "fails" because of that oddity. But it could lead to there being paused buffers that are inaccessible to refinement from the end of the safepoint where that happens until the next safepoint. And paused buffer contents are counted in num_cards, to encourage refinement work to move them back to the normal queue. This could lead to spinning by refinement threads, with there being enough oddly paused cards to indicate there is work to do, but being unable to obtain any work from the empty normal queue and the inaccessible "next" paused list. That seems pretty unlikely, but still.
A possible fix might be to change the STS suspension request flag to be based on the safepoint counter. That way we don't have two different request "flags". That would require some reordering in safepoint entry that would need careful examination.