Concurrent marking can potentially hang forever if the following scenario happens:
1) Concurrent mark starts.
2) Global mark stack overflows.
3) Immediately after the overflow condition occurs a Full GC is started which aborts the concurrent mark.
4) There's a race between discovering the overflow condition and the abort condition. Marking threads discovering the overflow condition will go into the overflow protocol and block inside enter_first_sync_barrier() waiting for the other threads to do the same. However, threads that discovered the abort condition first will abort the marking without going through the barrier. The WorkerGang spawned from markFromRoots() will then never terminate.
The end results of this is that concurrent mark will say "in progress", because the abort operation failed to complete. This in turn means that G1 thinks concurrent mark is ongoing, will not try to initiate another concurrent mark phase and hence mixed GCs will never happen. Young GC and Full GCs will continue to work because the hanging marking threads left the STS before blocking on the barrier.