Compiling Mali Midgard driver for Linux v6.10-rc4 to obtain OpenCL with closed-source libMali

| 9 min read

As Linux kernel versions advance some out-of-tree modules begin to fall into obscurity and obsolescence!

While I appreciate the efforts of LibreELEC team to try to maintain Mali Midgard drivers working the latest kernel supported is 5.16 which is eternity past if you need Mainline Linux.

This is a diffstat specially aimed at Rock Pi N10 users - perhaps it could work for Rock Pi 4, I don't know! - for Linux kernel v6.10-rc4, latest Mainline as of last week...

Just cd to mali-midgard/driver/product/kernel/drivers/gpu/arm/midgard and make.

Make sure you adhere to the exact same compiler you used to build the kernel. For example, I used distcc to build the kernel but forgot to pass CC environment variable as in make -j16 CC="distcc gcc" and that was enough for build to fail.

Mali driver you just built which creates /dev/mali0 node for closed-source libMali needs to be inserted without panfrost loaded. Make sure you modprobe -r panfrost from a real console or via ssh and then insmod mali-midgard/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase.ko which should result in the following lines to your kern.log:

    Jun 24 01:19:47 geday kernel: mali_kbase: loading out-of-tree module taints kernel.
Jun 24 01:19:47 geday kernel: mali ff9a0000.gpu: Continuing without Mali regulator control
Jun 24 01:19:47 geday kernel: mali ff9a0000.gpu: Continuing without Mali bus clock
Jun 24 01:19:47 geday kernel: mali ff9a0000.gpu: GPU identified as 0x0860 r2p0 status 0
Jun 24 01:19:47 geday kernel: mali ff9a0000.gpu: Protected mode not available
Jun 24 01:19:47 geday kernel: workqueue: name exceeds WQ_NAME_LEN. Truncating to: kbase_job_fault_resume_work_que
Jun 24 01:19:47 geday kernel: mali ff9a0000.gpu: Probed as mali0

Make sure /etc/OpenCL/vendors/ has some .icd pointing to the correct libMali.so (vendor provided). I recommend you give dlprimitives and its children pytorch_dlprim a good try with your newly-acquired OpenCL capabilities.

From 65df8d090cfeff8a692008e20f2241f7d325e267 Mon Sep 17 00:00:00 2001
From: Geraldo Nascimento <[email protected]>
Date: Fri, 1 Sep 2023 00:50:56 -0300
Subject: [PATCH 1/1] Very hacky, tentative support for Linux v6.5.0 (Mainline)

---
.../kernel/drivers/gpu/arm/midgard/Makefile | 5 +-
.../backend/gpu/mali_kbase_irq_linux.c | 16 +---
.../gpu/arm/midgard/mali_kbase_core_linux.c | 15 +--
.../drivers/gpu/arm/midgard/mali_kbase_defs.h | 4 +-
.../drivers/gpu/arm/midgard/mali_kbase_mem.c | 2 +-
.../gpu/arm/midgard/mali_kbase_mem_linux.c | 38 ++++----
.../gpu/arm/midgard/mali_kbase_mem_pool.c | 2 +-
.../arm/midgard/thirdparty/mali_kbase_mmap.c | 91 ++-----------------
8 files changed, 47 insertions(+), 126 deletions(-)

diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/Makefile b/driver/product/kernel/drivers/gpu/arm/midgard/Makefile
index 08b2fa9..22929b6 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/Makefile
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/Makefile
@@ -20,7 +20,8 @@
#


-KDIR ?= /lib/modules/$(shell uname -r)/build
+#KDIR ?= /lib/modules/$(shell uname -r)/build
+KDIR=/usr/src/linux

BUSLOG_PATH_RELATIVE = $(CURDIR)/../../../..
KBASE_PATH_RELATIVE = $(CURDIR)
@@ -32,7 +33,7 @@ endif

# we get the symbols from modules using KBUILD_EXTRA_SYMBOLS to prevent warnings about unknown functions
all:
- $(MAKE) -C $(KDIR) M=$(CURDIR) EXTRA_CFLAGS="-I$(CURDIR)/../../../../include -I$(CURDIR)/../../../../tests/include $(SCONS_CFLAGS)" $(SCONS_CONFIGS) KBUILD_EXTRA_SYMBOLS="$(EXTRA_SYMBOLS)" modules
+ $(MAKE) -C $(KDIR) M=$(CURDIR) EXTRA_CFLAGS="-I$(CURDIR)/../../../../include" KBUILD_EXTRA_SYMBOLS="$(EXTRA_SYMBOLS)" CONFIG_MALI_MIDGARD=m CONFIG_MALI_PLATFORM_NAME=rk modules

clean:
$(MAKE) -C $(KDIR) M=$(CURDIR) clean
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_irq_linux.c b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_irq_linux.c
index dd0279a..5b4b405 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_irq_linux.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_irq_linux.c
@@ -426,8 +426,8 @@ int kbase_install_interrupts(struct kbase_device *kbdev)
u32 i;

for (i = 0; i < nr; i++) {
- err = request_irq(kbdev->irqs[i].irq, kbase_handler_table[i],
- kbdev->irqs[i].flags | IRQF_SHARED,
+ err = devm_request_irq(kbdev->dev, kbdev->irqs[i].irq, kbase_handler_table[i],
+ 0,
dev_name(kbdev->dev),
kbase_tag(kbdev, i));
if (err) {
@@ -436,17 +436,11 @@ int kbase_install_interrupts(struct kbase_device *kbdev)
#ifdef CONFIG_SPARSE_IRQ
dev_err(kbdev->dev, "You have CONFIG_SPARSE_IRQ support enabled - is the interrupt number correct for this configuration?\n");
#endif /* CONFIG_SPARSE_IRQ */
- goto release;
+ return err;
}
}

return 0;
-
- release:
- while (i-- > 0)
- free_irq(kbdev->irqs[i].irq, kbase_tag(kbdev, i));
-
- return err;
}

void kbase_release_interrupts(struct kbase_device *kbdev)
@@ -454,10 +448,10 @@ void kbase_release_interrupts(struct kbase_device *kbdev)
u32 nr = ARRAY_SIZE(kbase_handler_table);
u32 i;

- for (i = 0; i < nr; i++) {
+ /*for (i = 0; i < nr; i++) {
+
if (kbdev->irqs[i].irq)
free_irq(kbdev->irqs[i].irq, kbase_tag(kbdev, i));
- }
+ }*/
}

void kbase_synchronize_irqs(struct kbase_device *kbdev)
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c
index 58e7335..ee0d6fe 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_core_linux.c
@@ -888,16 +888,16 @@ static int assign_irqs(struct platform_device *pdev)

/* 3 IRQ resources */
for (i = 0; i < 3; i++) {
- struct resource *irq_res;
+ int irq_res;
int irqtag;

- irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
- if (!irq_res) {
+ irq_res = platform_get_irq(pdev, i);
+ if (irq_res < 0) {
dev_err(kbdev->dev, "No IRQ resource at index %d\n", i);
return -ENOENT;
}

-#ifdef CONFIG_OF
+/*#ifdef CONFIG_OF
+
if (!strncmp(irq_res->name, "job", 4)) {
irqtag = JOB_IRQ_TAG;
} else if (!strncmp(irq_res->name, "mmu", 4)) {
@@ -911,9 +911,10 @@ static int assign_irqs(struct platform_device *pdev)
}
#else
irqtag = i;
-#endif /* CONFIG_OF */
- kbdev->irqs[irqtag].irq = irq_res->start;
- kbdev->irqs[irqtag].flags = irq_res->flags & IRQF_TRIGGER_MASK;
+#endif*/ /* CONFIG_OF */
+ irqtag = i;
+ kbdev->irqs[irqtag].irq = irq_res;
+ kbdev->irqs[irqtag].flags = 0;
}

return 0;
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h
index 1836485..922dc70 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h
@@ -1419,8 +1419,8 @@ struct kbase_device {
void __iomem *reg;

struct {
- int irq;
- int flags;
+ unsigned int irq;
+ unsigned long flags;
} irqs[3];

struct clk *clock;
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.c
index 04015e1..9415c97 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem.c
@@ -3401,7 +3401,7 @@ static int kbase_jd_user_buf_map(struct kbase_context *kctx,
address,
alloc->imported.user_buf.nr_pages,
reg->flags & KBASE_REG_GPU_WR ? FOLL_WRITE : 0,
- pages, NULL, NULL);
+ pages, NULL);
#endif

if (pinned_pages <= 0)
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c
index 248fa12..58bf3be 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c
@@ -640,7 +640,7 @@ int kbase_mem_evictable_init(struct kbase_context *kctx)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
kctx->reclaim.batch = 0;
#endif
- register_shrinker(&kctx->reclaim);
+ register_shrinker(&kctx->reclaim, "mali_kbase");
return 0;
}

@@ -1113,7 +1113,7 @@ static struct kbase_va_region *kbase_mem_from_user_buffer(
#else
faulted_pages = get_user_pages(address, *va_pages,
reg->flags & KBASE_REG_GPU_WR ? FOLL_WRITE : 0,
- pages, NULL);
+ pages);
#endif

up_read(&current->mm->mmap_lock);
@@ -1827,11 +1827,7 @@ static int kbase_cpu_mmap(struct kbase_context *kctx,
* See MIDBASE-1057
*/

-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
- vma->vm_flags |= VM_DONTCOPY | VM_DONTDUMP | VM_DONTEXPAND | VM_IO;
-#else
- vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_IO;
-#endif
+ vm_flags_set(vma, VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP | VM_IO);
vma->vm_ops = &kbase_vm_ops;
vma->vm_private_data = map;

@@ -1883,7 +1879,7 @@ static int kbase_cpu_mmap(struct kbase_context *kctx,
if (!kaddr) {
unsigned long addr = vma->vm_start + aligned_offset;

- vma->vm_flags |= VM_PFNMAP;
+ vm_flags_set(vma, VM_PFNMAP);
for (i = 0; i < nr_pages; i++) {
phys_addr_t phys;

@@ -1898,7 +1894,7 @@ static int kbase_cpu_mmap(struct kbase_context *kctx,
} else {
WARN_ON(aligned_offset);
/* MIXEDMAP so we can vfree the kaddr early and not track it after map time */
- vma->vm_flags |= VM_MIXEDMAP;
+ vm_flags_set(vma, VM_MIXEDMAP);
/* vmalloc remaping is easy... */
err = remap_vmalloc_range(vma, kaddr, 0);
WARN_ON(err);
@@ -2079,9 +2075,9 @@ int kbase_mmap(struct file *file, struct vm_area_struct *vma)
dev_dbg(dev, "kbase_mmap\n");

if (!(vma->vm_flags & VM_READ))
- vma->vm_flags &= ~VM_MAYREAD;
+ vm_flags_clear(vma, VM_MAYREAD);
if (!(vma->vm_flags & VM_WRITE))
- vma->vm_flags &= ~VM_MAYWRITE;
+ vm_flags_clear(vma, VM_MAYWRITE);

if (0 == nr_pages) {
err = -EINVAL;
@@ -2420,14 +2416,16 @@ void kbasep_os_process_page_usage_update(struct kbase_context *kctx, int pages)
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0))
add_mm_counter(mm, MM_FILEPAGES, pages);
#else
- atomic_long_add(pages, &mm->rss_stat.count[MM_FILEPAGES]);
+ //atomic_long_add(pages, &mm->rss_stat.count[MM_FILEPAGES]);
+ percpu_counter_add(&mm->rss_stat[MM_FILEPAGES], pages);
#endif
#else
spin_lock(&mm->page_table_lock);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0))
add_mm_counter(mm, MM_FILEPAGES, pages);
#else
- atomic_long_add(pages, &mm->rss_stat.count[MM_FILEPAGES]);
+ //atomic_long_add(pages, &mm->rss_stat.count[MM_FILEPAGES]);
+ percpu_counter_add(&mm->rss_stat[MM_FILEPAGES], pages);
#endif
spin_unlock(&mm->page_table_lock);
#endif
@@ -2456,14 +2454,16 @@ static void kbasep_os_process_page_usage_drain(struct kbase_context *kctx)
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0))
add_mm_counter(mm, MM_FILEPAGES, -pages);
#else
- atomic_long_add(pages, &mm->rss_stat.count[MM_FILEPAGES]);
+ //atomic_long_add(pages, &mm->rss_stat.count[MM_FILEPAGES]);
+ percpu_counter_add(&mm->rss_stat[MM_FILEPAGES], -pages);
#endif
#else
spin_lock(&mm->page_table_lock);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0))
add_mm_counter(mm, MM_FILEPAGES, -pages);
#else
- atomic_long_add(pages, &mm->rss_stat.count[MM_FILEPAGES]);
+ //atomic_long_add(pages, &mm->rss_stat.count[MM_FILEPAGES]);
+ percpu_counter_add(&mm->rss_stat[MM_FILEPAGES], -pages);
#endif
spin_unlock(&mm->page_table_lock);
#endif
@@ -2495,12 +2495,8 @@ static int kbase_tracking_page_setup(struct kbase_context *kctx, struct vm_area_
spin_unlock(&kctx->mm_update_lock);

/* no real access */
- vma->vm_flags &= ~(VM_READ | VM_MAYREAD | VM_WRITE | VM_MAYWRITE | VM_EXEC | VM_MAYEXEC);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
- vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
-#else
- vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_IO;
-#endif
+ vm_flags_clear(vma, VM_READ | VM_MAYREAD | VM_WRITE | VM_MAYWRITE | VM_EXEC | VM_MAYEXEC);
+ vm_flags_set(vma, VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP | VM_IO);
vma->vm_ops = &kbase_vm_special_ops;
vma->vm_private_data = kctx;

diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool.c
index 0f91be1..26578f2 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool.c
@@ -397,7 +397,7 @@ int kbase_mem_pool_init(struct kbase_mem_pool *pool,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
pool->reclaim.batch = 0;
#endif
- register_shrinker(&pool->reclaim);
+ register_shrinker(&pool->reclaim, "mali_kbase_pool");

pool_dbg(pool, "initialized\n");

diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/thirdparty/mali_kbase_mmap.c b/driver/product/kernel/drivers/gpu/arm/midgard/thirdparty/mali_kbase_mmap.c
index 3aab51a..eaed808 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/thirdparty/mali_kbase_mmap.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/thirdparty/mali_kbase_mmap.c
@@ -29,6 +29,7 @@
* Boston, MA 02110-1301, USA.
*/

+#include <linux/maple_tree.h>
#include "linux/mman.h"
#include "../mali_kbase.h"

@@ -153,97 +154,25 @@ static unsigned long kbase_unmapped_area_topdown(struct vm_unmapped_area_info
*info, bool is_shader_code, bool is_same_4gb_page)
{
struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- unsigned long length, low_limit, high_limit, gap_start, gap_end;
+ //struct vm_area_struct *vma;
+ //unsigned long length, low_limit, high_limit, gap_start, gap_end;
+ unsigned long length, gap_start, gap_end;

+ MA_STATE(mas, &mm->mm_mt, 0, 0);
/* Adjust search length to account for worst case alignment overhead */
length = info->length + info->align_mask;
if (length < info->length)
return -ENOMEM;

- /*
- * Adjust search limits by the desired length.
- * See implementation comment at top of unmapped_area().
- */

- gap_end = info->high_limit;
- if (gap_end < length)
+ if (mas_empty_area_rev(&mas, info->low_limit, info->high_limit - 1,
+ length))
return -ENOMEM;
- high_limit = gap_end - length;

- if (info->low_limit > high_limit)
- return -ENOMEM;
- low_limit = info->low_limit + length;
-
- /* Check highest gap, which does not precede any rbtree node */
- gap_start = mm->highest_vm_end;
- if (gap_start <= high_limit) {
- if (align_and_check(&gap_end, gap_start, info,
+ gap_end = mas.last + 1;
+ gap_start = mas.index;
+ if (align_and_check(&gap_end, gap_start, info,
is_shader_code, is_same_4gb_page))
return gap_end;
- }
-
- /* Check if rbtree root looks promising */
- if (RB_EMPTY_ROOT(&mm->mm_rb))
- return -ENOMEM;
- vma = rb_entry(mm->mm_rb.rb_node, struct vm_area_struct, vm_rb);
- if (vma->rb_subtree_gap < length)
- return -ENOMEM;
-
- while (true) {
- /* Visit right subtree if it looks promising */
- gap_start = vma->vm_prev ? vma->vm_prev->vm_end : 0;
- if (gap_start <= high_limit && vma->vm_rb.rb_right) {
- struct vm_area_struct *right =
- rb_entry(vma->vm_rb.rb_right,
- struct vm_area_struct, vm_rb);
- if (right->rb_subtree_gap >= length) {
- vma = right;
- continue;
- }
- }
-
-check_current:
- /* Check if current node has a suitable gap */
- gap_end = vma->vm_start;
- if (gap_end < low_limit)
- return -ENOMEM;
- if (gap_start <= high_limit && gap_end - gap_start >= length) {
- /* We found a suitable gap. Clip it with the original
- * high_limit. */

- if (gap_end > info->high_limit)
- gap_end = info->high_limit;
-
- if (align_and_check(&gap_end, gap_start, info,
- is_shader_code, is_same_4gb_page))
- return gap_end;
- }
-
- /* Visit left subtree if it looks promising */
- if (vma->vm_rb.rb_left) {
- struct vm_area_struct *left =
- rb_entry(vma->vm_rb.rb_left,
- struct vm_area_struct, vm_rb);
- if (left->rb_subtree_gap >= length) {
- vma = left;
- continue;
- }
- }
-
- /* Go back up the rbtree to find next candidate node */
- while (true) {
- struct rb_node *prev = &vma->vm_rb;
-
- if (!rb_parent(prev))
- return -ENOMEM;
- vma = rb_entry(rb_parent(prev),
- struct vm_area_struct, vm_rb);
- if (prev == vma->vm_rb.rb_right) {
- gap_start = vma->vm_prev ?
- vma->vm_prev->vm_end : 0;
- goto check_current;
- }
- }
- }

return -ENOMEM;
}
--
2.39.0

And this too:

From 71157b34285695a84933d1d7bcfa5402304111da Mon Sep 17 00:00:00 2001
From: Geraldo Nascimento <[email protected]>
Date: Mon, 24 Jun 2024 01:44:53 -0300
Subject: [PATCH 2/2] Update to Linux 6.10-rc4

strscpy enforced, explicitly include of.h, changed get_rcu_file
signature to pointer variable, and mainly, the lockless slab shrink
that breaks naive compatibility with #ifdefs for older kernels
---
.../arm/midgard/mali_kbase_debug_mem_view.c | 2 +-
.../drivers/gpu/arm/midgard/mali_kbase_defs.h | 4 +--
.../gpu/arm/midgard/mali_kbase_device.c | 1 +
.../gpu/arm/midgard/mali_kbase_mem_linux.c | 28 ++++++++-----------
.../gpu/arm/midgard/mali_kbase_mem_pool.c | 28 ++++++++-----------
.../gpu/arm/midgard/mali_kbase_tlstream.c | 2 +-
6 files changed, 29 insertions(+), 36 deletions(-)

diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_mem_view.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_mem_view.c
index 8f46117..789e721 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_mem_view.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_debug_mem_view.c
@@ -203,7 +203,7 @@ static int debug_mem_open(struct inode *i, struct file *file)
struct debug_mem_data *mem_data;
int ret;

- if (get_file_rcu(kctx_file) == 0)
+ if (get_file_rcu(&kctx_file) == 0)
return -ENOENT;

ret = seq_open(file, &ops);
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h
index 922dc70..bb1bfe9 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_defs.h
@@ -1100,7 +1100,7 @@ struct kbase_mem_pool {
size_t order;
spinlock_t pool_lock;
struct list_head page_list;
- struct shrinker reclaim;
+ struct shrinker *reclaim;

struct kbase_mem_pool *next_pool;

@@ -2013,7 +2013,7 @@ struct kbase_context {
struct kbase_mem_pool mem_pool;
struct kbase_mem_pool lp_mem_pool;

- struct shrinker reclaim;
+ struct shrinker *reclaim;
struct list_head evict_list;

struct list_head waiting_soft_jobs;
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_device.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_device.c
index 7d79e96..eef571e 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_device.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_device.c
@@ -32,6 +32,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_platform.h>
+#include <linux/of.h>

#include <mali_kbase.h>
#include <mali_kbase_defs.h>
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c
index 58bf3be..4829aef 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_linux.c
@@ -527,7 +527,7 @@ unsigned long kbase_mem_evictable_reclaim_count_objects(struct shrinker *s,
struct kbase_mem_phy_alloc *alloc;
unsigned long pages = 0;

- kctx = container_of(s, struct kbase_context, reclaim);
+ kctx = s->private_data;

mutex_lock(&kctx->jit_evict_lock);

@@ -566,7 +566,7 @@ unsigned long kbase_mem_evictable_reclaim_scan_objects(struct shrinker *s,
struct kbase_mem_phy_alloc *tmp;
unsigned long freed = 0;

- kctx = container_of(s, struct kbase_context, reclaim);
+ kctx = s->private_data;
mutex_lock(&kctx->jit_evict_lock);

list_for_each_entry_safe(alloc, tmp, &kctx->evict_list, evict_node) {
@@ -628,25 +628,21 @@ int kbase_mem_evictable_init(struct kbase_context *kctx)
mutex_init(&kctx->jit_evict_lock);

/* Register shrinker */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
- kctx->reclaim.shrink = kbase_mem_evictable_reclaim_shrink;
-#else
- kctx->reclaim.count_objects = kbase_mem_evictable_reclaim_count_objects;
- kctx->reclaim.scan_objects = kbase_mem_evictable_reclaim_scan_objects;
-#endif
- kctx->reclaim.seeks = DEFAULT_SEEKS;
- /* Kernel versions prior to 3.1 :
- * struct shrinker does not define batch */

-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
- kctx->reclaim.batch = 0;
-#endif
- register_shrinker(&kctx->reclaim, "mali_kbase");
+ kctx->reclaim = shrinker_alloc(0, "mali_kmem_base");
+ if (!kctx->reclaim)
+ return 1;
+ kctx->reclaim->count_objects = kbase_mem_evictable_reclaim_count_objects;
+ kctx->reclaim->scan_objects = kbase_mem_evictable_reclaim_scan_objects;
+ kctx->reclaim->seeks = DEFAULT_SEEKS;
+ kctx->reclaim->batch = 0;
+ kctx->reclaim->private_data = kctx;
+ shrinker_register(kctx->reclaim);
return 0;
}

void kbase_mem_evictable_deinit(struct kbase_context *kctx)
{
- unregister_shrinker(&kctx->reclaim);
+ shrinker_free(kctx->reclaim);
}

/**
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool.c
index 26578f2..fd07d15 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_mem_pool.c
@@ -319,7 +319,7 @@ static unsigned long kbase_mem_pool_reclaim_count_objects(struct shrinker *s,
struct kbase_mem_pool *pool;
size_t pool_size;

- pool = container_of(s, struct kbase_mem_pool, reclaim);
+ pool = s->private_data;

kbase_mem_pool_lock(pool);
if (pool->dont_reclaim && !pool->dying) {
@@ -338,7 +338,7 @@ static unsigned long kbase_mem_pool_reclaim_scan_objects(struct shrinker *s,
struct kbase_mem_pool *pool;
unsigned long freed;

- pool = container_of(s, struct kbase_mem_pool, reclaim);
+ pool = s->private_data;

kbase_mem_pool_lock(pool);
if (pool->dont_reclaim && !pool->dying) {
@@ -385,19 +385,15 @@ int kbase_mem_pool_init(struct kbase_mem_pool *pool,
INIT_LIST_HEAD(&pool->page_list);

/* Register shrinker */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
- pool->reclaim.shrink = kbase_mem_pool_reclaim_shrink;
-#else
- pool->reclaim.count_objects = kbase_mem_pool_reclaim_count_objects;
- pool->reclaim.scan_objects = kbase_mem_pool_reclaim_scan_objects;
-#endif
- pool->reclaim.seeks = DEFAULT_SEEKS;
- /* Kernel versions prior to 3.1 :
- * struct shrinker does not define batch */

-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)
- pool->reclaim.batch = 0;
-#endif
- register_shrinker(&pool->reclaim, "mali_kbase_pool");
+ pool->reclaim = shrinker_alloc(0, "mali_kbase_pool");
+ if (!pool->reclaim)
+ return 1;
+ pool->reclaim->count_objects = kbase_mem_pool_reclaim_count_objects;
+ pool->reclaim->scan_objects = kbase_mem_pool_reclaim_scan_objects;
+ pool->reclaim->seeks = DEFAULT_SEEKS;
+ pool->reclaim->batch = 0;
+ pool->reclaim->private_data = pool;
+ shrinker_register(pool->reclaim);

pool_dbg(pool, "initialized\n");

@@ -422,7 +418,7 @@ void kbase_mem_pool_term(struct kbase_mem_pool *pool)

pool_dbg(pool, "terminate()\n");

- unregister_shrinker(&pool->reclaim);
+ shrinker_free(pool->reclaim);

kbase_mem_pool_lock(pool);
pool->max_size = 0;
diff --git a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.c b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.c
index 56e4ebe..0270d55 100644
--- a/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.c
+++ b/driver/product/kernel/drivers/gpu/arm/midgard/mali_kbase_tlstream.c
@@ -663,7 +663,7 @@ static size_t kbasep_tlstream_write_string(
KBASE_DEBUG_ASSERT(max_write_size >= sizeof(string_len) + sizeof(char));
max_write_size -= sizeof(string_len);

- string_len = strlcpy(
+ string_len = strscpy(
&buffer[pos + sizeof(string_len)],
string,
max_write_size);
--
2.45.2

Ah, there's also this, if it doesn't get solved in this development cycle then it's worth reporting to panfrost:

Jun 24 01:19:33 geday kernel: ------------[ cut here ]------------
Jun 24 01:19:33 geday kernel: WARNING: CPU: 4 PID: 28712 at drivers/opp/core.c:1640 _opp_table_kref_release+0x148/0x158
Jun 24 01:19:33 geday kernel: Modules linked in: xt_set ip_set_hash_net ip_set nfnetlink xt_conntrack iptable_nat xt_MASQUERADE nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_filter xt_TCPMSS xt_tcpudp ip_tables x_tables ipv6 pppoe pppox ppp_generic slhc cdc_ether usbnet joydev crct10dif_ce gpio_ir_recv panfrost(-) hantro_vpu rockchip_vdec(C) rc_core gpu_sched dw_hdmi_cec drm_shmem_helper dw_hdmi_i2s_audio v4l2_vp9 v4l2_h264 phy_rockchip_pcie rockchip_rga videobuf2_dma_contig r8152 videobuf2_dma_sg v4l2_mem2mem videobuf2_memops videobuf2_v4l2 snd_soc_rockchip_i2s rtc_hym8563 snd_soc_es8316 videodev nvmem_rockchip_efuse dw_mmc_rockchip videobuf2_common mc dw_mmc_pltfm snd_soc_simple_card snd_soc_simple_card_utils pcie_rockchip_host dwmac_rk dw_mmc uas
Jun 24 01:19:33 geday kernel: CPU: 4 PID: 28712 Comm: modprobe Tainted: G C 6.10.0-rc4+ #48
Jun 24 01:19:33 geday kernel: Hardware name: Radxa ROCK Pi N10 (DT)
Jun 24 01:19:33 geday kernel: pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
Jun 24 01:19:33 geday kernel: pc : _opp_table_kref_release+0x148/0x158
Jun 24 01:19:33 geday kernel: lr : _opp_table_kref_release+0x80/0x158
Jun 24 01:19:33 geday kernel: sp : ffff80008e093bb0
Jun 24 01:19:33 geday kernel: x29: ffff80008e093bb0 x28: ffff0000038eb240 x27: 0000000000000000
Jun 24 01:19:33 geday kernel: x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
Jun 24 01:19:33 geday kernel: x23: 000000000000000e x22: ffff000008cae470 x21: ffff000008cae478
Jun 24 01:19:33 geday kernel: x20: ffff000008cae400 x19: ffff000004747190 x18: ffffffffffffffff
Jun 24 01:19:33 geday kernel: x17: 3966662f71657266 x16: 7665642f7570672e x15: 3030303061396666
Jun 24 01:19:33 geday kernel: x14: ffff800081f7b158 x13: 00313838333d4d55 x12: 0000000000000000
Jun 24 01:19:33 geday kernel: x11: 0000000000000004 x10: 000000000000003f x9 : 0000000000000001
Jun 24 01:19:33 geday kernel: x8 : 000000000000003f x7 : 0000000000000001 x6 : ffff000000ccc180
Jun 24 01:19:33 geday kernel: x5 : 00000000002a000a x4 : fffffdffc01755a0 x3 : fffffdffc01755a0
Jun 24 01:19:33 geday kernel: x2 : 0000000000000000 x1 : ffff000004747e40 x0 : ffff000008cae460
Jun 24 01:19:33 geday kernel: Call trace:
Jun 24 01:19:33 geday kernel: _opp_table_kref_release+0x148/0x158
Jun 24 01:19:33 geday kernel: dev_pm_opp_remove_table+0xf4/0x184
Jun 24 01:19:33 geday kernel: devm_pm_opp_of_table_release+0x10/0x1c
Jun 24 01:19:33 geday kernel: devm_action_release+0x14/0x20
Jun 24 01:19:33 geday kernel: devres_release_all+0xb0/0x120
Jun 24 01:19:33 geday kernel: device_unbind_cleanup+0x18/0x60
Jun 24 01:19:33 geday kernel: device_release_driver_internal+0x1ec/0x224
Jun 24 01:19:33 geday kernel: driver_detach+0x4c/0x94
Jun 24 01:19:33 geday kernel: bus_remove_driver+0x70/0x100
Jun 24 01:19:33 geday kernel: driver_unregister+0x30/0x60
Jun 24 01:19:33 geday kernel: platform_driver_unregister+0x14/0x20
Jun 24 01:19:33 geday kernel: panfrost_driver_exit+0x18/0xcc4 [panfrost]
Jun 24 01:19:33 geday kernel: __arm64_sys_delete_module+0x184/0x298
Jun 24 01:19:33 geday kernel: invoke_syscall.constprop.0+0x50/0xe4
Jun 24 01:19:33 geday kernel: do_el0_svc+0x40/0xdc
Jun 24 01:19:33 geday kernel: el0_svc+0x40/0x188
Jun 24 01:19:33 geday kernel: el0t_64_sync_handler+0x120/0x138
Jun 24 01:19:33 geday kernel: el0t_64_sync+0x1a4/0x1a8
Jun 24 01:19:33 geday kernel: ---[ end trace 0000000000000000 ]---