lyther/agent-surface/lint-kernel
Claude Code and agent skill by lyther/agent-surface
- community
Checking that the SKILL.md file is still in the repository.
Apply Linux kernel patch and C review discipline.
Install
npx vskill@latest install lyther/agent-surface/lint-kernelSKILL.md
Objective
Lint and prepare Linux kernel C patches, in-tree or out-of-tree modules, to the standard of Documentation/process/submitting-patches.rst; read it. This skill is the lint gate; hand the commit and distribution steps to ship-commit. If a constraint below cannot be met, stop and name the blocker.
Scope
Apply when any of these hold:
- Top-level
MAINTAINERS,Kbuild, andDocumentation/process/submitting-patches.rstexist. scripts/checkpatch.plandscripts/get_maintainer.plexist.- The top-level
MakefiledeclaresVERSION =,PATCHLEVEL =, andSUBLEVEL =. - Sources include
<linux/...>headers and use kernel idioms (EXPORT_SYMBOL,module_init,MODULE_LICENSE).
Otherwise say no kernel lint applies and use the repository's own C tooling.
Procedure
- List the touched
.c,.h,Kconfig, andMakefilefiles. For an existing series, checkoutgoing/*.patchinstead of the working tree. - Select the checks this patch needs (a documentation-only change needs no smatch) and record one state per check:
PASS(ran, found nothing),FAIL(ran, found a defect),SKIP(does not apply; say why), orMISS(applies but could not run: tool absent, no built tree, no hardware; say why). AMISSnever counts as a pass or toward an "N/N" score, and it blocks only the claim its check supports: missing sparse blocks "no new type errors", not "checkpatch is clean". The patch states testing in one line; otherMISSentries stay in your report. A runtime result binds only the patch ID it ran; rerun it after any code change.
``bash # Style gate: --strict for new code; add --no-tree for a lone .patch outside a kernel tree. scripts/checkpatch.pl --strict --codespell <file-or-patch> # Sparse. C=2 checks every source; C=1 checks only recompiled files, often none on a warm tree. make C=2 W=1 <touched-subdir>/ # Smatch (null derefs, lock imbalance). Its cross-function database is optional and only widens cross-call reach. make CHECK=smatch C=2 W=1 <touched-subdir>/ # Coccinelle semantic patches for kernel anti-patterns. make coccicheck MODE=report COCCI=scripts/coccinelle/<area>/<rule>.cocci # kernel-doc warnings, when kernel-doc comments change. Capture first so make's status survives the filter. make htmldocs > /tmp/htmldocs.log 2>&1; rc=$? grep -E 'warning|error' /tmp/htmldocs.log; exit $rc ``
Report how many files each analyzer processed; a pass over zero files is MISS. Most of these tools exit 0 with findings; read references/tool-invocation.md before trusting a status. An indexed navigator (references/semcode.md) is optional help for repeated lookups in a large tree, never a prerequisite and never a substitute for reading the source.
- Check every commit in the series against "Commit Message" below. Draft the message but never add
Signed-off-by:or run the sign-off: only the human author certifies the DCO, so hand over the exactgit commit -s -m "subsystem: imperative subject" -m "Body.". - Prepare recipients locally:
``bash # Against the review base you established (often a subsystem tree; origin/master is not universal). git format-patch -M --base=<review-base> --cover-letter -o outgoing/ <review-base>.. # Keep the defaults: git fallback adds history-derived reviewers that MAINTAINERS alone does not list. scripts/get_maintainer.pl --no-rolestats outgoing/*.patch # MAINTAINERS-only inspection, never for deriving recipients: # scripts/get_maintainer.pl --nogit --no-git-fallback outgoing/*.patch echo "Proposed: git send-email --to=<maintainer> --cc=<list> outgoing/*.patch" ``
Never pipe recipients into git send-email or run it: print the plan and stop. SMTP traffic needs explicit user authorization, and the user runs the send. A root .get_maintainer.conf is prepended to the arguments, so explicit flags win; read it before trusting output whose flags you did not fully set. Splice notes below --- into the exported files; never hand-build a mail. Compare recipient runs under PERL_HASH_SEED=0 PERL_PERTURB_KEYS=0; unseeded runs break history ties at random. K: patterns match all text before the diff, so rewording can change recipients.
- When the fix may reach stable, answer six questions separately: affected range, target branches, prerequisite investigation, application, build, behavioral evidence. History searches (
git log -S/-G,git describe --contains) give leads to read, not verdicts; they misreport renames, reverts, and substring matches. An affected branch that needs an adapted patch or a prerequisite is not an excluded branch. Procedure:references/backport-review.md. - Before
git format-patchfor a public list:
- Rerun
qa-tracewith the error path, not the happy path, as the entry point. - Have a fresh agent or reviewer review the patch without the earlier context; if the design survives only with the backstory, it is not ready.
- For each
(input × concurrent-op)quadrant no test reaches, state in your report why and how you verified it by inspection. - If an earlier version went public, write the vN changelog as a real diff of the design.
- Read a subsystem CI reply (patchwork,
bluez.test.bot) per check. A crash inside the userspace test harness, such as a sanitizer report from BlueZsrc/shared/, is not a kernel finding, but every test after it never ran against the patch: check whether unrelated series fail the same way, then rerun the full suite locally on a harness revision without the breakage before calling those tests passed. - Before reporting, apply
references/finding-discipline.md: each issue needs concrete evidence on at least one execution path, style points are capped and held to a higher bar than correctness, and you never assert authorship or comment on a disclosure trailer. Report in the Output format.
Never push to a branch named master, main, linus, or next.
Checklist
Style
Fix every checkpatch CHECK, WARNING, and ERROR.
- Tabs for indentation, 8 columns wide; lines at most 100 columns, without awkward splits of one logical statement.
- K&R braces: the opening brace on the
if/while/for/doline, on its own line for function definitions. /* … */comments (no//outsidetools/); kernel-doc on exported symbols.- No trailing whitespace, DOS line endings, or smart quotes.
Correctness
- No mixed pointer/integer arithmetic without an explicit cast and reason.
- Keep
__user,__kernel,__iomem, and__rcuon every pointer that needs them; act on sparse's warnings. - Use endianness types (
__le32,__be64) consistently, with no implicitcpu_to_*round-trips. - No sleeping in atomic context against the
gfp_tflags (smatch flags this). - Release every lock on every exit path; no double lock; document lock ordering.
- Balance
rcu_read_lock/rcu_read_unlock; free an RCU-protected pointer only withkfree_rcuor aftersynchronize_rcu. - Use
WARN_ON_ONCEplus an error return, notBUG_ON, for runtime-recoverable conditions.
Memory and API
- Pair
kmalloc/kzalloc/vmallocwith the matching free, check forNULL, and unwind through a cleanup pattern orgoto err_*ladder with no silent leak path. - Use
strscpy/scnprintf, neverstrcpy/sprintf. - Cross the user/kernel boundary with
copy_from_user/copy_to_userand check the return; no rawmemcpy. - Choose DMA mapping by lifetime:
dma_alloc_coherent/dma_poolfor long-lived structures the CPU and device touch in parallel (ring descriptors, mailboxes);dma_map_single/dma_map_sgwith the matchingdma_unmap_*for one-shot transfers. Coherent memory can be expensive and page-granular, so it is not the default. - Never DMA to or from stack, static or module-image, vmalloc, or kmap addresses: they may map differently from the rest of physical memory, and unaligned buffers corrupt shared cachelines on DMA-incoherent CPUs.
dma_map_singlebuffers come from a physically contiguous source (kmalloc or the page allocator). - Give every
printka level (pr_err,pr_warn,dev_err); rate-limit repeated noise with*_ratelimited.
Build and Modules
Kconfigentries havehelptext and a depends-on chain that matches the code; noselectof unselectable symbols.Makefileusesobj-$(CONFIG_FOO); build both built-in and as a module whenCONFIG_FOO=mis meaningful.- New modules declare
MODULE_LICENSE,MODULE_AUTHOR, andMODULE_DESCRIPTION. - No new
EXPORT_SYMBOLwithout justification; preferEXPORT_SYMBOL_GPL.
Concurrency
- A patch touching locking, IRQ context, RCU, atomics, or scheduler hooks needs a
qa-tracepass before commit (ship-commit"Review Once"). - Each added cancel, disable, or barrier needs a producer the caller or core does not already exclude; otherwise drop it and its race claim.
- Delete a flag or guard that existing state already implies; prove it through every caller's locking.
- Check any locking claim, yours or a reviewer's, against the target tree's version; lock types change across releases.
- Mark accesses per
tools/memory-model/Documentation/access-marking.txt, a four-way choice: - Plain C when a held lock or seqlock excludes the access, for init-before-publication or cleanup, for CPU- or task-private data, or with no concurrent store; marking these hides real bugs from KCSAN.
READ_ONCE/WRITE_ONCEwhen the race is intentional and the value is load-bearing for the concurrency design.data_race()(or__data_racy) when the race is intentional and the value is diagnostic, re-validated against a marked reload, or feeds an error-tolerant heuristic;data_race(READ_ONCE(x))when both apply.- Comment each marking's reason and document the design with
ASSERT_EXCLUSIVE_WRITER/ASSERT_EXCLUSIVE_ACCESS. KCSAN is an input, not the arbiter: its silence is not correctness, and churning markings to quiet it does not help. - Order with
smp_*barriers, nevervolatile.
Error Paths and Cleanup
When a patch adds or changes out_*: labels, goto err_*, or if (failed) cleanup(...), run every check below; an "undo" helper is not automatically the inverse of the step it undoes.
- Read the cleanup helper end to end and list every side effect: locks taken and released, counters, list mutations, conditional state changes, the return value's meaning. Never infer them from its name (a
*_put_pageshelper may also restore reservations, drop a refcount, or free the object). - Search the file for
out_,goto err_,unwind, and the struct's other failure paths, and mirror the existing pattern instead of inventing one. - Enumerate the cross-product of every input that selects a path (e.g.
gbl_chg ∈ {0, >0}×map_chg ∈ {0, 1}×max_hpages ∈ {-1, finite}). Every cell needs a documented cleanup; "shouldn't happen" or "covered by the other branch" is a bug. - For each cell, list the concurrent operations on the same struct that can race with the failure (
*_put_pages,*_unreserve_pages, free to buddy, cgroup migration) and walk the cleanup as if each fires between the failed step and the unwind. It must stay correct and create no phantom state, such as incrementing a reserve count after a concurrent free drained the pool. - When one local pointer would span two charges (regular vs reserved, vmalloc vs kmalloc, DMA vs CPU), use separate locals per ownership domain; migration, preemption, or an interrupt between the charges can rebind ownership.
- Keep severity attached to the bug: if v1 was wrong, v2 has the same severity until proven otherwise.
- Do not bundle unrelated fixes, but bundle fixes that share the change's charge, failure, or commit window (the same
out_uncharge_*ladder); a fix in another function ships separately.
Commit Message
Follow Documentation/process/submitting-patches.rst and 5.Posting.rst.
Subject:
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/lint-kernel/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/lyther/agent-surface/lint-kernel)