]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
accel/qaic: Use kvcalloc() for slice requests allocation
authorYoussef Samir <quic_yabdulra@quicinc.com>
Tue, 7 Oct 2025 12:18:45 +0000 (14:18 +0200)
committerJeff Hugo <jeff.hugo@oss.qualcomm.com>
Tue, 14 Oct 2025 14:39:10 +0000 (08:39 -0600)
When a BO is created, qaic will use the page allocator to request the
memory chunks that the BO will be composed of in-memory. The number of
chunks increases when memory is segmented. For example, a 16MB BO can
be composed of four 4MB chunks or 4096 4KB chunks.

A BO is then sliced into a single or multiple slices to be transferred
to the device on the DBC's xfer queue. For that to happen, the slice
needs to encode its memory chunks into DBC requests and keep track of
them in an array, which is allocated using kcalloc(). Knowing that the
BO might be very fragmented, this array can grow so large that the
allocation may fail to find contiguous memory for it.

Replace kcalloc() with kvcalloc() to allocate the DBC requests array
for a slice.

Signed-off-by: Youssef Samir <quic_yabdulra@quicinc.com>
Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
Reviewed-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
Reviewed-by: Carl Vanderlip <carl.vanderlip@oss.qualcomm.com>
Signed-off-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20251007121845.337382-1-youssef.abdulrahman@oss.qualcomm.com
drivers/accel/qaic/qaic_data.c

index 85c155c74fca11a48b7058d20b7e50932db81a48..42feb7509ca9d76c28f284c90a6bba032d04cdca 100644 (file)
@@ -166,7 +166,7 @@ static void free_slice(struct kref *kref)
        drm_gem_object_put(&slice->bo->base);
        sg_free_table(slice->sgt);
        kfree(slice->sgt);
-       kfree(slice->reqs);
+       kvfree(slice->reqs);
        kfree(slice);
 }
 
@@ -405,7 +405,7 @@ static int qaic_map_one_slice(struct qaic_device *qdev, struct qaic_bo *bo,
                goto free_sgt;
        }
 
-       slice->reqs = kcalloc(sgt->nents, sizeof(*slice->reqs), GFP_KERNEL);
+       slice->reqs = kvcalloc(sgt->nents, sizeof(*slice->reqs), GFP_KERNEL);
        if (!slice->reqs) {
                ret = -ENOMEM;
                goto free_slice;
@@ -431,7 +431,7 @@ static int qaic_map_one_slice(struct qaic_device *qdev, struct qaic_bo *bo,
        return 0;
 
 free_req:
-       kfree(slice->reqs);
+       kvfree(slice->reqs);
 free_slice:
        kfree(slice);
 free_sgt: