Skip to content

gk7205v500: build the CMA allocator into osal - #236

Merged
widgetii merged 2 commits into
mainfrom
gk7205v500/osal-cma
Oct 3, 2026
Merged

widgetii merged 2 commits into
mainfrom
gk7205v500/osal-cma

Conversation

@widgetii

@widgetii widgetii commented Oct 3, 2026

Copy link
Copy Markdown
Member

mmz_allocator=cma could not work on the gk7205v500 family. The kbuild
left mmz/cma_allocator.o out of the osal module. So on a CMA kernel
osal.c's call to cma_allocator_setopt() went unresolved, and the module
would not load:

open_osal: Unknown symbol cma_allocator_setopt (err 0)

The file had also never been ported from the HiSilicon kernel's API:

  • It called get_cma_zone(). The xmedia kernel's drivers/xmedia/cma
    exports xmedia_get_cma_zone().
  • It kept a private copy of struct cma_zone. It now includes
    <linux/xmedia_cma.h>, so the layout cannot drift from the kernel's.
  • It defined max_malloc_size, which allocator.c already defines. That
    was a link error once the file was actually built.

It is now built only when the kernel has CONFIG_CMA, so a non-CMA build
is unchanged. The printk of the zone casts its gfp_t/phys_addr_t
arguments to match the %lx format.

Verified on a GK7205V510 (128 MiB DDR) running openipc/linux 4.9.37 with
CMA + DMA_CMA, booted with mem=128M mmz_allocator=cma
mmz=anonymous,0,0x42000000,96M:

cma: Reserved 96 MiB at 0x42000000
Media Memory Zone Manager
cmz zone gfp 0x0, phys 0x42000000, nbytes 0x6000000
osal 1.0 init success!

All 28 modules load, majestic starts the SDK, and CmaFree falls by the
~15 MB the media stack allocates from the zone. Linux keeps the rest of
the DDR: MemTotal is 125840 kB, against 28612 kB with mem=32M and the
xmedia carve-out.

Testing notes

  • This repo's CI builds against firmware master, whose gk7205v500 kernel has no CMA yet. CI therefore checks that the non-CMA build is unchanged; it doesn't compile cma_allocator.o.
  • The CMA build was exercised in gk7205v500 NAND: FIT kernel volume, CMA, and sysupgrade for UBI layouts firmware#2526. That PR enables CMA for gk7205v500 and carries this change as a package patch on ecbc855, which is this repo's main.
  • Once this is merged, a hisilicon-opensdk bump replaces that patch.

mmz_allocator=cma could not work on the gk7205v500 family. The kbuild
left mmz/cma_allocator.o out of the osal module. So on a CMA kernel
osal.c's call to cma_allocator_setopt() went unresolved, and the module
would not load:

  open_osal: Unknown symbol cma_allocator_setopt (err 0)

The file had also never been ported from the HiSilicon kernel's API:

- It called get_cma_zone(). The xmedia kernel's drivers/xmedia/cma
  exports xmedia_get_cma_zone().
- It kept a private copy of struct cma_zone. It now includes
  <linux/xmedia_cma.h>, so the layout cannot drift from the kernel's.
- It defined max_malloc_size, which allocator.c already defines. That
  was a link error once the file was actually built.

It is now built only when the kernel has CONFIG_CMA, so a non-CMA build
is unchanged. The printk of the zone casts its gfp_t/phys_addr_t
arguments to match the %lx format.

Verified on a GK7205V510 (128 MiB DDR) running openipc/linux 4.9.37 with
CMA + DMA_CMA, booted with mem=128M mmz_allocator=cma
mmz=anonymous,0,0x42000000,96M:

  cma: Reserved 96 MiB at 0x42000000
  Media Memory Zone Manager
  cmz zone gfp 0x0, phys 0x42000000, nbytes 0x6000000
  osal 1.0 init success!

All 28 modules load, majestic starts the SDK, and CmaFree falls by the
~15 MB the media stack allocates from the zone. Linux keeps the rest of
the DDR: MemTotal is 125840 kB, against 28612 kB with mem=32M and the
xmedia carve-out.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Enable CMA allocation in gk7205v500 OSAL

🐞 Bug fix 🕐 10-20 Minutes

Grey Divider

AI Description

• Link the CMA allocator into OSAL when CONFIG_CMA is enabled, resolving the missing symbol.
• Use the xmedia kernel’s CMA API and shared zone definition to avoid incompatible layouts.
• Share the existing allocation limit; leave non-CMA builds unchanged.
Diagram

graph TD
  config{"CONFIG_CMA?"} -->|enabled| build["OSAL kbuild"] --> osal["OSAL module"] --> allocator["CMA allocator"] --> api["xmedia zone API"] --> zone["Reserved CMA zone"]
Loading
High-Level Assessment

Conditionally linking the existing allocator and using the kernel-owned CMA definition is the direct fix. Reimplementing allocation or retaining a private zone layout would add risk without addressing the integration more effectively.

Files changed (2) +13 / -15

Bug fix (2) +13 / -15
gk7205v500.kbuildLink the CMA allocator when CONFIG_CMA is enabled +5/-0

Link the CMA allocator when CONFIG_CMA is enabled

• Adds cma_allocator.o to the gk7205v500 OSAL module only for CMA-enabled kernels. Non-CMA builds keep their existing object list.

kernel/gk7205v500.kbuild

cma_allocator.cAlign CMA zone lookup and definitions with xmedia +8/-15

Align CMA zone lookup and definitions with xmedia

• Replaces the private CMA zone structure and legacy lookup with the xmedia kernel header and API. References the allocation limit already defined in allocator.c and casts zone fields to match their printk format.

kernel/osal/gk7205v500/mmz/cma_allocator.c

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. CMA callers can receive misaligned memory ✓ Resolved
Description
__mmb_alloc() accepts the requested align value but passes only the page count and size-derived
order to dma_alloc_from_contiguous(). When a caller requests alignment greater than that implied
by the allocation size, the returned physical address need not meet the requested alignment, unlike
an allocation through the existing fixed-region allocator.
Code

kernel/gk7205v500.kbuild[70]

+$(PREFIX)osal-objs += osal/gk7205v500/mmz/cma_allocator.o
Evidence
The PR links the previously dormant CMA implementation. The exported allocation API and user-device
ioctl both pass through the caller's alignment, but the CMA allocation call does not use it; the
existing fixed-region allocator explicitly aligns candidate addresses.

kernel/gk7205v500.kbuild[69-71]
kernel/osal/gk7205v500/mmz/mmz-userdev.c[145-155]
kernel/osal/gk7205v500/mmz/media-mem.c[233-245]
kernel/osal/gk7205v500/mmz/cma_allocator.c[74-99]
kernel/osal/gk7205v500/mmz/allocator.c[58-65]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The newly linked CMA allocator can return physical addresses that do not satisfy the caller's requested alignment.
## Fix Focus Areas
- kernel/gk7205v500.kbuild[69-71]
- kernel/osal/gk7205v500/mmz/cma_allocator.c[58-103]
## Recommended Fix
Apply the requested alignment when allocating CMA pages. If the allocator cannot satisfy an alignment, return failure rather than returning a misaligned block.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. OSAL loads without a usable CMA zone ✓ Resolved
Description
__allocator_init() skips missing or failed zone registrations but returns zero even when none were
registered. If every configured zone lookup or registration fails, media_mem_init() continues
successfully while subsequent CMA allocations return NULL because the zone list is empty.
Code

kernel/gk7205v500.kbuild[70]

+$(PREFIX)osal-objs += osal/gk7205v500/mmz/cma_allocator.o
Evidence
The new kbuild entry activates this initializer. Failed lookups are skipped and failed registrations
are destroyed, but the function still returns success; media initialization proceeds, and allocation
without a zone returns NULL. The repository's other CMA initializer checks for the
all-registrations-failed case.

kernel/gk7205v500.kbuild[69-71]
kernel/osal/gk7205v500/mmz/cma_allocator.c[396-438]
kernel/osal/gk7205v500/mmz/cma_allocator.c[88-109]
kernel/osal/gk7205v500/mmz/media-mem.c[849-876]
kernel/osal/linux/kernel/mmz/cma_allocator.c[604-623]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The newly activated CMA initializer reports success even if it registers no usable zone.
## Fix Focus Areas
- kernel/gk7205v500.kbuild[69-71]
- kernel/osal/gk7205v500/mmz/cma_allocator.c[382-439]
## Recommended Fix
Track successful CMA zone registrations and return an error when the configured zones yield none. Let `media_mem_init()` propagate that error so OSAL does not load with a nonfunctional allocator.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can copy the agent prompt from any finding and feed it to your IDE agent

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread kernel/gk7205v500.kbuild
Comment thread kernel/gk7205v500.kbuild
Review of the CMA allocator this PR starts building.

- Alignment. __mmb_alloc() took the caller's alignment and ignored it.
  It asked dma_alloc_from_contiguous() for the size's own order only, so
  an alignment larger than that came back unmet. The fixed-region
  allocator honours it, and the same callers (the MMZ API, the userdev
  ioctl) reach both. It now asks for the larger of the two orders.
  dma_alloc_from_contiguous() silently caps the order at
  CONFIG_CMA_ALIGNMENT, so an alignment beyond that is refused rather
  than returned unmet. Every allocation that worked before gets the same
  block.

- No zone. __allocator_init() returned success when no configured zone
  could be found or registered. osal then loaded and failed every
  allocation. It now counts the attempts and returns -ENODEV when none
  registered, which media_mem_init() turns into a failed modprobe -- the
  rule kernel/osal/linux's CMA allocator already follows.

Verified on a GK7205V510 with mmz_allocator=cma
mmz=anonymous,0,0x42000000,96M:
- "cmz zone gfp 0x0, phys 0x42000000, nbytes 0x6000000";
- "osal 1.0 init success!";
- all 28 modules load;
- CmaFree falls by the same ~15 MB as before;
- majestic reports "HiSilicon SDK started";
- no allocation is refused for its alignment.
@widgetii

widgetii commented Oct 3, 2026

Copy link
Copy Markdown
Member Author

Both review findings were real; addressed in 84fd543:

  1. Alignment. __mmb_alloc() ignored the caller's align. It now asks dma_alloc_from_contiguous() for max(get_order(size), get_order(align)), so existing allocations get the same block and a larger requested alignment is honoured. That call silently caps the order at CONFIG_CMA_ALIGNMENT, so an alignment beyond the cap is refused rather than returned unmet.
  2. No usable zone. __allocator_init() now counts attempted and registered zones and returns -ENODEV when none registered, as kernel/osal/linux's CMA allocator does. media_mem_init() already propagates it, so modprobe fails instead of osal loading with an empty zone list.

Re-verified on a GK7205V510 with mmz_allocator=cma mmz=anonymous,0,0x42000000,96M:

  • the zone registers and osal 1.0 init success!;
  • all 28 modules load, and CmaFree falls by the same ~15 MB;
  • majestic reports HiSilicon SDK started;
  • no allocation is refused for its alignment.

@widgetii
widgetii merged commit dfc3a81 into main Oct 3, 2026
35 checks passed
widgetii added a commit to OpenIPC/firmware that referenced this pull request Oct 3, 2026
The gk7205v500 family ran with mem=${osmem} (32M) and an xmedia
carve-out for the MMZ, so Linux saw a quarter of a V510's 128 MiB. That
is the wrong configuration for this SoC. On gk7205v200 the MMZ is a CMA
zone inside Linux's memory; this does the same for gk7205v500.

- Kernel: CMA, DMA_CMA, CMA_MEM_SHARED, plus COMPACTION and MIGRATION.
  The xmedia kernel reserves the zone named by mmz= on the command line
  (drivers/xmedia/cma) and, with CMA_MEM_SHARED, lends it to movable
  pages while the media stack does not need it.

- load_goke:
  - A command line that names no allocator is rewritten for the next
    boot:
    mem=${totalmem} ... mmz_allocator=cma mmz=anonymous,0,<osmem>,<rest>
    Every other bootargs token is kept (#2281). totalmem is the DDR size
    u-boot-xmedia writes into the env.
  - xm_osal then loads with mmz_allocator=cma mmz=$MMZ.
  - mmz_allocator=xmedia in bootargs keeps the carve-out.
  - The "os_mem from mem=" override (for vendor bootloaders passing
    mem=70M) now applies to the carve-out only. Under CMA, mem= is the
    whole DDR, and the override tripped load_goke's own
    "os_mem over total_mem" guard, so no module loaded.

- hisilicon-opensdk is bumped to dfc3a81 (OpenIPC/openhisilicon#236). The
  gk7205v500 osal now builds its CMA allocator against the xmedia
  kernel's API, honours the caller's alignment, and refuses to load with
  no usable zone. Both variants take every xm_*.ko from opensdk, so all
  are rebuilt against this kernel.

Verified on a GK7205V510 (128 MiB DDR):
- First boot after the change, still on mem=32M with the carve-out:
  29 modules, no oops, and bootargs rewritten.
- Next boot: "cma: Reserved 96 MiB at 0x42000000", "cmz zone phys
  0x42000000, nbytes 0x6000000". MemTotal is 125840 kB with ~97 MB
  available, against 28612 kB total and ~15 MB available before.
  CmaFree falls by the ~15 MB the media stack allocates.
- majestic reports "HiSilicon SDK started".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant