Thread (389 messages) flat view 389 messages, 13 authors, 2021-08-21

Re: [PATCH v14 054/138] mm: Add kmap_local_folio()

From: Matthew Wilcox <willy@infradead.org>
Date: 2021-07-21 15:03:33
Also in: linux-fsdevel, lkml

On Wed, Jul 21, 2021 at 05:22:16PM +0300, Mike Rapoport wrote:
On Wed, Jul 21, 2021 at 03:12:03PM +0100, Matthew Wilcox wrote:
quoted
On Wed, Jul 21, 2021 at 12:58:24PM +0300, Mike Rapoport wrote:
quoted
quoted
+/**
+ * kmap_local_folio - Map a page in this folio for temporary usage
+ * @folio:	The folio to be mapped.
+ * @offset:	The byte offset within the folio.
+ *
+ * Returns: The virtual address of the mapping
+ *
+ * Can be invoked from any context.
Context: Can be invoked from any context.
quoted
+ *
+ * Requires careful handling when nesting multiple mappings because the map
+ * management is stack based. The unmap has to be in the reverse order of
+ * the map operation:
+ *
+ * addr1 = kmap_local_folio(page1, offset1);
+ * addr2 = kmap_local_folio(page2, offset2);
Please s/page/folio/g here and in the description below
quoted
+ * ...
+ * kunmap_local(addr2);
+ * kunmap_local(addr1);
+ *
+ * Unmapping addr1 before addr2 is invalid and causes malfunction.
+ *
+ * Contrary to kmap() mappings the mapping is only valid in the context of
+ * the caller and cannot be handed to other contexts.
+ *
+ * On CONFIG_HIGHMEM=n kernels and for low memory pages this returns the
+ * virtual address of the direct mapping. Only real highmem pages are
+ * temporarily mapped.
+ *
+ * While it is significantly faster than kmap() for the higmem case it
+ * comes with restrictions about the pointer validity. Only use when really
+ * necessary.
+ *
+ * On HIGHMEM enabled systems mapping a highmem page has the side effect of
+ * disabling migration in order to keep the virtual address stable across
+ * preemption. No caller of kmap_local_folio() can rely on this side effect.
+ */
kmap_local_folio() only maps one page from the folio.  So it's not
appropriate to s/page/folio/g.  I fiddled with the description a bit to
make this clearer:

 /**
  * kmap_local_folio - Map a page in this folio for temporary usage
- * @folio:     The folio to be mapped.
- * @offset:    The byte offset within the folio.
- *
- * Returns: The virtual address of the mapping
- *
- * Can be invoked from any context.
+ * @folio: The folio containing the page.
+ * @offset: The byte offset within the folio which identifies the page.
  *
  * Requires careful handling when nesting multiple mappings because the map
  * management is stack based. The unmap has to be in the reverse order of
  * the map operation:
  *
- * addr1 = kmap_local_folio(page1, offset1);
- * addr2 = kmap_local_folio(page2, offset2);
+ * addr1 = kmap_local_folio(folio1, offset1);
+ * addr2 = kmap_local_folio(folio2, offset2);
  * ...
  * kunmap_local(addr2);
  * kunmap_local(addr1);
@@ -131,6 +127,9 @@ static inline void *kmap_local_page(struct page *page);
  * On HIGHMEM enabled systems mapping a highmem page has the side effect of
  * disabling migration in order to keep the virtual address stable across
  * preemption. No caller of kmap_local_folio() can rely on this side effect.
+ *
+ * Context: Can be invoked from any context.
+ * Return: The virtual address of @offset.
  */
 static inline void *kmap_local_folio(struct folio *folio, size_t offset)
This is clearer, thanks! 

Maybe just add page to Return: description:

* Return: The virtual address of page @offset.
No, it really does return the virtual address of @offset.  If you ask
for offset 0x1234 within a (sufficiently large) folio, it will map the
second page of that folio and return the address of the 0x234'th byte
within it.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help