Re: [PATCH] ublk: avoid teardown retry loop on xarray allocation failure

Ming Lei <[email protected]> Thu, 6 Aug 2026 11:28:40 -0500
Newsgroups org.kernel.vger.linux-block
Message-ID <CACVXFVO000kDV6CnuBKRs=NALPXK+QMLM0y_d2mZz=KwD-yKiQ@mail.gmail.com>
On Tue, Aug 4, 2026 at 7:57 AM Yao Sang <[email protected]> wrote:
>
> __ublk_shmem_remove_ranges() removes matching maple tree ranges in
> batches, but first stores each range into a temporary xarray so that the
> pages can be unpinned after dropping the maple tree lock.
>
> That temporary xarray is filled under the maple tree lock with
> xa_store(..., GFP_ATOMIC). If the store fails before mas_erase(), the
> current range is left in the tree and the helper returns false. The
> outer ublk_shmem_remove_ranges() loop then immediately retries the same
> range. While the atomic allocation keeps failing, the teardown path has
> no forward progress.
>
> The issue can be reproduced with radix_tree_node failslab injection after
> a SHMEM_ZC buffer has already been registered:
>
>   # Kernel config:
>   #   CONFIG_BLK_DEV_UBLK=y
>   #   CONFIG_DEBUG_FS=y
>   #   CONFIG_FAULT_INJECTION=y
>   #   CONFIG_FAULT_INJECTION_DEBUG_FS=y
>   #   CONFIG_FAILSLAB=y
>
>   echo 10 > /proc/sys/vm/nr_hugepages
>   mkdir -p /tmp/htlb
>   mount -t hugetlbfs none /tmp/htlb
>   fallocate -l 4M /tmp/htlb/ublk_buf
>
>   dev_id=$(kublk add -t null --shmem_zc \
>                 --htlb /tmp/htlb/ublk_buf |
>            awk -F '[ :]' '/dev id/ {print $3}')
>
>   echo 1 > /sys/kernel/slab/radix_tree_node/failslab
>   echo Y > /sys/kernel/debug/failslab/cache-filter
>   echo Y > /sys/kernel/debug/failslab/ignore-gfp-wait
>   echo 1 > /sys/kernel/debug/failslab/interval
>   echo -1 > /sys/kernel/debug/failslab/times
>   echo 100 > /sys/kernel/debug/failslab/probability
>
>   kublk del -n "$dev_id"
>
> On the unfixed kernel the delete command was still running after 3
> seconds. Disabling failslab made it return. The fault-injection stack
> showed:
>
>   should_failslab
>   kmem_cache_alloc_lru_noprof
>   __xas_nomem
>   __xa_store
>   xa_store
>   __ublk_shmem_remove_ranges
>   ublk_cdev_rel
>   ublk_ctrl_del_dev
>
> Remove the allocation from the teardown loop. Keep the existing batch
> limit, but collect {base_pfn, nr_pages} pairs in a fixed-size stack array.
> Once a matching range is found, the range is erased from the maple tree
> before dropping the lock, so each successful scan makes progress without
> depending on any GFP_ATOMIC allocation.
>
> With the same failslab settings, the fixed kernel completed
> "kublk del -n $dev_id" successfully in about 45 ms.
>
> Fixes: 309e02dccf64 ("ublk: avoid unpinning pages under maple tree spinlock")
> Signed-off-by: Yao Sang <[email protected]>

Reviewed-by: Ming Lei <[email protected]>