hugetlbfs: allocate structures for reservation tracking outside of spinlocks
authorAndy Whitcroft <apw@shadowen.org>
Tue, 12 Aug 2008 22:08:47 +0000 (15:08 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 12 Aug 2008 23:07:28 +0000 (16:07 -0700)
commit57303d80175e10056bf51206f9961d586f02f967
tree3979c1d3e6bf154227ef94245c5a7b6141512211
parentff1a4a7b14ae146142b1c93a001304caf662ae13
hugetlbfs: allocate structures for reservation tracking outside of spinlocks

In the normal case, hugetlbfs reserves hugepages at map time so that the
pages exist for future faults.  A struct file_region is used to track when
reservations have been consumed and where.  These file_regions are
allocated as necessary with kmalloc() which can sleep with the
mm->page_table_lock held.  This is wrong and triggers may-sleep warning
when PREEMPT is enabled.

Updates to the underlying file_region are done in two phases.  The first
phase prepares the region for the change, allocating any necessary memory,
without actually making the change.  The second phase actually commits the
change.  This patch makes use of this by checking the reservations before
the page_table_lock is taken; triggering any necessary allocations.  This
may then be safely repeated within the locks without any allocations being
required.

Credit to Mel Gorman for diagnosing this failure and initial versions of
the patch.

Signed-off-by: Andy Whitcroft <apw@shadowen.org>
Tested-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/hugetlb.c