@@ -2728,6 +2728,109 @@ enum scan_balance {
2728
2728
SCAN_FILE ,
2729
2729
};
2730
2730
2731
+ static void prepare_scan_count (pg_data_t * pgdat , struct scan_control * sc )
2732
+ {
2733
+ unsigned long file ;
2734
+ struct lruvec * target_lruvec ;
2735
+
2736
+ target_lruvec = mem_cgroup_lruvec (sc -> target_mem_cgroup , pgdat );
2737
+
2738
+ /*
2739
+ * Flush the memory cgroup stats, so that we read accurate per-memcg
2740
+ * lruvec stats for heuristics.
2741
+ */
2742
+ mem_cgroup_flush_stats ();
2743
+
2744
+ /*
2745
+ * Determine the scan balance between anon and file LRUs.
2746
+ */
2747
+ spin_lock_irq (& target_lruvec -> lru_lock );
2748
+ sc -> anon_cost = target_lruvec -> anon_cost ;
2749
+ sc -> file_cost = target_lruvec -> file_cost ;
2750
+ spin_unlock_irq (& target_lruvec -> lru_lock );
2751
+
2752
+ /*
2753
+ * Target desirable inactive:active list ratios for the anon
2754
+ * and file LRU lists.
2755
+ */
2756
+ if (!sc -> force_deactivate ) {
2757
+ unsigned long refaults ;
2758
+
2759
+ /*
2760
+ * When refaults are being observed, it means a new
2761
+ * workingset is being established. Deactivate to get
2762
+ * rid of any stale active pages quickly.
2763
+ */
2764
+ refaults = lruvec_page_state (target_lruvec ,
2765
+ WORKINGSET_ACTIVATE_ANON );
2766
+ if (refaults != target_lruvec -> refaults [WORKINGSET_ANON ] ||
2767
+ inactive_is_low (target_lruvec , LRU_INACTIVE_ANON ))
2768
+ sc -> may_deactivate |= DEACTIVATE_ANON ;
2769
+ else
2770
+ sc -> may_deactivate &= ~DEACTIVATE_ANON ;
2771
+
2772
+ refaults = lruvec_page_state (target_lruvec ,
2773
+ WORKINGSET_ACTIVATE_FILE );
2774
+ if (refaults != target_lruvec -> refaults [WORKINGSET_FILE ] ||
2775
+ inactive_is_low (target_lruvec , LRU_INACTIVE_FILE ))
2776
+ sc -> may_deactivate |= DEACTIVATE_FILE ;
2777
+ else
2778
+ sc -> may_deactivate &= ~DEACTIVATE_FILE ;
2779
+ } else
2780
+ sc -> may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE ;
2781
+
2782
+ /*
2783
+ * If we have plenty of inactive file pages that aren't
2784
+ * thrashing, try to reclaim those first before touching
2785
+ * anonymous pages.
2786
+ */
2787
+ file = lruvec_page_state (target_lruvec , NR_INACTIVE_FILE );
2788
+ if (file >> sc -> priority && !(sc -> may_deactivate & DEACTIVATE_FILE ))
2789
+ sc -> cache_trim_mode = 1 ;
2790
+ else
2791
+ sc -> cache_trim_mode = 0 ;
2792
+
2793
+ /*
2794
+ * Prevent the reclaimer from falling into the cache trap: as
2795
+ * cache pages start out inactive, every cache fault will tip
2796
+ * the scan balance towards the file LRU. And as the file LRU
2797
+ * shrinks, so does the window for rotation from references.
2798
+ * This means we have a runaway feedback loop where a tiny
2799
+ * thrashing file LRU becomes infinitely more attractive than
2800
+ * anon pages. Try to detect this based on file LRU size.
2801
+ */
2802
+ if (!cgroup_reclaim (sc )) {
2803
+ unsigned long total_high_wmark = 0 ;
2804
+ unsigned long free , anon ;
2805
+ int z ;
2806
+
2807
+ free = sum_zone_node_page_state (pgdat -> node_id , NR_FREE_PAGES );
2808
+ file = node_page_state (pgdat , NR_ACTIVE_FILE ) +
2809
+ node_page_state (pgdat , NR_INACTIVE_FILE );
2810
+
2811
+ for (z = 0 ; z < MAX_NR_ZONES ; z ++ ) {
2812
+ struct zone * zone = & pgdat -> node_zones [z ];
2813
+
2814
+ if (!managed_zone (zone ))
2815
+ continue ;
2816
+
2817
+ total_high_wmark += high_wmark_pages (zone );
2818
+ }
2819
+
2820
+ /*
2821
+ * Consider anon: if that's low too, this isn't a
2822
+ * runaway file reclaim problem, but rather just
2823
+ * extreme pressure. Reclaim as per usual then.
2824
+ */
2825
+ anon = node_page_state (pgdat , NR_INACTIVE_ANON );
2826
+
2827
+ sc -> file_is_tiny =
2828
+ file + free <= total_high_wmark &&
2829
+ !(sc -> may_deactivate & DEACTIVATE_ANON ) &&
2830
+ anon >> sc -> priority ;
2831
+ }
2832
+ }
2833
+
2731
2834
/*
2732
2835
* Determine how aggressively the anon and file LRU lists should be
2733
2836
* scanned.
@@ -3197,109 +3300,16 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc)
3197
3300
unsigned long nr_reclaimed , nr_scanned ;
3198
3301
struct lruvec * target_lruvec ;
3199
3302
bool reclaimable = false;
3200
- unsigned long file ;
3201
3303
3202
3304
target_lruvec = mem_cgroup_lruvec (sc -> target_mem_cgroup , pgdat );
3203
3305
3204
3306
again :
3205
- /*
3206
- * Flush the memory cgroup stats, so that we read accurate per-memcg
3207
- * lruvec stats for heuristics.
3208
- */
3209
- mem_cgroup_flush_stats ();
3210
-
3211
3307
memset (& sc -> nr , 0 , sizeof (sc -> nr ));
3212
3308
3213
3309
nr_reclaimed = sc -> nr_reclaimed ;
3214
3310
nr_scanned = sc -> nr_scanned ;
3215
3311
3216
- /*
3217
- * Determine the scan balance between anon and file LRUs.
3218
- */
3219
- spin_lock_irq (& target_lruvec -> lru_lock );
3220
- sc -> anon_cost = target_lruvec -> anon_cost ;
3221
- sc -> file_cost = target_lruvec -> file_cost ;
3222
- spin_unlock_irq (& target_lruvec -> lru_lock );
3223
-
3224
- /*
3225
- * Target desirable inactive:active list ratios for the anon
3226
- * and file LRU lists.
3227
- */
3228
- if (!sc -> force_deactivate ) {
3229
- unsigned long refaults ;
3230
-
3231
- /*
3232
- * When refaults are being observed, it means a new
3233
- * workingset is being established. Deactivate to get
3234
- * rid of any stale active pages quickly.
3235
- */
3236
- refaults = lruvec_page_state (target_lruvec ,
3237
- WORKINGSET_ACTIVATE_ANON );
3238
- if (refaults != target_lruvec -> refaults [WORKINGSET_ANON ] ||
3239
- inactive_is_low (target_lruvec , LRU_INACTIVE_ANON ))
3240
- sc -> may_deactivate |= DEACTIVATE_ANON ;
3241
- else
3242
- sc -> may_deactivate &= ~DEACTIVATE_ANON ;
3243
-
3244
- refaults = lruvec_page_state (target_lruvec ,
3245
- WORKINGSET_ACTIVATE_FILE );
3246
- if (refaults != target_lruvec -> refaults [WORKINGSET_FILE ] ||
3247
- inactive_is_low (target_lruvec , LRU_INACTIVE_FILE ))
3248
- sc -> may_deactivate |= DEACTIVATE_FILE ;
3249
- else
3250
- sc -> may_deactivate &= ~DEACTIVATE_FILE ;
3251
- } else
3252
- sc -> may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE ;
3253
-
3254
- /*
3255
- * If we have plenty of inactive file pages that aren't
3256
- * thrashing, try to reclaim those first before touching
3257
- * anonymous pages.
3258
- */
3259
- file = lruvec_page_state (target_lruvec , NR_INACTIVE_FILE );
3260
- if (file >> sc -> priority && !(sc -> may_deactivate & DEACTIVATE_FILE ))
3261
- sc -> cache_trim_mode = 1 ;
3262
- else
3263
- sc -> cache_trim_mode = 0 ;
3264
-
3265
- /*
3266
- * Prevent the reclaimer from falling into the cache trap: as
3267
- * cache pages start out inactive, every cache fault will tip
3268
- * the scan balance towards the file LRU. And as the file LRU
3269
- * shrinks, so does the window for rotation from references.
3270
- * This means we have a runaway feedback loop where a tiny
3271
- * thrashing file LRU becomes infinitely more attractive than
3272
- * anon pages. Try to detect this based on file LRU size.
3273
- */
3274
- if (!cgroup_reclaim (sc )) {
3275
- unsigned long total_high_wmark = 0 ;
3276
- unsigned long free , anon ;
3277
- int z ;
3278
-
3279
- free = sum_zone_node_page_state (pgdat -> node_id , NR_FREE_PAGES );
3280
- file = node_page_state (pgdat , NR_ACTIVE_FILE ) +
3281
- node_page_state (pgdat , NR_INACTIVE_FILE );
3282
-
3283
- for (z = 0 ; z < MAX_NR_ZONES ; z ++ ) {
3284
- struct zone * zone = & pgdat -> node_zones [z ];
3285
- if (!managed_zone (zone ))
3286
- continue ;
3287
-
3288
- total_high_wmark += high_wmark_pages (zone );
3289
- }
3290
-
3291
- /*
3292
- * Consider anon: if that's low too, this isn't a
3293
- * runaway file reclaim problem, but rather just
3294
- * extreme pressure. Reclaim as per usual then.
3295
- */
3296
- anon = node_page_state (pgdat , NR_INACTIVE_ANON );
3297
-
3298
- sc -> file_is_tiny =
3299
- file + free <= total_high_wmark &&
3300
- !(sc -> may_deactivate & DEACTIVATE_ANON ) &&
3301
- anon >> sc -> priority ;
3302
- }
3312
+ prepare_scan_count (pgdat , sc );
3303
3313
3304
3314
shrink_node_memcgs (pgdat , sc );
3305
3315
0 commit comments