ForEachAsyncSemaphore asynchronously processing tasks but enable fast fail
First let me share with you my revised version then I will detail the changes what I've made:
public static async Task ThrottledConcurrenctForeach&lt;T&gt;(
    this IEnumerable&lt;T&gt; toBeProcessedItems, Func&lt;T, Task&gt; asyncOperation,
    int maxDegreeOfConcurrency, CancellationToken externalCancellationToken)
{
    ExceptionDispatchInfo capturedException = null;

    var internalCancellation = new CancellationTokenSource();
    var internalCancellationSignal = new TaskCompletionSource&lt;object&gt;();

    var combinedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(externalCancellationToken, internalCancellation.Token);
    combinedCancellationTokenSource.Token.Register(() =&gt; internalCancellationSignal.TrySetCanceled(), useSynchronizationContext: false);

    using var throttler = new SemaphoreSlim(maxDegreeOfConcurrency);
                
    var processingOperations = toBeProcessedItems.Select(async item =&gt;
    {
        await throttler.WaitAsync(combinedCancellationTokenSource.Token);

        try { await asyncOperation(item); }
        catch (Exception ex)
        {
            capturedException = ExceptionDispatchInfo.Capture(ex);
            internalCancellation.Cancel();
        }
        finally { throttler.Release(); }

    });

    await Task.WhenAny(Task.WhenAll(processingOperations), internalCancellationSignal.Task);
    capturedException?.Throw();
}

Naming
As you can see I've done a lots of renaming. I do believe that using the meaningful names improves readability and gives clarity. Here are a few examples:

ForEachAsyncSemaphore

Semaphore is an implementation detail

Try to focus on the provided functionality instead: throttling
You are using SemaphoreSlim not Semaphore that's why it's misleading


In case of I/O bound operations we are normally talking about Concurrency, in case of CPU bound operations we talk about Parallelism

If you want to emphasize your intent then make it visible to your
consumers




dop

This is a useless abbreviation

No-one will understand what that means unless (s)he reads the
implementation (if (s)he can access it)


Try to use as expressive parameter names as possible if you do not provide documentation comments


childCts

Yet again try to focus on the provided functionality



ExceptionDispatchInfo

If you don't want to change the StackTrace of the already thrown exception then please prefer ExceptionDispatchInfo
It preserves the original StackTrace with the re-throwability

CancellationToken's Register

Even though Task.Delay(Timeout.Infinite, linkedTokens.Token) works that's not the most elegant way to provide cancellation ability to Task.WhenAll
You can use the TaskCompletionSource&lt;object&gt; for signalling. It works fine with CancellationToken by combining Register and TrySetCanceled

using declaration

In order to reduce indentations (to streamline your code) please prefer using declaration if you are using C# 8 or greater