History

Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull scheduler fixes from Thomas Gleixner: "Two fixes for the fair scheduling class: - Prevent freeing memory which is accessible by concurrent readers - Make the RCU annotations for numa groups consistent" * 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: sched/fair: Use RCU accessors consistently for ->numa_group sched/fair: Don't free p->numa_faults with concurrent readers

Linus Torvalds committed 7 years ago

Commit e24ce842 parents 750991f cb361d85 files · +114 −48Browse files

Unified · Split

5 files
  1. fs/exec.c +1 −1
  2. include/linux/sched.h +9 −1
  3. include/linux/sched/numa_balancing.h +2 −2
  4. kernel/fork.c +1 −1
  5. kernel/sched/fair.c +101 −43
fs/exec.c+1−1
@@ -1828,7 +1828,7 @@ static int __do_execve_file(int fd, struct filename *filename, · 1827 unmodified lines
1828 membarrier_execve(current);1828 membarrier_execve(current);
1829 rseq_execve(current);1829 rseq_execve(current);
1830 acct_update_integrals(current);1830 acct_update_integrals(current);
1831 task_numa_free(current);1831 task_numa_free(current, false);
1832 free_bprm(bprm);1832 free_bprm(bprm);
1833 kfree(pathbuf);1833 kfree(pathbuf);
1834 if (filename)1834 if (filename)
include/linux/sched.h+9−1
@@ -1092,7 +1092,15 @@ struct task_struct { · 1091 unmodified lines
1092 u64 last_sum_exec_runtime;1092 u64 last_sum_exec_runtime;
1093 struct callback_head numa_work;1093 struct callback_head numa_work;
1094 1094
1095 struct numa_group *numa_group;1095 /*
1096 * This pointer is only modified for current in syscall and
1097 * pagefault context (and for tasks being destroyed), so it can be read
1098 * from any of the following contexts:
1099 * - RCU read-side critical section
1100 * - current->numa_group from everywhere
1101 * - task's runqueue locked, task not running
1102 */
1103 struct numa_group __rcu *numa_group;
1096 1104
1097 /*1105 /*
1098 * numa_faults is an array split into four regions:1106 * numa_faults is an array split into four regions:
include/linux/sched/numa_balancing.h+2−2
@@ -19,7 +19,7 @@ · 18 unmodified lines
19extern void task_numa_fault(int last_node, int node, int pages, int flags);19extern void task_numa_fault(int last_node, int node, int pages, int flags);
20extern pid_t task_numa_group_id(struct task_struct *p);20extern pid_t task_numa_group_id(struct task_struct *p);
21extern void set_numabalancing_state(bool enabled);21extern void set_numabalancing_state(bool enabled);
22extern void task_numa_free(struct task_struct *p);22extern void task_numa_free(struct task_struct *p, bool final);
23extern bool should_numa_migrate_memory(struct task_struct *p, struct page *page,23extern bool should_numa_migrate_memory(struct task_struct *p, struct page *page,
24 int src_nid, int dst_cpu);24 int src_nid, int dst_cpu);
25#else25#else
@@ -34,7 +34,7 @@ static inline pid_t task_numa_group_id(struct task_struct *p) · 8 unmodified lines
34static inline void set_numabalancing_state(bool enabled)34static inline void set_numabalancing_state(bool enabled)
35{35{
36}36}
37static inline void task_numa_free(struct task_struct *p)37static inline void task_numa_free(struct task_struct *p, bool final)
38{38{
39}39}
40static inline bool should_numa_migrate_memory(struct task_struct *p,40static inline bool should_numa_migrate_memory(struct task_struct *p,
kernel/fork.c+1−1
@@ -726,7 +726,7 @@ void __put_task_struct(struct task_struct *tsk) · 725 unmodified lines
726 WARN_ON(tsk == current);726 WARN_ON(tsk == current);
727 727
728 cgroup_free(tsk);728 cgroup_free(tsk);
729 task_numa_free(tsk);729 task_numa_free(tsk, true);
730 security_task_free(tsk);730 security_task_free(tsk);
731 exit_creds(tsk);731 exit_creds(tsk);
732 delayacct_tsk_free(tsk);732 delayacct_tsk_free(tsk);
kernel/sched/fair.c+101−43
@@ -1086,6 +1086,21 @@ struct numa_group { · 1085 unmodified lines
1086 unsigned long faults[0];1086 unsigned long faults[0];
1087};1087};
1088 1088
1089/*
1090 * For functions that can be called in multiple contexts that permit reading
1091 * ->numa_group (see struct task_struct for locking rules).
1092 */
1093static struct numa_group *deref_task_numa_group(struct task_struct *p)
1094{
1095 return rcu_dereference_check(p->numa_group, p == current ||
1096 (lockdep_is_held(&task_rq(p)->lock) && !READ_ONCE(p->on_cpu)));
1097}
1098
1099static struct numa_group *deref_curr_numa_group(struct task_struct *p)
1100{
1101 return rcu_dereference_protected(p->numa_group, p == current);
1102}
1103
1089static inline unsigned long group_faults_priv(struct numa_group *ng);1104static inline unsigned long group_faults_priv(struct numa_group *ng);
1090static inline unsigned long group_faults_shared(struct numa_group *ng);1105static inline unsigned long group_faults_shared(struct numa_group *ng);
1091 1106
@@ -1129,10 +1144,12 @@ static unsigned int task_scan_start(struct task_struct *p) · 37 unmodified lines
1129{1144{
1130 unsigned long smin = task_scan_min(p);1145 unsigned long smin = task_scan_min(p);
1131 unsigned long period = smin;1146 unsigned long period = smin;
1147 struct numa_group *ng;
1132 1148
1133 /* Scale the maximum scan period with the amount of shared memory. */1149 /* Scale the maximum scan period with the amount of shared memory. */
1134 if (p->numa_group) {1150 rcu_read_lock();
1135 struct numa_group *ng = p->numa_group;1151 ng = rcu_dereference(p->numa_group);
1152 if (ng) {
1136 unsigned long shared = group_faults_shared(ng);1153 unsigned long shared = group_faults_shared(ng);
1137 unsigned long private = group_faults_priv(ng);1154 unsigned long private = group_faults_priv(ng);
1138 1155
@@ -1140,6 +1157,7 @@ static unsigned int task_scan_start(struct task_struct *p) · 1 unmodified line
1140 period *= shared + 1;1157 period *= shared + 1;
1141 period /= private + shared + 1;1158 period /= private + shared + 1;
1142 }1159 }
1160 rcu_read_unlock();
1143 1161
1144 return max(smin, period);1162 return max(smin, period);
1145}1163}
@@ -1148,13 +1166,14 @@ static unsigned int task_scan_max(struct task_struct *p) · 2 unmodified lines
1148{1166{
1149 unsigned long smin = task_scan_min(p);1167 unsigned long smin = task_scan_min(p);
1150 unsigned long smax;1168 unsigned long smax;
1169 struct numa_group *ng;
1151 1170
1152 /* Watch for min being lower than max due to floor calculations */1171 /* Watch for min being lower than max due to floor calculations */
1153 smax = sysctl_numa_balancing_scan_period_max / task_nr_scan_windows(p);1172 smax = sysctl_numa_balancing_scan_period_max / task_nr_scan_windows(p);
1154 1173
1155 /* Scale the maximum scan period with the amount of shared memory. */1174 /* Scale the maximum scan period with the amount of shared memory. */
1156 if (p->numa_group) {1175 ng = deref_curr_numa_group(p);
1157 struct numa_group *ng = p->numa_group;1176 if (ng) {
1158 unsigned long shared = group_faults_shared(ng);1177 unsigned long shared = group_faults_shared(ng);
1159 unsigned long private = group_faults_priv(ng);1178 unsigned long private = group_faults_priv(ng);
1160 unsigned long period = smax;1179 unsigned long period = smax;
@@ -1186,7 +1205,7 @@ void init_numa_balancing(unsigned long clone_flags, struct task_struct *p) · 25 unmodified lines
1186 p->numa_scan_period = sysctl_numa_balancing_scan_delay;1205 p->numa_scan_period = sysctl_numa_balancing_scan_delay;
1187 p->numa_work.next = &p->numa_work;1206 p->numa_work.next = &p->numa_work;
1188 p->numa_faults = NULL;1207 p->numa_faults = NULL;
1189 p->numa_group = NULL;1208 RCU_INIT_POINTER(p->numa_group, NULL);
1190 p->last_task_numa_placement = 0;1209 p->last_task_numa_placement = 0;
1191 p->last_sum_exec_runtime = 0;1210 p->last_sum_exec_runtime = 0;
1192 1211
@@ -1233,7 +1252,16 @@ static void account_numa_dequeue(struct rq *rq, struct task_struct *p) · 40 unmodified lines
1233 1252
1234pid_t task_numa_group_id(struct task_struct *p)1253pid_t task_numa_group_id(struct task_struct *p)
1235{1254{
1236 return p->numa_group ? p->numa_group->gid : 0;1255 struct numa_group *ng;
1256 pid_t gid = 0;
1257
1258 rcu_read_lock();
1259 ng = rcu_dereference(p->numa_group);
1260 if (ng)
1261 gid = ng->gid;
1262 rcu_read_unlock();
1263
1264 return gid;
1237}1265}
1238 1266
1239/*1267/*
@@ -1258,11 +1286,13 @@ static inline unsigned long task_faults(struct task_struct *p, int nid) · 18 unmodified lines
1258 1286
1259static inline unsigned long group_faults(struct task_struct *p, int nid)1287static inline unsigned long group_faults(struct task_struct *p, int nid)
1260{1288{
1261 if (!p->numa_group)1289 struct numa_group *ng = deref_task_numa_group(p);
1290
1291 if (!ng)
1262 return 0;1292 return 0;
1263 1293
1264 return p->numa_group->faults[task_faults_idx(NUMA_MEM, nid, 0)] +1294 return ng->faults[task_faults_idx(NUMA_MEM, nid, 0)] +
1265 p->numa_group->faults[task_faults_idx(NUMA_MEM, nid, 1)];1295 ng->faults[task_faults_idx(NUMA_MEM, nid, 1)];
1266}1296}
1267 1297
1268static inline unsigned long group_faults_cpu(struct numa_group *group, int nid)1298static inline unsigned long group_faults_cpu(struct numa_group *group, int nid)
@@ -1400,12 +1430,13 @@ static inline unsigned long task_weight(struct task_struct *p, int nid, · 131 unmodified lines
1400static inline unsigned long group_weight(struct task_struct *p, int nid,1430static inline unsigned long group_weight(struct task_struct *p, int nid,
1401 int dist)1431 int dist)
1402{1432{
1433 struct numa_group *ng = deref_task_numa_group(p);
1403 unsigned long faults, total_faults;1434 unsigned long faults, total_faults;
1404 1435
1405 if (!p->numa_group)1436 if (!ng)
1406 return 0;1437 return 0;
1407 1438
1408 total_faults = p->numa_group->total_faults;1439 total_faults = ng->total_faults;
1409 1440
1410 if (!total_faults)1441 if (!total_faults)
1411 return 0;1442 return 0;
@@ -1419,7 +1450,7 @@ static inline unsigned long group_weight(struct task_struct *p, int nid, · 7 unmodified lines
1419bool should_numa_migrate_memory(struct task_struct *p, struct page * page,1450bool should_numa_migrate_memory(struct task_struct *p, struct page * page,
1420 int src_nid, int dst_cpu)1451 int src_nid, int dst_cpu)
1421{1452{
1422 struct numa_group *ng = p->numa_group;1453 struct numa_group *ng = deref_curr_numa_group(p);
1423 int dst_nid = cpu_to_node(dst_cpu);1454 int dst_nid = cpu_to_node(dst_cpu);
1424 int last_cpupid, this_cpupid;1455 int last_cpupid, this_cpupid;
1425 1456
@@ -1600,13 +1631,14 @@ static bool load_too_imbalanced(long src_load, long dst_load, · 174 unmodified lines
1600static void task_numa_compare(struct task_numa_env *env,1631static void task_numa_compare(struct task_numa_env *env,
1601 long taskimp, long groupimp, bool maymove)1632 long taskimp, long groupimp, bool maymove)
1602{1633{
1634 struct numa_group *cur_ng, *p_ng = deref_curr_numa_group(env->p);
1603 struct rq *dst_rq = cpu_rq(env->dst_cpu);1635 struct rq *dst_rq = cpu_rq(env->dst_cpu);
1636 long imp = p_ng ? groupimp : taskimp;
1604 struct task_struct *cur;1637 struct task_struct *cur;
1605 long src_load, dst_load;1638 long src_load, dst_load;
1606 long load;
1607 long imp = env->p->numa_group ? groupimp : taskimp;
1608 long moveimp = imp;
1609 int dist = env->dist;1639 int dist = env->dist;
1640 long moveimp = imp;
1641 long load;
1610 1642
1611 if (READ_ONCE(dst_rq->numa_migrate_on))1643 if (READ_ONCE(dst_rq->numa_migrate_on))
1612 return;1644 return;
@@ -1645,21 +1677,22 @@ static void task_numa_compare(struct task_numa_env *env, · 32 unmodified lines
1645 * If dst and source tasks are in the same NUMA group, or not1677 * If dst and source tasks are in the same NUMA group, or not
1646 * in any group then look only at task weights.1678 * in any group then look only at task weights.
1647 */1679 */
1648 if (cur->numa_group == env->p->numa_group) {1680 cur_ng = rcu_dereference(cur->numa_group);
1681 if (cur_ng == p_ng) {
1649 imp = taskimp + task_weight(cur, env->src_nid, dist) -1682 imp = taskimp + task_weight(cur, env->src_nid, dist) -
1650 task_weight(cur, env->dst_nid, dist);1683 task_weight(cur, env->dst_nid, dist);
1651 /*1684 /*
1652 * Add some hysteresis to prevent swapping the1685 * Add some hysteresis to prevent swapping the
1653 * tasks within a group over tiny differences.1686 * tasks within a group over tiny differences.
1654 */1687 */
1655 if (cur->numa_group)1688 if (cur_ng)
1656 imp -= imp / 16;1689 imp -= imp / 16;
1657 } else {1690 } else {
1658 /*1691 /*
1659 * Compare the group weights. If a task is all by itself1692 * Compare the group weights. If a task is all by itself
1660 * (not part of a group), use the task weight instead.1693 * (not part of a group), use the task weight instead.
1661 */1694 */
1662 if (cur->numa_group && env->p->numa_group)1695 if (cur_ng && p_ng)
1663 imp += group_weight(cur, env->src_nid, dist) -1696 imp += group_weight(cur, env->src_nid, dist) -
1664 group_weight(cur, env->dst_nid, dist);1697 group_weight(cur, env->dst_nid, dist);
1665 else1698 else
@@ -1757,11 +1790,12 @@ static int task_numa_migrate(struct task_struct *p) · 91 unmodified lines
1757 .best_imp = 0,1790 .best_imp = 0,
1758 .best_cpu = -1,1791 .best_cpu = -1,
1759 };1792 };
1793 unsigned long taskweight, groupweight;
1760 struct sched_domain *sd;1794 struct sched_domain *sd;
1795 long taskimp, groupimp;
1796 struct numa_group *ng;
1761 struct rq *best_rq;1797 struct rq *best_rq;
1762 unsigned long taskweight, groupweight;
1763 int nid, ret, dist;1798 int nid, ret, dist;
1764 long taskimp, groupimp;
1765 1799
1766 /*1800 /*
1767 * Pick the lowest SD_NUMA domain, as that would have the smallest1801 * Pick the lowest SD_NUMA domain, as that would have the smallest
@@ -1807,7 +1841,8 @@ static int task_numa_migrate(struct task_struct *p) · 39 unmodified lines
1807 * multiple NUMA nodes; in order to better consolidate the group,1841 * multiple NUMA nodes; in order to better consolidate the group,
1808 * we need to check other locations.1842 * we need to check other locations.
1809 */1843 */
1810 if (env.best_cpu == -1 || (p->numa_group && p->numa_group->active_nodes > 1)) {1844 ng = deref_curr_numa_group(p);
1845 if (env.best_cpu == -1 || (ng && ng->active_nodes > 1)) {
1811 for_each_online_node(nid) {1846 for_each_online_node(nid) {
1812 if (nid == env.src_nid || nid == p->numa_preferred_nid)1847 if (nid == env.src_nid || nid == p->numa_preferred_nid)
1813 continue;1848 continue;
@@ -1840,7 +1875,7 @@ static int task_numa_migrate(struct task_struct *p) · 26 unmodified lines
1840 * A task that migrated to a second choice node will be better off1875 * A task that migrated to a second choice node will be better off
1841 * trying for a better one later. Do not set the preferred node here.1876 * trying for a better one later. Do not set the preferred node here.
1842 */1877 */
1843 if (p->numa_group) {1878 if (ng) {
1844 if (env.best_cpu == -1)1879 if (env.best_cpu == -1)
1845 nid = env.src_nid;1880 nid = env.src_nid;
1846 else1881 else
@@ -2135,6 +2170,7 @@ static void task_numa_placement(struct task_struct *p) · 288 unmodified lines
2135 unsigned long total_faults;2170 unsigned long total_faults;
2136 u64 runtime, period;2171 u64 runtime, period;
2137 spinlock_t *group_lock = NULL;2172 spinlock_t *group_lock = NULL;
2173 struct numa_group *ng;
2138 2174
2139 /*2175 /*
2140 * The p->mm->numa_scan_seq field gets updated without2176 * The p->mm->numa_scan_seq field gets updated without
@@ -2152,8 +2188,9 @@ static void task_numa_placement(struct task_struct *p) · 11 unmodified lines
2152 runtime = numa_get_avg_runtime(p, &period);2188 runtime = numa_get_avg_runtime(p, &period);
2153 2189
2154 /* If the task is part of a group prevent parallel updates to group stats */2190 /* If the task is part of a group prevent parallel updates to group stats */
2155 if (p->numa_group) {2191 ng = deref_curr_numa_group(p);
2156 group_lock = &p->numa_group->lock;2192 if (ng) {
2193 group_lock = &ng->lock;
2157 spin_lock_irq(group_lock);2194 spin_lock_irq(group_lock);
2158 }2195 }
2159 2196
@@ -2194,7 +2231,7 @@ static void task_numa_placement(struct task_struct *p) · 34 unmodified lines
2194 p->numa_faults[cpu_idx] += f_diff;2231 p->numa_faults[cpu_idx] += f_diff;
2195 faults += p->numa_faults[mem_idx];2232 faults += p->numa_faults[mem_idx];
2196 p->total_numa_faults += diff;2233 p->total_numa_faults += diff;
2197 if (p->numa_group) {2234 if (ng) {
2198 /*2235 /*
2199 * safe because we can only change our own group2236 * safe because we can only change our own group
2200 *2237 *
@@ -2202,14 +2239,14 @@ static void task_numa_placement(struct task_struct *p) · 1 unmodified line
2202 * nid and priv in a specific region because it2239 * nid and priv in a specific region because it
2203 * is at the beginning of the numa_faults array.2240 * is at the beginning of the numa_faults array.
2204 */2241 */
2205 p->numa_group->faults[mem_idx] += diff;2242 ng->faults[mem_idx] += diff;
2206 p->numa_group->faults_cpu[mem_idx] += f_diff;2243 ng->faults_cpu[mem_idx] += f_diff;
2207 p->numa_group->total_faults += diff;2244 ng->total_faults += diff;
2208 group_faults += p->numa_group->faults[mem_idx];2245 group_faults += ng->faults[mem_idx];
2209 }2246 }
2210 }2247 }
2211 2248
2212 if (!p->numa_group) {2249 if (!ng) {
2213 if (faults > max_faults) {2250 if (faults > max_faults) {
2214 max_faults = faults;2251 max_faults = faults;
2215 max_nid = nid;2252 max_nid = nid;
@@ -2220,8 +2257,8 @@ static void task_numa_placement(struct task_struct *p) · 4 unmodified lines
2220 }2257 }
2221 }2258 }
2222 2259
2223 if (p->numa_group) {2260 if (ng) {
2224 numa_group_count_active_nodes(p->numa_group);2261 numa_group_count_active_nodes(ng);
2225 spin_unlock_irq(group_lock);2262 spin_unlock_irq(group_lock);
2226 max_nid = preferred_group_nid(p, max_nid);2263 max_nid = preferred_group_nid(p, max_nid);
2227 }2264 }
@@ -2255,7 +2292,7 @@ static void task_numa_group(struct task_struct *p, int cpupid, int flags, · 27 unmodified lines
2255 int cpu = cpupid_to_cpu(cpupid);2292 int cpu = cpupid_to_cpu(cpupid);
2256 int i;2293 int i;
2257 2294
2258 if (unlikely(!p->numa_group)) {2295 if (unlikely(!deref_curr_numa_group(p))) {
2259 unsigned int size = sizeof(struct numa_group) +2296 unsigned int size = sizeof(struct numa_group) +
2260 4*nr_node_ids*sizeof(unsigned long);2297 4*nr_node_ids*sizeof(unsigned long);
2261 2298
@@ -2291,7 +2328,7 @@ static void task_numa_group(struct task_struct *p, int cpupid, int flags, · 29 unmodified lines
2291 if (!grp)2328 if (!grp)
2292 goto no_join;2329 goto no_join;
2293 2330
2294 my_grp = p->numa_group;2331 my_grp = deref_curr_numa_group(p);
2295 if (grp == my_grp)2332 if (grp == my_grp)
2296 goto no_join;2333 goto no_join;
2297 2334
@@ -2353,13 +2390,24 @@ no_join: · 55 unmodified lines
2353 return;2390 return;
2354}2391}
2355 2392
2356void task_numa_free(struct task_struct *p)2393/*
2394 * Get rid of NUMA staticstics associated with a task (either current or dead).
2395 * If @final is set, the task is dead and has reached refcount zero, so we can
2396 * safely free all relevant data structures. Otherwise, there might be
2397 * concurrent reads from places like load balancing and procfs, and we should
2398 * reset the data back to default state without freeing ->numa_faults.
2399 */
2400void task_numa_free(struct task_struct *p, bool final)
2357{2401{
2358 struct numa_group *grp = p->numa_group;2402 /* safe: p either is current or is being freed by current */
2359 void *numa_faults = p->numa_faults;2403 struct numa_group *grp = rcu_dereference_raw(p->numa_group);
2404 unsigned long *numa_faults = p->numa_faults;
2360 unsigned long flags;2405 unsigned long flags;
2361 int i;2406 int i;
2362 2407
2408 if (!numa_faults)
2409 return;
2410
2363 if (grp) {2411 if (grp) {
2364 spin_lock_irqsave(&grp->lock, flags);2412 spin_lock_irqsave(&grp->lock, flags);
2365 for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++)2413 for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++)
@@ -2372,8 +2420,14 @@ void task_numa_free(struct task_struct *p) · 6 unmodified lines
2372 put_numa_group(grp);2420 put_numa_group(grp);
2373 }2421 }
2374 2422
2375 p->numa_faults = NULL;2423 if (final) {
2376 kfree(numa_faults);2424 p->numa_faults = NULL;
2425 kfree(numa_faults);
2426 } else {
2427 p->total_numa_faults = 0;
2428 for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++)
2429 numa_faults[i] = 0;
2430 }
2377}2431}
2378 2432
2379/*2433/*
@@ -2426,7 +2480,7 @@ void task_numa_fault(int last_cpupid, int mem_node, int pages, int flags) · 46 unmodified lines
2426 * actively using should be counted as local. This allows the2480 * actively using should be counted as local. This allows the
2427 * scan rate to slow down when a workload has settled down.2481 * scan rate to slow down when a workload has settled down.
2428 */2482 */
2429 ng = p->numa_group;2483 ng = deref_curr_numa_group(p);
2430 if (!priv && !local && ng && ng->active_nodes > 1 &&2484 if (!priv && !local && ng && ng->active_nodes > 1 &&
2431 numa_is_active_node(cpu_node, ng) &&2485 numa_is_active_node(cpu_node, ng) &&
2432 numa_is_active_node(mem_node, ng))2486 numa_is_active_node(mem_node, ng))
@@ -10444,18 +10498,22 @@ void show_numa_stats(struct task_struct *p, struct seq_file *m) · 8011 unmodified lines
10444{10498{
10445 int node;10499 int node;
10446 unsigned long tsf = 0, tpf = 0, gsf = 0, gpf = 0;10500 unsigned long tsf = 0, tpf = 0, gsf = 0, gpf = 0;
10501 struct numa_group *ng;
10447 10502
10503 rcu_read_lock();
10504 ng = rcu_dereference(p->numa_group);
10448 for_each_online_node(node) {10505 for_each_online_node(node) {
10449 if (p->numa_faults) {10506 if (p->numa_faults) {
10450 tsf = p->numa_faults[task_faults_idx(NUMA_MEM, node, 0)];10507 tsf = p->numa_faults[task_faults_idx(NUMA_MEM, node, 0)];
10451 tpf = p->numa_faults[task_faults_idx(NUMA_MEM, node, 1)];10508 tpf = p->numa_faults[task_faults_idx(NUMA_MEM, node, 1)];
10452 }10509 }
10453 if (p->numa_group) {10510 if (ng) {
10454 gsf = p->numa_group->faults[task_faults_idx(NUMA_MEM, node, 0)],10511 gsf = ng->faults[task_faults_idx(NUMA_MEM, node, 0)],
10455 gpf = p->numa_group->faults[task_faults_idx(NUMA_MEM, node, 1)];10512 gpf = ng->faults[task_faults_idx(NUMA_MEM, node, 1)];
10456 }10513 }
10457 print_numa_stats(m, node, tsf, tpf, gsf, gpf);10514 print_numa_stats(m, node, tsf, tpf, gsf, gpf);
10458 }10515 }
10516 rcu_read_unlock();
10459}10517}
10460#endif /* CONFIG_NUMA_BALANCING */10518#endif /* CONFIG_NUMA_BALANCING */
10461#endif /* CONFIG_SCHED_DEBUG */10519#endif /* CONFIG_SCHED_DEBUG */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t