latency improvements, one reschedule moved
Subsystems (4)
PATCH 1/1 latency improvements, one reschedule moved
Hi Linus, Paul, Benno, ...,
[patch against linux-2.4.0-test3-pre2]
I cleaned up kswapd and moved its reschedule point. Disk performance is close to the same.
Latencies have improved a lot (tested with Bennos latencytest)
* sync is still problematic
* mmap002 (Quintinela) still gives a 212 ms latency (compared to 423 ms for the unpatched...)
* other disk related latencies are down under 30 ms. (streaming read, copy, write)
* the number of overruns has dropped considerably! (running 4 buffers with a deadline of 23 ms)
/RogerL
--
Home page:
http://www.norran.net/nra02596/
mm/vmscan.c renamed from mm/vmscan.c.orig +67 -24
@@ -419,6 +419,48 @@ }/* +* Check if there is any memory pressure (free_pages < pages_low) +*/ +static inline int memory_pressure (void ) +{ +pg_data_t *pgdat = pgdat_list; + +do { +int i; +for (i =0 ; i <MAX_NR_ZONES ; i++) { +zone_t *zone = pgdat->node_zones+ i; +if (!zone->size && + zone->free_pages < zone->pages_low) +return 1 ; + } + pgdat = pgdat->node_next; + }while (pgdat); + +return 0 ; +} + +/* +* Check if there is any memory pressure (free_pages < pages_low) +*/ +static inline int keep_kswapd_awake (void ) +{ +pg_data_t *pgdat = pgdat_list; + +do { +int i; +for (i =0 ; i <MAX_NR_ZONES ; i++) { +zone_t *zone = pgdat->node_zones+ i; +if (!zone->size && + zone->zone_wake_kswapd) +return 1 ; + } + pgdat = pgdat->node_next; + }while (pgdat); + +return 0 ; +} + +/* * We need to make the locks finer granularity, but right * now we need this so that we can do page allocations * without holding the kernel lock etc.
@@ -442,7 +484,20 @@ priority =64 ; do { + /* should __GFP_WAIT be checked? + * assume not - not WAITING for a free page + * let more important task execute before + * continuing (Note: kswapd does not use it). + */ + if (current->need_resched) { + schedule(); + /* time has passed - pressure too? */ + if (!memory_pressure()) + goto done; + } + while (shrink_mmap(priority, gfp_mask)) { + /* check __GFP_WAIT ? see below */ if (!--count) goto done; }
@@ -477,16 +532,21 @@if (--swap_count <0 )break ; - }while (--priority >=0 ); + priority--; + }while (priority >=0 );/* Always end on a shrink_mmap.. */ while (shrink_mmap (0 , gfp_mask)) { +if (current->need_resched) +schedule (); +if (!memory_pressure ()) +return 1 ;if (!--count) goto done; }/* We return 1 if we are freed some page */ return (count !=FREE_COUNT ); - + done:return 1 ; }
@@ -530,29 +590,12 @@ tsk->flags |=PF_MEMALLOC ;for (;;) { -pg_data_t *pgdat; -int something_to_do =0 ; - - pgdat = pgdat_list; -do { -int i; -for (i =0 ; i <MAX_NR_ZONES ; i++) { -zone_t *zone = pgdat->node_zones+ i; -if (tsk->need_resched) -schedule (); -if (!zone->size || !zone->zone_wake_kswapd) -continue ; -if (zone->free_pages < zone->pages_low) - something_to_do =1 ; -do_try_to_free_pages (GFP_KSWAPD ); - } - pgdat = pgdat->node_next; - }while (pgdat); - -if (!something_to_do) { - tsk->state =TASK_INTERRUPTIBLE ; -interruptible_sleep_on (&kswapd_wait); +if (!keep_kswapd_awake ()) { + tsk->state =TASK_INTERRUPTIBLE ; +interruptible_sleep_on (&kswapd_wait); } + +do_try_to_free_pages (GFP_KSWAPD ); } }