accel/ivpu: use kmem_cache for IPC rx_msg allocations

Use a dedicated kmem_cache for ivpu_ipc_rx_msg allocations instead of
the generic kmalloc. This gives each CPU its own hot freelist for this
object type, reducing allocator overhead in the IRQ handler and threaded
IRQ path where rx_msg objects are allocated and freed at high frequency.

Reviewed-by: Andrzej Kacprowski <andrzej.kacprowski@linux.intel.com>
Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Link: https://patch.msgid.link/20260611055214.948748-1-karol.wachowski@linux.intel.com
This commit is contained in:
Karol Wachowski
2026-06-11 07:52:14 +02:00
parent 85c9cc2d25
commit a7640c07cb
2 changed files with 15 additions and 3 deletions

View File

@@ -146,7 +146,7 @@ ivpu_ipc_rx_msg_add(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
lockdep_assert_held(&ipc->cons_lock);
rx_msg = kzalloc_obj(*rx_msg, GFP_ATOMIC);
rx_msg = kmem_cache_zalloc(ipc->rx_msg_cache, GFP_ATOMIC);
if (!rx_msg) {
ivpu_ipc_rx_mark_free(vdev, ipc_hdr, jsm_msg);
return;
@@ -174,7 +174,7 @@ ivpu_ipc_rx_msg_del(struct ivpu_device *vdev, struct ivpu_ipc_rx_msg *rx_msg)
list_del(&rx_msg->link);
ivpu_ipc_rx_mark_free(vdev, rx_msg->ipc_hdr, rx_msg->jsm_msg);
atomic_dec(&vdev->ipc->rx_msg_count);
kfree(rx_msg);
kmem_cache_free(vdev->ipc->rx_msg_cache, rx_msg);
}
void ivpu_ipc_consumer_add(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
@@ -490,10 +490,18 @@ int ivpu_ipc_init(struct ivpu_device *vdev)
struct ivpu_ipc_info *ipc = vdev->ipc;
int ret;
ipc->rx_msg_cache = kmem_cache_create("ivpu_ipc_rx_msg", sizeof(struct ivpu_ipc_rx_msg), 0,
SLAB_HWCACHE_ALIGN, NULL);
if (!ipc->rx_msg_cache) {
ivpu_err(vdev, "Failed to create rx_msg_cache\n");
return -ENOMEM;
}
ipc->mem_tx = ivpu_bo_create_global(vdev, SZ_16K, DRM_IVPU_BO_WC | DRM_IVPU_BO_MAPPABLE);
if (!ipc->mem_tx) {
ivpu_err(vdev, "Failed to allocate mem_tx\n");
return -ENOMEM;
ret = -ENOMEM;
goto err_destroy_cache;
}
ipc->mem_rx = ivpu_bo_create_global(vdev, SZ_16K, DRM_IVPU_BO_WC | DRM_IVPU_BO_MAPPABLE);
@@ -532,6 +540,8 @@ int ivpu_ipc_init(struct ivpu_device *vdev)
ivpu_bo_free(ipc->mem_rx);
err_free_tx:
ivpu_bo_free(ipc->mem_tx);
err_destroy_cache:
kmem_cache_destroy(ipc->rx_msg_cache);
return ret;
}
@@ -544,6 +554,7 @@ void ivpu_ipc_fini(struct ivpu_device *vdev)
drm_WARN_ON(&vdev->drm, atomic_read(&ipc->rx_msg_count) > 0);
ivpu_ipc_mem_fini(vdev);
kmem_cache_destroy(ipc->rx_msg_cache);
}
void ivpu_ipc_enable(struct ivpu_device *vdev)

View File

@@ -70,6 +70,7 @@ struct ivpu_ipc_info {
struct gen_pool *mm_tx;
struct ivpu_bo *mem_tx;
struct ivpu_bo *mem_rx;
struct kmem_cache *rx_msg_cache;
atomic_t rx_msg_count;