Skip to content

gk7205v500: let the kernel unload modules - #2528

Merged
widgetii merged 2 commits into
masterfrom
gk7205v500/module-unload
Oct 4, 2026
Merged

widgetii merged 2 commits into
masterfrom
gk7205v500/module-unload

Conversation

@widgetii

@widgetii widgetii commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

Problem

The gk7205v500 family kernel (gk7205v500_lite / gk7205v500_ultimate, and the gk7205v510 / gk7205v530 aliases) is built without CONFIG_MODULE_UNLOAD. A loaded module can never be removed, so the media stack cannot be reloaded, or swapped for a test build, without rebooting the camera. That makes the open GK7205V510 video bring-up much slower to debug.

The setting was off because the vendor's tiny defconfig has it off, not because the closed V500 objects need it off:

  • They carry no struct module of their own. modpost generates __this_module with this kernel's layout, and the objects already export cleanup_module.
  • The vendor's own xm72050500_full_defconfig ships with CONFIG_MODULE_UNLOAD=y.
  • The real layout hazard is CONFIG_PM, which moves struct device's fields. It stays off.

gk7201v200.generic.config is separate and not touched.

Once the kernel can unload, load_goke's -r, -a and sensor-detection paths reach remove_ko() and remove_detect() for the first time, and neither removed anything. The from-source build installs xm_<m>.ko, but each module registers as open_<m>, so every rmmod xm_<m> failed. modprobe -r exits 0 and leaves the module loaded, and xm_sys_config named no module at all. As a result, detection left sysconfig loaded with sensors=unknown. The second commit adds unload(), which tries open_<m> first, and puts both lists in dependency order.

Changing the setting changes vermagic (mod_unload), so the kernel and every module in an image must come from the same build. A normal image build already does that.

Hardware tested on

GK7205V510, Zenointel SD-2N-4G (MIS2008, 128 MB SPI-NAND), gk7205v500_ultimate NAND image.

The image was built from 9bde58d's content (#2526) plus this commit, and flashed with sysupgrade --archive with the overlay kept. Since then master has added only #2527 (wifibroadcast), which does not touch this family.

Evidence

Before: stock vermagic, and rmmod refuses every media module.

vermagic=4.9.37 ARMv7 thumb2 p2v8
RMMOD FAIL open_mipi_rx
RMMOD FAIL open_acodec
...
RMMOD FAIL open_vi

After: every module in the image carries mod_unload. All 26 open_* modules come out; load_goke -i puts them back; majestic restarts; dmesg shows no oops.

# strings /lib/modules/4.9.37/goke/xm_vi.ko | grep vermagic=
vermagic=4.9.37 mod_unload ARMv7 thumb2 p2v8
# (stop majestic; rmmod open_mipi_rx ... open_osal)
left: 0
# load_goke -i
reloaded: 26
# /etc/init.d/S95majestic start; pidof majestic
1216

load_goke on the same kernel, shipped script vs this PR's:

shipped load_goke -r:  26 modules before, 26 after
  rmmod: can't unload module 'xm_acodec': No such file or directory
  ...
fixed   load_goke -r:  26 -> 0;  -i: 26, sensors=mis2008
detection path (sensor env cleared): 26 loaded, sensors=mis2008, env=mis2008
-a: 26

Image sizes from this build: uImage: [1910KB/2048KB], fitImage: [1911KB/4096KB], rootfs.ubi: [15104KB/16384KB].

Scope

  • No kernel patches under general/package/all-patches/linux/ (those go to OpenIPC/linux)
  • No files specific to a single retail camera model (those go to OpenIPC/builder)
  • No probing or bring-up tooling (that goes to OpenIPC/ipctool)
  • Nothing under general/overlay/ or in a shared load_<vendor> script hardcodes a value specific to my board
  • Package sources come from an OpenIPC repository, and any version bump keeps at least the specificity of the pin it replaces (a new package should pin a full 40-character SHA)
  • No LD_PRELOAD, and no binaries that cannot be rebuilt from source
  • New code is selected by a defconfig, so CI actually builds it

With CONFIG_MODULE_UNLOAD off, a module that is in cannot come out again, so
nothing on this family can be swapped or reloaded without a reboot. That
includes the media stack itself while a fault in it is being chased.

The setting was left off with the vendor's tiny defconfig, but it is not part
of the ABI the closed V500 objects depend on. They carry no struct module of
their own: modpost generates __this_module with this kernel's layout, and they
already export cleanup_module. The vendor's own xm72050500_full_defconfig ships
with MODULE_UNLOAD=y. The layout hazard is CONFIG_PM, which moves struct
device's fields, and it stays off.

gk7201v200 has its own kernel config and is not touched.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Enable module unloading for GK7205V500 kernels

⚙️ Configuration changes ✨ Enhancement 🕐 10-20 Minutes

Grey Divider

AI Description

• Enable module unloading for GK7205V500 lite and ultimate images so media modules can be reloaded
 without rebooting.
• Keep CONFIG_PM disabled to preserve the device layout expected by closed vendor objects.
Diagram

graph TD
    D["Lite and ultimate builds"] --> C["V500 kernel config"] --> K(["Unload-capable kernel"]) --> M["Media modules"]
    L["load_goke"] --> M
Loading
High-Level Assessment

The shared kernel config is the appropriate scope: both V500 variants select it, while gk7201v200 uses a separate config. Runtime tooling cannot enable unloading in a kernel built without it. Rebuild the kernel and all image modules together because enabling the option changes vermagic.

Files changed (1) +3 / -1

Other (1) +3 / -1
gk7205v500.generic.configEnable GK7205V500 kernel module unloading +3/-1

Enable GK7205V500 kernel module unloading

• Sets CONFIG_MODULE_UNLOAD=y in the kernel config shared by the lite and ultimate builds. Adds a comment explaining why the closed V500 objects permit this change while CONFIG_PM remains unsafe to enable.

br-ext-chip-goke/board/gk7205v500/gk7205v500.generic.config

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

qodo-free-for-open-source-projects Bot commented Oct 4, 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. Reloads keep old sensor settings ✓ Resolved
Description
Enabling module unloading lets load_goke -a reach remove_ko(), which calls rmmod on
xm_sys_config instead of the loaded xm_sysconfig. When a reload supplies new sensor or chip
parameters, the module remains loaded, so the subsequent modprobe xm_sysconfig cannot apply them.
Code

br-ext-chip-goke/board/gk7205v500/gk7205v500.generic.config[234]

+CONFIG_MODULE_UNLOAD=y
Evidence
Both image variants use the changed kernel config. The script rejects -r and -a when unloading
is unavailable, so the new setting makes its removal path accessible; that path names a different
module from the one installed and loaded, then proceeds to insertion.

br-ext-chip-goke/configs/gk7205v500_lite_defconfig[20-24]
br-ext-chip-goke/configs/gk7205v500_ultimate_defconfig[18-22]
general/package/goke-osdrv-gk7205v500/files/script/load_goke[309-317]
general/package/goke-osdrv-gk7205v500/files/script/load_goke[215-220]
general/package/goke-osdrv-gk7205v500/files/script/load_goke[156-162]
general/package/goke-osdrv-gk7205v500/goke-osdrv-gk7205v500.mk[72-76]

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 enabled module-unload setting makes `load_goke -a` available, but its cleanup uses the wrong name for the loaded sysconfig module. Reloading can therefore retain old sensor and chip parameters.
## Fix Focus Areas
- br-ext-chip-goke/board/gk7205v500/gk7205v500.generic.config[232-234]
- general/package/goke-osdrv-gk7205v500/files/script/load_goke[117-124]
- general/package/goke-osdrv-gk7205v500/files/script/load_goke[214-221]
## Recommended Fix
Change both cleanup paths to remove `xm_sysconfig` by its installed name, before removing `xm_osal`. Ensure the reload path does not proceed with insertion if required modules failed to unload.

ⓘ 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 tweak Display settings with a live preview to see your comment before it ships

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Once the kernel can unload, -r, -a and the sensor-detection pass reach
remove_ko() and remove_detect() for the first time, and neither removed
anything. The from-source build installs xm_<m>.ko, but each module registers
as open_<m>, so every `rmmod xm_<m>` failed with "No such file or directory".
`modprobe -r xm_<m>` is no better: it exits 0 and leaves the module loaded.
The sysconfig line also named a module that does not exist, xm_sys_config.

So detection left sysconfig loaded with sensors=unknown, and the modprobe that
should have reloaded it with the detected sensor found it already in and did
nothing.

unload() tries open_<m> first, then the name as given. Both lists now run in
dependency order: venc before rc, and sysconfig before osal.
@widgetii
widgetii merged commit ce750d6 into master Oct 4, 2026
28 of 29 checks passed
@widgetii
widgetii deleted the gk7205v500/module-unload branch October 4, 2026 07:45
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