]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
s390/cpum_sf: Simplify release of SDBs and SDBTs
authorThomas Richter <tmricht@linux.ibm.com>
Tue, 19 Nov 2024 12:22:47 +0000 (13:22 +0100)
committerHeiko Carstens <hca@linux.ibm.com>
Thu, 21 Nov 2024 11:44:07 +0000 (12:44 +0100)
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 <tmricht@linux.ibm.com>
Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/kernel/perf_cpum_sf.c

index 0cde42f8af6ef582dc72747427655a26c58f0d4e..1e99514fb7ae3db42cef70e34255b4432e76c536 100644 (file)
@@ -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));
 }