Skip to content

Commit

Permalink
iommu: convert mutex to rwlock for @map->lock
Browse files Browse the repository at this point in the history
The mapping table managed for IOMMU page table is a skiplist protected
by mutex with @map->lock. This has led performance impact with multiple
threads looking up the page table at the same time, especially when
manipulating PRP or SGL data structures per I/O.

Application might optimize their own IOMMU-related paths like they
prepare the bulk of memory buffers at the beginning time and map them to
IOMMU at that time.  After that, they can do I/Os based on pre-mapped
memory buffers without inserting or deleting entries from page tables.

To improve performance scalability, convert existing mutex @map->lock to
read-write lock which leads to great performance on read(look-up)-most
scenarios.

Signed-off-by: Minwoo Im <[email protected]>
  • Loading branch information
minwooim authored and birkelund committed Jan 6, 2025
1 parent edbf47d commit bebd991
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/iommu/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,5 @@ void iommu_ctx_init(struct iommu_ctx *ctx)
pthread_mutex_init(&ctx->lock, NULL);

skiplist_init(&ctx->map.list);
pthread_mutex_init(&ctx->map.lock, NULL);
pthread_rwlock_init(&ctx->map.lock, NULL);
}
2 changes: 1 addition & 1 deletion src/iommu/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ struct iova_mapping {
};

struct iova_map {
pthread_mutex_t lock;
pthread_rwlock_t lock;
struct skiplist list;
};

Expand Down
8 changes: 4 additions & 4 deletions src/iommu/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static int iova_cmp(const void *vaddr, const struct skiplist_node *n)
static int iova_map_add(struct iova_map *map, void *vaddr, size_t len, uint64_t iova,
unsigned long flags)
{
__autolock(&map->lock);
__autowrlock(&map->lock);

struct skiplist_node *update[SKIPLIST_LEVELS] = {};
struct iova_mapping *m;
Expand Down Expand Up @@ -70,7 +70,7 @@ static int iova_map_add(struct iova_map *map, void *vaddr, size_t len, uint64_t

static void iova_map_remove(struct iova_map *map, void *vaddr)
{
__autolock(&map->lock);
__autowrlock(&map->lock);

struct skiplist_node *n, *update[SKIPLIST_LEVELS] = {};

Expand All @@ -83,15 +83,15 @@ static void iova_map_remove(struct iova_map *map, void *vaddr)

static struct iova_mapping *iova_map_find(struct iova_map *map, void *vaddr)
{
__autolock(&map->lock);
__autordlock(&map->lock);

return container_of_or_null(skiplist_find(&map->list, vaddr, iova_cmp, NULL),
struct iova_mapping, list);
}

static void iova_map_clear_with(struct iova_map *map, skiplist_iter_fn fn, void *opaque)
{
__autolock(&map->lock);
__autowrlock(&map->lock);

skiplist_clear_with(&map->list, fn, opaque);
}
Expand Down

0 comments on commit bebd991

Please sign in to comment.