From: Thomas Richter Date: Tue, 19 Nov 2024 12:22:47 +0000 (+0100) Subject: s390/cpum_sf: Simplify release of SDBs and SDBTs X-Git-Tag: v6.13-rc1~34^2~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7bc1ee28f4d21fc1e2f3d09534baf86ce7f3ba5e;p=thirdparty%2Fkernel%2Flinux.git s390/cpum_sf: Simplify release of SDBs and SDBTs Free_sampling_buffer() releases the Sampling Data Buffers (SDBs) and Sampling Data Buffer Table (SDBTs) allocated at event initialization. Both buffers are of PAGE_SIZE bytes. Each SDBT consists of 512 entries. The first 511 entries point to SDBs the last entry points to a successor SDBT. The last SDBT in the list points to the origin of all SDBTs. SDBTs do not contain holes, that is an entry always points to a SDB. If less than 511 SDBs have been allocation, the last entry points to the origin SDBT. Simplify the release of the SDBs and SDBTs, walk along the SDBT chain, release SDBs and SDBTs and stop when reaching the origin again. Signed-off-by: Thomas Richter Reviewed-by: Sumanth Korikkar Signed-off-by: Heiko Carstens --- diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index 0cde42f8af6ef..1e99514fb7ae3 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -180,39 +180,27 @@ static int sf_buffer_available(struct cpu_hw_sf *cpuhw) */ static void free_sampling_buffer(struct sf_buffer *sfb) { - unsigned long *sdbt, *curr; - - if (!sfb->sdbt) - return; + unsigned long *sdbt, *curr, *head; sdbt = sfb->sdbt; - curr = sdbt; - + if (!sdbt) + return; + sfb->sdbt = NULL; /* Free the SDBT after all SDBs are processed... */ - while (1) { - if (!*curr || !sdbt) - break; - - /* Process table-link entries */ + head = sdbt; + curr = sdbt; + do { if (is_link_entry(curr)) { + /* Process table-link entries */ curr = get_next_sdbt(curr); - if (sdbt) - free_page((unsigned long)sdbt); - - /* If the origin is reached, sampling buffer is freed */ - if (curr == sfb->sdbt) - break; - else - sdbt = curr; + free_page((unsigned long)sdbt); + sdbt = curr; } else { /* Process SDB pointer */ - if (*curr) { - free_page((unsigned long)phys_to_virt(*curr)); - curr++; - } + free_page((unsigned long)phys_to_virt(*curr)); + curr++; } - } - + } while (curr != head); memset(sfb, 0, sizeof(*sfb)); }