linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [RFC][PATCH 1/2] HugeTLB mapping for drivers (Alloc/free for drivers, hstate_nores)
@ 2009-07-14  1:47 Alexey Korolev
  2009-07-14  9:37 ` Mel Gorman
  0 siblings, 1 reply; 3+ messages in thread
From: Alexey Korolev @ 2009-07-14  1:47 UTC (permalink / raw)
  To: mel, linux-mm

This patch provides interface  functions for allocating/dealocating of
hugepages for use of device drivers. The main difference from
alloc_buddy_huge_page is related to using of special hstate which does not
interact with hugetlbfs reservations.
This is different to prototype. Why it is implemented? HugetlbFs and
drivers reservations has completely different sources of reservations. 
In hugetlbfs case it is dictated by users. So it is necessary to bother
about restrictions/ quotas etc.
In driver case it is dictated by HW. In thius case it is necessary involve user 
in tuning process as less as possible. 
If we would use HugeTlbFs reservations - we would need to force user to
supply how much huge pages needs to be reserved for drivers.
To protect drivers to interract with htlbfs reservations the state hstate_nores was 
introduced. Reservations with a state hstate_nores should not touch htlb
pools.

Note: Introduced interface functions have some elements of common code.
I did not bother about duplications as it is an early revision. 

P/S: In patch description I forgot to mention where it make sence to have
htlb mapping for drivers:
HD video capture/frame buffer (LFB)
Plenty of different data acquisition systems(logic analyzers, DSO, packet capture)
Probably RDMA (Infiniband)

hugetlb.c |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 52 insertions(+), 1 deletion(-)

Signed-off-by: Alexey Korolev <akorolev@infradead.org>
---
diff -aurp ORIG/mm/hugetlb.c NEW/mm/hugetlb.c
--- ORIG/mm/hugetlb.c	2009-07-05 05:58:48.000000000 +1200
+++ NEW/mm/hugetlb.c	2009-07-13 18:38:45.000000000 +1200
@@ -33,6 +33,7 @@ unsigned long hugepages_treat_as_movable
 static int max_hstate;
 unsigned int default_hstate_idx;
 struct hstate hstates[HUGE_MAX_HSTATE];
+struct hstate hstate_nores;
 
 __initdata LIST_HEAD(huge_boot_pages);
 
@@ -1040,6 +1041,50 @@ static void prep_compound_huge_page(stru
 		prep_compound_page(page, order);
 }
 
+/*
+ * hugetlb_alloc_pages_node - Allocate a single huge page for use with a driver
+ * @nid: The node to allocate memory on
+ * @gfp_mask: GFP flags for the allocation
+ * This function is intended for use by device drivers that want to
+ * back regions of memory with huge pages that will be later mapped to
+ * userspace. This is done outside of hugetlbfs and pages are allocated
+ * directly from the buddy allocator. It doesn't interact with hugetlbfs
+ * reservations.
+ */
+struct page *hugetlb_alloc_pages_node(int nid, gfp_t gfp_mask)
+{
+	struct page *page;
+	struct hstate *h = &hstate_nores;
+
+	page = alloc_pages_exact_node(nid, gfp_mask|__GFP_COMP,
+					huge_page_order(h));
+	if (page && arch_prepare_hugepage(page)) {
+		__free_pages(page, huge_page_order(h));
+		return NULL;
+	}
+	return page;
+}
+EXPORT_SYMBOL(hugetlb_alloc_pages_node);
+
+void hugetlb_free_pages(struct page *page)
+{
+	int i;
+	struct hstate *h = &hstate_nores;
+
+	VM_BUG_ON(h->order >= MAX_ORDER);
+
+	for (i = 0; i < pages_per_huge_page(h); i++) {
+		page[i].flags &= ~(1 << PG_locked | 1 << PG_error |
+			1 << PG_referenced | 1 << PG_dirty | 1 << PG_active |
+			1 << PG_reserved | 1 << PG_private | 1 << PG_writeback);
+	}
+	set_compound_page_dtor(page, NULL);
+	set_page_refcounted(page);
+	arch_release_hugepage(page);
+	__free_pages(page, huge_page_order(h));
+}
+EXPORT_SYMBOL(hugetlb_free_pages);
+
 /* Put bootmem huge pages into the standard lists after mem_map is up */
 static void __init gather_bootmem_prealloc(void)
 {
@@ -1078,7 +1123,13 @@ static void __init hugetlb_init_hstates(
 		if (h->order < MAX_ORDER)
 			hugetlb_hstate_alloc_pages(h);
 	}
+	/* Special hstate for use of drivers, allocations are not
+	 * tracked by hugetlbfs */
+	hstate_nores.order = default_hstate.order;
+	hstate_nores.mask = default_hstate.mask;
+
 }
+EXPORT_SYMBOL(hstate_nores);
 
 static char * __init memfmt(char *buf, unsigned long n)
 {
@@ -2309,7 +2360,7 @@ int hugetlb_reserve_pages(struct inode *
 	 * attempt will be made for VM_NORESERVE to allocate a page
 	 * and filesystem quota without using reserves
 	 */
-	if (acctflag & VM_NORESERVE)
+	if ((acctflag & VM_NORESERVE) || (h == &hstate_nores))
 		return 0;
 
 	/*

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-07-14 11:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-14  1:47 [RFC][PATCH 1/2] HugeTLB mapping for drivers (Alloc/free for drivers, hstate_nores) Alexey Korolev
2009-07-14  9:37 ` Mel Gorman
2009-07-14 11:51   ` Alexey Korolev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).