Loading mm/Kconfig +13 −0 Original line number Diff line number Diff line Loading @@ -540,3 +540,16 @@ config BALANCE_ANON_FILE_RECLAIM config GENERIC_EARLY_IOREMAP bool config KSWAPD_CPU_AFFINITY_MASK string "kswapd cpu affinity mask" depends on SMP help Set the cpu affinity for the kswapd task. There can be power benefits on certain targets when limiting kswapd to run only on certain cores. The cpu affinity bitmask is represented by a hex string where commas group hex digits into chunks. Each chunk defines exactly 32 bits of the resultant bitmask. For example to limit kswapd to the first 4 cores use the following: CONFIG_KSWAPD_CPU_AFFINITY_MASK="f" mm/vmscan.c +28 −2 Original line number Diff line number Diff line Loading @@ -133,6 +133,12 @@ struct scan_control { int vm_swappiness = 60; unsigned long vm_total_pages; /* The total number of pages which the VM controls */ #ifdef CONFIG_KSWAPD_CPU_AFFINITY_MASK char *kswapd_cpu_mask = CONFIG_KSWAPD_CPU_AFFINITY_MASK; #else char *kswapd_cpu_mask = NULL; #endif static LIST_HEAD(shrinker_list); static DECLARE_RWSEM(shrinker_rwsem); Loading Loading @@ -3077,7 +3083,7 @@ static int kswapd(void *p) lockdep_set_current_reclaim_state(GFP_KERNEL); if (!cpumask_empty(cpumask)) if (kswapd_cpu_mask == NULL && !cpumask_empty(cpumask)) set_cpus_allowed_ptr(tsk, cpumask); current->reclaim_state = &reclaim_state; Loading Loading @@ -3251,6 +3257,22 @@ static int cpu_callback(struct notifier_block *nfb, unsigned long action, return NOTIFY_OK; } static int set_kswapd_cpu_mask(pg_data_t *pgdat) { int ret = 0; cpumask_t tmask; if (!kswapd_cpu_mask) return 0; cpus_clear(tmask); ret = cpumask_parse(kswapd_cpu_mask, &tmask); if (ret) return ret; return set_cpus_allowed_ptr(pgdat->kswapd, &tmask); } /* * This kswapd start function will be called by init and node-hot-add. * On node-hot-add, kswapd will moved to proper cpus if cpus are hot-added. Loading @@ -3270,6 +3292,9 @@ int kswapd_run(int nid) pr_err("Failed to start kswapd on node %d\n", nid); ret = PTR_ERR(pgdat->kswapd); pgdat->kswapd = NULL; } else if (kswapd_cpu_mask) { if (set_kswapd_cpu_mask(pgdat)) pr_warn("error setting kswapd cpu affinity mask\n"); } return ret; } Loading @@ -3295,6 +3320,7 @@ static int __init kswapd_init(void) swap_setup(); for_each_node_state(nid, N_MEMORY) kswapd_run(nid); if (kswapd_cpu_mask == NULL) hotcpu_notifier(cpu_callback, 0); return 0; } Loading Loading
mm/Kconfig +13 −0 Original line number Diff line number Diff line Loading @@ -540,3 +540,16 @@ config BALANCE_ANON_FILE_RECLAIM config GENERIC_EARLY_IOREMAP bool config KSWAPD_CPU_AFFINITY_MASK string "kswapd cpu affinity mask" depends on SMP help Set the cpu affinity for the kswapd task. There can be power benefits on certain targets when limiting kswapd to run only on certain cores. The cpu affinity bitmask is represented by a hex string where commas group hex digits into chunks. Each chunk defines exactly 32 bits of the resultant bitmask. For example to limit kswapd to the first 4 cores use the following: CONFIG_KSWAPD_CPU_AFFINITY_MASK="f"
mm/vmscan.c +28 −2 Original line number Diff line number Diff line Loading @@ -133,6 +133,12 @@ struct scan_control { int vm_swappiness = 60; unsigned long vm_total_pages; /* The total number of pages which the VM controls */ #ifdef CONFIG_KSWAPD_CPU_AFFINITY_MASK char *kswapd_cpu_mask = CONFIG_KSWAPD_CPU_AFFINITY_MASK; #else char *kswapd_cpu_mask = NULL; #endif static LIST_HEAD(shrinker_list); static DECLARE_RWSEM(shrinker_rwsem); Loading Loading @@ -3077,7 +3083,7 @@ static int kswapd(void *p) lockdep_set_current_reclaim_state(GFP_KERNEL); if (!cpumask_empty(cpumask)) if (kswapd_cpu_mask == NULL && !cpumask_empty(cpumask)) set_cpus_allowed_ptr(tsk, cpumask); current->reclaim_state = &reclaim_state; Loading Loading @@ -3251,6 +3257,22 @@ static int cpu_callback(struct notifier_block *nfb, unsigned long action, return NOTIFY_OK; } static int set_kswapd_cpu_mask(pg_data_t *pgdat) { int ret = 0; cpumask_t tmask; if (!kswapd_cpu_mask) return 0; cpus_clear(tmask); ret = cpumask_parse(kswapd_cpu_mask, &tmask); if (ret) return ret; return set_cpus_allowed_ptr(pgdat->kswapd, &tmask); } /* * This kswapd start function will be called by init and node-hot-add. * On node-hot-add, kswapd will moved to proper cpus if cpus are hot-added. Loading @@ -3270,6 +3292,9 @@ int kswapd_run(int nid) pr_err("Failed to start kswapd on node %d\n", nid); ret = PTR_ERR(pgdat->kswapd); pgdat->kswapd = NULL; } else if (kswapd_cpu_mask) { if (set_kswapd_cpu_mask(pgdat)) pr_warn("error setting kswapd cpu affinity mask\n"); } return ret; } Loading @@ -3295,6 +3320,7 @@ static int __init kswapd_init(void) swap_setup(); for_each_node_state(nid, N_MEMORY) kswapd_run(nid); if (kswapd_cpu_mask == NULL) hotcpu_notifier(cpu_callback, 0); return 0; } Loading