Skip to content

Commit f5f4745

Browse files
committed
Merge tag 'mm-nonmm-stable-2024-11-24-02-05' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Pull non-MM updates from Andrew Morton: - The series "resource: A couple of cleanups" from Andy Shevchenko performs some cleanups in the resource management code - The series "Improve the copy of task comm" from Yafang Shao addresses possible race-induced overflows in the management of task_struct.comm[] - The series "Remove unnecessary header includes from {tools/}lib/list_sort.c" from Kuan-Wei Chiu adds some cleanups and a small fix to the list_sort library code and to its selftest - The series "Enhance min heap API with non-inline functions and optimizations" also from Kuan-Wei Chiu optimizes and cleans up the min_heap library code - The series "nilfs2: Finish folio conversion" from Ryusuke Konishi finishes off nilfs2's folioification - The series "add detect count for hung tasks" from Lance Yang adds more userspace visibility into the hung-task detector's activity - Apart from that, singelton patches in many places - please see the individual changelogs for details * tag 'mm-nonmm-stable-2024-11-24-02-05' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (71 commits) gdb: lx-symbols: do not error out on monolithic build kernel/reboot: replace sprintf() with sysfs_emit() lib: util_macros_kunit: add kunit test for util_macros.h util_macros.h: fix/rework find_closest() macros Improve consistency of '#error' directive messages ocfs2: fix uninitialized value in ocfs2_file_read_iter() hung_task: add docs for hung_task_detect_count hung_task: add detect count for hung tasks dma-buf: use atomic64_inc_return() in dma_buf_getfile() fs/proc/kcore.c: fix coccinelle reported ERROR instances resource: avoid unnecessary resource tree walking in __region_intersects() ocfs2: remove unused errmsg function and table ocfs2: cluster: fix a typo lib/scatterlist: use sg_phys() helper checkpatch: always parse orig_commit in fixes tag nilfs2: convert metadata aops from writepage to writepages nilfs2: convert nilfs_recovery_copy_block() to take a folio nilfs2: convert nilfs_page_count_clean_buffers() to take a folio nilfs2: remove nilfs_writepage nilfs2: convert checkpoint file to be folio-based ...
2 parents 7f4f3b1 + 2c259a9 commit f5f4745

File tree

102 files changed

+1951
-895
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+1951
-895
lines changed

Documentation/admin-guide/sysctl/kernel.rst

+9
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,15 @@ The upper bound on the number of tasks that are checked.
401401
This file shows up if ``CONFIG_DETECT_HUNG_TASK`` is enabled.
402402

403403

404+
hung_task_detect_count
405+
======================
406+
407+
Indicates the total number of tasks that have been detected as hung since
408+
the system boot.
409+
410+
This file shows up if ``CONFIG_DETECT_HUNG_TASK`` is enabled.
411+
412+
404413
hung_task_timeout_secs
405414
======================
406415

Documentation/core-api/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Library functionality that is used throughout the kernel.
5252
wrappers/atomic_bitops
5353
floating-point
5454
union_find
55+
min_heap
5556

5657
Low level entry and exit
5758
========================

Documentation/core-api/min_heap.rst

+300
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
============
4+
Min Heap API
5+
============
6+
7+
Introduction
8+
============
9+
10+
The Min Heap API provides a set of functions and macros for managing min-heaps
11+
in the Linux kernel. A min-heap is a binary tree structure where the value of
12+
each node is less than or equal to the values of its children, ensuring that
13+
the smallest element is always at the root.
14+
15+
This document provides a guide to the Min Heap API, detailing how to define and
16+
use min-heaps. Users should not directly call functions with **__min_heap_*()**
17+
prefixes, but should instead use the provided macro wrappers.
18+
19+
In addition to the standard version of the functions, the API also includes a
20+
set of inline versions for performance-critical scenarios. These inline
21+
functions have the same names as their non-inline counterparts but include an
22+
**_inline** suffix. For example, **__min_heap_init_inline** and its
23+
corresponding macro wrapper **min_heap_init_inline**. The inline versions allow
24+
custom comparison and swap functions to be called directly, rather than through
25+
indirect function calls. This can significantly reduce overhead, especially
26+
when CONFIG_MITIGATION_RETPOLINE is enabled, as indirect function calls become
27+
more expensive. As with the non-inline versions, it is important to use the
28+
macro wrappers for inline functions instead of directly calling the functions
29+
themselves.
30+
31+
Data Structures
32+
===============
33+
34+
Min-Heap Definition
35+
-------------------
36+
37+
The core data structure for representing a min-heap is defined using the
38+
**MIN_HEAP_PREALLOCATED** and **DEFINE_MIN_HEAP** macros. These macros allow
39+
you to define a min-heap with a preallocated buffer or dynamically allocated
40+
memory.
41+
42+
Example:
43+
44+
.. code-block:: c
45+
46+
#define MIN_HEAP_PREALLOCATED(_type, _name, _nr)
47+
struct _name {
48+
int nr; /* Number of elements in the heap */
49+
int size; /* Maximum number of elements that can be held */
50+
_type *data; /* Pointer to the heap data */
51+
_type preallocated[_nr]; /* Static preallocated array */
52+
}
53+
54+
#define DEFINE_MIN_HEAP(_type, _name) MIN_HEAP_PREALLOCATED(_type, _name, 0)
55+
56+
A typical heap structure will include a counter for the number of elements
57+
(`nr`), the maximum capacity of the heap (`size`), and a pointer to an array of
58+
elements (`data`). Optionally, you can specify a static array for preallocated
59+
heap storage using **MIN_HEAP_PREALLOCATED**.
60+
61+
Min Heap Callbacks
62+
------------------
63+
64+
The **struct min_heap_callbacks** provides customization options for ordering
65+
elements in the heap and swapping them. It contains two function pointers:
66+
67+
.. code-block:: c
68+
69+
struct min_heap_callbacks {
70+
bool (*less)(const void *lhs, const void *rhs, void *args);
71+
void (*swp)(void *lhs, void *rhs, void *args);
72+
};
73+
74+
- **less** is the comparison function used to establish the order of elements.
75+
- **swp** is a function for swapping elements in the heap. If swp is set to
76+
NULL, the default swap function will be used, which swaps the elements based on their size
77+
78+
Macro Wrappers
79+
==============
80+
81+
The following macro wrappers are provided for interacting with the heap in a
82+
user-friendly manner. Each macro corresponds to a function that operates on the
83+
heap, and they abstract away direct calls to internal functions.
84+
85+
Each macro accepts various parameters that are detailed below.
86+
87+
Heap Initialization
88+
--------------------
89+
90+
.. code-block:: c
91+
92+
min_heap_init(heap, data, size);
93+
94+
- **heap**: A pointer to the min-heap structure to be initialized.
95+
- **data**: A pointer to the buffer where the heap elements will be stored. If
96+
`NULL`, the preallocated buffer within the heap structure will be used.
97+
- **size**: The maximum number of elements the heap can hold.
98+
99+
This macro initializes the heap, setting its initial state. If `data` is
100+
`NULL`, the preallocated memory inside the heap structure will be used for
101+
storage. Otherwise, the user-provided buffer is used. The operation is **O(1)**.
102+
103+
**Inline Version:** min_heap_init_inline(heap, data, size)
104+
105+
Accessing the Top Element
106+
-------------------------
107+
108+
.. code-block:: c
109+
110+
element = min_heap_peek(heap);
111+
112+
- **heap**: A pointer to the min-heap from which to retrieve the smallest
113+
element.
114+
115+
This macro returns a pointer to the smallest element (the root) of the heap, or
116+
`NULL` if the heap is empty. The operation is **O(1)**.
117+
118+
**Inline Version:** min_heap_peek_inline(heap)
119+
120+
Heap Insertion
121+
--------------
122+
123+
.. code-block:: c
124+
125+
success = min_heap_push(heap, element, callbacks, args);
126+
127+
- **heap**: A pointer to the min-heap into which the element should be inserted.
128+
- **element**: A pointer to the element to be inserted into the heap.
129+
- **callbacks**: A pointer to a `struct min_heap_callbacks` providing the
130+
`less` and `swp` functions.
131+
- **args**: Optional arguments passed to the `less` and `swp` functions.
132+
133+
This macro inserts an element into the heap. It returns `true` if the insertion
134+
was successful and `false` if the heap is full. The operation is **O(log n)**.
135+
136+
**Inline Version:** min_heap_push_inline(heap, element, callbacks, args)
137+
138+
Heap Removal
139+
------------
140+
141+
.. code-block:: c
142+
143+
success = min_heap_pop(heap, callbacks, args);
144+
145+
- **heap**: A pointer to the min-heap from which to remove the smallest element.
146+
- **callbacks**: A pointer to a `struct min_heap_callbacks` providing the
147+
`less` and `swp` functions.
148+
- **args**: Optional arguments passed to the `less` and `swp` functions.
149+
150+
This macro removes the smallest element (the root) from the heap. It returns
151+
`true` if the element was successfully removed, or `false` if the heap is
152+
empty. The operation is **O(log n)**.
153+
154+
**Inline Version:** min_heap_pop_inline(heap, callbacks, args)
155+
156+
Heap Maintenance
157+
----------------
158+
159+
You can use the following macros to maintain the heap's structure:
160+
161+
.. code-block:: c
162+
163+
min_heap_sift_down(heap, pos, callbacks, args);
164+
165+
- **heap**: A pointer to the min-heap.
166+
- **pos**: The index from which to start sifting down.
167+
- **callbacks**: A pointer to a `struct min_heap_callbacks` providing the
168+
`less` and `swp` functions.
169+
- **args**: Optional arguments passed to the `less` and `swp` functions.
170+
171+
This macro restores the heap property by moving the element at the specified
172+
index (`pos`) down the heap until it is in the correct position. The operation
173+
is **O(log n)**.
174+
175+
**Inline Version:** min_heap_sift_down_inline(heap, pos, callbacks, args)
176+
177+
.. code-block:: c
178+
179+
min_heap_sift_up(heap, idx, callbacks, args);
180+
181+
- **heap**: A pointer to the min-heap.
182+
- **idx**: The index of the element to sift up.
183+
- **callbacks**: A pointer to a `struct min_heap_callbacks` providing the
184+
`less` and `swp` functions.
185+
- **args**: Optional arguments passed to the `less` and `swp` functions.
186+
187+
This macro restores the heap property by moving the element at the specified
188+
index (`idx`) up the heap. The operation is **O(log n)**.
189+
190+
**Inline Version:** min_heap_sift_up_inline(heap, idx, callbacks, args)
191+
192+
.. code-block:: c
193+
194+
min_heapify_all(heap, callbacks, args);
195+
196+
- **heap**: A pointer to the min-heap.
197+
- **callbacks**: A pointer to a `struct min_heap_callbacks` providing the
198+
`less` and `swp` functions.
199+
- **args**: Optional arguments passed to the `less` and `swp` functions.
200+
201+
This macro ensures that the entire heap satisfies the heap property. It is
202+
called when the heap is built from scratch or after many modifications. The
203+
operation is **O(n)**.
204+
205+
**Inline Version:** min_heapify_all_inline(heap, callbacks, args)
206+
207+
Removing Specific Elements
208+
--------------------------
209+
210+
.. code-block:: c
211+
212+
success = min_heap_del(heap, idx, callbacks, args);
213+
214+
- **heap**: A pointer to the min-heap.
215+
- **idx**: The index of the element to delete.
216+
- **callbacks**: A pointer to a `struct min_heap_callbacks` providing the
217+
`less` and `swp` functions.
218+
- **args**: Optional arguments passed to the `less` and `swp` functions.
219+
220+
This macro removes an element at the specified index (`idx`) from the heap and
221+
restores the heap property. The operation is **O(log n)**.
222+
223+
**Inline Version:** min_heap_del_inline(heap, idx, callbacks, args)
224+
225+
Other Utilities
226+
===============
227+
228+
- **min_heap_full(heap)**: Checks whether the heap is full.
229+
Complexity: **O(1)**.
230+
231+
.. code-block:: c
232+
233+
bool full = min_heap_full(heap);
234+
235+
- `heap`: A pointer to the min-heap to check.
236+
237+
This macro returns `true` if the heap is full, otherwise `false`.
238+
239+
**Inline Version:** min_heap_full_inline(heap)
240+
241+
- **min_heap_empty(heap)**: Checks whether the heap is empty.
242+
Complexity: **O(1)**.
243+
244+
.. code-block:: c
245+
246+
bool empty = min_heap_empty(heap);
247+
248+
- `heap`: A pointer to the min-heap to check.
249+
250+
This macro returns `true` if the heap is empty, otherwise `false`.
251+
252+
**Inline Version:** min_heap_empty_inline(heap)
253+
254+
Example Usage
255+
=============
256+
257+
An example usage of the min-heap API would involve defining a heap structure,
258+
initializing it, and inserting and removing elements as needed.
259+
260+
.. code-block:: c
261+
262+
#include <linux/min_heap.h>
263+
264+
int my_less_function(const void *lhs, const void *rhs, void *args) {
265+
return (*(int *)lhs < *(int *)rhs);
266+
}
267+
268+
struct min_heap_callbacks heap_cb = {
269+
.less = my_less_function, /* Comparison function for heap order */
270+
.swp = NULL, /* Use default swap function */
271+
};
272+
273+
void example_usage(void) {
274+
/* Pre-populate the buffer with elements */
275+
int buffer[5] = {5, 2, 8, 1, 3};
276+
/* Declare a min-heap */
277+
DEFINE_MIN_HEAP(int, my_heap);
278+
279+
/* Initialize the heap with preallocated buffer and size */
280+
min_heap_init(&my_heap, buffer, 5);
281+
282+
/* Build the heap using min_heapify_all */
283+
my_heap.nr = 5; /* Set the number of elements in the heap */
284+
min_heapify_all(&my_heap, &heap_cb, NULL);
285+
286+
/* Peek at the top element (should be 1 in this case) */
287+
int *top = min_heap_peek(&my_heap);
288+
pr_info("Top element: %d\n", *top);
289+
290+
/* Pop the top element (1) and get the new top (2) */
291+
min_heap_pop(&my_heap, &heap_cb, NULL);
292+
top = min_heap_peek(&my_heap);
293+
pr_info("New top element: %d\n", *top);
294+
295+
/* Insert a new element (0) and recheck the top */
296+
int new_element = 0;
297+
min_heap_push(&my_heap, &new_element, &heap_cb, NULL);
298+
top = min_heap_peek(&my_heap);
299+
pr_info("Top element after insertion: %d\n", *top);
300+
}

MAINTAINERS

+9
Original file line numberDiff line numberDiff line change
@@ -15585,6 +15585,15 @@ F: arch/arm/boot/dts/marvell/armada-xp-crs326-24g-2s.dts
1558515585
F: arch/arm/boot/dts/marvell/armada-xp-crs328-4c-20s-4s-bit.dts
1558615586
F: arch/arm/boot/dts/marvell/armada-xp-crs328-4c-20s-4s.dts
1558715587

15588+
MIN HEAP
15589+
M: Kuan-Wei Chiu <[email protected]>
15590+
15591+
S: Maintained
15592+
F: Documentation/core-api/min_heap.rst
15593+
F: include/linux/min_heap.h
15594+
F: lib/min_heap.c
15595+
F: lib/test_min_heap.c
15596+
1558815597
MIPI CCS, SMIA AND SMIA++ IMAGE SENSOR DRIVER
1558915598
M: Sakari Ailus <[email protected]>
1559015599

arch/alpha/include/asm/spinlock_types.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#define _ALPHA_SPINLOCK_TYPES_H
44

55
#ifndef __LINUX_SPINLOCK_TYPES_RAW_H
6-
# error "please don't include this file directly"
6+
# error "Please do not include this file directly."
77
#endif
88

99
typedef struct {

arch/arm/include/asm/spinlock_types.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#define __ASM_SPINLOCK_TYPES_H
44

55
#ifndef __LINUX_SPINLOCK_TYPES_RAW_H
6-
# error "please don't include this file directly"
6+
# error "Please do not include this file directly."
77
#endif
88

99
#define TICKET_SHIFT 16

arch/arm64/include/asm/spinlock_types.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#define __ASM_SPINLOCK_TYPES_H
77

88
#if !defined(__LINUX_SPINLOCK_TYPES_RAW_H) && !defined(__ASM_SPINLOCK_H)
9-
# error "please don't include this file directly"
9+
# error "Please do not include this file directly."
1010
#endif
1111

1212
#include <asm-generic/qspinlock_types.h>

arch/hexagon/include/asm/spinlock_types.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#define _ASM_SPINLOCK_TYPES_H
1010

1111
#ifndef __LINUX_SPINLOCK_TYPES_RAW_H
12-
# error "please don't include this file directly"
12+
# error "Please do not include this file directly."
1313
#endif
1414

1515
typedef struct {

arch/powerpc/include/asm/simple_spinlock_types.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#define _ASM_POWERPC_SIMPLE_SPINLOCK_TYPES_H
44

55
#ifndef __LINUX_SPINLOCK_TYPES_RAW_H
6-
# error "please don't include this file directly"
6+
# error "Please do not include this file directly."
77
#endif
88

99
typedef struct {

arch/powerpc/include/asm/spinlock_types.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#define _ASM_POWERPC_SPINLOCK_TYPES_H
44

55
#ifndef __LINUX_SPINLOCK_TYPES_RAW_H
6-
# error "please don't include this file directly"
6+
# error "Please do not include this file directly."
77
#endif
88

99
#ifdef CONFIG_PPC_QUEUED_SPINLOCKS

0 commit comments

Comments
 (0)