OSDN Git Service

swiotlb: allocate a new memory pool when existing pools are full
authorPetr Tesarik <petr.tesarik.ext@huawei.com>
Tue, 1 Aug 2023 06:24:03 +0000 (08:24 +0200)
committerChristoph Hellwig <hch@lst.de>
Tue, 1 Aug 2023 16:02:27 +0000 (18:02 +0200)
commit1aaa736815eb04f4dae3f0b3e977b2a0677a4cfb
tree49a199f7e78ee1556f97e08ccde26ad7d86c67c4
parentad96ce3252dbab773cb343220662df3d84dd8e80
swiotlb: allocate a new memory pool when existing pools are full

When swiotlb_find_slots() cannot find suitable slots, schedule the
allocation of a new memory pool. It is not possible to allocate the pool
immediately, because this code may run in interrupt context, which is not
suitable for large memory allocations. This means that the memory pool will
be available too late for the currently requested mapping, but the stress
on the software IO TLB allocator is likely to continue, and subsequent
allocations will benefit from the additional pool eventually.

Keep all memory pools for an allocator in an RCU list to avoid locking on
the read side. For modifications, add a new spinlock to struct io_tlb_mem.

The spinlock also protects updates to the total number of slabs (nslabs in
struct io_tlb_mem), but not reads of the value. Readers may therefore
encounter a stale value, but this is not an issue:

- swiotlb_tbl_map_single() and is_swiotlb_active() only check for non-zero
  value. This is ensured by the existence of the default memory pool,
  allocated at boot.

- The exact value is used only for non-critical purposes (debugfs, kernel
  messages).

Signed-off-by: Petr Tesarik <petr.tesarik.ext@huawei.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
include/linux/swiotlb.h
kernel/dma/swiotlb.c