Response cache stats#206
Conversation
|
Hi @acmel, thank you for the PR. Here's gemini's output via the Other than that, the db changes look safe. @rgushchin I am not sure how you handle the database migrations for adding new columns but if they are allowed to be null, then it should be fine. |
|
Thanks for the review, Derek! On the two Gemini findings:
On the migration question: yes, all four new columns ( |
|
I'll force push now with the merge conflicts resolved. |
19cd4d5 to
dccf6e0
Compare
find_best_review_for_patch_refs() used a broken status-preference heuristic that could select a stale "Reviewed" result from a previous run over the most recent "Failed" retry. Replace with a simple highest-id comparison so the most recent review always wins. rerun_patchset() only reset the patchset-level status but left per-patch statuses (and apply_error) from the previous run. Add a step to reset all patches to "Pending" with apply_error cleared. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Derek Barbosa <debarbos@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add layered configuration loading so users can place personal overrides (credentials, paths, custom settings) in ~/.config/sashiko/Settings.toml without modifying the repo-level Settings.toml. Settings are loaded in order (last wins): 1. ./Settings.toml — repo-level defaults 2. ~/.config/sashiko/Settings.toml — user overrides (optional) 3. SASHIKO__* env vars — per-invocation overrides The user config path follows the XDG Base Directory Specification: $XDG_CONFIG_HOME/sashiko/Settings.toml if set, else ~/.config/sashiko/. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Derek Barbosa <debarbos@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…cache_stats setting Extend CacheStats with two new fields: `misses` (requests that missed the cache and triggered an API call) and `tokens_stored` (total tokens in newly created cache entries, representing future savings potential). Add `show_cache_stats` boolean to AiSettings (default false) as the gate for all cache statistics display in CLI, web UI, and daemon logs. Add `fmt_tokens()` helper for human-readable token counts (42.1k, 1.5M). Document the response_cache, response_cache_ttl_days, and show_cache_stats settings in Settings.toml with commented examples. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Derek Barbosa <debarbos@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add four nullable INTEGER columns to the reviews table via migration: cache_hits, cache_misses, cache_tokens_saved, cache_tokens_stored. Extend complete_review() with an optional ReviewCacheStats parameter to populate these columns. In process_patch_review(), snapshot CacheStats before run_review_tool() and compute the delta after it returns. This gives per-patch cache hit/miss/tokens data without new synchronization — atomic counters only grow, so the difference is the per-review contribution. Gate the patchset-level cache summary log and add per-patch cache log lines behind the show_cache_stats setting. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Derek Barbosa <debarbos@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wire show_cache_stats through the API layer: add it to AppState, pass it
from main.rs, and inject it into patchset detail responses alongside the
existing smtp_enabled and dry_run flags.
Extend the reviews SELECT in get_patchset_details() with cache_hits,
cache_misses, cache_tokens_saved, cache_tokens_stored columns.
In the CLI, extend print_patch_line() with a cache_suffix parameter.
When show_cache_stats is enabled, build per-patch suffixes like
"{cache: 7/7 hits, 42.1k tokens saved}" and display a patchset-level
summary line with hit rate and token totals.
Add fmt_tokens() helper for human-readable token counts (k/M suffixes).
Document the response cache feature and previously undocumented CLI
commands (rerun, cancel, local, --watch) in README.md.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Derek Barbosa <debarbos@redhat.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When show_cache_stats is enabled in the API response, the web UI now shows cache statistics via tap/click-to-expand panels that work on both desktop and mobile browsers. Per-patch: each patch row in the summary table shows a ▶ indicator when cache stats are available. Tapping it expands an animated stats panel with a 3-column grid (hits, misses, hit rate, tokens saved, tokens stored, total calls) and a hit-rate progress bar. The row click still scrolls to the patch detail as before. Patchset-level: the Model line in the metadata section gains a ▶ indicator that expands to show aggregate cache stats across all patches in the series. Uses CSS max-height/opacity transitions for smooth animation. Adds fmtTokens() JS helper for human-readable token counts (k/M suffixes). Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Derek Barbosa <debarbos@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The cancel_patchset endpoint was the only mutation endpoint missing the .to_canonical() call before .is_loopback(), causing 403 Forbidden when a CLI on the same machine connects via IPv4 (127.0.0.1) to a dual-stack server (bound to ::). The IPv4 address arrives as the mapped ::ffff:127.0.0.1, which is_loopback() rejects. The submit, rerun_patch, and rerun_patchset endpoints already use to_canonical() — this was simply missed on cancel. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Derek Barbosa <debarbos@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
cancel_patchset returned the same "not in a cancellable state" message whether the patchset didn't exist or existed in a non-cancellable status. Change the DB function to return Option<bool> (None = not found, Some(true) = cancelled, Some(false) = wrong status) so the API can return 404 and the CLI can show "Patchset N not found". Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Derek Barbosa <debarbos@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The reviewer only checked for cancellation after completing all patch reviews, so a cancelled patchset would keep submitting LLM requests until every patch was processed. Add a cancellation check before each process_patch_review call in both the concurrent and main worker loops — when cancellation is detected, the shared job queue is drained so all workers stop promptly. This does not interrupt an in-flight LLM call (that would require threading a CancellationToken through the AI provider), but it stops between patches, which is the useful granularity. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Derek Barbosa <debarbos@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fetching custom remotes (e.g. pahole) from git.kernel.org over IPv6 can be sluggish, and the sequential ensure_remote() calls in main() blocked the Reviewer service from starting until all fetches completed. This meant no patchsets were picked up while waiting for a slow git fetch. Move the Reviewer::new() + start() before the custom remote loop and spawn the remote fetches in a background task. The reviewer already calls ensure_remote() itself when it encounters a RemoteTarget baseline candidate, so patchsets that need a custom remote will wait for the fetch at that point — while patchsets targeting other repos proceed without delay. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Derek Barbosa <debarbos@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add an "Opening response cache" message before the DB initialization begins and a "Response cache ready" summary when it completes, reporting the number of cached entries, file size (MB/GB), lifetime tokens saved, and elapsed wall-clock time. This makes it easy to spot slow cache opens and provides useful diagnostics at startup. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Derek Barbosa <debarbos@redhat.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
dccf6e0 to
993c672
Compare
|
I rebased it to resolve some conflicts, have been using it for a while. Also have a ai_pricing branch on top and now I'm working on LFU/LRU'ing the response cache contents, with a cache contents page that will show which are the entries most used, to help understand where is that all those hits are coming from :-) |
|
Thank for the PR, I’ll try to merge it soon. Sorry, busy with some other stuff. But I still do’t fully understand how this cache works: I don’t think sashiko sends too many identical requests. Am I wrong? Can you provide some examples? |
|
On Fri, May 22, 2026 at 12:32:14PM -0700, Roman Gushchin wrote:
[8522129?s=20&v=4] rgushchin left a comment
[1](sashiko-dev/sashiko#206)
Thank for the PR, I’ll try to merge it soon. Sorry, busy with some
other stuff. But I still do’t fully understand how this cache works: I
don’t think sashiko sends too many identical requests. Am I wrong? Can
you provide some examples?
So, the work I'm doing now helps shed light on this, which is to have a
page with the response cache contents and how many times each entry was
hit, etc.
Maybe I can add these to the existing PR and that would answer all this
questions, for instance, in my local system, that you can access if you
have IPv6 connectivity:
http://[2804:2bf0:60e7:ae00:ab42:4fdd:ae0:7df6]:8080/#/cache
It reads:
Response Cache
Total Entries
35,743
Total Hits
8,250
Tokens Saved
1703.0M
DB Size
7821732.0KB
Hit Distribution
Entries by Model
Top Entries by Hit Count
Hash Context Model Hits Tokens Saved Created Last Accessed
780fe9378705 [ps:68 p:17 s:0] gemini-3.1-pro-preview 24 4.4k 5/22/2026, 3:44:05 PM 5/22/2026, 4:14:43 PM
add23ce87769 [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 133.8k 5/22/2026, 3:59:06 PM 5/22/2026, 4:15:00 PM
623c639d42d1 [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 133.0k 5/22/2026, 3:58:52 PM 5/22/2026, 4:15:00 PM
fb39d0f4f8ac [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 132.4k 5/22/2026, 3:58:45 PM 5/22/2026, 4:15:00 PM
652b593232c8 [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 131.6k 5/22/2026, 3:58:36 PM 5/22/2026, 4:15:00 PM
94e6943e5378 [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 130.9k 5/22/2026, 3:58:30 PM 5/22/2026, 4:15:00 PM
c052c6c95c00 [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 130.6k 5/22/2026, 3:58:25 PM 5/22/2026, 4:14:59 PM
f67e21f84c66 [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 129.8k 5/22/2026, 3:58:19 PM 5/22/2026, 4:14:59 PM
5dce50368868 [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 129.5k 5/22/2026, 3:58:13 PM 5/22/2026, 4:14:59 PM
761d123827e5 [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 128.6k 5/22/2026, 3:58:09 PM 5/22/2026, 4:14:59 PM
5aecbb37d6a7 [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 128.3k 5/22/2026, 3:57:59 PM 5/22/2026, 4:14:58 PM
9de2a8404cad [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 127.4k 5/22/2026, 3:57:54 PM 5/22/2026, 4:14:58 PM
14f9906e92d5 [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 126.2k 5/22/2026, 3:57:42 PM 5/22/2026, 4:14:58 PM
955ad51e82d9 [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 125.4k 5/22/2026, 3:57:33 PM 5/22/2026, 4:14:58 PM
ac0d5a2abcbf [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 123.8k 5/22/2026, 3:57:23 PM 5/22/2026, 4:14:57 PM
e84dbc2463ac [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 102.6k 5/22/2026, 3:57:05 PM 5/22/2026, 4:14:57 PM
15ac38ff0dac [ps:68 p:17 s:1] gemini-3.1-pro-preview 23 83.3k 5/22/2026, 3:56:40 PM 5/22/2026, 4:14:56 PM
See the number of hits? the patch series I'm working on has 27 entries
and I'm submitting it several times, my workflow is:
1) Write patches with Claude Code
2) ask Claude to submit to local sashiko, using 'sashiko-cli submit FIRST^..LAST-SHA
3) Claude immediately schedules a cron job to look at 'sashiko-cli show
--issues', that I introduced previously and is already in sashiko
upstream.
4) Claude immediately analyses what sashiko reported and works with me
to decide on how to address it, fixing stuff and giving credit to
Sashiko # running on a local machine
5) goto 2
If you click on the first line, the one with hash 780fe9378705, you see
the following, and look at the very end for some extra stats:
780fe93787051e48f11a707bff80ab960dcfbc99bc150aa15a513f790f408dc0
Request
System Prompt
You are an AI assistant preparing a Linux kernel patch review.
Review the provided Patch and select all potentially relevant subsystem guides from the index below.
CRITICAL BIAS RULE: You MUST err on the side of inclusion. Only exclude a guide if it is 100% irrelevant to the modified code. If there is any doubt, include the file.
You MUST respond with ONLY a JSON object, no other text. Example:
```json
{"selected_prompts": ["networking.md", "locking.md"]}
```
Messages
user:
<subsystem_guide_index>
# Subsystem Guide Index
Load subsystem guides from the prompt directory based on what the code touches.
Each guide contains subsystem-specific invariants, API contracts, and common
bug patterns. Each subsystem guide may reference additional pattern files to
load conditionally.
The triggers column below includes both path names, function calls, and symbols
regexes
## Subsystem Guides
| Subsystem | Triggers | File |
|-----------|----------|------|
| Networking Core | net/, skb_, sockets, xfrm, dst_, sock_put, release_sock, pskb_may_pull, SNMP_*_STATS | networking-core.md |
| Networking Drivers | drivers/net/, ethtool_ops, net_device_ops | networking-drivers.md |
| Netlink | `genl_`, `nla_`, `NLA_`, `NLM_F_`, `nlmsg_`, `netlink_callback`, Documentation/netlink/specs/, files marked `YNL-GEN` | netlink.md |
| MM Page Tables | `pte_*`, `pmd_*`, `pud_*`, `set_pte`, `ptep_*`, `tlb_*`, `page_vma_mapped_walk`, `walk_page_range`, `zap_pte_range`, mm/memory.c, mm/mprotect.c, mm/pagewalk.c | mm-pagetable.md |
| MM Folio/Page Cache | `folio_*`, `page_folio`, `compound_head`, `filemap_*`, `xa_*`, `xas_*`, `page_cache_*`, mm/filemap.c, mm/swap.c, mm/truncate.c | mm-folio.md |
| MM Large Folios/THP/Hugetlb | `huge_memory`, `hugetlb`, `split_huge_*`, `folio_test_large`, `hstate`, PMD sharing, mm/huge_memory.c, mm/hugetlb.c, mm/memory-failure.c | mm-largepage.md |
| MM VMA Operations | `vma_*`, `mmap_*`, `vm_area_struct`, `vm_flags`, `anon_vma`, `maple_tree`, mm/vma.c, mm/mmap.c, mm/mmap_lock.c | mm-vma.md |
| MM Allocation | `alloc_pages`, `__GFP_*`, `kmalloc`, `kmem_cache_*`, `slub`, `vmalloc`, `zone_watermark`, `mempool`, `memblock`, mm/page_alloc.c, mm/slub.c, mm/vmalloc.c | mm-alloc.md |
| MM Reclaim/Swap/Migration | `vmscan`, `shrink_*`, `lru_*`, `swap_*`, `shmem_*`, `mem_cgroup_*`, `writeback`, `migrate_*`, mm/vmscan.c, mm/swap_state.c, mm/migrate.c, mm/memcontrol.c | mm-reclaim.md |
| VFS | inode, dentry, vfs_, fs/*.c | vfs.md |
| Locking | spin_lock*, mutex_*, rwsem*, seqlock*, *seqcount* | locking.md |
| Scheduler | kernel/sched/, sched_, schedule, *wakeup* | scheduler.md |
| Timers | timer_list, timer_setup, mod_timer, del_timer, hrtimer, delayed_work | timers.md |
| BPF | kernel/bpf/, tools/lib/bpf/, tools/testing/selftests/bpf, bpf, verifier | bpf.md |
| RCU | rcu*, call_rcu, synchronize_rcu, kfree_rcu, kvfree_call_rcu | rcu.md |
| Encryption | crypto, fscrypt_ | fscrypt.md |
| Tracing | trace_, tracepoints | tracing.md |
| Workqueue | kernel/workqueue.c, work_struct | workqueue.md |
| Syscalls | `SYSCALL_DEFINE`, `copy_from_user`, `copy_to_user`, `get_user`, `put_user`, any change to syscall parameter validation | syscall.md |
| btrfs | fs/btrfs/ | btrfs.md |
| DAX | dax operations | dax.md |
| Block/NVMe | block layer, nvme | block.md |
| DRM/GPU | drivers/gpu/drm/, drm_atomic_, drm_crtc_, hwseq, hw_sequencer | drm.md |
| NFSD | fs/nfsd/*, fs/lockd/* | nfsd.md |
| SunRPC | net/sunrpc/* | sunrpc.md |
| io_uring | io_uring/, io_uring_, io_ring_, io_sq_, io_cq_, io_wq_, IORING_ | io_uring.md |
| Cleanup API | `__free`, `guard(`, `scoped_guard`, `DEFINE_FREE`, `DEFINE_GUARD`, `no_free_ptr`, `return_ptr` | cleanup.md |
| RCU lifecycle | `call_rcu(`, `kfree_rcu(`, `synchronize_rcu(`, `rhashtable_*` + `call_rcu`, `hlist_del_rcu` + `call_rcu`, `list_del_rcu` + `call_rcu` | rcu.md |
| Power Domains | drivers/pmdomain/, pm_genpd_, of_genpd_, exynos_pd_ | pmdomain.md |
| PM Runtime | include/linux/pm_runtime.h, pm_runtime_, __pm_runtime_, rpm_idle, rpm_suspend, rpm_resume | pm.md |
| Sysfs | fs/sysfs/, sysfs_create_group, sysfs_update_group, attribute_group, is_visible | sysfs.md |
| CXL | drivers/cxl/, cxl_, hmat_get_extended_linear_cache_size | cxl.md |
| Bluetooth | net/bluetooth/, hci_, HCI_LE_ADV, adv_instances, cur_adv_instance | bluetooth.md |
| TTY/Serial | drivers/tty/, uart_add_one_port, uart_ops, serial_core | tty.md |
| PCI | drivers/pci/, pci_epc_, pci_epf_, pci_ep_ | pci.md |
| SMB/ksmbd | fs/smb/server/, ksmbd_, smb_direct_ | smb-ksmbd.md |
| Open Firmware (DT) | drivers/of/, of_node, of_find_, of_get_, of_parse_, for_each_child_of_node, for_each_available_child_of_node, of_node_put, of_node_get | of.md |
| Perf Tools | tools/perf/, openat, fdopendir, closedir | perf.md |
| MIPS | arch/mips/, tlb_probe, tlb_read, tlb_write_indexed, write_c0_entryhi, read_c0_index, TLBP, TLBR, TLBWI | mips.md |
| hwmon | drivers/hwmon/, hwmon_*, asus-ec-sensors, ec_board_info | hwmon.md |
| Media/Video | drivers/media/, v4l2_, V4L2_PIX_FMT_, iris_, video_device | media.md |
| Wireless/mac80211 | drivers/net/wireless/, net/mac80211/, BSS_CHANGED_, vif_cfg_changed, link_info_changed, bss_info_changed | wireless.md |
| Selftests | tools/testing/selftests/, TEST_PROGS, TEST_FILES, TEST_GEN_FILES | selftests.md |
| IRQ Chip | drivers/irqchip/, gic_, its_, irq_chip, irq_domain | irqchip.md |
| CAN | drivers/net/can/, can_, canfd_, rcar_canfd, socketcan | can.md |
| DT Bindings | Documentation/devicetree/bindings/, *.yaml in devicetree | dt-bindings.md |
| USB Storage | drivers/usb/storage/, unusual_devs.h, UNUSUAL_DEV, USB_SC_, USB_PR_ | usb-storage.md |
| ATA/libata | drivers/ata/, ata_dev_, ata_port_, ata_read_log_, ATA_QUIRK_ | ata.md |
| I/O Accessors | writesl, readsl, writesw, readsw, writesb, readsb, __raw_writel, __raw_readl, FIFO | io-accessors.md |
| DPLL | drivers/dpll/, dpll_, zl3073x_, ZL_REG_, ZL_INFO_ | dpll.md |
| Kconfig | Kconfig, `config `, `select `, `depends on `, `tristate `, `bool ` | kconfig.md |
| I3C | drivers/i3c/, i3c_master_, i3c_device_, i2c_adapter, svc-i3c-master | i3c.md |
| Input | drivers/input/, edt-ft5x06, touchscreen@, report-rate-hz | input.md |
| Objtool | tools/objtool/, INSN_BUG, INSN_TRAP, decode.c | objtool.md |
| KHO (Kexec Handover) | lib/test_kho.c, kho_, kho_is_enabled, kho_retrieve_subtree, kho_preserve_folio, kho_add_subtree, register_kho_notifier | kho.md |
| I2C | drivers/i2c/, i2c_*, | i2c.md |
| Rust | any Rust code | rust.md |
## Optional Patterns
Load only when explicitly requested in the prompt:
- **Subjective Review** (subjective-review.md): Subjective general assessment
</subsystem_guide_index>
<patch>
commit f8d99f198a85e07e09bc986d3c8ca915ab4a68b4
Author: Arnaldo Carvalho de Melo ***@***.***>
Date: Sat May 2 14:24:02 2026 -0300
perf header: Propagate feature section processing errors
perf_session__read_header() discards the return value from
perf_header__process_sections(), so any error from a feature
section processor (process_nrcpus, process_compressed, etc.)
is silently ignored and the session opens as if nothing went
wrong.
This defeats the validation added by subsequent commits in this
series: a crafted perf.data that fails a feature section check
would still be processed with partially-initialized state.
Check the return value and fail the session if any feature
section processor returns an error.
For truncated files (data.size == 0, i.e. recording was
interrupted before the header was finalized), skip feature
section processing entirely and clear the feature bitmap so
tools use their "feature not present" fallbacks instead of
accessing uninitialized env fields.
Change the feature processor stubs for optional libraries
(libtraceevent, libbpf) from returning -1 to returning 0,
so that perf.data files containing these features can still be
opened on builds without the optional library — the feature is
simply skipped rather than causing a fatal error.
Also fix evlist__prepare_tracepoint_events() failure to return
-EINVAL instead of -ENOMEM, since the failure is a data
validation issue, not an allocation failure.
Fixes: 1c0b04d12ae9 ("perf tools: Add perf_session__read_header function")
Cc: Ian Rogers ***@***.***>
Cc: Jiri Olsa ***@***.***>
Cc: Namhyung Kim ***@***.***>
Assisted-by: Claude Opus 4.6 (1M context) ***@***.***>
Signed-off-by: Arnaldo Carvalho de Melo ***@***.***>
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index a5acdcb1a4c02fca..01288c08b6e09284 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2748,8 +2748,9 @@ static int process_tracing_data(struct feat_fd *ff __maybe_unused, void *data __
return ret < 0 ? -1 : 0;
#else
- pr_err("ERROR: Trying to read tracing data without libtraceevent support.\n");
- return -1;
+ /* Not an error — the feature is simply unsupported in this build */
+ pr_debug("Tracing data present but libtraceevent not available, skipping.\n");
+ return 0;
#endif
}
@@ -3643,8 +3644,9 @@ static int process_bpf_prog_info(struct feat_fd *ff __maybe_unused, void *data _
up_write(&env->bpf_progs.lock);
return err;
#else
- pr_err("ERROR: Trying to read bpf_prog_info without libbpf support.\n");
- return -1;
+ /* Not an error — the feature is simply unsupported in this build */
+ pr_debug("BPF prog info present but libbpf not available, skipping.\n");
+ return 0;
#endif // HAVE_LIBBPF_SUPPORT
}
@@ -3712,8 +3714,9 @@ static int process_bpf_btf(struct feat_fd *ff __maybe_unused, void *data __mayb
free(node);
return err;
#else
- pr_err("ERROR: Trying to read btf data without libbpf support.\n");
- return -1;
+ /* Not an error — the feature is simply unsupported in this build */
+ pr_debug("BTF data present but libbpf not available, skipping.\n");
+ return 0;
#endif // HAVE_LIBBPF_SUPPORT
}
@@ -4900,7 +4903,7 @@ int perf_session__read_header(struct perf_session *session)
struct perf_file_header f_header;
struct perf_file_attr f_attr;
u64 f_id;
- int nr_attrs, nr_ids, i, j, err;
+ int nr_attrs, nr_ids, i, j, err = -ENOMEM;
int fd = perf_data__fd(data);
session->evlist = evlist__new();
@@ -4920,6 +4923,7 @@ int perf_session__read_header(struct perf_session *session)
return err;
}
+ err = -ENOMEM;
if (perf_file_header__read(&f_header, header, fd) < 0)
return -EINVAL;
@@ -4997,15 +5001,36 @@ int perf_session__read_header(struct perf_session *session)
lseek(fd, tmp, SEEK_SET);
}
+ /*
+ * Skip feature section processing for truncated files
+ * (data.size == 0 means recording was interrupted). The
+ * section table is unreliable in that case, and the event
+ * data can still be processed without the feature headers.
+ * Clear the bitmap so has_feat() returns false and tools
+ * use their "feature not present" fallbacks instead of
+ * accessing uninitialized env fields.
+ */
+ if (f_header.data.size == 0) {
+ bitmap_zero(header->adds_features, HEADER_FEAT_BITS);
+ } else {
#ifdef HAVE_LIBTRACEEVENT
- perf_header__process_sections(header, fd, &session->tevent,
- perf_file_section__process);
+ err = perf_header__process_sections(header, fd, &session->tevent,
+ perf_file_section__process);
+ if (err < 0)
+ goto out_delete_evlist;
- if (evlist__prepare_tracepoint_events(session->evlist, session->tevent.pevent))
- goto out_delete_evlist;
+ if (evlist__prepare_tracepoint_events(session->evlist,
+ session->tevent.pevent)) {
+ err = -EINVAL;
+ goto out_delete_evlist;
+ }
#else
- perf_header__process_sections(header, fd, NULL, perf_file_section__process);
+ err = perf_header__process_sections(header, fd, NULL,
+ perf_file_section__process);
+ if (err < 0)
+ goto out_delete_evlist;
#endif
+ }
return 0;
out_errno:
@@ -5014,7 +5039,7 @@ int perf_session__read_header(struct perf_session *session)
out_delete_evlist:
evlist__delete(session->evlist);
session->evlist = NULL;
- return -ENOMEM;
+ return err;
}
int perf_event__process_feature(const struct perf_tool *tool __maybe_unused,
</patch>
Response
{
"content": "{\"selected_prompts\": [\"perf.md\"]}",
"thought": "**Analyzing the Patch's Impact on the Perf Tools Documentation**\n\nOkay, so this patch is touching `tools/perf/util/header.c`. My initial thought is to figure out the relevant documentation. Let's see... I'll check the subsystem guide index. Ah, right, the guide has an entry for \"Perf Tools\" which covers `tools/perf/`, as well as those `openat`, `fdopendir`, and `closedir` functions. And the associated documentation file for that subsystem is `perf.md`. Now, the crucial step is to connect the dots: the patch is modifying a file within `tools/perf/`, and the subsystem guide directly links `tools/perf/` to the `perf.md` documentation. It's pretty straightforward, actually, given the structure. Therefore, I'm confident that updating `perf.md` is the correct action to address this patch.\n\n\n",
"usage": {
"completion_tokens": 11,
"prompt_tokens": 4393,
"total_tokens": 4492
}
}
Token Usage
Prompt Tokens
4,393
Completion Tokens
11
The second entry:
|
|
And here are some lines from the sashiko output, as you can see there it finds hits in the cache for things in the current session (supposedly it submitted it multiple times, perhaps for different patches the same prompt?) and some hits are for the same request submitted on a previous session, for the a previous version of the patchset being submitted, I'll put the branch I have with the cache stats page available in my repo, so you can look at it and see if it makes sense, from your point of view, or if something is wrong. It all seems to work, at least I'm getting good review that I then address, resubmit, notice that it solved the previous report, get new reports, rinse, repeat. 2026-05-22T20:02:01.965359Z INFO sashiko::ai::cache: Cache hit [0665e4942100] (previous session) — 36.458 tokens saved (total previous session: 214.707.298) |
|
An excerpt from a Claude session that is talking with sashiko: ● Patch 15 came back clean (Reviewed). Three left: 6, 25, 26 still in review. No new findings. Will check again in 4 minutes. ✻ Cogitated for 8s ✻ Running scheduled task (May 22 4:56pm) ● Bash(sashiko-cli show 68 2>&1 | head -55) ● Patch 26 reviewed clean. Two left: 6 and 25 still in review. Almost done. Will check again in 4 minutes. ✻ Cogitated for 8s ✻ Running scheduled task (May 22 5:00pm) ● Bash(sashiko-cli show 68 2>&1 | head -55) ● No change — patches 6 and 25 still in review. Will check again in 4 minutes. ✻ Baked for 9s ✻ Running scheduled task (May 22 5:04pm) ● Bash(sashiko-cli show 68 2>&1 | head -55) ● Review is complete — all 27 patches have a final status. No new "Issues Found" since last check (6 and 25 both failed infra). Final tally:
One actionable fix was found and already applied: patch 19's lseek pipe mode regression. All other findings were pre-existing, theoretical TOCTOU, or already addressed. ● CronDelete(0d31cf39) ● Cron job stopped. Submission 68 review complete — no new actionable issues beyond the patch 19 lseek fix already applied. ✻ Cogitated for 19s ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── perf-tools-next ── acme@number:~$ |
|
cache_lru_eviction branch has the page with the cache contents and the reference counting of response cache entries, etc, look at the bottom of the main page, there is a "Cache" link next to the other stats links. |
● Response cache statistics, startup improvements, and bug fixes
This series adds observability into the response cache, fixes several
bugs found during testing, and improves daemon startup behavior.
Response cache statistics (patches 3-6)
Track per-review cache hit/miss/token counts in the database and expose
them through the API, CLI (sashiko show), and web UI. The web UI uses
tap-to-expand panels with hit-rate progress bars — available per-patch
and aggregated at the patchset level. All cache stats display is gated
behind the show_cache_stats setting (default off).
Example sashiko-cli show output with cache stats enabled:
Patchset Details:
ID: 61
Subject: perf session: Add minimum event size and alignment validation
Author: Arnaldo Carvalho de Melo acme@redhat.com
Status: Failed
Date: 2026-05-19 14:48:09
Patches (28):
[1] perf session: Add minimum event size and alignment validation (Failed) [Failed] {cache: 502/543 hits, 23.1M tokens saved}
[2] perf tools: Fix event_contains() macro to verify full field extent (Reviewed) [Issues Found] {cache: 413/807 hits, 15.7M tokens saved}
...
[27] perf kwork: Bounds check work->cpu before indexing cpus_runtime[] (Reviewed) [Reviewed] {cache: 3667/4155 hits, 163.0M tokens saved}
[28] perf test: Add truncated perf.data robustness test (Reviewed) [Issues Found] {cache: 3080/3334 hits, 134.8M tokens saved}
Cache: 64296/78526 hits (81.9%), 2841.6M tokens saved, 647.2M tokens stored
Model: gemini-3.1-pro-preview
In the web interface, these stats are available by tapping the ▶ indicator
next to each patch row for per-patch details, and on the Model: line in
the patchset header for aggregate stats across all patches.
Startup and operational improvements (patches 2, 11, 12)
personal credentials and overrides don't live in the repo checkout
immediately instead of blocking on slow git.kernel.org IPv6 fetches
Bug fixes (patches 1, 7-10)
"Failed" retry after patchset resubmission
servers (missing to_canonical() call)
is cancelled
Docs (patch 0)
I'll work now on adding limits to the cache and hopefully some sort of LRU to keep LLM requests that have tons of hits while making space for new entries by purging seldom used ones and then make the request cache a default feature with a given reasonable size based on the experience we gather by exposing the stats using this patch series publicly, which is something I encourage the admin for https:://sashiko.dev to do when upgrading to the next release.
Saving "I know that this is not something introduced by your patch, but there is this pre-existing problem that I analysed and found problematic, can you postpone submitting this series and fixing just this one more issue, pretty please?" cases in some sort of database that gets exposed in the https://sashiko.dev site in one special session of "please help picking up from this cache of query/response tokens cache of problems" is another idea I plan to work on Real Soon Now. :-)
Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com