Messages in this thread Patch in this message |  | | | From | KOSAKI Motohiro <> | | Subject | [PATCH 3/8] Don't use sleep_on() | | Date | Mon, 14 Dec 2009 21:29:28 +0900 (JST) |
| |
sleep_on() is SMP and/or kernel preemption unsafe. This patch replace it with safe code.
Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> --- mm/vmscan.c | 40 ++++++++++++++++++++++++++++++---------- 1 files changed, 30 insertions(+), 10 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 74c36fe..3be5345 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1599,15 +1599,32 @@ static unsigned long nr_scan_try_batch(unsigned long nr_to_scan, static int shrink_zone_begin(struct zone *zone, struct scan_control *sc) { - if (!current_is_kswapd() && - atomic_read(&zone->concurrent_reclaimers) > max_zone_concurrent_reclaimers && - (sc->gfp_mask & (__GFP_IO|__GFP_FS)) == (__GFP_IO|__GFP_FS)) { - /* - * Do not add to the lock contention if this zone has - * enough processes doing page reclaim already, since - * we would just make things slower. - */ - sleep_on(&zone->reclaim_wait); + DEFINE_WAIT(wait); + wait_queue_head_t *wq = &zone->reclaim_wait; + + if (current_is_kswapd()) + goto out; + + /* + * GFP_NOIO and GFP_NOFS mean caller may have some lock implicitly. + * Thus, we can't wait here. otherwise it might cause deadlock. + */ + if ((sc->gfp_mask & (__GFP_IO|__GFP_FS)) != (__GFP_IO|__GFP_FS)) + goto out; + + /* + * Do not add to the lock contention if this zone has + * enough processes doing page reclaim already, since + * we would just make things slower. + */ + for (;;) { + prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); + + if (atomic_read(&zone->concurrent_reclaimers) <= + max_zone_concurrent_reclaimers) + break; + + schedule(); /* * If other processes freed enough memory while we waited, @@ -1615,12 +1632,15 @@ static int shrink_zone_begin(struct zone *zone, struct scan_control *sc) */ if (zone_watermark_ok(zone, sc->order, low_wmark_pages(zone), 0, 0)) { - wake_up(&zone->reclaim_wait); + wake_up(wq); + finish_wait(wq, &wait); sc->nr_reclaimed += sc->nr_to_reclaim; return -ERESTARTSYS; } } + finish_wait(wq, &wait); + out: atomic_inc(&zone->concurrent_reclaimers); return 0; } -- 1.6.5.2
|  |