| From: "Fabio M. De Francesco" <fmdefrancesco@gmail.com> |
| Subject: mm/highmem: add notes about conversions from kmap{,_atomic}() |
| Date: Wed, 7 Dec 2022 23:53:08 +0100 |
| |
| kmap() and kmap_atomic() have been deprecated. kmap_local_page() should |
| always be used in new code and the call sites of the two deprecated |
| functions should be converted. This latter task can lead to errors if it |
| is not carried out with the necessary attention to the context around and |
| between the maps and unmaps. |
| |
| Therefore, add further information to the Highmem's documentation for the |
| purpose to make it clearer that (1) kmap() and kmap_atomic() must not any |
| longer be called in new code and (2) developers doing conversions from |
| kmap() amd kmap_atomic() are expected to take care of the context around |
| and between the maps and unmaps, in order to not break the code. |
| |
| Relevant parts of this patch have been taken from messages exchanged |
| privately with Ira Weiny (thanks!). |
| |
| [fmdefrancesco@gmail.com: merge two sentences into one, per Bagas] |
| Link: https://lkml.kernel.org/r/20230119123945.10471-1-fmdefrancesco@gmail.com |
| Link: https://lkml.kernel.org/r/20221207225308.8290-1-fmdefrancesco@gmail.com |
| Signed-off-by: Fabio M. De Francesco <fmdefrancesco@gmail.com> |
| Cc: Ira Weiny <ira.weiny@intel.com> |
| Cc: Jonathan Corbet <corbet@lwn.net> |
| Cc: Mike Rapoport <rppt@linux.ibm.com> |
| Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> |
| Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| |
| --- a/Documentation/mm/highmem.rst~mm-highmem-add-notes-about-conversions-from-kmap_atomic |
| +++ a/Documentation/mm/highmem.rst |
| @@ -57,7 +57,8 @@ list shows them in order of preference o |
| It can be invoked from any context (including interrupts) but the mappings |
| can only be used in the context which acquired them. |
| |
| - This function should be preferred, where feasible, over all the others. |
| + This function should always be used, whereas kmap_atomic() and kmap() have |
| + been deprecated. |
| |
| These mappings are thread-local and CPU-local, meaning that the mapping |
| can only be accessed from within this thread and the thread is bound to the |
| @@ -100,10 +101,21 @@ list shows them in order of preference o |
| (included in the "Functions" section) for details on how to manage nested |
| mappings. |
| |
| -* kmap_atomic(). This permits a very short duration mapping of a single |
| - page. Since the mapping is restricted to the CPU that issued it, it |
| - performs well, but the issuing task is therefore required to stay on that |
| - CPU until it has finished, lest some other task displace its mappings. |
| +* kmap_atomic(). This function has been deprecated; use kmap_local_page(). |
| + |
| + NOTE: Conversions to kmap_local_page() must take care to follow the mapping |
| + restrictions imposed on kmap_local_page(). Furthermore, the code between |
| + calls to kmap_atomic() and kunmap_atomic() may implicitly depend on the side |
| + effects of atomic mappings, i.e. disabling page faults or preemption, or both. |
| + In that case, explicit calls to pagefault_disable() or preempt_disable() or |
| + both must be made in conjunction with the use of kmap_local_page(). |
| + |
| + [Legacy documentation] |
| + |
| + This permits a very short duration mapping of a single page. Since the |
| + mapping is restricted to the CPU that issued it, it performs well, but |
| + the issuing task is therefore required to stay on that CPU until it has |
| + finished, lest some other task displace its mappings. |
| |
| kmap_atomic() may also be used by interrupt contexts, since it does not |
| sleep and the callers too may not sleep until after kunmap_atomic() is |
| @@ -115,11 +127,20 @@ list shows them in order of preference o |
| |
| It is assumed that k[un]map_atomic() won't fail. |
| |
| -* kmap(). This should be used to make short duration mapping of a single |
| - page with no restrictions on preemption or migration. It comes with an |
| - overhead as mapping space is restricted and protected by a global lock |
| - for synchronization. When mapping is no longer needed, the address that |
| - the page was mapped to must be released with kunmap(). |
| +* kmap(). This function has been deprecated; use kmap_local_page(). |
| + |
| + NOTE: Conversions to kmap_local_page() must take care to follow the mapping |
| + restrictions imposed on kmap_local_page(). In particular, it is necessary to |
| + make sure that the kernel virtual memory pointer is only valid in the thread |
| + that obtained it. |
| + |
| + [Legacy documentation] |
| + |
| + This should be used to make short duration mapping of a single page with no |
| + restrictions on preemption or migration. It comes with an overhead as mapping |
| + space is restricted and protected by a global lock for synchronization. When |
| + mapping is no longer needed, the address that the page was mapped to must be |
| + released with kunmap(). |
| |
| Mapping changes must be propagated across all the CPUs. kmap() also |
| requires global TLB invalidation when the kmap's pool wraps and it might |
| _ |