numa/core patches
Subsystems (19)
cover numa/core patches
Hi all,
Here's a re-post of the NUMA scheduling and migration improvement patches that we are working on. These include techniques from AutoNUMA and the sched/numa tree and form a unified basis - it has got all the bits that look good and mergeable.
With these patches applied, the mbind system calls expand to new modes of lazy-migration binding, and if the CONFIG_SCHED_NUMA=y .config option is enabled the scheduler will automatically sample the working set of tasks via page faults. Based on that information the scheduler then tries to balance smartly, put tasks on a home node and migrate CPU work and memory on the same node.
They are functional in their current state and have had testing on a variety of x86 NUMA hardware.
These patches will continue their life in tip:numa/core and unless there are major showstoppers they are intended for the v3.8 merge window.
We believe that they provide a solid basis for future work.
Please review .. once again and holler if you see anything funny! :-)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/31 sched, numa, mm: Make find_busiest_queue() a method
Its a bit awkward but it was the least painful means of modifying the queue selection. Used in a later patch to conditionally use a random queue.
--- kernel/sched/fair.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
kernel/sched/fair.c +12 -8
@@ -3063,6 +3063,9 @@ struct lb_env {unsigned int loop;unsigned int loop_break;unsigned int loop_max; + +struct rq * (*find_busiest_queue)(struct lb_env *, +struct sched_group *); };/*
@@ -4236,13 +4239,14 @@ static int load_balance(int this_cpu, ststruct cpumask *cpus =__get_cpu_var (load_balance_tmpmask);struct lb_env env = { - .sd = sd, - .dst_cpu = this_cpu, - .dst_rq = this_rq, - .dst_grpmask =sched_group_cpus (sd->groups), - .idle = idle, - .loop_break = sched_nr_migrate_break, - .cpus = cpus, + .sd = sd, + .dst_cpu = this_cpu, + .dst_rq = this_rq, + .dst_grpmask =sched_group_cpus (sd->groups), + .idle = idle, + .loop_break = sched_nr_migrate_break, + .cpus = cpus, + .find_busiest_queue = find_busiest_queue, };cpumask_copy (cpus, cpu_active_mask);
@@ -4261,7 +4265,7 @@ redo: goto out_balanced; } - busiest =find_busiest_queue (&env, group); + busiest = env.find_busiest_queue (&env, group);if (!busiest) {schedstat_inc (sd, lb_nobusyq[idle]); goto out_balanced;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 2/31 sched, numa, mm: Describe the NUMA scheduling problem formally
In reply to Peter ZijlstraThis is probably a first: formal description of a complex high-level computing problem, within the kernel source.
Rik van Riel <[email protected]>
--- Documentation/scheduler/numa-problem.txt | 230 +++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 Documentation/scheduler/numa-problem.txt
Documentation/scheduler/numa-problem.txt new file +230 -0
@@ -0,0 +1,230 @@ + + +Effective NUMA scheduling problem statement, described formally: + + * minimize interconnect traffic + +For each task 't_i' we have memory, this memory can be spread over multiple +physical nodes, let us denote this as: 'p_i,k', the memory task 't_i' has on +node 'k' in [pages]. + +If a task shares memory with another task let us denote this as: +'s_i,k', the memory shared between tasks including 't_i' residing on node +'k'. + +Let 'M' be the distribution that governs all 'p' and 's', ie. the page placement. + +Similarly, lets define 'fp_i,k' and 'fs_i,k' resp. as the (average) usage +frequency over those memory regions [1/s] such that the product gives an +(average) bandwidth 'bp' and 'bs' in [pages/s]. + +(note: multiple tasks sharing memory naturally avoid duplicat accounting + because each task will have its own access frequency 'fs') + +(pjt: I think this frequency is more numerically consistent if you explicitly + restrict p/s above to be the working-set. (It also makes explicit the + requirement for <C0,M0> to change about a change in the working set.) + + Doing this does have the nice property that it lets you use your frequency + measurement as a weak-ordering for the benefit a task would receive when + we can't fit everything. + + e.g. task1 has working set 10mb, f=90% + task2 has working set 90mb, f=10% + + Both are using 9mb/s of bandwidth, but we'd expect a much larger benefit + from task1 being on the right node than task2. ) + +Let 'C' map every task 't_i' to a cpu 'c_i' and its corresponding node 'n_i': + + C: t_i -> {c_i, n_i} + +This gives us the total interconnect traffic between nodes 'k' and 'l', +'T_k,l', as: + + T_k,l = \Sum_i bp_i,l + bs_i,l + \Sum bp_j,k + bs_j,k where n_i == k, n_j == l + +And our goal is to obtain C0 and M0 such that: + + T_k,l(C0, M0) =< T_k,l(C, M) for all C, M where k != l + +(note: we could introduce 'nc(k,l)' as the cost function of accessing memory + on node 'l' from node 'k', this would be useful for bigger NUMA systems + + pjt: I agree nice to have, but intuition suggests diminishing returns on more + usual systems given factors like things like Haswell's enormous 35mb l3 + cache and QPI being able to do a direct fetch.) + +(note: do we need a limit on the total memory per node?) + + + * fairness + +For each task 't_i' we have a weight 'w_i' (related to nice), and each cpu +'c_n' has a compute capacity 'P_n', again, using our map 'C' we can formulate a +load 'L_n': + + L_n = 1/P_n * \Sum_i w_i for all c_i = n + +using that we can formulate a load difference between CPUs + + L_n,m = | L_n - L_m | + +Which allows us to state the fairness goal like: + + L_n,m(C0) =< L_n,m(C) for all C, n != m + +(pjt: It can also be usefully stated that, having converged at C0: + + | L_n(C0) - L_m(C0) | <= 4/3 * | G_n( U(t_i, t_j) ) - G_m( U(t_i, t_j) ) | + + Where G_n,m is the greedy partition of tasks between L_n and L_m. This is + the "worst" partition we should accept; but having it gives us a useful + bound on how much we can reasonably adjust L_n/L_m at a Pareto point to + favor T_n,m. ) + +Together they give us the complete multi-objective optimization problem: + + min_C,M [ L_n,m(C), T_k,l(C,M) ] + + + +Notes: + + - the memory bandwidth problem is very much an inter-process problem, in + particular there is no such concept as a process in the above problem. + + - the naive solution would completely prefer fairness over interconnect + traffic, the more complicated solution could pick another Pareto point using + an aggregate objective function such that we balance the loss of work + efficiency against the gain of running, we'd want to more or less suggest + there to be a fixed bound on the error from the Pareto line for any + such solution. + +References: + + http://en.wikipedia.org/wiki/Mathematical_optimization + http://en.wikipedia.org/wiki/Multi-objective_optimization + + +* warning, significant hand-waving ahead, improvements welcome * + + +Partial solutions / approximations: + + 1) have task node placement be a pure preference from the 'fairness' pov. + +This means we always prefer fairness over interconnect bandwidth. This reduces +the problem to: + + min_C,M [ T_k,l(C,M) ] + + 2a) migrate memory towards 'n_i' (the task's node). + +This creates memory movement such that 'p_i,k for k != n_i' becomes 0 -- +provided 'n_i' stays stable enough and there's sufficient memory (looks like +we might need memory limits for this). + +This does however not provide us with any 's_i' (shared) information. It does +however remove 'M' since it defines memory placement in terms of task +placement. + +XXX properties of this M vs a potential optimal + + 2b) migrate memory towards 'n_i' using 2 samples. + +This separates pages into those that will migrate and those that will not due +to the two samples not matching. We could consider the first to be of 'p_i' +(private) and the second to be of 's_i' (shared). + +This interpretation can be motivated by the previously observed property that +'p_i,k for k != n_i' should become 0 under sufficient memory, leaving only +'s_i' (shared). (here we loose the need for memory limits again, since it +becomes indistinguishable from shared). + +XXX include the statistical babble on double sampling somewhere near + +This reduces the problem further; we loose 'M' as per 2a, it further reduces +the 'T_k,l' (interconnect traffic) term to only include shared (since per the +above all private will be local): + + T_k,l = \Sum_i bs_i,l for every n_i = k, l != k + +[ more or less matches the state of sched/numa and describes its remaining + problems and assumptions. It should work well for tasks without significant + shared memory usage between tasks. ] + +Possible future directions: + +Motivated by the form of 'T_k,l', try and obtain each term of the sum, so we +can evaluate it; + + 3a) add per-task per node counters + +At fault time, count the number of pages the task faults on for each node. +This should give an approximation of 'p_i' for the local node and 's_i,k' for +all remote nodes. + +While these numbers provide pages per scan, and so have the unit [pages/s] they +don't count repeat access and thus aren't actually representable for our +bandwidth numberes. + + 3b) additional frequency term + +Additionally (or instead if it turns out we don't need the raw 'p' and 's' +numbers) we can approximate the repeat accesses by using the time since marking +the pages as indication of the access frequency. + +Let 'I' be the interval of marking pages and 'e' the elapsed time since the +last marking, then we could estimate the number of accesses 'a' as 'a = I / e'. +If we then increment the node counters using 'a' instead of 1 we might get +a better estimate of bandwidth terms. + + 3c) additional averaging; can be applied on top of either a/b. + +[ Rik argues that decaying averages on 3a might be sufficient for bandwidth since + the decaying avg includes the old accesses and therefore has a measure of repeat + accesses. + + Rik also argued that the sample frequency is too low to get accurate access + frequency measurements, I'm not entirely convinced, event at low sample + frequencies the avg elapsed time 'e' over multiple samples should still + give us a fair approximation of the avg access frequency 'a'. + + So doing both b&c has a fair chance of working and allowing us to distinguish + between important and less important memory accesses. + + Experimentation has shown no benefit from the added frequency term so far. ] + +This will give us 'bp_i' and 'bs_i,k' so that we can approximately compute +'T_k,l' Our optimization problem now reads: + + min_C [ \Sum_i bs_i,l for every n_i = k, l != k ] + +And includes only shared terms, this makes sense since all task private memory +will become local as per 2. + +This suggests that if there is significant shared memory, we should try and +move towards it. + + 4) move towards where 'most' memory is + +The simplest significance test is comparing the biggest shared 's_i,k' against +the private 'p_i'. If we have more shared than private, move towards it. + +This effectively makes us move towards where most our memory is and forms a +feed-back loop with 2. We migrate memory towards us and we migrate towards +where 'most' memory is. + +(Note: even if there were two tasks fully trashing the same shared memory, it + is very rare for there to be an 50/50 split in memory, lacking a perfect + split, the small will move towards the larger. In case of the perfect + split, we'll tie-break towards the lower node number.) + + 5) 'throttle' 4's node placement + +Since per 2b our 's_i,k' and 'p_i' require at least two scans to 'stabilize' +and show representative numbers, we should limit node-migration to not be +faster than this. + + n) poke holes in previous that require more stuff and describe it.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 02/31] sched, numa, mm: Describe the NUMA scheduling problem formally
Quoted 3 lines · Peter Zijlstra
This is probably a first: formal description of a complex high-level computing problem, within the kernel source.
Who does not love the smell of formal methods first thing in the morning?
Quoted 8 lines
Signed-off-by Peter Zijlstra <[email protected]>Cc Linus Torvalds <[email protected]>Cc Andrew Morton <[email protected]>Cc Peter Zijlstra <[email protected]>Cc "H. Peter Anvin" <[email protected]>Cc Mike Galbraith <[email protected]>Rik van Riel <[email protected]>
[ Next step: generate the kernel source from such formal descriptions and retire to a tropical island! ]
You can use the computing award monies as a pension.
Quoted 15 lines
Signed-off-by Ingo Molnar <[email protected]>--- Documentation/scheduler/numa-problem.txt | 230 +++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 Documentation/scheduler/numa-problem.txtIndex:
tip/Documentation/scheduler/numa-problem.txt
===================================================================Documentation/scheduler/numa-problem.txt new file +4
-0@@ -0,0 +1,230 @@ + + +Effective NUMA scheduling problem statement, described formally: +
Documentation/scheduler/numa-problem.txt line 14
Quoted 10 lines
Documentation/scheduler/numa-problem.txt new file +10
-0+ * minimize interconnect traffic + +For each task 't_i' we have memory, this memory can be spread over multiple +physical nodes, let us denote this as: 'p_i,k', the memory task 't_i' has on +node 'k' in [pages]. + +If a task shares memory with another task let us denote this as: +'s_i,k', the memory shared between tasks including 't_i' residing on node +'k'. +
This does not take into account false sharing. T_0 and T_1 could map a region MAP_SHARED that is not page-aligned. It is approximately, but not quite, a shared page and how it is detected matters. For the purposes of the optimisation, it sounds like it should not matter but as the NUMA01 test case is a worst-case scenario for false-sharing and sched-numa suffers badly badly there, it might be important.
Documentation/scheduler/numa-problem.txt line 20
Quoted 6 lines
Documentation/scheduler/numa-problem.txt new file +6
-0+Let 'M' be the distribution that governs all 'p' and 's', ie. the page placement. + +Similarly, lets define 'fp_i,k' and 'fs_i,k' resp. as the (average) usage +frequency over those memory regions [1/s] such that the product gives an +(average) bandwidth 'bp' and 'bs' in [pages/s]. +
We cannot directly measure this without using profiles all of the time. I assume we will approximate this with sampling but it does mean we depend very heavily on that sampling being representative to make the correct decisions.
Documentation/scheduler/numa-problem.txt line 27
Quoted 7 lines
Documentation/scheduler/numa-problem.txt new file +7
-0+(note: multiple tasks sharing memory naturally avoid duplicat accounting + because each task will have its own access frequency 'fs') + +(pjt: I think this frequency is more numerically consistent if you explicitly + restrict p/s above to be the working-set. (It also makes explicit the + requirement for <C0,M0> to change about a change in the working set.) +
Do you mean p+s? i.e. explicitly restrict p and s to be all task-local and task-shared pages currently used by the system? If so, I agree that it would be numerically more consistent. If p_i is all mapped pages instead of the working set then depending on exactly how it is calculated, the "average usage" can appear to drop if the process maps more regions. This would be unhelpful because it sets of perverse incentives for tasks to game the algorithm.
Quoted 9 lines
Documentation/scheduler/numa-problem.txt new file +9
-0+ Doing this does have the nice property that it lets you use your frequency + measurement as a weak-ordering for the benefit a task would receive when + we can't fit everything. + + e.g. task1 has working set 10mb, f=90% + task2 has working set 90mb, f=10% + + Both are using 9mb/s of bandwidth, but we'd expect a much larger benefit + from task1 being on the right node than task2. )
Documentation/scheduler/numa-problem.txt line 46
Quoted 10 lines
Documentation/scheduler/numa-problem.txt new file +10
-0+ +Let 'C' map every task 't_i' to a cpu 'c_i' and its corresponding node 'n_i': + + C: t_i -> {c_i, n_i} + +This gives us the total interconnect traffic between nodes 'k' and 'l', +'T_k,l', as: + + T_k,l = \Sum_i bp_i,l + bs_i,l + \Sum bp_j,k + bs_j,k where n_i == k, n_j == l +
Task in this case must really mean a kernel task. It does not and should not distinguish between processes and threads because for the purposes of p_i and s_i, it doesn't matter. If this is right, there is no harm in clarifying it.
Documentation/scheduler/numa-problem.txt line 50
Quoted 4 lines
Documentation/scheduler/numa-problem.txt new file +4
-0+And our goal is to obtain C0 and M0 such that: + + T_k,l(C0, M0) =< T_k,l(C, M) for all C, M where k != l +
You could add "Informally, the goal is to minimise interconnect traffic".
Documentation/scheduler/numa-problem.txt line 57
Quoted 7 lines
Documentation/scheduler/numa-problem.txt new file +7
-0+(note: we could introduce 'nc(k,l)' as the cost function of accessing memory + on node 'l' from node 'k', this would be useful for bigger NUMA systems + + pjt: I agree nice to have, but intuition suggests diminishing returns on more + usual systems given factors like things like Haswell's enormous 35mb l3 + cache and QPI being able to do a direct fetch.) +
Besides, even if the NUMA distance is fixed that does not mean the cost of a NUMA miss from the perspective of a process is fixed because it could prefetched on one hand or cached locally in L1 or L2 cache on the other. It's just not worth taking the weight into account.
Documentation/scheduler/numa-problem.txt line 59
Quoted 2 lines
Documentation/scheduler/numa-problem.txt new file +2
-0+(note: do we need a limit on the total memory per node?) +
It only needs to be taken into account if the task is using more memory than fits into a node. You may be able to indirectly measure this in practive using the numa_foreign counter.
If schednuma is enabled and numa_foreign is rapidly increasing it might indiate that the total memory available and \Sum_i p_i,k + s_i,k has to be taken into account. Hopefully such a thing can be avoided because it would be expensive to calculate.
Documentation/scheduler/numa-problem.txt line 72
Quoted 13 lines
Documentation/scheduler/numa-problem.txt new file +13
-0+ + * fairness + +For each task 't_i' we have a weight 'w_i' (related to nice), and each cpu +'c_n' has a compute capacity 'P_n', again, using our map 'C' we can formulate a +load 'L_n': + + L_n = 1/P_n * \Sum_i w_i for all c_i = n + +using that we can formulate a load difference between CPUs + + L_n,m = | L_n - L_m | +
This is showing a strong bias towards the scheduler. As you take w_i into account, it potentially means that higher priority tasks can "push" lower priority tasks and their memory off a node. This can lead to a situation where a high priority task can starve a lower priority task as the lower priority task now must dedicate cycles to moving its memory around.
I understand your motivation for taking weight into account here but I wonder if it's premature?
Quoted 7 lines
Documentation/scheduler/numa-problem.txt new file +7
-0+Which allows us to state the fairness goal like: + + L_n,m(C0) =< L_n,m(C) for all C, n != m + +(pjt: It can also be usefully stated that, having converged at C0: + + | L_n(C0) - L_m(C0) | <= 4/3 * | G_n( U(t_i, t_j) ) - G_m( U(t_i, t_j) ) |
Documentation/scheduler/numa-problem.txt line 89
Quoted 10 lines
Documentation/scheduler/numa-problem.txt new file +10
-0+ + Where G_n,m is the greedy partition of tasks between L_n and L_m. This is + the "worst" partition we should accept; but having it gives us a useful + bound on how much we can reasonably adjust L_n/L_m at a Pareto point to + favor T_n,m. ) + +Together they give us the complete multi-objective optimization problem: + + min_C,M [ L_n,m(C), T_k,l(C,M) ] +
I admire the goal and the apparent simplicity but I think there are potentially unexpected outcomes when you try to minimise both.
For example
2-node machine, 24 cores, 4G per node
1 compute process, 24 threads - workload is adaptive mesh computation
of some sort that fits in 3G
Early in the lifetime of this, it will be balanced between the two nodes (minimising interconnect traffic and CPU load). As it computes it might refine the mesh such that all 24 threads are operating on just 1G of memory on one node with a lot of false sharing within pages. In this case you effectively want the memory to be pinned on one node even if all threads are in use. As these pages are all probably in p (but maybe s, it's a gray area in this case) it potentially leads to a ping-pong effect when we minimise for L_n,m(C). I know we would try to solve for both but as T_k,l is based on something we cannot accurately measure at runtime, there will be drift.
Another example
2-node machine, 24 cores, 4G per node
1 compute process, 2 threads, 1 thread needs 6G
In this case we cannot minimise for T_k,l as spillover is inevitable and interconnect traffic will never be 0. To get around this, the scheduled CPU would always have to follow memory i.e. the thread uses cpu on node 0 when operating on that memory and switching to a cpu on node 1 otherwise. I'm not sure how this can be modelled under the optimization problem as presented.
At this point I'm not proposing a solution - I'm just pointing out that there are potential corner cases where this can get screwy.
FWIW, we still benefit from having this formally described even if it cannot cover all the cases.
Documentation/scheduler/numa-problem.txt line 96
Quoted 7 lines
Documentation/scheduler/numa-problem.txt new file +7
-0+ + +Notes: + + - the memory bandwidth problem is very much an inter-process problem, in + particular there is no such concept as a process in the above problem. +
Yep.
Documentation/scheduler/numa-problem.txt line 103
Quoted 7 lines
Documentation/scheduler/numa-problem.txt new file +7
-0+ - the naive solution would completely prefer fairness over interconnect + traffic, the more complicated solution could pick another Pareto point using + an aggregate objective function such that we balance the loss of work + efficiency against the gain of running, we'd want to more or less suggest + there to be a fixed bound on the error from the Pareto line for any + such solution. +
I suspect that the Pareto point and objective function will depend on the workload, whether it fits in the node and whether its usage of memory between nodes and tasks is balanced or not.
It would be ideal though to have such a function.
Quoted 8 lines
Documentation/scheduler/numa-problem.txt new file +8
-0+References: + + http://en.wikipedia.org/wiki/Mathematical_optimization + http://en.wikipedia.org/wiki/Multi-objective_optimization + + +* warning, significant hand-waving ahead, improvements welcome * +
Documentation/scheduler/numa-problem.txt line 121
Quoted 10 lines
Documentation/scheduler/numa-problem.txt new file +10
-0+ +Partial solutions / approximations: + + 1) have task node placement be a pure preference from the 'fairness' pov. + +This means we always prefer fairness over interconnect bandwidth. This reduces +the problem to: + + min_C,M [ T_k,l(C,M) ] +
Is this not preferring interconnect bandwidth over fairness? i.e. always reduce interconnect bandwidth regardless of how the CPUs are being used?
Documentation/scheduler/numa-problem.txt line 127
Quoted 6 lines
Documentation/scheduler/numa-problem.txt new file +6
-0+ 2a) migrate memory towards 'n_i' (the task's node). + +This creates memory movement such that 'p_i,k for k != n_i' becomes 0 -- +provided 'n_i' stays stable enough and there's sufficient memory (looks like +we might need memory limits for this). +
Not just memory limits, you may need to detect if p_i fits in k. Last thing you need is an effect like zone_reclaim_mode==1 where t_i is reclaiming its own memory to migrate pages to a local node. Such a thing could not be happening currently as the benchmarks would have shown the scanning.
Documentation/scheduler/numa-problem.txt line 139
Quoted 12 lines
Documentation/scheduler/numa-problem.txt new file +12
-0+This does however not provide us with any 's_i' (shared) information. It does +however remove 'M' since it defines memory placement in terms of task +placement. + +XXX properties of this M vs a potential optimal + + 2b) migrate memory towards 'n_i' using 2 samples. + +This separates pages into those that will migrate and those that will not due +to the two samples not matching. We could consider the first to be of 'p_i' +(private) and the second to be of 's_i' (shared). +
When minimising for L_n,m this could cause problems. Lets say we are dealing with the first example above. The memory should be effectively pinned on one node. If we minimise for L_n, we are using CPUs on a remote node and if it samples twice, it will migrate the memory setting up a potential ping-pong effect if there is any false sharing of pages.
Of course, this is not a problem if the memory of a task can be partitioned into s_i and p_i but it heavily depends on detecting s_i correctly.
Documentation/scheduler/numa-problem.txt line 146
Quoted 7 lines
Documentation/scheduler/numa-problem.txt new file +7
-0+This interpretation can be motivated by the previously observed property that +'p_i,k for k != n_i' should become 0 under sufficient memory, leaving only +'s_i' (shared). (here we loose the need for memory limits again, since it +becomes indistinguishable from shared). + +XXX include the statistical babble on double sampling somewhere near +
Minimally, I do not see an obvious way of describing why 3, 4, 7 or eleventy samples would be better than 2. To high and it migrates too slowly. Too low and it ping-pongs and the ideal number of samples is workload-dependant.
Quoted 11 lines
Documentation/scheduler/numa-problem.txt new file +11
-0+This reduces the problem further; we loose 'M' as per 2a, it further reduces +the 'T_k,l' (interconnect traffic) term to only include shared (since per the +above all private will be local): + + T_k,l = \Sum_i bs_i,l for every n_i = k, l != k + +[ more or less matches the state of sched/numa and describes its remaining + problems and assumptions. It should work well for tasks without significant + shared memory usage between tasks. ] + +Possible future directions:
Documentation/scheduler/numa-problem.txt line 167
Quoted 10 lines
Documentation/scheduler/numa-problem.txt new file +10
-0+ +Motivated by the form of 'T_k,l', try and obtain each term of the sum, so we +can evaluate it; + + 3a) add per-task per node counters + +At fault time, count the number of pages the task faults on for each node. +This should give an approximation of 'p_i' for the local node and 's_i,k' for +all remote nodes. +
Yes. The rate of sampling will determine how accurate it is.
Documentation/scheduler/numa-problem.txt line 171
Quoted 4 lines
Documentation/scheduler/numa-problem.txt new file +4
-0+While these numbers provide pages per scan, and so have the unit [pages/s] they +don't count repeat access and thus aren't actually representable for our +bandwidth numberes. +
Counting repeat accesses would require either continual profiling (and hardware that can identify the data address not just the IP) or aggressive sampling - neither which is appealing. In other words, an approximation of p_i is as good as we are going to get.
Documentation/scheduler/numa-problem.txt line 177
Quoted 6 lines
Documentation/scheduler/numa-problem.txt new file +6
-0+ 3b) additional frequency term + +Additionally (or instead if it turns out we don't need the raw 'p' and 's' +numbers) we can approximate the repeat accesses by using the time since marking +the pages as indication of the access frequency. +
Risky. If the process blocks on IO this could skew in unexpected ways because such an approximation assumes the task is CPU or memory bound.
Documentation/scheduler/numa-problem.txt line 182
Quoted 5 lines
Documentation/scheduler/numa-problem.txt new file +5
-0+Let 'I' be the interval of marking pages and 'e' the elapsed time since the +last marking, then we could estimate the number of accesses 'a' as 'a = I / e'. +If we then increment the node counters using 'a' instead of 1 we might get +a better estimate of bandwidth terms. +
Not keen on this one. It really assumes that there is more or less constant use of the CPU.
Documentation/scheduler/numa-problem.txt line 188
Quoted 6 lines
Documentation/scheduler/numa-problem.txt new file +6
-0+ 3c) additional averaging; can be applied on top of either a/b. + +[ Rik argues that decaying averages on 3a might be sufficient for bandwidth since + the decaying avg includes the old accesses and therefore has a measure of repeat + accesses. +
Minimally, it would be less vunerable to spikes.
Documentation/scheduler/numa-problem.txt line 193
Quoted 5 lines
Documentation/scheduler/numa-problem.txt new file +5
-0+ Rik also argued that the sample frequency is too low to get accurate access + frequency measurements, I'm not entirely convinced, event at low sample + frequencies the avg elapsed time 'e' over multiple samples should still + give us a fair approximation of the avg access frequency 'a'. +
Sampling too high also increases the risk of a ping-pong effect.
Documentation/scheduler/numa-problem.txt line 198
Quoted 5 lines
Documentation/scheduler/numa-problem.txt new file +5
-0+ So doing both b&c has a fair chance of working and allowing us to distinguish + between important and less important memory accesses. + + Experimentation has shown no benefit from the added frequency term so far. ] +
At this point, I prefer a&c over b&c but that could just be because I'm wary of time-based heuristics having been bit by them once or twice.
Quoted 6 lines
Documentation/scheduler/numa-problem.txt new file +6
-0+This will give us 'bp_i' and 'bs_i,k' so that we can approximately compute +'T_k,l' Our optimization problem now reads: + + min_C [ \Sum_i bs_i,l for every n_i = k, l != k ] + +And includes only shared terms, this makes sense since all task private memory
Documentation/scheduler/numa-problem.txt line 214
Quoted 10 lines
Documentation/scheduler/numa-problem.txt new file +10
-0+will become local as per 2. + +This suggests that if there is significant shared memory, we should try and +move towards it. + + 4) move towards where 'most' memory is + +The simplest significance test is comparing the biggest shared 's_i,k' against +the private 'p_i'. If we have more shared than private, move towards it. +
Depending on how s_i is calculated, this might also mitigate the ping-pong problem.
Quoted 7 lines
Documentation/scheduler/numa-problem.txt new file +6
-0+This effectively makes us move towards where most our memory is and forms a +feed-back loop with 2. We migrate memory towards us and we migrate towards +where 'most' memory is. + +(Note: even if there were two tasks fully trashing the same shared memory, it + is very rare for there to be an 50/50 split in memory, lacking a perfect
Documentation/scheduler/numa-problem.txt line 230
Quoted 10 lines
Documentation/scheduler/numa-problem.txt new file +10
-0+ split, the small will move towards the larger. In case of the perfect + split, we'll tie-break towards the lower node number.) + + 5) 'throttle' 4's node placement + +Since per 2b our 's_i,k' and 'p_i' require at least two scans to 'stabilize' +and show representative numbers, we should limit node-migration to not be +faster than this. + + n) poke holes in previous that require more stuff and describe it.
Even as it is, this is a helpful description of the problem! Thanks.
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 02/31] sched, numa, mm: Describe the NUMA scheduling problem formally
Quoted 7 lines · Mel Gorman
Quoted 3 lines · Peter Zijlstra
This is probably a first: formal description of a complex high-level computing problem, within the kernel source.
Who does not love the smell of formal methods first thing in the morning?
The only issue I have with this document is that it does not have any description of how the source code tries to solve the problem at hand.
A description of how the problem is solved will make the documentation useful to people trying to figure out why the NUMA code does what it does.
Of course, since we still do not know what sched-numa needs to do in order to match autonuma performance, that description would have to be updated later, anyway.
Signature · 7 lines
All rights reversed -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 3/31 mm/thp: Preserve pgprot across huge page split
In reply to Peter ZijlstraWe're going to play games with page-protections, ensure we don't lose them over a THP split.
Collapse seems to always allocate a new (huge) page which should already end up on the new target node so loosing protections there isn't a problem.
--- arch/x86/include/asm/pgtable.h | 1 mm/huge_memory.c | 105 +++++++++++++++++++---------------------- 2 files changed, 51 insertions(+), 55 deletions(-)
arch/x86/include/asm/pgtable.h +1 -0
@@ -349,6 +349,7 @@ static inline pgprot_t pgprot_modify(pgp }#define pte_pgprot (x) __pgprot(pte_flags(x) & PTE_FLAGS_MASK) +#define pmd_pgprot (x) __pgprot(pmd_val(x) & ~_HPAGE_CHG_MASK)#define canon_pgprot (p) __pgprot(massage_pgprot(p))
mm/huge_memory.c +50 -55
123 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 03/31] mm/thp: Preserve pgprot across huge page split
Quoted 3 lines · Peter Zijlstra
We're going to play games with page-protections, ensure we don't lose them over a THP split.
Why?
If PROT_NONE becomes a present pte, we lose samples. If a present pte becomes PROT_NONE, we get spurious faults and some sampling oddities. Both situations only apply when a THP is being split which implies distruption anyway (mprotect, page reclaim etc.) and neither seems that series. It seems premature at this point of the series and looks like it could have been dropped entirely.
Quoted 86 lines
Collapse seems to always allocate a new (huge) page which should already end up on the new target node so loosing protections there isn't a problem.
Signed-off-by Peter Zijlstra <[email protected]>Reviewed-by Rik van Riel <[email protected]>Cc Paul Turner <[email protected]>Cc Linus Torvalds <[email protected]>Cc Andrew Morton <[email protected]>Cc Andrea Arcangeli <[email protected]>Signed-off-by Ingo Molnar <[email protected]>--- arch/x86/include/asm/pgtable.h | 1 mm/huge_memory.c | 105 +++++++++++++++++++---------------------- 2 files changed, 51 insertions(+), 55 deletions(-)Index:
tip/arch/x86/include/asm/pgtable.h
===================================================================arch/x86/include/asm/pgtable.h +1
-0@@ -349,6 +349,7 @@ static inline pgprot_t pgprot_modify(pgp }#define pte_pgprot (x) __pgprot(pte_flags(x) & PTE_FLAGS_MASK) +#define pmd_pgprot (x) __pgprot(pmd_val(x) & ~_HPAGE_CHG_MASK)#define canon_pgprot (p) __pgprot(massage_pgprot(p))Index:
tip/mm/huge_memory.c
===================================================================mm/huge_memory.c +1
-45@@ -1343,63 +1343,60 @@ static int __split_huge_page_map(structint ret =0 , i;pgtable_t pgtable;unsigned long haddr; +pgprot_t prot;spin_lock (&mm->page_table_lock); pmd =page_check_address_pmd (page, mm, address,PAGE_CHECK_ADDRESS_PMD_SPLITTING_FLAG ); -if (pmd) { - pgtable =pgtable_trans_huge_withdraw (mm); -pmd_populate (mm, &_pmd, pgtable); - - haddr = address; -for (i =0 ; i <HPAGE_PMD_NR ; i++, haddr +=PAGE_SIZE ) { -pte_t *pte, entry; -BUG_ON (PageCompound (page+i)); - entry =mk_pte (page + i, vma->vm_page_prot); - entry =maybe_mkwrite (pte_mkdirty (entry), vma); -if (!pmd_write (*pmd)) - entry =pte_wrprotect (entry); -else -BUG_ON (page_mapcount (page) !=1 ); -if (!pmd_young (*pmd)) - entry =pte_mkold (entry); - pte =pte_offset_map (&_pmd, haddr); -BUG_ON (!pte_none (*pte)); -set_pte_at (mm, haddr, pte, entry); -pte_unmap (pte); - } - -smp_wmb ();/* make pte visible before pmd */ -/* -* Up to this point the pmd is present and huge and -* userland has the whole access to the hugepage -* during the split (which happens in place). If we -* overwrite the pmd with the not-huge version -* pointing to the pte here (which of course we could -* if all CPUs were bug free), userland could trigger -* a small page size TLB miss on the small sized TLB -* while the hugepage TLB entry is still established -* in the huge TLB. Some CPU doesn't like that. See -* http://support.amd.com/us/Processor_TechDocs/41322.pdf, -* Erratum 383 on page 93. Intel should be safe but is -* also warns that it's only safe if the permission -* and cache attributes of the two entries loaded in -* the two TLB is identical (which should be the case -* here). But it is generally safer to never allow -* small and huge TLB entries for the same virtual -* address to be loaded simultaneously. So instead of -* doing "pmd_populate(); flush_tlb_range();" we first -* mark the current pmd notpresent (atomically because -* here the pmd_trans_huge and pmd_trans_splitting -* must remain set at all times on the pmd until the
mm/huge_memory.c static int __split_huge_page_map(struct · line 1353
Quoted 10 lines
mm/huge_memory.c +3
-7-* split is complete for this pmd), then we flush the -* SMP TLB and finally we write the non-huge version -* of the pmd entry with pmd_populate. -*/ -pmdp_invalidate (vma, address, pmd); -pmd_populate (mm, pmd, pgtable); - ret =1 ; +if (!pmd) + goto unlock; +
*whinge*
Changing the pmd check like this churned the code a more than necessary making it harder to review. It forces me to move back and forth to figure out exactly what it is you added. If you wanted to do this cleanup, it should have been a separate patch.
mm/huge_memory.c static int __split_huge_page_map(struct · line 1363
Quoted 10 lines
mm/huge_memory.c +10
-0+ prot =pmd_pgprot (*pmd); + pgtable =pgtable_trans_huge_withdraw (mm); +pmd_populate (mm, &_pmd, pgtable); + +for (i =0 , haddr = address; i <HPAGE_PMD_NR ; i++, haddr +=PAGE_SIZE ) { +pte_t *pte, entry; + +BUG_ON (PageCompound (page+i)); + entry =mk_pte (page + i, prot); + entry =pte_mkdirty (entry);
For example, because of the churn, it's not obvious that the
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
if (!pmd_write(*pmd))
entry = pte_wrprotect(entry);
else
BUG_ON(page_mapcount(page) != 1);checks went away and you are instead using the prot flags retrieved by pmd_pgprot to preserve _PAGE_RW which I think is the actual point of the patch even if it's not obvious from the diff.
Quoted 42 lines
mm/huge_memory.c +35
-0+if (!pmd_young (*pmd)) + entry =pte_mkold (entry); + pte =pte_offset_map (&_pmd, haddr); +BUG_ON (!pte_none (*pte)); +set_pte_at (mm, haddr, pte, entry); +pte_unmap (pte); } + +smp_wmb ();/* make ptes visible before pmd, see __pte_alloc */ +/* +* Up to this point the pmd is present and huge. +* +* If we overwrite the pmd with the not-huge version, we could trigger +* a small page size TLB miss on the small sized TLB while the hugepage +* TLB entry is still established in the huge TLB. +* +* Some CPUs don't like that. See +* http://support.amd.com/us/Processor_TechDocs/41322.pdf, Erratum 383 +* on page 93. +* +* Thus it is generally safer to never allow small and huge TLB entries +* for overlapping virtual addresses to be loaded. So we first mark the +* current pmd not present, then we flush the TLB and finally we write +* the non-huge version of the pmd entry with pmd_populate. +* +* The above needs to be done under the ptl because pmd_trans_huge and +* pmd_trans_splitting must remain set on the pmd until the split is +* complete. The ptl also protects against concurrent faults due to +* making the pmd not-present. +*/ +set_pmd_at (mm, address, pmd,pmd_mknotpresent (*pmd)); +flush_tlb_range (vma, address, address +HPAGE_PMD_SIZE ); +pmd_populate (mm, pmd, pgtable); + ret =1 ; + +unlock:spin_unlock (&mm->page_table_lock);return ret;@@ -2287,10 +2284,8 @@ static void khugepaged_do_scan(void) {
mm/huge_memory.c static void khugepaged_do_scan(void) · line 2291
Quoted 10 lines
mm/huge_memory.c +1
-3struct page *hpage =NULL ;unsigned int progress =0 , pass_through_head =0 ; -unsigned int pages = khugepaged_pages_to_scan;bool wait = true; - -barrier ();/* write khugepaged_pages_to_scan to local stack */ +unsigned int pages =ACCESS_ONCE (khugepaged_pages_to_scan);while (progress < pages) {if (!khugepaged_prealloc_page (&hpage, &wait))
This hunk looks fine but has nothing to do with the patch or the changelog.
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 4/31 x86/mm: Introduce pte_accessible()
In reply to Peter ZijlstraFrom: Rik van Riel <[email protected]>
We need pte_present to return true for _PAGE_PROTNONE pages, to indicate that the pte is associated with a page.
However, for TLB flushing purposes, we would like to know whether the pte points to an actually accessible page. This allows us to skip remote TLB flushes for pages that are not actually accessible.
--- arch/x86/include/asm/pgtable.h | 6 ++++++ include/asm-generic/pgtable.h | 4 ++++ 2 files changed, 10 insertions(+)
arch/x86/include/asm/pgtable.h +6 -0
@@ -408,6 +408,12 @@ static inline int pte_present(pte_t a)return pte_flags (a) & (_PAGE_PRESENT | _PAGE_PROTNONE); } +#define __HAVE_ARCH_PTE_ACCESSIBLE +static inline int pte_accessible (pte_t a) +{ +return pte_flags (a) & _PAGE_PRESENT; +} +static inline int pte_hidden (pte_t pte) {return pte_flags (pte) & _PAGE_HIDDEN;
include/asm-generic/pgtable.h +4 -0
@@ -219,6 +219,10 @@ static inline int pmd_same(pmd_t pmd_a,#define move_pte (pte, prot, old_addr, new_addr) (pte)#endif +#ifndef __HAVE_ARCH_PTE_ACCESSIBLE +#define pte_accessible (pte) pte_present(pte) +#endif +#ifndef flush_tlb_fix_spurious_fault#define flush_tlb_fix_spurious_fault (vma, address) flush_tlb_page(vma, address)#endif
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 04/31] x86/mm: Introduce pte_accessible()
NAK NAK NAK.
arch/x86/include/asm/pgtable.h static inline int pte_present(pte_t a) · line 412
Quoted 3 lines · Peter Zijlstra
arch/x86/include/asm/pgtable.h +2
-0+#define __HAVE_ARCH_PTE_ACCESSIBLE +static inline int pte_accessible (pte_t a)
Stop doing this f*cking crazy ad-hoc "I have some other name available" #defines.
Use the same name, for chissake! Don't make up new random names.
Just do
#define pte_accessible pte_accessible
and then you can use
#ifndef pte_accessible
to define the generic thing. Instead of having this INSANE "two different names for the same f*cking thing" crap.
Stop it. Really.
Also, this:
include/asm-generic/pgtable.h static inline int pmd_same(pmd_t pmd_a, · line 224
Quoted 3 lines
include/asm-generic/pgtable.h +3
-0+#ifndef __HAVE_ARCH_PTE_ACCESSIBLE +#define pte_accessible (pte) pte_present(pte) +#endif
looks unsafe and like a really bad idea.
You should probably do
#ifndef pte_accessible
#define pte_accessible(pte) ((void)(pte),1)
#endifbecause you have no idea if other architectures do
(a) the same trick as x86 does for PROT_NONE (I can already tell you
from a quick grep that ia64, m32r, m68k and sh do it)
(b) might not perhaps be caching non-present pte's anyway
So NAK on this whole patch. It's bad. It's ugly, it's wrong, and it's actively buggy.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v2 4/31 x86/mm: Introduce pte_accessible()
Quoted 14 lines · Linus Torvalds
NAK NAK NAK.
Review
Quoted 3 lines · Peter Zijlstra
(quoted diff) +2
-0+#define __HAVE_ARCH_PTE_ACCESSIBLE +static inline int pte_accessible(pte_t a)Stop doing this f*cking crazy ad-hoc "I have some other name available" #defines.
Use the same name, for chissake! Don't make up new random names.
Just do
Quoted 8 lines
#define pte_accessible pte_accessibleand then you can use
#ifndef pte_accessibleto define the generic thing. Instead of having this INSANE "two different names for the same f*cking thing" crap.
Yeah...
Quoted 16 lines
Stop it. Really.
Also, this:
Review
Quoted 3 lines
(quoted diff) +3
-0+#ifndef __HAVE_ARCH_PTE_ACCESSIBLE +#define pte_accessible(pte) pte_present(pte) +#endiflooks unsafe and like a really bad idea.
You should probably do
#ifndef pte_accessible #define pte_accessible(pte) ((void)(pte),1) #endif
Quoted 5 lines
because you have no idea if other architectures do
(a) the same trick as x86 does for
PROT_NONE(I can already tell you
from a quick grep that ia64, m32r, m68k and sh do it)
(b) might not perhaps be caching non-present pte's anyway
Indeed that's much safer and each arch can opt-in consciously instead of us offering a potentially unsafe optimization.
Quoted 2 lines
So NAK on this whole patch. It's bad. It's ugly, it's wrong, and it's actively buggy.
I have fixed it as per the updated patch below. Only very lightly tested.
Thanks,
Ingo
----------------------------->
Subject: x86/mm: Introduce pte_accessible()
From: Rik van Riel <[email protected]>
Date: Tue, 9 Oct 2012 15:31:12 +0200
We need pte_present to return true for _PAGE_PROTNONE pages, to indicate that the pte is associated with a page.
However, for TLB flushing purposes, we would like to know whether the pte points to an actually accessible page. This allows us to skip remote TLB flushes for pages that are not actually accessible.
Fill in this method for x86 and provide a safe (but slower) method on other architectures.
--- arch/x86/include/asm/pgtable.h | 6 ++++++ include/asm-generic/pgtable.h | 4 ++++ 2 files changed, 10 insertions(+)
arch/x86/include/asm/pgtable.h +6 -0
@@ -408,6 +408,12 @@ static inline int pte_present(pte_t a)return pte_flags (a) & (_PAGE_PRESENT | _PAGE_PROTNONE); } +#define pte_accessible pte_accessible +static inline int pte_accessible (pte_t a) +{ +return pte_flags (a) & _PAGE_PRESENT; +} +static inline int pte_hidden (pte_t pte) {return pte_flags (pte) & _PAGE_HIDDEN;
include/asm-generic/pgtable.h +4 -0
@@ -219,6 +219,10 @@ static inline int pmd_same(pmd_t pmd_a,#define move_pte (pte, prot, old_addr, new_addr) (pte)#endif +#ifndef pte_accessible +# define pte_accessible (pte) ((void)(pte),1) +#endif +#ifndef flush_tlb_fix_spurious_fault#define flush_tlb_fix_spurious_fault (vma, address) flush_tlb_page(vma, address)#endif
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 04/31] x86/mm: Introduce pte_accessible()
In reply to Peter ZijlstraQuoted 9 lines · Peter Zijlstra
From: Rik van Riel <[email protected]>
We need
pte_presentto return true for_PAGE_PROTNONEpages, to indicate that the pte is associated with a page.However, for TLB flushing purposes, we would like to know whether the pte points to an actually accessible page. This allows us to skip remote TLB flushes for pages that are not actually accessible.
It feels like we are putting the cart before the horse to be taking TLB flushing optimisations into account this early in the series. That aside, what was wrong with the following patches?
autonuma: define _PAGE_NUMA
arch-dependant definition of a flag that happens to be PROT_NONE on x86 but could be anything at all really which would help portability
autonuma: pte_numa() and pmd_numa()
makes pte_present do what you want
adds pte_numa and pmd_numa which potentially could have been used instead of pte_accessible
autonuma: teach gup_fast about pmd_numa
sortof self-explanatory
and building on those? The arch-dependant nature of _PAGE_NUMA might have avoided Linus sending the childrens college fund to the swear jar and avoided this complaint;
===
because you have no idea if other architectures do
(a) the same trick as x86 does for PROT_NONE (I can already tell you from a quick grep that ia64, m32r, m68k and sh do it)
(b) might not perhaps be caching non-present pte's anyway
====
The "autonuma: define _PAGE_NUMA" happens to use PROT_NONE but as an implementation detail rather than by design and as a bonus point describes what it is doing. The "autonuma" part in the title is misleading, it's not autonuma-specific at all and could have been dropped or just renamed "numa:"
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 5/31 x86/mm: Reduce tlb flushes from ptep_set_access_flags()
In reply to Peter ZijlstraFrom: Rik van Riel <[email protected]>
If ptep_set_access_flags() is invoked to upgrade access permissions on a PTE, there is no security or data integrity reason to do a remote TLB flush.
Lazily letting another CPU incur a spurious page fault occasionally is (much!) cheaper than aggressively flushing everybody else's TLB.
--- arch/x86/mm/pgtable.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
arch/x86/mm/pgtable.c +16 -1
@@ -306,11 +306,26 @@ int ptep_set_access_flags(struct vm_area pte_t entry, int dirty) { int changed = !pte_same(*ptep, entry); +/* +* If the page used to be inaccessible (_PAGE_PROTNONE), or +* this call upgrades the access permissions on the same page, +* it is safe to skip the remote TLB flush. +*/ +bool flush_remote = false; +if (!pte_accessible (*ptep)) + flush_remote = false; +else if (pte_pfn (*ptep) !=pte_pfn (entry) || + (pte_write (*ptep) && !pte_write (entry)) || + (pte_exec (*ptep) && !pte_exec (entry))) + flush_remote = true;if (changed && dirty) { *ptep = entry;pte_update_defer (vma->vm_mm, address, ptep); -flush_tlb_page (vma, address); +if (flush_remote) +flush_tlb_page (vma, address); +else +__flush_tlb_one (address); }return changed;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 10 lines · Peter Zijlstra
From: Rik van Riel <[email protected]>
arch/x86/mm/pgtable.c +4
-0@@ -306,11 +306,26 @@ int ptep_set_access_flags(struct vm_area pte_t entry, int dirty) {int changed = !pte_same (*ptep, entry); +/* +* If the page used to be inaccessible (_PAGE_PROTNONE), or +* this call upgrades the access permissions on the same page, +* it is safe to skip the remote TLB flush.
arch/x86/mm/pgtable.c int ptep_set_access_flags(struct vm_area · line 322
Quoted 10 lines
arch/x86/mm/pgtable.c +8
-0+*/ +bool flush_remote = false; +if (!pte_accessible (*ptep)) + flush_remote = false; +else if (pte_pfn (*ptep) !=pte_pfn (entry) || + (pte_write (*ptep) && !pte_write (entry)) || + (pte_exec (*ptep) && !pte_exec (entry))) + flush_remote = true;if (changed && dirty) {
Did anybody ever actually look at this sh*t-for-brains patch?
Yeah, I'm grumpy. But I'm wasting time looking at patches that have new code in them that is stupid and retarded.
This is the VM, guys, we don't add stupid and retarded code.
LOOK at the code, for chrissake. Just look at it. And if you don't see why the above is stupid and retarded, you damn well shouldn't be touching VM code.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 24 lines · Linus Torvalds
Quoted 10 lines · Peter Zijlstra
From: Rik van Riel <[email protected]>
arch/x86/mm/pgtable.c +4
-0@@ -306,11 +306,26 @@ int ptep_set_access_flags(struct vm_area pte_t entry, int dirty) {int changed = !pte_same (*ptep, entry); +/* +* If the page used to be inaccessible (_PAGE_PROTNONE), or +* this call upgrades the access permissions on the same page, +* it is safe to skip the remote TLB flush. arch/x86/mm/pgtable.c int ptep_set_access_flags(struct vm_area · line 322
Quoted 10 lines
arch/x86/mm/pgtable.c +8
-0+*/ +bool flush_remote = false; +if (!pte_accessible (*ptep)) + flush_remote = false; +else if (pte_pfn (*ptep) !=pte_pfn (entry) || + (pte_write (*ptep) && !pte_write (entry)) || + (pte_exec (*ptep) && !pte_exec (entry))) + flush_remote = true;if (changed && dirty) {Did anybody ever actually look at this sh*t-for-brains patch?
Quoted 8 lines
Yeah, I'm grumpy. But I'm wasting time looking at patches that have new code in them that is stupid and retarded.
This is the VM, guys, we don't add stupid and retarded code.
LOOK at the code, for chrissake. Just look at it. And if you don't see why the above is stupid and retarded, you damn well shouldn't be touching VM code.
I agree it is pretty ugly. However, the above patch did get rid of a gigantic performance regression with Peter's code.
Doing unnecessary remote TLB flushes was costing about 90% performance with specjbb on a 4 node system.
However, if we can guarantee that ptep_set_access_flags is only ever called for pte permission _upgrades_, we can simply get rid of the remote TLB flush on x86, and skip the paranoia tests we are doing above.
Do we have that kind of guarantee?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 8 lines · Rik van Riel
Quoted 4 lines
LOOK at the code, for chrissake. Just look at it. And if you don't see why the above is stupid and retarded, you damn well shouldn't be touching VM code.
I agree it is pretty ugly. However, the above patch did get rid of a gigantic performance regression with Peter's code.
Rik, *LOOK* at the code like I asked you to, instead of making excuses for it.
I'm not necessarily arguing with what the code tries to do. I'm arguing with the fact that the code is pure and utter *garbage*.
It has two major (and I mean *MAJOR*) problems, both of which individually should make you ashamed for ever posting that piece of shit:
The obvious-without-even-understanding-semantics problem:
- it's humongously stupidly written. It calculates that
'flush_remote' flag WHETHER IT GETS USED OR NOT.
Christ. I can kind of expect stuff like that in driver code etc,
but in VM routines?
Yes, the compiler may be smart enough to actually fix up the
idiocy. That doesn't make it less stupid.
The more-subtle-but-fundamental-problem:
- regardless of how stupidly written it is on a very superficial
level, it's even more stupid in a much more fundamental way.
That whole routine is explicitly written to be opportunistic. It is
*documented* to only set the access flags, so comparing anything else is stupid, wouldn't you say?
Documented where? It's actually explicitly documented in the pgtable-generic.c file which has the generic implementation of that thing. But it's implicitly documented both in the name of the function (do take another look) *and* in the actual implementation of the function.
Look at the code: it doesn't even always update the page tables AT ALL (and no, the return value does *not* reflect whether it updated it or not!)
Also, notice how we update the pte entry with a simple
*ptep = entry;
statement, not with the usual expensive page table updates? The only thing that makes this safe is that we *only* do it with the exact same page frame number (anything else would be disastrously buggy on 32-bit PAE, for example). And we only ever do it with the dirty bit always set, because otherwise we might be silently dropping a concurrent hardware update of the dirty bit of the previous pte value on another CPU.
The latter requirement is why the x86 code does
if (changed && dirty) {while the generic code checks just "If (changed)" (and then uses the much more expensive set_pte_at() that has the proper dirty-bit guarantees, and generates atomic accesses, not to mention various virtualization crap).
In other words, everything that was added by that patch is PURE AND UTTER SHIT. And THAT is what I'm objecting to.
Guess what? If you want to optimize the function to not do remote TLB flushes, then just do that! None of the garbage. Just change the
flush_tlb_page(vma, address);
line to
__flush_tlb_one(address);
and it should damn well work. Because everything I see about "flush_remote" looks just wrong, wrong, wrong.
And if there really is some reason for that whole flush_remote braindamage, then we have much bigger problems, namely the fact that we've broken the documented semantics of that function, and we're doing various other things that are completely and utterly invalid unless the above semantics hold.
So that patch should be burned, and possibly used as an example of horribly crappy code for later generations. At no point should it be applied.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 8 lines · Linus Torvalds
Guess what? If you want to optimize the function to not do remote TLB flushes, then just do that! None of the garbage. Just change the
flush_tlb_page(vma, address);line to
__flush_tlb_one(address);
That may not even be needed. Apparently Intel chips automatically flush an entry from the TLB when it causes a page fault. I assume AMD chips do the same, because flush_tlb_fix_spurious_fault evaluates to nothing on x86.
Quoted 2 lines
and it should damn well work. Because everything I see about "
flush_remote" looks just wrong, wrong, wrong.
Are there architectures where we do need to flush remote TLBs on upgrading the permissions on a PTE?
Because that is what the implementation inpgtable-generic.c seems to be doing as well...
Quoted 5 lines
And if there really is some reason for that whole
flush_remotebraindamage, then we have much bigger problems, namely the fact that we've broken the documented semantics of that function, and we're doing various other things that are completely and utterly invalid unless the above semantics hold.
Want to just remove the TLB flush entirely and see if anything breaks in 3.8-rc1?
From reading the code again, it looks like things should indeed work ok.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 6 lines · Rik van Riel
That may not even be needed. Apparently Intel chips automatically flush an entry from the TLB when it causes a page fault. I assume AMD chips do the same, because
flush_tlb_fix_spurious_faultevaluates to nothing on x86.
Yes. It's not architected as far as I know, though. But I agree, it's possible - even likely - we could avoid TLB flushing entirely on x86.
If you want to try it, I would seriously suggest you do it as a separate commit though, just in case.
Quoted 2 lines
Are there architectures where we do need to flush remote TLBs on upgrading the permissions on a PTE?
I *suspect* that whole TLB flush just magically became an SMP one without anybody ever really thinking about it.
So it's quite possible we could do this to the pgtable-generic.c code too. However, we don't actually have any generic way to do a local single-address flush (the __flush_tlb_one() thing is architecture-specific, although it exists on a few architectures). We'd need to add a local_flush_tlb_page(vma, address) function.
Alternatively, we could decide to use the "tlb_fix_spurious_fault()" thing in there. Possibly just do it unconditionally in the caller - or even just specify that the fault handler has to do it. And stop returning a value at all from ptep_set_access_flags() (I *think* that's the only thing the return value gets used for - flushing the TLB on the local cpu for the cpu's that want it).
Quoted 5 lines
Want to just remove the TLB flush entirely and see if anything breaks in 3.8-rc1?
From reading the code again, it looks like things should indeed work ok.
I would be open to it, but just in case it causes bisectable problems I'd really want to see it in two patches ("make it always do the local flush" followed by "remove even the local flush"), and then it would pinpoint any need.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 7 lines · Linus Torvalds
Quoted 5 lines · Rik van Riel
That may not even be needed. Apparently Intel chips automatically flush an entry from the TLB when it causes a page fault. I assume AMD chips do the same, because
flush_tlb_fix_spurious_faultevaluates to nothing on x86.
Quoted 6 lines
Yes. It's not architected as far as I know, though. But I agree, it's possible - even likely - we could avoid TLB flushing entirely on x86.
If you want to try it, I would seriously suggest you do it as a separate commit though, just in case.
Ok, will do it like that. INVLPG overhead is small effect, nevertheless it's worth trying.
What *has* shown up in my profiles though, and which drove some of these changes is that for heavily threaded VM-intense workloads such as a single SPECjbb JVM instance running on all CPUs and all nodes, TLB flushes with any sort of serialization aspect are absolutely deadly.
So just to be *able* to verify the performance benefit and impact of some of the later NUMA-directed changes, we had to eliminate a number of scalability bottlenecks and put these optimization patches in front of the main changes.
That is why you have to go 20+ patches into the queue to see the real point :-/
Quoted 5 lines
Quoted 2 lines
Are there architectures where we do need to flush remote TLBs on upgrading the permissions on a PTE?
I *suspect* that whole TLB flush just magically became an SMP one without anybody ever really thinking about it.
Yeah, and I think part of the problem is that it's also a not particularly straightforward to analyze performance bottleneck:
SMP TLB flushing does not show up as visible high overhead in profiles mainly, it mostly shows up as extra idle time.
If the nature of the workload is that it has extra available paralellism that can fill in the idle time, it will mask much of the effect and there's only a slight shift in the profile.
It needs a borderline loaded system and sleep profiling to pinpoint these sources of overhead.
[...]
Quoted 7 lines
Quoted 2 lines
From reading the code again, it looks like things should indeed work ok.
I would be open to it, but just in case it causes bisectable problems I'd really want to see it in two patches ("make it always do the local flush" followed by "remove even the local flush"), and then it would pinpoint any need.
Yeah, 100% agreed.
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
In reply to Linus TorvaldsQuoted 10 lines · Linus Torvalds
Quoted 6 lines · Rik van Riel
That may not even be needed. Apparently Intel chips automatically flush an entry from the TLB when it causes a page fault. I assume AMD chips do the same, because
flush_tlb_fix_spurious_faultevaluates to nothing on x86.Yes. It's not architected as far as I know, though. But I agree, it's possible - even likely - we could avoid TLB flushing entirely on x86.
Actually, it is architected on x86. This was first described in the intel appnote 317080 "TLBs, Paging-Structure Caches, and Their Invalidation", last paragraph of section 5.1. Nowadays, the same contents are buried somewhere in Volume 3 of the architecture manual (in my copy: 4.10.4.1 Operations that Invalidate TLBs and Paging-Structure Caches)
Quoted 8 lines
If you want to try it, I would seriously suggest you do it as a separate commit though, just in case.
Quoted 2 lines
Are there architectures where we do need to flush remote TLBs on upgrading the permissions on a PTE?
I *suspect* that whole TLB flush just magically became an SMP one without anybody ever really thinking about it.
I would be very worried about assuming every non-x86 arch has similar TLB semantics. However, if their fault handlers always invalidate TLB for pages that get spurious faults, then skipping the remote invalidation would be fine. (I believe this is what tlb_fix_spurious_fault() is for ?)
Signature · 8 lines
Michel "Walken" Lespinasse A program is never fully debugged until the last user dies. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 13 lines · Michel Lespinasse
Quoted 10 lines · Linus Torvalds
Quoted 6 lines · Rik van Riel
That may not even be needed. Apparently Intel chips automatically flush an entry from the TLB when it causes a page fault. I assume AMD chips do the same, because
flush_tlb_fix_spurious_faultevaluates to nothing on x86.Yes. It's not architected as far as I know, though. But I agree, it's possible - even likely - we could avoid TLB flushing entirely on x86.
Quoted 6 lines
Actually, it is architected on x86. This was first described in the intel appnote 317080 "TLBs, Paging-Structure Caches, and Their Invalidation", last paragraph of section 5.1. Nowadays, the same contents are buried somewhere in Volume 3 of the architecture manual (in my copy: 4.10.4.1 Operations that Invalidate TLBs and Paging-Structure Caches)
This unfortunately would only work for processes with no threads because it only works on the current logical CPU.
-Andi
Signature · 7 lines
[email protected] -- Speaking for myself only -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 22 lines · Andi Kleen
Quoted 13 lines · Michel Lespinasse
Quoted 10 lines · Linus Torvalds
Quoted 6 lines · Rik van Riel
That may not even be needed. Apparently Intel chips automatically flush an entry from the TLB when it causes a page fault. I assume AMD chips do the same, because
flush_tlb_fix_spurious_faultevaluates to nothing on x86.Yes. It's not architected as far as I know, though. But I agree, it's possible - even likely - we could avoid TLB flushing entirely on x86.
Quoted 6 lines
Actually, it is architected on x86. This was first described in the intel appnote 317080 "TLBs, Paging-Structure Caches, and Their Invalidation", last paragraph of section 5.1. Nowadays, the same contents are buried somewhere in Volume 3 of the architecture manual (in my copy: 4.10.4.1 Operations that Invalidate TLBs and Paging-Structure Caches)
Quoted 2 lines
This unfortunately would only work for processes with no threads because it only works on the current logical CPU.
That is fine.
Potentially triggering a spurious page fault on
another CPU is bound to be better than always
doing a synchronous remote TLB flush, waiting
for who knows how many CPUs to acknowledge the
IPI...
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 26 lines · Rik van Riel
Quoted 22 lines · Andi Kleen
Quoted 13 lines · Michel Lespinasse
Quoted 10 lines · Linus Torvalds
Quoted 6 lines · Rik van Riel
That may not even be needed. Apparently Intel chips automatically flush an entry from the TLB when it causes a page fault. I assume AMD chips do the same, because
flush_tlb_fix_spurious_faultevaluates to nothing on x86.Yes. It's not architected as far as I know, though. But I agree, it's possible - even likely - we could avoid TLB flushing entirely on x86.
Quoted 6 lines
Actually, it is architected on x86. This was first described in the intel appnote 317080 "TLBs, Paging-Structure Caches, and Their Invalidation", last paragraph of section 5.1. Nowadays, the same contents are buried somewhere in Volume 3 of the architecture manual (in my copy: 4.10.4.1 Operations that Invalidate TLBs and Paging-Structure Caches)
Quoted 2 lines
This unfortunately would only work for processes with no threads because it only works on the current logical CPU.
Quoted 7 lines
That is fine.
Potentially triggering a spurious page fault on another CPU is bound to be better than always doing a synchronous remote TLB flush, waiting for who knows how many CPUs to acknowledge the IPI...
The other killer is the fundamental IPI delay - which makes it 'invisible' to regular profiling and makes it hard to analyze.
So yes, even the local flush is a win, a major one - and the flush-less one is likely a win too, because INVLPG has some TLB-cache-walking costs.
Rik, mind sending an updated patch that addresses Linus's concerns, or should I code it up if you are busy?
We can also certainly try the second patch, but I'd do it at the end of the series, to put some tree distance between the two patches, to not concentrate regression risks too tightly in the Git space, to help out with hard to bisect problems...
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 9 lines · Ingo Molnar
[...]
Rik, mind sending an updated patch that addresses Linus's concerns, or should I code it up if you are busy?
We can also certainly try the second patch, but I'd do it at the end of the series, to put some tree distance between the two patches, to not concentrate regression risks too tightly in the Git space, to help out with hard to bisect problems...
I'd also like to have the second patch separately because I'd like to measure spurious fault frequency before and after the change, with a reference workload.
Just a single page fault, even it's a minor one, might make a micro-optimization a net loss. INVLPG might be the cheaper option on average - it needs to be measured. (I'll do that, just please keep it separate from the main TLB-flush optimization.)
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/3 x86/mm: only do a local TLB flush in ptep_set_access_flags()
In reply to Ingo MolnarHere are the TLB patches as requested:
---8<---
The function ptep_set_access_flags() is only ever invoked to upgrade access permissions on a PTE. That makes it safe to skip flushing the TLBs on remote TLBs. The worst that can happen is a spurious page fault on other CPUs, which would flush that TLB entry.
Lazily letting another CPU incur a spurious page fault occasionally is (much!) cheaper than aggressively flushing everybody else's TLB.
--- arch/x86/mm/pgtable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/mm/pgtable.c +1 -1
@@ -310,7 +310,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,if (changed && dirty) { *ptep = entry;pte_update_defer (vma->vm_mm, address, ptep); -flush_tlb_page (vma, address); +__flush_tlb_one (address); }return changed;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/3] x86/mm: only do a local TLB flush in ptep_set_access_flags()
Quoted 3 lines · Rik van Riel
The function
ptep_set_access_flags()is only ever invoked to upgrade access permissions on a PTE
Same deal. Please don't call these "access permissions". That confuses the issue.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/3] x86/mm: only do a local TLB flush in ptep_set_access_flags()
Quoted 7 lines · Linus Torvalds
Quoted 3 lines · Rik van Riel
The function
ptep_set_access_flags()is only ever invoked to upgrade access permissions on a PTESame deal. Please don't call these "access permissions". That confuses the issue.
I can change the text of the changelog, however it looks like do_wp_page does actually use ptep_set_access_flags to set the write bit in the pte...
I guess both need to be reflected in the changelog text somehow?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/3] x86/mm: only do a local TLB flush in ptep_set_access_flags()
Quoted 7 lines · Rik van Riel
I can change the text of the changelog, however it looks like
do_wp_pagedoes actually useptep_set_access_flagsto set the write bit in the pte...I guess both need to be reflected in the changelog text somehow?
Yeah, and by now, after all this discussion, I suspect it should be committed with a comment too. Commit messages are good and all, but unless chasing a particular bug they introduced, we shouldn't expect people to read them for background information.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/3] x86/mm: only do a local TLB flush in ptep_set_access_flags()
Quoted 6 lines · Linus Torvalds
Quoted 5 lines · Rik van Riel
I can change the text of the changelog, however it looks like
do_wp_pagedoes actually useptep_set_access_flagsto set the write bit in the pte...
Quoted 7 lines
Quoted 2 lines
I guess both need to be reflected in the changelog text somehow?
Yeah, and by now, after all this discussion, I suspect it should be committed with a comment too. Commit messages are good and all, but unless chasing a particular bug they introduced, we shouldn't expect people to read them for background information.
Will do :)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/3] x86/mm: only do a local TLB flush in ptep_set_access_flags()
In reply to Linus TorvaldsQuoted 6 lines · Linus Torvalds
Quoted 5 lines · Rik van Riel
I can change the text of the changelog, however it looks like
do_wp_pagedoes actually useptep_set_access_flagsto set the write bit in the pte...
Quoted 7 lines
Quoted 2 lines
I guess both need to be reflected in the changelog text somehow?
Yeah, and by now, after all this discussion, I suspect it should be committed with a comment too. Commit messages are good and all, but unless chasing a particular bug they introduced, we shouldn't expect people to read them for background information.
Now that we have the TLB things taken care of, and comments to patches 10/31 and 26/31 have been addressed, is there anything else that needs to be done before these NUMA patches can be merged?
Anyone, this is a good time to speak up. We have some time to address whatever concern you may have.
(besides waiting for the next merge window)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
trailing flush_tlb_fix_spurious_fault in handle_pte_fault (was Re: [PATCH 1/3] x86/mm: only do a local TLB flush in ptep_set_access_flags())
Quoted 15 lines · Rik van Riel
Quoted 6 lines · Linus Torvalds
Quoted 5 lines · Rik van Riel
I can change the text of the changelog, however it looks like
do_wp_pagedoes actually useptep_set_access_flagsto set the write bit in the pte...Quoted 7 lines
Quoted 2 lines
I guess both need to be reflected in the changelog text somehow?
Yeah, and by now, after all this discussion, I suspect it should be committed with a comment too. Commit messages are good and all, but unless chasing a particular bug they introduced, we shouldn't expect people to read them for background information.
Quoted 8 lines
Now that we have the TLB things taken care of, and comments to patches 10/31 and 26/31 have been addressed, is there anything else that needs to be done before these NUMA patches can be merged?
Anyone, this is a good time to speak up. We have some time to address whatever concern you may have.
Hi,
I know I'm very late in speaking up - but still I'll hazard a try. This is not exactly the same topic but closely related.
There is a a different call to flush_tlb_fix_spurious( ), towards the end of handle_pte_fault( ) which commit 61c77326d "x86, mm: Avoid unnecessary TLB flush" made no-op for X86. However is this really needed for any arch at all - even if we don't know all the arch specific quirks.
Given the code flow below
handle_pte_fault( )
....
....
if ptep_set_access_flags()-> if PTE chg remote TLB shot (pgtable-generic.c ver)
update_mmu_cache -> if PTE chg local TLB possibly shot too
else
flush_tlb_fix_spurious_fault -> PTE didn't change - still remote TLB shotdown
So for PTE unchanged case, we default to doing remote TLB IPIs (barring X86) - unless arch makes this macro NULL.
Thing is, in case of SMP races - due to PTE being different - any fixups to local/remote will be handled within ptep_set_access_flags( ) - arch-specific or generic versions. What I fail to understand is need to do anything - specially a remote shootdown, for PTE not changed case.
I could shut up and just make it NO-OP for ARC, but ....
Please note that for the record, the addition of this special case was done via following change. It might help answer what I feel to comprehend.
2005-10-29 1a44e14 [PATCH] .text page fault SMP scalability optimization
I might be totally off track so please feel free to bash me - but atleast I would end up knowing more !
Thx,
-Vineet
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 2/3 x86,mm: drop TLB flush from ptep_set_access_flags
In reply to Ingo MolnarIntel has an architectural guarantee that the TLB entry causing a page fault gets invalidated automatically. This means we should be able to drop the local TLB invalidation.
Because of the way other areas of the page fault code work, chances are good that all x86 CPUs do this. However, if someone somewhere has an x86 CPU that does not invalidate the TLB entry causing a page fault, this one-liner should be easy to revert.
--- arch/x86/mm/pgtable.c | 1 - 1 file changed, 1 deletion(-)
arch/x86/mm/pgtable.c +0 -1
@@ -310,7 +310,6 @@ int ptep_set_access_flags(struct vm_area_struct *vma,if (changed && dirty) { *ptep = entry;pte_update_defer (vma->vm_mm, address, ptep); -__flush_tlb_one (address); }return changed;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/3] x86,mm: drop TLB flush from ptep_set_access_flags
Quoted 9 lines · On Fri, 26 Oct 2012 14:45:02 -0400 Rik van Riel <[email protected]> wrote:
Intel has an architectural guarantee that the TLB entry causing a page fault gets invalidated automatically. This means we should be able to drop the local TLB invalidation.
Because of the way other areas of the page fault code work, chances are good that all x86 CPUs do this. However, if someone somewhere has an x86 CPU that does not invalidate the TLB entry causing a page fault, this one-liner should be easy to revert.
This does not strike me as a good standard of validation for such a change
At the very least we should have an ACK from AMD and from VIA, and preferably ping RDC and some of the other embedded folks. Given an AMD and VIA ACK I'd be fine. I doubt anyone knows any more what Cyrix CPUs did or cared about and I imagine H Peter or Linus can answer for Transmeta ;-)
Alan
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/3] x86,mm: drop TLB flush from ptep_set_access_flags
Quoted 13 lines · Alan Cox
Quoted 9 lines · On Fri, 26 Oct 2012 14:45:02 -0400 Rik van Riel <[email protected]> wrote:
Intel has an architectural guarantee that the TLB entry causing a page fault gets invalidated automatically. This means we should be able to drop the local TLB invalidation.
Because of the way other areas of the page fault code work, chances are good that all x86 CPUs do this. However, if someone somewhere has an x86 CPU that does not invalidate the TLB entry causing a page fault, this one-liner should be easy to revert.
Quoted 7 lines
This does not strike me as a good standard of validation for such a change
At the very least we should have an ACK from AMD and from VIA, and preferably ping RDC and some of the other embedded folks. Given an AMD and VIA ACK I'd be fine. I doubt anyone knows any more what Cyrix CPUs did or cared about and I imagine H Peter or Linus can answer for Transmeta ;-)
Fair enough.
If it turns out any of those CPUs need an explicit flush, then we can also adjust flush_tlb_fix_spurious_fault to actually do a local flush on x86 (or at least on those CPUs).
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/3] x86,mm: drop TLB flush from ptep_set_access_flags
Quoted 22 lines · Rik van Riel
Quoted 13 lines · Alan Cox
Quoted 9 lines · On Fri, 26 Oct 2012 14:45:02 -0400 Rik van Riel <[email protected]> wrote:
Intel has an architectural guarantee that the TLB entry causing a page fault gets invalidated automatically. This means we should be able to drop the local TLB invalidation.
Because of the way other areas of the page fault code work, chances are good that all x86 CPUs do this. However, if someone somewhere has an x86 CPU that does not invalidate the TLB entry causing a page fault, this one-liner should be easy to revert.
Quoted 7 lines
This does not strike me as a good standard of validation for such a change
At the very least we should have an ACK from AMD and from VIA, and preferably ping RDC and some of the other embedded folks. Given an AMD and VIA ACK I'd be fine. I doubt anyone knows any more what Cyrix CPUs did or cared about and I imagine H Peter or Linus can answer for Transmeta ;-)
Quoted 5 lines
Fair enough.
If it turns out any of those CPUs need an explicit flush, then we can also adjust
flush_tlb_fix_spurious_faultto actually do a local flush on x86 (or at least on those CPUs).
Yes. And even if we have 'confirmation' from documentation and elsewhere, testing has to be done to see actual real behavior of CPUs, so this is going to be a separate, bisectable commit put under surveillance ;-)
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/3] x86,mm: drop TLB flush from ptep_set_access_flags
In reply to Alan CoxQuoted 13 lines · Alan Cox
Quoted 9 lines · On Fri, 26 Oct 2012 14:45:02 -0400 Rik van Riel <[email protected]> wrote:
Intel has an architectural guarantee that the TLB entry causing a page fault gets invalidated automatically. This means we should be able to drop the local TLB invalidation.
Because of the way other areas of the page fault code work, chances are good that all x86 CPUs do this. However, if someone somewhere has an x86 CPU that does not invalidate the TLB entry causing a page fault, this one-liner should be easy to revert.
Quoted 7 lines
This does not strike me as a good standard of validation for such a change
At the very least we should have an ACK from AMD and from VIA, and preferably ping RDC and some of the other embedded folks. Given an AMD and VIA ACK I'd be fine. I doubt anyone knows any more what Cyrix CPUs did or cared about and I imagine H Peter or Linus can answer for Transmeta ;-)
Florian, would you happen to know who at RDC could be contacted to verify whether a TLB entry causing a page fault gets invalidated automatically, upon entering the page fault path?
Borislav, would you happen to know whether AMD (and VIA) CPUs automatically invalidate TLB entries that cause page faults? If you do not know, would you happen who to ask? :)
If these CPUs do not invalidate a TLB entry causing a page fault (a write fault on a read-only PTE), then we may have to change the kernel so flush_tlb_fix_spurious_fault does something on the CPU models in question...
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Borislav Petkov
maintainerRe: [PATCH 2/3] x86,mm: drop TLB flush from ptep_set_access_flags
Quoted 3 lines · Rik van Riel
Borislav, would you happen to know whether AMD (and VIA) CPUs automatically invalidate TLB entries that cause page faults? If you do not know, would you happen who to ask? :)
Short answer: yes.
Long answer (from APM v2, section 5.5.2):
Use of Cached Entries When Reporting a Page Fault Exception.
On current AMD64 processors, when any type of page fault exception is encountered by the MMU, any cached upper-level entries that lead to the faulting entry are flushed (along with the TLB entry, if already cached) and the table walk is repeated to confirm the page fault using the table entries in memory. This is done because a table entry is allowed to be upgraded (by marking it as present, or by removing its write, execute or supervisor restrictions) without explicitly maintaining TLB coherency. Such an upgrade will be found when the table is re-walked, which resolves the fault. If the fault is confirmed on the re-walk however, a page fault exception is reported, and upper level entries that may have been cached on the re-walk are flushed.
HTH.
Signature · 8 lines
Regards/Gruss, Boris. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/3] x86,mm: drop TLB flush from ptep_set_access_flags
Quoted 2 lines · Borislav Petkov
On current AMD64 processors,
Can you verify that this is true for older cpu's too (ie the old pre-64-bit ones, say K6 and original Athlon)?
Quoted 2 lines
This is done because a table entry is allowed
to be upgraded (by marking it as present
Well, that was traditionally solved by not caching not-present entries at all. Which can be a problem for some things (prefetch of NULL etc), so caching and then re-checking on faults is potentially the correct thing, but I'm just mentioning it because it might not be much of an argument for older microarchitectures..
Quoted 4 lines
, or by removing its write,
execute or supervisor restrictions) without explicitly maintaining TLB coherency. Such an upgrade will be found when the table is re-walked, which resolves the fault.
.. but this is obviously what we're interested in. And since AMD has documented it (as well as Intel), I have this strong suspicion that operating systems have traditionally relied on this behavior.
I don't remember the test coverage details from my Transmeta days, and while I certainly saw the page table walker, it wasn't my code.
My gut feel is that this is likely something x86 just always does (because it's the right thing to do to keep things simple for software), but getting explicit confirmation about older AMD cpu's would definitely be good.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Borislav Petkov
maintainerRe: [PATCH 2/3] x86,mm: drop TLB flush from ptep_set_access_flags
Quoted 6 lines · Linus Torvalds
Quoted 2 lines · Borislav Petkov
On current AMD64 processors,
Can you verify that this is true for older cpu's too (ie the old pre-64-bit ones, say K6 and original Athlon)?
Albeit with a slight delay, the answer is yes: all AMD cpus automatically invalidate cached TLB entries (and intermediate walk results, for that matter) on a #PF.
I don't know, however, whether it would be prudent to have some sort of a cheap assertion in the code (cheaper than INVLPG %ADDR, although on older cpus we do MOV CR3) just in case. This should be enabled only with DEBUG_VM on, of course...
HTH.
Signature · 8 lines
Regards/Gruss, Boris. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/3] x86,mm: drop TLB flush from ptep_set_access_flags
Quoted 4 lines · Borislav Petkov
Albeit with a slight delay, the answer is yes: all AMD cpus automatically invalidate cached TLB entries (and intermediate walk results, for that matter) on a #PF.
Thanks. I suspect it ends up being basically architectural, and that Windows (and quite possibly Linux versions too) have depended on the behavior.
Quoted 4 lines
I don't know, however, whether it would be prudent to have some sort of a cheap assertion in the code (cheaper than INVLPG %ADDR, although on older cpus we do MOV CR3) just in case. This should be enabled only with
DEBUG_VMon, of course...
I wonder how we could actually test for it. We'd have to have some per-cpu page-fault address check (along with a generation count on the mm or similar). I doubt we'd figure out anything that works reliably and efficiently and would actually show any problems (plus we would have no way to ever know we even got the code right, since presumably we'd never find hardware that actually shows the behavior we'd be looking for..)
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Borislav Petkov
maintainerRe: [PATCH 2/3] x86,mm: drop TLB flush from ptep_set_access_flags
Quoted 7 lines · Linus Torvalds
I wonder how we could actually test for it. We'd have to have some per-cpu page-fault address check (along with a generation count on the mm or similar). I doubt we'd figure out anything that works reliably and efficiently and would actually show any problems (plus we would have no way to ever know we even got the code right, since presumably we'd never find hardware that actually shows the behavior we'd be looking for..)
Hmm, touching some wrong page through the stale TLB entry could be a pretty nasty issue to debug. But you're probably right: how does one test cheaply whether a PTE just got kicked out of the TLB? Maybe mark it not-present but this would force a rewalk in the case when it is shared, which is penalty we don't want to pay.
Oh well...
Signature · 8 lines
Regards/Gruss, Boris. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/3] x86,mm: drop TLB flush from ptep_set_access_flags
In reply to Linus TorvaldsQuoted 10 lines · Linus Torvalds
Quoted 4 lines · Borislav Petkov
I don't know, however, whether it would be prudent to have some sort of a cheap assertion in the code (cheaper than INVLPG %ADDR, although on older cpus we do MOV CR3) just in case. This should be enabled only with
DEBUG_VMon, of course...I wonder how we could actually test for it. We'd have to have some per-cpu page-fault address check (along with a generation count on the mm or similar). I doubt we'd figure out anything that works reliably and efficiently and would actually show any problems
Would it be enough to simply print out a warning if we fault on the same address twice (or three times) in a row, and then flush the local TLB?
I realize this would not just trigger on CPUs that fail to invalidate TLB entries that cause faults, but also on kernel paths that cause a page fault to be re-taken...
... but then again, don't we want to find those paths and fix them, anyway? :)
Signature · 7 lines
All rights reversed -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/3] x86,mm: drop TLB flush from ptep_set_access_flags
Quoted 15 lines · Rik van Riel
Quoted 9 lines · Linus Torvalds
Quoted 5 lines · Borislav Petkov
I don't know, however, whether it would be prudent to have some sort of a cheap assertion in the code (cheaper than INVLPG %ADDR, although on older cpus we do MOV CR3) just in case. This should be enabled only with
DEBUG_VMon, of course...Quoted 4 lines
I wonder how we could actually test for it. We'd have to have some per-cpu page-fault address check (along with a generation count on the mm or similar). I doubt we'd figure out anything that works reliably and efficiently and would actually show any problems
Quoted 7 lines
Would it be enough to simply print out a warning if we fault on the same address twice (or three times) in a row, and then flush the local TLB?
I realize this would not just trigger on CPUs that fail to invalidate TLB entries that cause faults, but also on kernel paths that cause a page fault to be re-taken...
I'm actually curious if the architecture docs/software developer manuals for IA-32 mandate any TLB invalidations on a #PF
Is there any official vendor documentation on the subject?
And perhaps equally valid, should we trust it if it exists?
Quoted 7 lines
... but then again, don't we want to find those paths and fix them, anyway? :)
--
All rights reversed
Quoted 5 lines
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/3] x86,mm: drop TLB flush from ptep_set_access_flags
Quoted 4 lines · Shentino
I'm actually curious if the architecture docs/software developer manuals for IA-32 mandate any TLB invalidations on a #PF
Is there any official vendor documentation on the subject?
Yes. Quoting a prior email:
Actually, it is architected on x86. This was first described in the intel appnote 317080 "TLBs, Paging-Structure Caches, and Their Invalidation", last paragraph of section 5.1. Nowadays, the same contents are buried somewhere in Volume 3 of the architecture manual (in my copy: 4.10.4.1 Operations that Invalidate TLBs and Paging-Structure Caches)
Quoted 1 line
And perhaps equally valid, should we trust it if it exists?
I know that Intel has been very careful in documenting the architected TLB behaviors and did it with the understanding that people should be able to depend on what's being written up there.
Signature · 8 lines
Michel "Walken" Lespinasse A program is never fully debugged until the last user dies. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 3/3 mm,generic: only flush the local TLB in ptep_set_access_flags
In reply to Ingo MolnarThe function ptep_set_access_flags is only ever used to upgrade access permissions to a page. That means the only negative side effect of not flushing remote TLBs is that other CPUs may incur spurious page faults, if they happen to access the same address, and still have a PTE with the old permissions cached in their TLB.
Having another CPU maybe incur a spurious page fault is faster than always incurring the cost of a remote TLB flush, so replace the remote TLB flush with a purely local one.
This should be safe on every architecture that correctly implements flush_tlb_fix_spurious_fault() to actually invalidate the local TLB entry that caused a page fault, as well as on architectures where the hardware invalidates TLB entries that cause page faults.
In the unlikely event that you are hitting what appears to be an infinite loop of page faults, and 'git bisect' took you to this changeset, your architecture needs to implement flush_tlb_fix_spurious_fault to actually flush the TLB entry.
--- mm/pgtable-generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/pgtable-generic.c +1 -1
@@ -27,7 +27,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,int changed = !pte_same (*ptep, entry);if (changed) {set_pte_at (vma->vm_mm, address, ptep, entry); -flush_tlb_page (vma, address); +flush_tlb_fix_spurious_fault (vma, address); }return changed; }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 3/3] mm,generic: only flush the local TLB in ptep_set_access_flags
Quoted 3 lines · Rik van Riel
The function
ptep_set_access_flagsis only ever used to upgrade access permissions to a page.
NOTE: It's *not* "access permissions". It's "access flags".
Big difference. This is not about permissions at all.
The access flags are the Accessed and Dirty bits. And the dirty bit is never *cleared* by this function, it's only ever potentially set. That, together with the fact that the accessed flag is "best effort" rather than exact, is what makes this function so special to begin with.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 3/3] mm,generic: only flush the local TLB in ptep_set_access_flags
Quoted 4 lines · Linus Torvalds
NOTE: It's *not* "access permissions". It's "access flags".
Big difference. This is not about permissions at all.
Anyway, modulo the misleading commit messages, ACK from on the series.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 3/3] mm,generic: only flush the local TLB in ptep_set_access_flags
In reply to Linus TorvaldsQuoted 8 lines · Linus Torvalds
Quoted 3 lines · Rik van Riel
The function
ptep_set_access_flagsis only ever used to upgrade access permissions to a page.NOTE: It's *not* "access permissions". It's "access flags".
Big difference. This is not about permissions at all.
It looks like do_wp_page also sets the write bit in the pte "entry" before passing it to ptep_set_access_flags, making that the place where the write bit is set in the pte.
Is this a bug in do_wp_page?
Am I reading things wrong?
reuse:
flush_cache_page(vma, address, pte_pfn(orig_pte));
entry = pte_mkyoung(orig_pte);
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
if (ptep_set_access_flags(vma, address, page_table,
entry,1))
update_mmu_cache(vma, address, page_table);--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 3/3] mm,generic: only flush the local TLB in ptep_set_access_flags
Quoted 6 lines · Rik van Riel
It looks like
do_wp_pagealso sets the write bit in the pte "entry" before passing it toptep_set_access_flags, making that the place where the write bit is set in the pte.Is this a bug in
do_wp_page?
Hmm. Right you are. That's indeed worth noting that it can indeed change access permissions in that particular way (ie enabling writes).
So yeah, good catch. And it's ok to add the writeable bits like this (and it can't race with hardware like the dirty bit can, since hardware never sets writability).
In fact, it should probably be documented in the source code somewhere. In particular, there's a very subtle requirement that you can only set the writable bit if the dirty bit is also set at the same time, for example.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 3/3 mm,generic: only flush the local TLB in ptep_set_access_flags
The function ptep_set_access_flags is only ever used to upgrade access permissions to a page. That means the only negative side effect of not flushing remote TLBs is that other CPUs may incur spurious page faults, if they happen to access the same address, and still have a PTE with the old permissions cached in their TLB.
Having another CPU maybe incur a spurious page fault is faster than always incurring the cost of a remote TLB flush, so replace the remote TLB flush with a purely local one.
This should be safe on every architecture that correctly implements flush_tlb_fix_spurious_fault() to actually invalidate the local TLB entry that caused a page fault, as well as on architectures where the hardware invalidates TLB entries that cause page faults.
In the unlikely event that you are hitting what appears to be an infinite loop of page faults, and 'git bisect' took you to this changeset, your architecture needs to implement flush_tlb_fix_spurious_fault to actually flush the TLB entry.
--- mm/pgtable-generic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
mm/pgtable-generic.c +3 -3
@@ -12,8 +12,8 @@#ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS/* -* Only sets the access flags (dirty, accessed, and -* writable). Furthermore, we know it always gets set to a "more +* Only sets the access flags (dirty, accessed), as well as write +* permission. Furthermore, we know it always gets set to a "more * permissive" setting, which allows most architectures to optimize * this. We return whether the PTE actually changed, which in turn * instructs the caller to do things like update__mmu_cache. This
@@ -27,7 +27,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,int changed = !pte_same (*ptep, entry);if (changed) {set_pte_at (vma->vm_mm, address, ptep, entry); -flush_tlb_page (vma, address); +flush_tlb_fix_spurious_fault (vma, address); }return changed; }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
In reply to Andi KleenQuoted 22 lines · Andi Kleen
Quoted 13 lines · Michel Lespinasse
Quoted 10 lines · Linus Torvalds
Quoted 6 lines · Rik van Riel
That may not even be needed. Apparently Intel chips automatically flush an entry from the TLB when it causes a page fault. I assume AMD chips do the same, because
flush_tlb_fix_spurious_faultevaluates to nothing on x86.Yes. It's not architected as far as I know, though. But I agree, it's possible - even likely - we could avoid TLB flushing entirely on x86.
Quoted 6 lines
Actually, it is architected on x86. This was first described in the intel appnote 317080 "TLBs, Paging-Structure Caches, and Their Invalidation", last paragraph of section 5.1. Nowadays, the same contents are buried somewhere in Volume 3 of the architecture manual (in my copy: 4.10.4.1 Operations that Invalidate TLBs and Paging-Structure Caches)
Quoted 2 lines
This unfortunately would only work for processes with no threads because it only works on the current logical CPU.
No, the point is, if we are only *increasing* permissions on a page, we can skip the remote TLB invalidations. Later on each remote CPU might possibly get a spurious fault on that page, but that spurious fault will resynchronize their TLBs for that page, so that the instruction retry after the fault won't fault again.
It is often cheaper to let remote CPUs get an occasional spurious fault than to synchronize with them on every permission change.
Of course, none of the above applies if we are *reducing* permissions on a page (we really can't skip TLB invalidations there)
Signature · 8 lines
Michel "Walken" Lespinasse A program is never fully debugged until the last user dies. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
In reply to Michel LespinasseQuoted 11 lines · Michel Lespinasse
Quoted 3 lines · Linus Torvalds
Yes. It's not architected as far as I know, though. But I agree, it's possible - even likely - we could avoid TLB flushing entirely on x86.
Actually, it is architected on x86. This was first described in the intel appnote 317080 "TLBs, Paging-Structure Caches, and Their Invalidation", last paragraph of section 5.1. Nowadays, the same contents are buried somewhere in Volume 3 of the architecture manual (in my copy: 4.10.4.1 Operations that Invalidate TLBs and Paging-Structure Caches)
Good. I should have known it must be architected, because we've gone back-and-forth on this in the kernel historically. We used to have some TLB invalidates in the faulting path because I wasn't sure whether they were needed or not, but we clearly don't have them any more (and I suspect coverage was always spotty).
And Intel (and AMD) have been very good at documenting as architected these kinds of details that people end up relying on even if they weren't necessarily originally explicitly documented.
Quoted 8 lines
Quoted 2 lines
I *suspect* that whole TLB flush just magically became an SMP one without anybody ever really thinking about it.
I would be very worried about assuming every non-x86 arch has similar TLB semantics. However, if their fault handlers always invalidate TLB for pages that get spurious faults, then skipping the remote invalidation would be fine. (I believe this is what
tlb_fix_spurious_fault()is for ?)
Yes. Of course, there may be some case where we unintentionally don't necessarily flush a faulting address (on some architecture that needs it), and then removing the cross-cpu invalidate could expose that pre-existing bug-let, and cause an infinite loop of page faults due to a TLB entry that never gets invalidated even if the page tables are actually up-to-date.
So changing the mm/pgtable-generic.c function sounds like the right thing to do, but would be a bit more scary.
Changing the x86 version sounds safe, *especially* since you point out that the "fault-causes-tlb-invalidate" is architected behavior.
So I'd almost be willing to drop the invalidate in just one single commit, because it really should be safe. The only thing it does is guarantee that the accessed bit gets updated, and the accessed bit just isn't that important. If we never flush the TLB on another CPU that continues to use a TLB entry where the accessed bit is set (even if it's cleared in the in-memory page tables), the worst that can happen is that the accessed bit doesn't ever get set even if that CPU constantly uses the page.
And nobody will *ever* care. The A bit is purely a heuristic for the page LRU thing, we don't care about irrelevant special cases that won't even affect correctness (much less performance - if that thing is really hot and stays in the TLB, if we evict it, it will immediately get reloaded anyway).
And doing a TLB invalidate even locally is worthless: sure, setting the dirty bit and not invalidating the TLB can cause a local micro-tlb fault (not a software-visible one, just microarchitectural pipeline restart with TLB reload) on the next write access (because the TLB would still contain D=0), so *eve*if* the CPU didn't invalidate-on-fault, there's no reason we should invalidate in software on x86.
Again, this can be different on non-x86 architectures with software dirty bits, where a stale TLB entry that never gets flushed could cause infinite TLB faults that never make progress, but that's really a TLB _walker_ issue, not a generic VM issue.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 45 lines · Linus Torvalds
Quoted 11 lines · Michel Lespinasse
Quoted 3 lines · Linus Torvalds
Yes. It's not architected as far as I know, though. But I agree, it's possible - even likely - we could avoid TLB flushing entirely on x86.
Actually, it is architected on x86. This was first described in the intel appnote 317080 "TLBs, Paging-Structure Caches, and Their Invalidation", last paragraph of section 5.1. Nowadays, the same contents are buried somewhere in Volume 3 of the architecture manual (in my copy: 4.10.4.1 Operations that Invalidate TLBs and Paging-Structure Caches)
Good. I should have known it must be architected, because we've gone back-and-forth on this in the kernel historically. We used to have some TLB invalidates in the faulting path because I wasn't sure whether they were needed or not, but we clearly don't have them any more (and I suspect coverage was always spotty).
And Intel (and AMD) have been very good at documenting as architected these kinds of details that people end up relying on even if they weren't necessarily originally explicitly documented.
Quoted 8 lines
Quoted 2 lines
I *suspect* that whole TLB flush just magically became an SMP one without anybody ever really thinking about it.
I would be very worried about assuming every non-x86 arch has similar TLB semantics. However, if their fault handlers always invalidate TLB for pages that get spurious faults, then skipping the remote invalidation would be fine. (I believe this is what
tlb_fix_spurious_fault()is for ?)Yes. Of course, there may be some case where we unintentionally don't necessarily flush a faulting address (on some architecture that needs it), and then removing the cross-cpu invalidate could expose that pre-existing bug-let, and cause an infinite loop of page faults due to a TLB entry that never gets invalidated even if the page tables are actually up-to-date.
So changing the
mm/pgtable-generic.cfunction sounds like the right thing to do, but would be a bit more scary.Changing the x86 version sounds safe, *especially* since you point out that the "fault-causes-tlb-invalidate" is architected behavior.
Quoted 8 lines
So I'd almost be willing to drop the invalidate in just one single commit, because it really should be safe. The only thing it does is guarantee that the accessed bit gets updated, and the accessed bit just isn't that important. If we never flush the TLB on another CPU that continues to use a TLB entry where the accessed bit is set (even if it's cleared in the in-memory page tables), the worst that can happen is that the accessed bit doesn't ever get set even if that CPU constantly uses the page.
I suspect it would be safe to simply call tlb_fix_spurious_fault() both on x86 and in the generic version.
If tlb_fix_spurious_fault is broken on some architecture, they would already be running into issues like "write page fault loops until the next context switch" :)
Quoted 4 lines
Again, this can be different on non-x86 architectures with software dirty bits, where a stale TLB entry that never gets flushed could cause infinite TLB faults that never make progress, but that's really a TLB _walker_ issue, not a generic VM issue.
Would tlb_fix_spurious_fault take care of that on those architectures?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 3 lines · Rik van Riel
Would
tlb_fix_spurious_faulttake care of that on those architectures?
.. assuming that they implement it as a real TLB flush, yes.
But maybe the architecture never noticed that it happened to depend on the fact that we do a cross-CPU invalidate? So a missing tlb_fix_spurious_fault() implementation could cause a short loop of repeated page faults, until the IPI happens. And it would be so incredibly rare that nobody would ever have noticed.
And if that could have happened, then with the cross-cpu invalidate removed, the "incredibly rare short-lived constant page fault retry" could turn into "incredibly rare lockup due to infinite page fault retry due to TLB entry that never turns dirty despite it being marked dirty by SW in the in-memory page tables".
Very unlikely, I agree. And this is only relevant for the non-x86 case, so changing the x86-specific optimized version is an independent issue.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 13 lines · Linus Torvalds
Quoted 3 lines · Rik van Riel
Would
tlb_fix_spurious_faulttake care of that on those architectures?.. assuming that they implement it as a real TLB flush, yes.
But maybe the architecture never noticed that it happened to depend on the fact that we do a cross-CPU invalidate? So a missing
tlb_fix_spurious_fault()implementation could cause a short loop of repeated page faults, until the IPI happens. And it would be so incredibly rare that nobody would ever have noticed.
Quoted 5 lines
And if that could have happened, then with the cross-cpu invalidate removed, the "incredibly rare short-lived constant page fault retry" could turn into "incredibly rare lockup due to infinite page fault retry due to TLB entry that never turns dirty despite it being marked dirty by SW in the in-memory page tables".
I suspect the next context switch would flush out the TLB, making it a slowdown, not a lockup.
Still a good reason to make such a change in its own commit, so it can be bisected and tracked down.
The commit message could tell architecture maintainers what to do if this particular commit got them into trouble:
implement a proper local TLB flush in tlb_fix_spurious_fault.
I'll send this in as a separate patch.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 05/31] x86/mm: Reduce tlb flushes from ptep_set_access_flags()
Quoted 3 lines · Rik van Riel
I suspect the next context switch would flush out the TLB, making it a slowdown, not a lockup.
Common case, yes. But the page fault might happen in kernel space (due to a "put_user()" call, say), and with CONFIG_PREEMPT=n.
Sure, put_user() is always done in a context where blocking (and scheduling) is legal, but that doesn't necessarily equate scheduling actually happening. If we're returning to kernel space and don't have any IO, it might never happen.
Anyway, I suspect such behavior it's almost impossible to trigger. Which would just make it rather hard to find.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 6/31 mm: Only flush the TLB when clearing an accessible pte
In reply to Peter ZijlstraFrom: Rik van Riel <[email protected]>
If ptep_clear_flush() is called to clear a page table entry that is accessible anyway by the CPU, eg. a _PAGE_PROTNONE page table entry, there is no need to flush the TLB on remote CPUs.
--- mm/pgtable-generic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
mm/pgtable-generic.c +2 -1
@@ -88,7 +88,8 @@ pte_t ptep_clear_flush(struct vm_area_st {pte_t pte; pte =ptep_get_and_clear ((vma)->vm_mm, address, ptep); -flush_tlb_page (vma, address); +if (pte_accessible (pte)) +flush_tlb_page (vma, address);return pte; }#endif
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 7/31 sched, numa, mm, s390/thp: Implement pmd_pgprot() for s390
In reply to Peter ZijlstraFrom: Gerald Schaefer <[email protected]>
This patch adds an implementation of pmd_pgprot() for s390, in preparation to future THP changes.
--- arch/s390/include/asm/pgtable.h | 13 +++++++++++++ 1 file changed, 13 insertions(+)
arch/s390/include/asm/pgtable.h +13 -0
@@ -1240,6 +1240,19 @@ static inline void set_pmd_at(struct mm_ *pmdp = entry; } +static inline pgprot_t pmd_pgprot (pmd_t pmd) +{ +pgprot_t prot =PAGE_RW ; + +if (pmd_val (pmd) & _SEGMENT_ENTRY_RO) { +if (pmd_val (pmd) & _SEGMENT_ENTRY_INV) + prot =PAGE_NONE ; +else + prot =PAGE_RO ; + } +return prot; +} +static inline unsigned long massage_pgprot_pmd (pgprot_t pgprot) {unsigned long pgprot_pmd =0 ;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 07/31] sched, numa, mm, s390/thp: Implement pmd_pgprot() for s390
Quoted 5 lines · Peter Zijlstra
From: Gerald Schaefer <[email protected]>
This patch adds an implementation of
pmd_pgprot()for s390, in preparation to future THP changes.
The additional pmd_pgprot implementations only are necessary if we want to preserve the PROT_NONE protections across a split but that somewhat forces that PROT_NONE be used as the protection bit across all architectures. Is that possible? I think I would prefer that prot-protection-across-splits just went away until it was proven necessary and potentially recoded in terms of _PAGE_NUMA and friends instead.
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 8/31 sched, numa, mm, MIPS/thp: Add pmd_pgprot() implementation
In reply to Peter ZijlstraFrom: Ralf Baechle <[email protected]>
Add the pmd_pgprot() method that will be needed
by the new NUMA code.
--- arch/mips/include/asm/pgtable.h | 2 ++ 1 file changed, 2 insertions(+)
arch/mips/include/asm/pgtable.h +2 -0
@@ -89,6 +89,8 @@ static inline int is_zero_pfn(unsigned lextern void paging_init (void ); +#define pmd_pgprot (x) __pgprot(pmd_val(x) & ~_PAGE_CHG_MASK) +/* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 9/31 mm/pgprot: Move the pgprot_modify() fallback definition to mm.h
In reply to Peter ZijlstraFrom: Ingo Molnar <[email protected]>
pgprot_modify() is available on x86, but on other architectures it only gets defined in mm/mprotect.c - breaking the build if anything outside of mprotect.c tries to make use of this function.
Move it to the generic pgprot area in mm.h, so that an upcoming patch can make use of it.
--- include/linux/mm.h | 13 +++++++++++++ mm/mprotect.c | 7 ------- 2 files changed, 13 insertions(+), 7 deletions(-)
include/linux/mm.h +13 -0
@@ -164,6 +164,19 @@ extern pgprot_t protection_map[16];#define FAULT_FLAG_TRIED 0x40/* second try */ /* +* Some architectures (such as x86) may need to preserve certain pgprot +* bits, without complicating generic pgprot code. +* +* Most architectures don't care: +*/ +#ifndef pgprot_modify +static inline pgprot_t pgprot_modify (pgprot_t oldprot,pgprot_t newprot) +{ +return newprot; +} +#endif + +/* * vm_fault is filled by the the pagefault handler and passed to the vma's * ->fault function. The vma's ->fault is responsible for returning a bitmask * of VM_FAULT_xxx flags that give details about how the fault was handled.
mm/mprotect.c +0 -7
@@ -28,13 +28,6 @@#include <asm/cacheflush.h> #include <asm/tlbflush.h> -#ifndef pgprot_modify -static inline pgprot_t pgprot_modify (pgprot_t oldprot,pgprot_t newprot) -{ -return newprot; -} -#endif -static void change_pte_range (struct mm_struct *mm,pmd_t *pmd,unsigned long addr,unsigned long end,pgprot_t newprot,int dirty_accountable)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 10/31 mm/mpol: Remove NUMA_INTERLEAVE_HIT
In reply to Peter ZijlstraSince the NUMA_INTERLEAVE_HIT statistic is useless on its own; it wants to be compared to either a total of interleave allocations or to a miss count, remove it.
Fixing it would be possible, but since we've gone years without these statistics I figure we can continue that way.
Also NUMA_HIT fully includes NUMA_INTERLEAVE_HIT so users might switch to using that.
This cleans up some of the weird MPOL_INTERLEAVE allocation exceptions.
--- drivers/base/node.c | 2 - include/linux/mmzone.h | 1 mm/mempolicy.c | 68 +++++++++++++++---------------------------------- mm/vmstat.c | 1 4 files changed, 22 insertions(+), 50 deletions(-)
drivers/base/node.c +1 -1
@@ -169,7 +169,7 @@ static ssize_t node_read_numastat(structnode_page_state (dev->id,NUMA_HIT ),node_page_state (dev->id,NUMA_MISS ),node_page_state (dev->id,NUMA_FOREIGN ), -node_page_state (dev->id,NUMA_INTERLEAVE_HIT ), +0UL ,node_page_state (dev->id,NUMA_LOCAL ), node_page_state(dev->id, NUMA_OTHER)); }
include/linux/mmzone.h +0 -1
@@ -137,7 +137,6 @@ enum zone_stat_item {NUMA_HIT ,/* allocated in intended node */ NUMA_MISS ,/* allocated in non intended node */ NUMA_FOREIGN ,/* was intended here, hit elsewhere */ -NUMA_INTERLEAVE_HIT ,/* interleaver preferred this zone */ NUMA_LOCAL ,/* allocation from local node */ NUMA_OTHER, /* allocation from other node */ #endif
mm/mempolicy.c +21 -47
103 lines not on this page · raw message
mm/vmstat.c +0 -1
@@ -729,7 +729,6 @@ const char * const vmstat_text[] = {"numa_hit" ,"numa_miss" ,"numa_foreign" , -"numa_interleave" ,"numa_local" , "numa_other", #endif
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andi Kleen
NAKRe: [PATCH 10/31] mm/mpol: Remove NUMA_INTERLEAVE_HIT
Quoted 3 lines · Peter Zijlstra
Since the
NUMA_INTERLEAVE_HITstatistic is useless on its own; it wants to be compared to either a total of interleave allocations or to a miss count, remove it.
NACK, as already posted several times.
This breaks the numactl test suite, which is the only way currently to test interleaving.
Please don't ignore review feedback.
-Andi
Signature · 7 lines
[email protected] -- Speaking for myself only -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 10/31] mm/mpol: Remove NUMA_INTERLEAVE_HIT
Quoted 12 lines · Andi Kleen
Quoted 10 lines · Peter Zijlstra
Since the
NUMA_INTERLEAVE_HITstatistic is useless on its own; it wants to be compared to either a total of interleave allocations or to a miss count, remove it.Fixing it would be possible, but since we've gone years without these statistics I figure we can continue that way.
Also
NUMA_HITfully includesNUMA_INTERLEAVE_HITso users might switch to using that.
Quoted 7 lines
Quoted 2 lines
This cleans up some of the weird
MPOL_INTERLEAVEallocation exceptions.NACK, as already posted several times.
This breaks the numactl test suite, which is the only way currently to test interleaving.
This patch is not essential to the NUMA series so I've zapped it from the patch queue and fixed up the roll-on effects.
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 11/31 mm/mpol: Make MPOL_LOCAL a real policy
In reply to Peter ZijlstraMake MPOL_LOCAL a real and exposed policy such that applications that relied on the previous default behaviour can explicitly request it.
--- include/uapi/linux/mempolicy.h | 1 + mm/mempolicy.c | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-)
include/uapi/linux/mempolicy.h +1 -0
@@ -20,6 +20,7 @@ enum {MPOL_PREFERRED ,MPOL_BIND ,MPOL_INTERLEAVE , +MPOL_LOCAL , MPOL_MAX, /* always last member of enum */ };
mm/mempolicy.c +6 -3
@@ -269,6 +269,10 @@ static struct mempolicy *mpol_new(unsign (flags & MPOL_F_RELATIVE_NODES)))return ERR_PTR (-EINVAL ); } + }else if (mode ==MPOL_LOCAL ) { +if (!nodes_empty (*nodes)) +return ERR_PTR (-EINVAL ); + mode =MPOL_PREFERRED ; }else if (nodes_empty (*nodes))return ERR_PTR (-EINVAL ); policy =kmem_cache_alloc (policy_cache,GFP_KERNEL );
@@ -2371,7 +2375,6 @@ void numa_default_policy(void)* "local" is pseudo-policy: MPOL_PREFERRED with MPOL_F_LOCAL flag * Used only for mpol_parse_str() and mpol_to_str() */ -#define MPOL_LOCAL MPOL_MAXstatic const char *const policy_modes[] = { [MPOL_DEFAULT ] ="default" ,
@@ -2424,12 +2427,12 @@ int mpol_parse_str(char *str, struct memif (flags) *flags++ ='\0' ;/* terminate mode string */ -for (mode =0 ; mode <=MPOL_LOCAL ; mode++) { +for (mode =0 ; mode <MPOL_MAX ; mode++) {if (!strcmp (str, policy_modes[mode])) {break ; } } -if (mode >MPOL_LOCAL ) +if (mode >=MPOL_MAX ) goto out;switch (mode) {
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 11/31] mm/mpol: Make MPOL_LOCAL a real policy
Quoted 10 lines · Peter Zijlstra
Make
MPOL_LOCALa real and exposed policy such that applications that relied on the previous default behaviour can explicitly request it.Requested-by Christoph Lameter <[email protected]>Reviewed-by Rik van Riel <[email protected]>Cc Lee Schermerhorn <[email protected]>Cc Andrew Morton <[email protected]>Cc Linus Torvalds <[email protected]>Signed-off-by Peter Zijlstra <[email protected]>Signed-off-by Ingo Molnar <[email protected]>
Seems reasonable but Michael Kerrisk should be cc'd because when the dust settles on this there may be a manual page update required.
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 12/31 mm/mpol: Add MPOL_MF_NOOP
In reply to Peter ZijlstraFrom: Lee Schermerhorn <[email protected]>
This patch augments the MPOL_MF_LAZY feature by adding a "NOOP" policy to mbind(). When the NOOP policy is used with the 'MOVE and 'LAZY flags, mbind() will map the pages PROT_NONE so that they will be migrated on the next touch.
This allows an application to prepare for a new phase of operation where different regions of shared storage will be assigned to worker threads, w/o changing policy. Note that we could just use "default" policy in this case. However, this also allows an application to request that pages be migrated, only if necessary, to follow any arbitrary policy that might currently apply to a range of pages, without knowing the policy, or without specifying multiple mbind()s for ranges with different policies.
[ Bug in early version of mpol_parse_str() reported by Fengguang Wu. ]
--- include/uapi/linux/mempolicy.h | 1 + mm/mempolicy.c | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-)
include/uapi/linux/mempolicy.h +1 -0
@@ -21,6 +21,7 @@ enum {MPOL_BIND ,MPOL_INTERLEAVE ,MPOL_LOCAL , +MPOL_NOOP ,/* retain existing policy for range */ MPOL_MAX, /* always last member of enum */ };
mm/mempolicy.c +6 -5
@@ -251,10 +251,10 @@ static struct mempolicy *mpol_new(unsignpr_debug ("setting mode %d flags %d nodes[0] %lx\n" , mode, flags, nodes ?nodes_addr (*nodes)[0 ] :-1 ); -if (mode ==MPOL_DEFAULT ) { +if (mode ==MPOL_DEFAULT || mode ==MPOL_NOOP ) {if (nodes && !nodes_empty (*nodes))return ERR_PTR (-EINVAL ); -return NULL ;/* simply delete any existing policy */ +return NULL ; }VM_BUG_ON (!nodes);
@@ -1146,7 +1146,7 @@ static long do_mbind(unsigned long startif (start & ~PAGE_MASK )return -EINVAL ; -if (mode ==MPOL_DEFAULT ) +if (mode ==MPOL_DEFAULT || mode ==MPOL_NOOP ) flags &= ~MPOL_MF_STRICT ; len = (len +PAGE_SIZE -1 ) &PAGE_MASK ;
@@ -2381,7 +2381,8 @@ static const char * const policy_modes[] [MPOL_PREFERRED] = "prefer", [MPOL_BIND] = "bind", [MPOL_INTERLEAVE] = "interleave", - [MPOL_LOCAL] = "local" + [MPOL_LOCAL] = "local", + [MPOL_NOOP] = "noop", /* should not actually be used */ };
@@ -2432,7 +2433,7 @@ int mpol_parse_str(char *str, struct membreak ; } } -if (mode >=MPOL_MAX ) +if (mode >=MPOL_MAX || mode ==MPOL_NOOP ) goto out;switch (mode) {
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 12/31] mm/mpol: Add MPOL_MF_NOOP
Quoted 3 lines · Peter Zijlstra
From: Lee Schermerhorn <[email protected]>
This patch augments the
MPOL_MF_LAZYfeature by adding a "NOOP" policy
The MPOL_MF_LAZY feature doesn't exist yet so it's hard to augment at this point :)
Quoted 4 lines
to
mbind(). When the NOOP policy is used with the 'MOVE and 'LAZY flags,mbind()will map the pagesPROT_NONEso that they will be migrated on the next touch.
This implies that a user-space application has a two-stage process. Stage 1, it marks a range NOOP and the stage 2 marks the range lazy. That feels like it might violate Rusty's API design rule of "The obvious use is wrong." What is the motivation for exposing NOOP to userspace? Instead why does mbind(addr, len, MPOL_MF_LAZY, nodemask, maxnode, flags) not imply that the range gets marked PROT_NONE (or PROT_NUMA or some other variant that is not arch-specific)?
It also seems that MPOL_MF_LAZY must imply MPOL_MF_MOVE or it's a bit pointless without the application having to specify the exact flag combination
Quoted 9 lines
This allows an application to prepare for a new phase of operation where different regions of shared storage will be assigned to worker threads, w/o changing policy. Note that we could just use "default" policy in this case. However, this also allows an application to request that pages be migrated, only if necessary, to follow any arbitrary policy that might currently apply to a range of pages, without knowing the policy, or without specifying multiple mbind()s for ranges with different policies.
I very much like the idea because potentially a motivated developer could use this mechanism to avoid any ping-pong problems with an automatic migration scheme. It could even be argued that any application using MPOL_MF_LAZY get unsubscribed from any automatic mechanism to avoid interference.
Quoted 53 lines
[ Bug in early version of
mpol_parse_str()reported by Fengguang Wu. ]Bug-Reported-by Reported-by: Fengguang Wu <[email protected]>Signed-off-by Lee Schermerhorn <[email protected]>Reviewed-by Rik van Riel <[email protected]>Cc Andrew Morton <[email protected]>Cc Linus Torvalds <[email protected]>Signed-off-by Peter Zijlstra <[email protected]>Signed-off-by Ingo Molnar <[email protected]>--- include/uapi/linux/mempolicy.h | 1 + mm/mempolicy.c | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-)Index:
tip/include/uapi/linux/mempolicy.h
===================================================================include/uapi/linux/mempolicy.h +1
-0@@ -21,6 +21,7 @@ enum {MPOL_BIND ,MPOL_INTERLEAVE ,MPOL_LOCAL , +MPOL_NOOP ,/* retain existing policy for range */ MPOL_MAX, /* always last member of enum */ };Index:
tip/mm/mempolicy.c
===================================================================mm/mempolicy.c +3
-3@@ -251,10 +251,10 @@ static struct mempolicy *mpol_new(unsignpr_debug ("setting mode %d flags %d nodes[0] %lx\n" , mode, flags, nodes ?nodes_addr (*nodes)[0 ] :-1 ); -if (mode ==MPOL_DEFAULT ) { +if (mode ==MPOL_DEFAULT || mode ==MPOL_NOOP ) {if (nodes && !nodes_empty (*nodes))return ERR_PTR (-EINVAL ); -return NULL ;/* simply delete any existing policy */ +return NULL ; }VM_BUG_ON (!nodes);@@ -1146,7 +1146,7 @@ static long do_mbind(unsigned long startif (start & ~PAGE_MASK )return -EINVAL ; -if (mode ==MPOL_DEFAULT ) +if (mode ==MPOL_DEFAULT || mode ==MPOL_NOOP ) flags &= ~MPOL_MF_STRICT ; len = (len +PAGE_SIZE -1 ) &PAGE_MASK ;
mm/mempolicy.c static const char * const policy_modes[] · line 2385
Quoted 6 lines
mm/mempolicy.c +2
-1@@ -2381,7 +2381,8 @@ static const char * const policy_modes[] [MPOL_PREFERRED] = "prefer", [MPOL_BIND] = "bind", [MPOL_INTERLEAVE] = "interleave", - [MPOL_LOCAL ] ="local" + [MPOL_LOCAL] = "local", + [MPOL_NOOP] = "noop", /* should not actually be used */
If it should not be used, why it is exposed to userspace?
Quoted 14 lines
mm/mempolicy.c +1
-1};@@ -2432,7 +2433,7 @@ int mpol_parse_str(char *str, struct membreak ; } } -if (mode >=MPOL_MAX ) +if (mode >=MPOL_MAX || mode ==MPOL_NOOP ) goto out;switch (mode) {
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 13/31 mm/mpol: Check for misplaced page
In reply to Peter ZijlstraFrom: Lee Schermerhorn <[email protected]>
This patch provides a new function to test whether a page resides on a node that is appropriate for the mempolicy for the vma and address where the page is supposed to be mapped. This involves looking up the node where the page belongs. So, the function returns that node so that it may be used to allocated the page without consulting the policy again.
A subsequent patch will call this function from the fault path. Because of this, I don't want to go ahead and allocate the page, e.g., via alloc_page_vma() only to have to free it if it has the correct policy. So, I just mimic the alloc_page_vma() node computation logic--sort of.
Note: we could use this function to implement a MPOL_MF_STRICT behavior when migrating pages to match mbind() mempolicy--e.g., to ensure that pages in an interleaved range are reinterleaved rather than left where they are when they reside on any page in the interleave nodemask.
[ Added MPOL_F_LAZY to trigger migrate-on-fault;
simplified code now that we don't have to bother with special crap for interleaved ]
--- include/linux/mempolicy.h | 8 ++++ include/uapi/linux/mempolicy.h | 1 mm/mempolicy.c | 76 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+)
include/linux/mempolicy.h +8 -0
@@ -198,6 +198,8 @@ static inline int vma_migratable(struct return 1; } +extern int mpol_misplaced (struct page *,struct vm_area_struct *,unsigned long ); +#else struct mempolicy {};
@@ -323,5 +325,11 @@ static inline int mpol_to_str(char *buffreturn 0 ; } +static inline int mpol_misplaced (struct page *page,struct vm_area_struct *vma, +unsigned long address) +{ +return -1 ;/* no node preference */ +} +#endif /* CONFIG_NUMA */ #endif
include/uapi/linux/mempolicy.h +1 -0
@@ -61,6 +61,7 @@ enum mpol_rebind_step {#define MPOL_F_SHARED (1 << 0)/* identify shared policies */ #define MPOL_F_LOCAL (1 << 1)/* preferred local allocation */ #define MPOL_F_REBINDING (1 << 2)/* identify policies in rebinding */ +#define MPOL_F_MOF (1 << 3)/* this policy wants migrate on fault */ #endif /* _UAPI_LINUX_MEMPOLICY_H */
mm/mempolicy.c +76 -0
82 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 14/31 mm/mpol: Create special PROT_NONE infrastructure
In reply to Peter ZijlstraIn order to facilitate a lazy -- fault driven -- migration of pages, create a special transient PROT_NONE variant, we can then use the 'spurious' protection faults to drive our migrations from.
Pages that already had an effective PROT_NONE mapping will not be detected to generate these 'spuriuos' faults for the simple reason that we cannot distinguish them on their protection bits, see pte_numa().
This isn't a problem since PROT_NONE (and possible PROT_WRITE with dirty tracking) aren't used or are rare enough for us to not care about their placement.
--- include/linux/huge_mm.h | 19 ++++++++++++ include/linux/mm.h | 18 +++++++++++ mm/huge_memory.c | 32 ++++++++++++++++++++ mm/memory.c | 75 +++++++++++++++++++++++++++++++++++++++++++----- mm/mprotect.c | 24 ++++++++++----- 5 files changed, 154 insertions(+), 14 deletions(-)
include/linux/huge_mm.h +19 -0
@@ -159,6 +159,13 @@ static inline struct page *compound_tran }return page; } + +extern bool pmd_numa (struct vm_area_struct *vma,pmd_t pmd); + +extern void do_huge_pmd_numa_page (struct mm_struct *mm,struct vm_area_struct *vma, +unsigned long address,pmd_t *pmd, +unsigned int flags,pmd_t orig_pmd); +#else /* CONFIG_TRANSPARENT_HUGEPAGE */ #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })#define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; })
@@ -195,6 +202,18 @@ static inline int pmd_trans_huge_lock(pm {return 0 ; } + +static inline bool pmd_numa (struct vm_area_struct *vma,pmd_t pmd) +{ +return false; +} + +static inline void do_huge_pmd_numa_page (struct mm_struct *mm,struct vm_area_struct *vma, +unsigned long address,pmd_t *pmd, +unsigned int flags,pmd_t orig_pmd) +{ +} +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #endif /* _LINUX_HUGE_MM_H */
include/linux/mm.h +18 -0
@@ -1091,6 +1091,9 @@ extern unsigned long move_page_tables(stextern unsigned long do_mremap (unsigned long addr,unsigned long old_len,unsigned long new_len,unsigned long flags,unsigned long new_addr); +extern void change_protection (struct vm_area_struct *vma,unsigned long start, +unsigned long end,pgprot_t newprot, +int dirty_accountable);extern int mprotect_fixup (struct vm_area_struct *vma,struct vm_area_struct **pprev,unsigned long start,unsigned long end,unsigned long newflags);
@@ -1561,6 +1564,21 @@ static inline pgprot_t vm_get_page_prot( }#endif +static inline pgprot_t vma_prot_none (struct vm_area_struct *vma) +{ +/* +* obtain PROT_NONE by removing READ|WRITE|EXEC privs +*/ +vm_flags_t vmflags = vma->vm_flags & ~(VM_READ |VM_WRITE |VM_EXEC ); +return pgprot_modify (vma->vm_page_prot,vm_get_page_prot (vmflags)); +} + +static inline void +change_prot_none (struct vm_area_struct *vma,unsigned long start,unsigned long end) +{ +change_protection (vma, start, end,vma_prot_none (vma),0 ); +} +struct vm_area_struct *find_extend_vma (struct mm_struct *,unsigned long addr);int remap_pfn_range (struct vm_area_struct *,unsigned long addr,unsigned long pfn,unsigned long size,pgprot_t );
mm/huge_memory.c +32 -0
@@ -725,6 +725,38 @@ out:return handle_pte_fault (mm, vma, address, pte, pmd, flags); } +bool pmd_numa (struct vm_area_struct *vma,pmd_t pmd) +{ +/* +* See pte_numa(). +*/ +if (pmd_same (pmd,pmd_modify (pmd, vma->vm_page_prot))) +return false; + +return pmd_same (pmd,pmd_modify (pmd,vma_prot_none (vma))); +} + +void do_huge_pmd_numa_page (struct mm_struct *mm,struct vm_area_struct *vma, +unsigned long address,pmd_t *pmd, +unsigned int flags,pmd_t entry) +{ +unsigned long haddr = address &HPAGE_PMD_MASK ; + +spin_lock (&mm->page_table_lock); +if (unlikely (!pmd_same (*pmd, entry))) + goto out_unlock; + +/* do fancy stuff */ + +/* change back to regular protection */ + entry =pmd_modify (entry, vma->vm_page_prot); +if (pmdp_set_access_flags (vma, haddr, pmd, entry,1 )) +update_mmu_cache_pmd (vma, address, entry); + +out_unlock: +spin_unlock (&mm->page_table_lock); +} +int copy_huge_pmd (struct mm_struct *dst_mm,struct mm_struct *src_mm,pmd_t *dst_pmd,pmd_t *src_pmd,unsigned long addr,struct vm_area_struct *vma)
mm/memory.c +68 -7
111 lines not on this page · raw message
mm/mprotect.c +17 -7
@@ -112,7 +112,7 @@ static inline void change_pud_range(stru }while (pud++, addr = next, addr != end); } -static void change_protection (struct vm_area_struct *vma, +static void change_protection_range (struct vm_area_struct *vma,unsigned long addr,unsigned long end,pgprot_t newprot,int dirty_accountable) {
@@ -134,6 +134,20 @@ static void change_protection(struct vm_flush_tlb_range (vma, start, end); } +void change_protection (struct vm_area_struct *vma,unsigned long start, +unsigned long end,pgprot_t newprot, +int dirty_accountable) +{ +struct mm_struct *mm = vma->vm_mm; + +mmu_notifier_invalidate_range_start (mm, start, end); +if (is_vm_hugetlb_page (vma)) +hugetlb_change_protection (vma, start, end, newprot); +else +change_protection_range (vma, start, end, newprot, dirty_accountable); +mmu_notifier_invalidate_range_end (mm, start, end); +} +int mprotect_fixup (struct vm_area_struct *vma,struct vm_area_struct **pprev,unsigned long start,unsigned long end,unsigned long newflags)
@@ -206,12 +220,8 @@ success: dirty_accountable =1 ; } -mmu_notifier_invalidate_range_start (mm, start, end); -if (is_vm_hugetlb_page (vma)) -hugetlb_change_protection (vma, start, end, vma->vm_page_prot); -else -change_protection (vma, start, end, vma->vm_page_prot, dirty_accountable); -mmu_notifier_invalidate_range_end (mm, start, end); +change_protection (vma, start, end, vma->vm_page_prot, dirty_accountable); +vm_stat_account (mm, oldflags, vma->vm_file, -nrpages);vm_stat_account (mm, newflags, vma->vm_file, nrpages);perf_event_mmap (vma);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 14/31] mm/mpol: Create special PROT_NONE infrastructure
Quoted 4 lines · Peter Zijlstra
In order to facilitate a lazy -- fault driven -- migration of pages, create a special transient
PROT_NONEvariant, we can then use the 'spurious' protection faults to drive our migrations from.
The changelog should mention that fault-driven migration also means that the full cost of migration is incurred by the process. If someone in the future tries to do the migration in a kernel thread they should be reminded that the fault-driven choice was deliberate.
Quoted 80 lines
Pages that already had an effective
PROT_NONEmapping will not be detected to generate these 'spuriuos' faults for the simple reason that we cannot distinguish them on their protection bits, seepte_numa().This isn't a problem since
PROT_NONE(and possiblePROT_WRITEwith dirty tracking) aren't used or are rare enough for us to not care about their placement.Suggested-by Rik van Riel <[email protected]>Signed-off-by Peter Zijlstra <[email protected]>Reviewed-by Rik van Riel <[email protected]>Cc Paul Turner <[email protected]>Cc Linus Torvalds <[email protected]>Cc Andrew Morton <[email protected]>Cc Andrea Arcangeli <[email protected]>[ fixed various cross-arch and THP/!THP details ]Signed-off-by Ingo Molnar <[email protected]>--- include/linux/huge_mm.h | 19 ++++++++++++ include/linux/mm.h | 18 +++++++++++ mm/huge_memory.c | 32 ++++++++++++++++++++ mm/memory.c | 75 +++++++++++++++++++++++++++++++++++++++++++----- mm/mprotect.c | 24 ++++++++++----- 5 files changed, 154 insertions(+), 14 deletions(-)Index:
tip/include/linux/huge_mm.h
===================================================================include/linux/huge_mm.h +19
-0@@ -159,6 +159,13 @@ static inline struct page *compound_tran }return page; } + +extern bool pmd_numa (struct vm_area_struct *vma,pmd_t pmd); + +extern void do_huge_pmd_numa_page (struct mm_struct *mm,struct vm_area_struct *vma, +unsigned long address,pmd_t *pmd, +unsigned int flags,pmd_t orig_pmd); +#else /* CONFIG_TRANSPARENT_HUGEPAGE */ #define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })#define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; })@@ -195,6 +202,18 @@ static inline int pmd_trans_huge_lock(pm {return 0 ; } + +static inline bool pmd_numa (struct vm_area_struct *vma,pmd_t pmd) +{ +return false; +} + +static inline void do_huge_pmd_numa_page (struct mm_struct *mm,struct vm_area_struct *vma, +unsigned long address,pmd_t *pmd, +unsigned int flags,pmd_t orig_pmd) +{ +} +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #endif /* _LINUX_HUGE_MM_H */ Index:
tip/include/linux/mm.h
===================================================================include/linux/mm.h +3
-0@@ -1091,6 +1091,9 @@ extern unsigned long move_page_tables(stextern unsigned long do_mremap (unsigned long addr,unsigned long old_len,unsigned long new_len,unsigned long flags,unsigned long new_addr); +extern void change_protection (struct vm_area_struct *vma,unsigned long start, +unsigned long end,pgprot_t newprot, +int dirty_accountable);extern int mprotect_fixup (struct vm_area_struct *vma,struct vm_area_struct **pprev,unsigned long start,unsigned long end,unsigned long newflags);@@ -1561,6 +1564,21 @@ static inline pgprot_t vm_get_page_prot( }#endif
include/linux/mm.h static inline pgprot_t vm_get_page_prot( · line 1575
Quoted 10 lines
include/linux/mm.h +9
-0+static inline pgprot_t vma_prot_none (struct vm_area_struct *vma) +{ +/* +* obtain PROT_NONE by removing READ|WRITE|EXEC privs +*/ +vm_flags_t vmflags = vma->vm_flags & ~(VM_READ |VM_WRITE |VM_EXEC ); +return pgprot_modify (vma->vm_page_prot,vm_get_page_prot (vmflags)); +} +
Again, this very much hard-codes the choice of prot_none as the _PAGE_NUMA bit.
include/linux/mm.h static inline pgprot_t vm_get_page_prot( · line 1581
Quoted 6 lines
include/linux/mm.h +6
-0+static inline void +change_prot_none (struct vm_area_struct *vma,unsigned long start,unsigned long end) +{ +change_protection (vma, start, end,vma_prot_none (vma),0 ); +} +
And this is somewhat explicit too. Steal pte_mknuma and shove this into the arch layer?
Quoted 24 lines
include/linux/mm.h +0
-0struct vm_area_struct *find_extend_vma (struct mm_struct *,unsigned long addr);int remap_pfn_range (struct vm_area_struct *,unsigned long addr,unsigned long pfn,unsigned long size,pgprot_t );Index:
tip/mm/huge_memory.c
===================================================================mm/huge_memory.c +13
-0@@ -725,6 +725,38 @@ out:return handle_pte_fault (mm, vma, address, pte, pmd, flags); } +bool pmd_numa (struct vm_area_struct *vma,pmd_t pmd) +{ +/* +* See pte_numa(). +*/ +if (pmd_same (pmd,pmd_modify (pmd, vma->vm_page_prot))) +return false; + +return pmd_same (pmd,pmd_modify (pmd,vma_prot_none (vma))); +} + +void do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma, + unsigned long address, pmd_t *pmd,
mm/huge_memory.c out: · line 750
Quoted 10 lines
mm/huge_memory.c +10
-0+ unsigned int flags, pmd_t entry) +{ +unsigned long haddr = address &HPAGE_PMD_MASK ; + +spin_lock (&mm->page_table_lock); +if (unlikely (!pmd_same (*pmd, entry))) + goto out_unlock; + +/* do fancy stuff */ +
Joking aside,
Quoted 50 lines
mm/huge_memory.c +9
-0+/* change back to regular protection */ + entry =pmd_modify (entry, vma->vm_page_prot); +if (pmdp_set_access_flags (vma, haddr, pmd, entry,1 )) +update_mmu_cache_pmd (vma, address, entry); + +out_unlock: +spin_unlock (&mm->page_table_lock); +} +int copy_huge_pmd (struct mm_struct *dst_mm,struct mm_struct *src_mm,pmd_t *dst_pmd,pmd_t *src_pmd,unsigned long addr,struct vm_area_struct *vma)Index:
tip/mm/memory.c
===================================================================mm/memory.c +23
-0@@ -1464,6 +1464,25 @@ int zap_vma_ptes(struct vm_area_struct * }EXPORT_SYMBOL_GPL (zap_vma_ptes); +static bool pte_numa (struct vm_area_struct *vma,pte_t pte) +{ +/* +* If we have the normal vma->vm_page_prot protections we're not a +* 'special' PROT_NONE page. +* +* This means we cannot get 'special' PROT_NONE faults from genuine +* PROT_NONE maps, nor from PROT_WRITE file maps that do dirty +* tracking. +* +* Neither case is really interesting for our current use though so we +* don't care. +*/ +if (pte_same (pte,pte_modify (pte, vma->vm_page_prot))) +return false; + +return pte_same (pte,pte_modify (pte,vma_prot_none (vma))); +} +/** * follow_page - look up a page descriptor from a user-virtual address * @vma: vm_area_struct mapping @address @@ -3433,6 +3452,41 @@ static int do_nonlinear_fault(struct mm_return __do_fault (mm, vma, address, pmd, pgoff, flags, orig_pte); } +static int do_numa_page (struct mm_struct *mm,struct vm_area_struct *vma, +unsigned long address,pte_t *ptep,pmd_t *pmd, +unsigned int flags,pte_t entry) +{
mm/memory.c static int do_nonlinear_fault(struct mm_ · line 3468
Quoted 10 lines
mm/memory.c +10
-0+spinlock_t *ptl; +int ret =0 ; + +if (!pte_unmap_same (mm, pmd, ptep, entry)) + goto out; + +/* +* Do fancy stuff... +*/ +
Ok, so we should not have to check for a splitting huge page at this point because it has been checked already.
mm/memory.c static int do_nonlinear_fault(struct mm_ · line 3478
Quoted 10 lines
mm/memory.c +10
-0+/* +* OK, nothing to do,.. change the protection back to what it +* ought to be. +*/ + ptep =pte_offset_map_lock (mm, pmd, address, &ptl); +if (unlikely (!pte_same (*ptep, entry))) + goto unlock; + +flush_cache_page (vma, address,pte_pfn (entry)); +
This page was marked PROT_NONE so why is it necessary to flush the cache? Needs a comment.
mm/memory.c static int do_nonlinear_fault(struct mm_ · line 3482
Quoted 4 lines
mm/memory.c +4
-0+ptep_modify_prot_start (mm, address, ptep); + entry =pte_modify (entry, vma->vm_page_prot); +ptep_modify_prot_commit (mm, address, ptep, entry); +
could have used pte_mknonnuma() if it was pulled in.
Quoted 23 lines
mm/memory.c +10
-0+update_mmu_cache (vma, address, ptep); +unlock: +pte_unmap_unlock (ptep, ptl); +out: +return ret; +} +/* * These routines also need to handle stuff like marking pages dirty * and/or accessed for architectures that don't do it in hardware (most @@ -3471,6 +3525,9 @@ int handle_pte_fault(struct mm_struct *m pte, pmd, flags, entry); } +if (pte_numa (vma, entry)) +return do_numa_page (mm, vma, address, pte, pmd, flags, entry); + ptl =pte_lockptr (mm, pmd);spin_lock (ptl);if (unlikely (!pte_same (*pte, entry)))@@ -3535,13 +3592,16 @@ retry: pmd, flags); }else {
mm/memory.c retry: · line 3598
Quoted 10 lines
mm/memory.c +2
-5pmd_t orig_pmd = *pmd; -int ret; +int ret =0 ;barrier (); -if (pmd_trans_huge (orig_pmd)) { -if (flags &FAULT_FLAG_WRITE && - !pmd_write (orig_pmd) && - !pmd_trans_splitting (orig_pmd)) { +if (pmd_trans_huge (orig_pmd) && !pmd_trans_splitting (orig_pmd)) {
Hmm ok, if it trans_huge and is splitting it now falls through
mm/memory.c retry: · line 3603
Quoted 5 lines
mm/memory.c +5
-0+if (pmd_numa (vma, orig_pmd)) { +do_huge_pmd_numa_page (mm, vma, address, pmd, + flags, orig_pmd); + } +
When this thing returns you are not holding the page_table_lock and mmap_sem on its own is not enough to protect against a split. Should you not recheck pmd_trans_splitting and potentially return 0 to retry the fault if it is?
I guess it does not matter per-se. If it's a write, you call do_huge_pmd_wp_page() which will eventually check if pmd_same (which will fail as PROT_NONE was fixed up) and retry the whole fault after a bunch of work like allocating a huge page. To avoid that, I strong suspect you should re-read orig_pmd after handling the NUMA fault or something similar. If the fault is a read fault, it'll fall through and return 0.
Quoted 71 lines
mm/memory.c +4
-2+if ((flags &FAULT_FLAG_WRITE ) && !pmd_write (orig_pmd)) { ret =do_huge_pmd_wp_page (mm, vma, address, pmd, orig_pmd);/* @@ -3551,12 +3611,13 @@ retry:*/ if (unlikely (ret &VM_FAULT_OOM )) goto retry; -return ret; } -return 0 ; + +return ret; } } +/* * Use __pte_alloc instead of pte_alloc_map, because we can't * run pte_offset_map on the pmd, if an huge pmd could Index:
tip/mm/mprotect.c
===================================================================mm/mprotect.c +17
-7@@ -112,7 +112,7 @@ static inline void change_pud_range(stru }while (pud++, addr = next, addr != end); } -static void change_protection (struct vm_area_struct *vma, +static void change_protection_range (struct vm_area_struct *vma,unsigned long addr,unsigned long end,pgprot_t newprot,int dirty_accountable) {@@ -134,6 +134,20 @@ static void change_protection(struct vm_flush_tlb_range (vma, start, end); } +void change_protection (struct vm_area_struct *vma,unsigned long start, +unsigned long end,pgprot_t newprot, +int dirty_accountable) +{ +struct mm_struct *mm = vma->vm_mm; + +mmu_notifier_invalidate_range_start (mm, start, end); +if (is_vm_hugetlb_page (vma)) +hugetlb_change_protection (vma, start, end, newprot); +else +change_protection_range (vma, start, end, newprot, dirty_accountable); +mmu_notifier_invalidate_range_end (mm, start, end); +} +int mprotect_fixup (struct vm_area_struct *vma,struct vm_area_struct **pprev,unsigned long start,unsigned long end,unsigned long newflags)@@ -206,12 +220,8 @@ success: dirty_accountable =1 ; } -mmu_notifier_invalidate_range_start (mm, start, end); -if (is_vm_hugetlb_page (vma)) -hugetlb_change_protection (vma, start, end, vma->vm_page_prot); -else -change_protection (vma, start, end, vma->vm_page_prot, dirty_accountable); -mmu_notifier_invalidate_range_end (mm, start, end); +change_protection (vma, start, end, vma->vm_page_prot, dirty_accountable); +vm_stat_account (mm, oldflags, vma->vm_file, -nrpages);vm_stat_account (mm, newflags, vma->vm_file, nrpages);perf_event_mmap (vma);
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 15/31 mm/mpol: Add MPOL_MF_LAZY
In reply to Peter ZijlstraFrom: Lee Schermerhorn <[email protected]>
This patch adds another mbind() flag to request "lazy migration". The flag, MPOL_MF_LAZY, modifies MPOL_MF_MOVE* such that the selected pages are marked PROT_NONE. The pages will be migrated in the fault path on "first touch", if the policy dictates at that time.
"Lazy Migration" will allow testing of migrate-on-fault via mbind(). Also allows applications to specify that only subsequently touched pages be migrated to obey new policy, instead of all pages in range. This can be useful for multi-threaded applications working on a large shared data area that is initialized by an initial thread resulting in all pages on one [or a few, if overflowed] nodes. After PROT_NONE, the pages in regions assigned to the worker threads will be automatically migrated local to the threads on 1st touch.
--- include/uapi/linux/mempolicy.h | 13 ++++++++-- mm/mempolicy.c | 49 ++++++++++++++++++++++++++--------------- 2 files changed, 42 insertions(+), 20 deletions(-)
include/uapi/linux/mempolicy.h +10 -3
@@ -49,9 +49,16 @@ enum mpol_rebind_step {/* Flags for mbind */ #define MPOL_MF_STRICT (1<<0)/* Verify existing pages in the mapping */ -#define MPOL_MF_MOVE (1<<1)/* Move pages owned by this process to conform to mapping */ -#define MPOL_MF_MOVE_ALL (1<<2)/* Move every page to conform to mapping */ -#define MPOL_MF_INTERNAL (1<<3)/* Internal flags start here */ +#define MPOL_MF_MOVE (1<<1)/* Move pages owned by this process to conform +to policy */ +#define MPOL_MF_MOVE_ALL (1<<2)/* Move every page to conform to policy */ +#define MPOL_MF_LAZY (1<<3)/* Modifies '_MOVE: lazy migrate on fault */ +#define MPOL_MF_INTERNAL (1<<4)/* Internal flags start here */ + +#define MPOL_MF_VALID (MPOL_MF_STRICT | \ + MPOL_MF_MOVE | \ + MPOL_MF_MOVE_ALL | \ + MPOL_MF_LAZY)/* * Internal flags that share the struct mempolicy flags word with
mm/mempolicy.c +32 -17
95 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 15/31] mm/mpol: Add MPOL_MF_LAZY
Quoted 7 lines · Peter Zijlstra
From: Lee Schermerhorn <[email protected]>
This patch adds another
mbind()flag to request "lazy migration". The flag,MPOL_MF_LAZY, modifies MPOL_MF_MOVE* such that the selected pages are markedPROT_NONE. The pages will be migrated in the fault path on "first touch", if the policy dictates at that time.
Quoted 9 lines
"Lazy Migration" will allow testing of migrate-on-fault via
mbind(). Also allows applications to specify that only subsequently touched pages be migrated to obey new policy, instead of all pages in range. This can be useful for multi-threaded applications working on a large shared data area that is initialized by an initial thread resulting in all pages on one [or a few, if overflowed] nodes. AfterPROT_NONE, the pages in regions assigned to the worker threads will be automatically migrated local to the threads on 1st touch.
I like the idea. Applications will need some way of progamatically detecting if MPOL_MF_LAZY is available. I guess they could always try the flag and if it fails, do nothing. When/if the manual page for it happens it probably will be a lot more obvious. The changelog does not actually describe what this patch does though
This patch is a preparation step for "lazy migration". When the flag is used, the range is marked prot_none. In a later patch it will be detected at fault time that the page is misplaced and migrate it at that point.
Quoted 60 lines
Signed-off-by Lee Schermerhorn <[email protected]>Reviewed-by Rik van Riel <[email protected]>Cc Lee Schermerhorn <[email protected]>Cc Andrew Morton <[email protected]>Cc Linus Torvalds <[email protected]>[ nearly complete rewrite.. ]Signed-off-by Peter Zijlstra <[email protected]>Signed-off-by Ingo Molnar <[email protected]>--- include/uapi/linux/mempolicy.h | 13 ++++++++-- mm/mempolicy.c | 49 ++++++++++++++++++++++++++--------------- 2 files changed, 42 insertions(+), 20 deletions(-)Index:
tip/include/uapi/linux/mempolicy.h
===================================================================include/uapi/linux/mempolicy.h +10
-3@@ -49,9 +49,16 @@ enum mpol_rebind_step {/* Flags for mbind */ #define MPOL_MF_STRICT (1<<0)/* Verify existing pages in the mapping */ -#define MPOL_MF_MOVE (1<<1)/* Move pages owned by this process to conform to mapping */ -#define MPOL_MF_MOVE_ALL (1<<2)/* Move every page to conform to mapping */ -#define MPOL_MF_INTERNAL (1<<3)/* Internal flags start here */ +#define MPOL_MF_MOVE (1<<1)/* Move pages owned by this process to conform +to policy */ +#define MPOL_MF_MOVE_ALL (1<<2)/* Move every page to conform to policy */ +#define MPOL_MF_LAZY (1<<3)/* Modifies '_MOVE: lazy migrate on fault */ +#define MPOL_MF_INTERNAL (1<<4)/* Internal flags start here */ + +#define MPOL_MF_VALID (MPOL_MF_STRICT | \ + MPOL_MF_MOVE | \ + MPOL_MF_MOVE_ALL | \ + MPOL_MF_LAZY)/* * Internal flags that share the struct mempolicy flags word with Index:
tip/mm/mempolicy.c
===================================================================mm/mempolicy.c +7
-1@@ -583,22 +583,32 @@ check_range(struct mm_struct *mm, unsignreturn ERR_PTR (-EFAULT ); prev =NULL ;for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) { +unsigned long endvma = vma->vm_end; + +if (endvma > end) + endvma = end; +if (vma->vm_start > start) + start = vma->vm_start; +if (!(flags &MPOL_MF_DISCONTIG_OK )) {if (!vma->vm_next && vma->vm_end < end)return ERR_PTR (-EFAULT );if (prev && prev->vm_end < vma->vm_start)return ERR_PTR (-EFAULT ); } - if (!is_vm_hugetlb_page(vma) &&
mm/mempolicy.c check_range(struct mm_struct *mm, unsign · line 607
Quoted 10 lines
mm/mempolicy.c +9
-1- ((flags & MPOL_MF_STRICT) || + +if (is_vm_hugetlb_page (vma)) + goto next; + +if (flags &MPOL_MF_LAZY ) { +change_prot_none (vma, start, endvma); + goto next; + } +
More hard-coding of prot_none.
Quoted 74 lines
mm/mempolicy.c +16
-15+if ((flags &MPOL_MF_STRICT ) || ((flags & (MPOL_MF_MOVE |MPOL_MF_MOVE_ALL )) && - vma_migratable(vma)))) { -unsigned long endvma = vma->vm_end; +vma_migratable (vma))) { -if (endvma > end) - endvma = end; -if (vma->vm_start > start) - start = vma->vm_start; err =check_pgd_range (vma, start, endvma, nodes, flags, private);if (err) {@@ -606,6 +616,7 @@ check_range(struct mm_struct *mm, unsignbreak ; } } +next: prev = vma; }return first;@@ -1137,8 +1148,7 @@ static long do_mbind(unsigned long startint err;LIST_HEAD (pagelist); -if (flags & ~(unsigned long )(MPOL_MF_STRICT | -MPOL_MF_MOVE |MPOL_MF_MOVE_ALL )) +if (flags & ~(unsigned long )MPOL_MF_VALID )return -EINVAL ;if ((flags &MPOL_MF_MOVE_ALL ) && !capable (CAP_SYS_NICE ))return -EPERM ;@@ -1161,6 +1171,9 @@ static long do_mbind(unsigned long startif (IS_ERR (new))return PTR_ERR (new); +if (flags &MPOL_MF_LAZY ) + new->flags |=MPOL_F_MOF ; +/* * If we are using the default policy then operation * on discontinuous address spaces is okay after all @@ -1197,21 +1210,23 @@ static long do_mbind(unsigned long start vma =check_range (mm, start, end, nmask, flags |MPOL_MF_INVERT , &pagelist); - err =PTR_ERR (vma); -if (!IS_ERR (vma)) { -int nr_failed =0 ; - + err =PTR_ERR (vma);/* maybe ... */ +if (!IS_ERR (vma) && mode !=MPOL_NOOP ) err =mbind_range (mm, start, end, new); +if (!err) { +int nr_failed =0 ; +if (!list_empty (&pagelist)) { +WARN_ON_ONCE (flags &MPOL_MF_LAZY ); nr_failed =migrate_pages (&pagelist, new_vma_page, - (unsigned long )vma, - false,MIGRATE_SYNC ); + (unsigned long )vma, + false,MIGRATE_SYNC );if (nr_failed)putback_lru_pages (&pagelist); } -if (!err && nr_failed && (flags &MPOL_MF_STRICT )) +if (nr_failed && (flags &MPOL_MF_STRICT )) err = -EIO ; }else putback_lru_pages (&pagelist);
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 16/31 numa, mm: Support NUMA hinting page faults from gup/gup_fast
In reply to Peter ZijlstraFrom: Ingo Molnar <[email protected]>
Introduce FOLL_NUMA to tell follow_page to check pte/pmd_numa. get_user_pages must use FOLL_NUMA, and it's safe to do so because it always invokes handle_mm_fault and retries the follow_page later.
KVM secondary MMU page faults will trigger the NUMA hinting page faults through gup_fast -> get_user_pages -> follow_page -> handle_mm_fault.
Other follow_page callers like KSM should not use FOLL_NUMA, or they would fail to get the pages if they use follow_page instead of get_user_pages.
[ This patch was picked up from the AutoNUMA tree. ]
--- include/linux/mm.h | 1 + mm/memory.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+)
include/linux/mm.h +1 -0
@@ -1600,6 +1600,7 @@ struct page *follow_page(struct vm_area_#define FOLL_MLOCK 0x40/* mark page as mlocked */ #define FOLL_SPLIT 0x80/* don't return transhuge pages, split them */ #define FOLL_HWPOISON 0x100/* check page is hwpoisoned */ +#define FOLL_NUMA 0x200/* force NUMA hinting page fault */ typedef int (*pte_fn_t )(pte_t *pte,pgtable_t token,unsigned long addr,void *data);
mm/memory.c +17 -0
@@ -1536,6 +1536,8 @@ struct page *follow_page(struct vm_area_ page =follow_huge_pmd (mm, address, pmd, flags &FOLL_WRITE ); goto out; } +if ((flags &FOLL_NUMA ) &&pmd_numa (vma, *pmd)) + goto no_page_table;if (pmd_trans_huge (*pmd)) {if (flags &FOLL_SPLIT ) {split_huge_page_pmd (mm, pmd);
@@ -1565,6 +1567,8 @@ split_fallthrough: pte = *ptep;if (!pte_present (pte)) goto no_page; +if ((flags &FOLL_NUMA ) &&pte_numa (vma, pte)) + goto no_page;if ((flags &FOLL_WRITE ) && !pte_write (pte)) goto unlock;
@@ -1716,6 +1720,19 @@ int __get_user_pages(struct task_struct (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD); vm_flags &= (gup_flags &FOLL_FORCE ) ? (VM_MAYREAD |VM_MAYWRITE ) : (VM_READ |VM_WRITE ); + +/* +* If FOLL_FORCE and FOLL_NUMA are both set, handle_mm_fault +* would be called on PROT_NONE ranges. We must never invoke +* handle_mm_fault on PROT_NONE ranges or the NUMA hinting +* page faults would unprotect the PROT_NONE ranges if +* _PAGE_NUMA and _PAGE_PROTNONE are sharing the same pte/pmd +* bitflag. So to avoid that, don't set FOLL_NUMA if +* FOLL_FORCE is set. +*/ +if (!(gup_flags &FOLL_FORCE )) + gup_flags |=FOLL_NUMA ; + i =0 ; do {
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 17/31 mm/migrate: Introduce migrate_misplaced_page()
In reply to Peter ZijlstraAdd migrate_misplaced_page() which deals with migrating pages from faults.
This includes adding a new MIGRATE_FAULT migration mode to deal with the extra page reference required due to having to look up the page.
--- include/linux/migrate.h | 7 +++ include/linux/migrate_mode.h | 3 + mm/migrate.c | 85 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 87 insertions(+), 8 deletions(-)
include/linux/migrate.h +7 -0
@@ -30,6 +30,7 @@ extern int migrate_vmas(struct mm_structextern void migrate_page_copy (struct page *newpage,struct page *page);extern int migrate_huge_page_move_mapping (struct address_space *mapping,struct page *newpage,struct page *page); +extern int migrate_misplaced_page (struct page *page,int node);#else static inline void putback_lru_pages (struct list_head *l) {}
@@ -63,5 +64,11 @@ static inline int migrate_huge_page_move#define migrate_page NULL#define fail_migrate_page NULL +static inline +int migrate_misplaced_page (struct page *page,int node) +{ +return -EAGAIN ;/* can't migrate now */ +}#endif /* CONFIG_MIGRATION */ +#endif /* _LINUX_MIGRATE_H */
include/linux/migrate_mode.h +3 -0
@@ -6,11 +6,14 @@* on most operations but not ->writepage as the potential stall time * is too significant * MIGRATE_SYNC will block when migrating pages +* MIGRATE_FAULT called from the fault path to migrate-on-fault for mempolicy +* this path has an extra reference count */ enum migrate_mode {MIGRATE_ASYNC ,MIGRATE_SYNC_LIGHT ,MIGRATE_SYNC , +MIGRATE_FAULT , };#endif /* MIGRATE_MODE_H_INCLUDED */
mm/migrate.c +77 -8
128 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 17/31] mm/migrate: Introduce migrate_misplaced_page()
Quoted 151 lines · Peter Zijlstra
Add
migrate_misplaced_page()which deals with migrating pages from faults.This includes adding a new
MIGRATE_FAULTmigration mode to deal with the extra page reference required due to having to look up the page.Based-on-work-by Lee Schermerhorn <[email protected]>Signed-off-by Peter Zijlstra <[email protected]>Reviewed-by Rik van Riel <[email protected]>Cc Paul Turner <[email protected]>Cc Linus Torvalds <[email protected]>Cc Andrew Morton <[email protected]>Signed-off-by Ingo Molnar <[email protected]>--- include/linux/migrate.h | 7 +++ include/linux/migrate_mode.h | 3 + mm/migrate.c | 85 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 87 insertions(+), 8 deletions(-)Index:
tip/include/linux/migrate.h
===================================================================include/linux/migrate.h +7
-0@@ -30,6 +30,7 @@ extern int migrate_vmas(struct mm_structextern void migrate_page_copy (struct page *newpage,struct page *page);extern int migrate_huge_page_move_mapping (struct address_space *mapping,struct page *newpage,struct page *page); +extern int migrate_misplaced_page (struct page *page,int node);#else static inline void putback_lru_pages (struct list_head *l) {}@@ -63,5 +64,11 @@ static inline int migrate_huge_page_move#define migrate_page NULL#define fail_migrate_page NULL +static inline +int migrate_misplaced_page (struct page *page,int node) +{ +return -EAGAIN ;/* can't migrate now */ +}#endif /* CONFIG_MIGRATION */ +#endif /* _LINUX_MIGRATE_H */ Index:
tip/include/linux/migrate_mode.h
===================================================================include/linux/migrate_mode.h +3
-0@@ -6,11 +6,14 @@* on most operations but not ->writepage as the potential stall time * is too significant * MIGRATE_SYNC will block when migrating pages +* MIGRATE_FAULT called from the fault path to migrate-on-fault for mempolicy +* this path has an extra reference count */ enum migrate_mode {MIGRATE_ASYNC ,MIGRATE_SYNC_LIGHT ,MIGRATE_SYNC , +MIGRATE_FAULT , };#endif /* MIGRATE_MODE_H_INCLUDED */ Index:
tip/mm/migrate.c
===================================================================mm/migrate.c +26
-8@@ -225,7 +225,7 @@ static bool buffer_migrate_lock_buffers(struct buffer_head *bh = head;/* Simple case, sync compaction */ -if (mode !=MIGRATE_ASYNC ) { +if (mode !=MIGRATE_ASYNC && mode !=MIGRATE_FAULT ) { do { get_bh(bh); lock_buffer(bh);@@ -279,12 +279,22 @@ static int migrate_page_move_mapping(str struct page *newpage, struct page *page, struct buffer_head *head, enum migrate_mode mode) { - int expected_count; + int expected_count = 0;void **pslot; +if (mode ==MIGRATE_FAULT ) { +/* +* MIGRATE_FAULT has an extra reference on the page and +* otherwise acts like ASYNC, no point in delaying the +* fault, we'll try again next time. +*/ + expected_count++; + } +if (!mapping) {/* Anonymous page without mapping */ -if (page_count (page) !=1 ) + expected_count +=1 ; +if (page_count (page) != expected_count)return -EAGAIN ;return 0 ; }@@ -294,7 +304,7 @@ static int migrate_page_move_mapping(str pslot =radix_tree_lookup_slot (&mapping->page_tree,page_index (page)); - expected_count =2 +page_has_private (page); + expected_count +=2 +page_has_private (page);if (page_count (page) != expected_count ||radix_tree_deref_slot_protected (pslot, &mapping->tree_lock) != page) {spin_unlock_irq (&mapping->tree_lock);@@ -313,7 +323,7 @@ static int migrate_page_move_mapping(str* the mapping back due to an elevated page count, we would have to * block waiting on other references to be dropped. */ -if (mode ==MIGRATE_ASYNC && head && +if ((mode ==MIGRATE_ASYNC || mode ==MIGRATE_FAULT ) && head && !buffer_migrate_lock_buffers (head, mode)) {page_unfreeze_refs (page, expected_count);spin_unlock_irq (&mapping->tree_lock);@@ -521,7 +531,7 @@ int buffer_migrate_page(struct address_s* with an IRQ-safe spinlock held. In the sync case, the buffers * need to be locked now */ -if (mode !=MIGRATE_ASYNC ) +if (mode !=MIGRATE_ASYNC && mode !=MIGRATE_FAULT )BUG_ON (!buffer_migrate_lock_buffers (head, mode));ClearPagePrivate (page);@@ -687,7 +697,7 @@ static int __unmap_and_move(struct pagestruct anon_vma *anon_vma =NULL ;if (!trylock_page (page)) { -if (!force || mode ==MIGRATE_ASYNC ) +if (!force || mode ==MIGRATE_ASYNC || mode ==MIGRATE_FAULT ) goto out;/* @@ -1403,4 +1413,63 @@ int migrate_vmas(struct mm_struct *mm, c }return err; } -#endif + +/* +* Attempt to migrate a misplaced page to the specified destination +* node. +*/ +int migrate_misplaced_page (struct page *page,int node) +{ +struct address_space *mapping =page_mapping (page); +int page_lru =page_is_file_cache (page);
mm/migrate.c int migrate_vmas(struct mm_struct *mm, c · line 1434
Quoted 10 lines
mm/migrate.c +10
-0+struct page *newpage; +int ret = -EAGAIN ; +gfp_t gfp =GFP_HIGHUSER_MOVABLE ; + +/* +* Don't migrate pages that are mapped in multiple processes. +*/ +if (page_mapcount (page) !=1 ) + goto out; +
Why?
I know why -- it's because we don't want to ping-pong shared library pages.
However, what if it's a shmem mapping? We might want to consider migrating those but with this check that will never happen.
mm/migrate.c int migrate_vmas(struct mm_struct *mm, c · line 1439
Quoted 5 lines
mm/migrate.c +5
-0+/* +* Never wait for allocations just to migrate on fault, but don't dip +* into reserves. And, only accept pages from the specified node. No +* sense migrating to a different "misplaced" page! +*/
Not only that, we do not want to reclaim on a remote node to allow migration. The cost of reclaim will exceed the benefit from local memory accesses.
Quoted 6 lines
mm/migrate.c +6
-0+if (mapping) + gfp =mapping_gfp_mask (mapping); + gfp &= ~__GFP_WAIT; + gfp |= __GFP_NOMEMALLOC |GFP_THISNODE ; + + newpage =alloc_pages_node (node, gfp,0 );
mm/migrate.c int migrate_vmas(struct mm_struct *mm, c · line 1455
Quoted 10 lines
mm/migrate.c +10
-0+if (!newpage) { + ret = -ENOMEM ; + goto out; + } + +if (isolate_lru_page (page)) { + ret = -EBUSY ; + goto put_new; + } +
Going to need to keep an eye on the hotness of the LRU lock during heavy migration states. Actually, a process using MPOL_MF_LAZY and then creating a large number of threads is going to hammer that lock. I've no proposed solution to this but if we see a bug report related to stalls after using that system call then this will be a candidate.
Compaction had to use trylock-like logic to get around this problem but it's not necessarily the right choice for lazy migration unless you are willing to depend on the automatic detection to fix it up later.
mm/migrate.c int migrate_vmas(struct mm_struct *mm, c · line 1457
Quoted 2 lines
mm/migrate.c +2
-0+inc_zone_page_state (page,NR_ISOLATED_ANON + page_lru); + ret =__unmap_and_move (page, newpage,0 ,0 ,MIGRATE_FAULT );
By bypassing __unmap_and_move, you miss the PageTransHuge() check in unmap_and_move and the splitting when a transhuge is encountered. Was that deliberate? Why?
Quoted 20 lines
mm/migrate.c +18
-0+/* +* A page that has been migrated has all references removed and will be +* freed. A page that has not been migrated will have kepts its +* references and be restored. +*/ +dec_zone_page_state (page,NR_ISOLATED_ANON + page_lru); +putback_lru_page (page); +put_new: +/* +* Move the new page to the LRU. If migration was not successful +* then this will free the page. +*/ +putback_lru_page (newpage); +out: + return ret; +} + +#endif /* CONFIG_NUMA */
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 18/31 mm/mpol: Use special PROT_NONE to migrate pages
In reply to Peter ZijlstraCombine our previous PROT_NONE, mpol_misplaced and migrate_misplaced_page() pieces into an effective migrate on fault scheme.
Note that (on x86) we rely on PROT_NONE pages being !present and avoid the TLB flush from try_to_unmap(TTU_MIGRATION). This greatly improves the page-migration performance.
--- mm/huge_memory.c | 41 ++++++++++++++++++++++++++++++++++- mm/memory.c | 63 +++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 85 insertions(+), 19 deletions(-)
mm/huge_memory.c +40 -1
@@ -18,6 +18,7 @@#include <linux/freezer.h> #include <linux/mman.h> #include <linux/pagemap.h> +#include <linux/migrate.h> #include <asm/tlb.h> #include <asm/pgalloc.h> #include "internal.h"
@@ -741,12 +742,48 @@ void do_huge_pmd_numa_page(struct mm_str unsigned int flags, pmd_t entry) {unsigned long haddr = address &HPAGE_PMD_MASK ; +struct page *page =NULL ; +int node;spin_lock (&mm->page_table_lock);if (unlikely (!pmd_same (*pmd, entry))) goto out_unlock; -/* do fancy stuff */ +if (unlikely (pmd_trans_splitting (entry))) { +spin_unlock (&mm->page_table_lock); +wait_split_huge_page (vma->anon_vma, pmd); +return ; + } + +#ifdef CONFIG_NUMA + page =pmd_page (entry); +VM_BUG_ON (!PageCompound (page) || !PageHead (page)); + +get_page (page); +spin_unlock (&mm->page_table_lock); + +/* +* XXX should we serialize against split_huge_page ? +*/ + + node =mpol_misplaced (page, vma, haddr); +if (node ==-1 ) + goto do_fixup; + +/* +* Due to lacking code to migrate thp pages, we'll split +* (which preserves the special PROT_NONE) and re-take the +* fault on the normal pages. +*/ +split_huge_page (page); +put_page (page); +return ; + +do_fixup: +spin_lock (&mm->page_table_lock); +if (unlikely (!pmd_same (*pmd, entry))) + goto out_unlock; +#endif /* change back to regular protection */ entry =pmd_modify (entry, vma->vm_page_prot);
@@ -755,6 +792,8 @@ void do_huge_pmd_numa_page(struct mm_str out_unlock:spin_unlock (&mm->page_table_lock); +if (page) +put_page (page); } int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
mm/memory.c +45 -18
94 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 19/31 sched, numa, mm: Introduce tsk_home_node()
In reply to Peter ZijlstraIntroduce the home-node concept for tasks. In order to keep memory locality we need to have a something to stay local to, we define the home-node of a task as the node we prefer to allocate memory from and prefer to execute on.
These are no hard guarantees, merely soft preferences. This allows for optimal resource usage, we can run a task away from the home-node, the remote memory hit -- while expensive -- is less expensive than not running at all, or very little, due to severe cpu overload.
Similarly, we can allocate memory from another node if our home-node is depleted, again, some memory is better than no memory.
This patch merely introduces the basic infrastructure, all policy comes later.
NOTE: we introduce the concept of EMBEDDED_NUMA, these are architectures where the memory access cost doesn't depend on the cpu but purely on the physical address -- embedded boards with cheap (slow) and expensive (fast) memory banks.
--- arch/sh/mm/Kconfig | 1 + include/linux/init_task.h | 8 ++++++++ include/linux/sched.h | 12 ++++++++++++ init/Kconfig | 14 ++++++++++++++ kernel/sched/core.c | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+)
arch/sh/mm/Kconfig +1 -0
@@ -111,6 +111,7 @@ config VSYSCALL config NUMA bool "Non Uniform Memory Access (NUMA) Support" depends on MMU && SYS_SUPPORTS_NUMA && EXPERIMENTAL + select EMBEDDED_NUMA default n help Some SH systems have many various memories scattered around
include/linux/init_task.h +8 -0
@@ -143,6 +143,13 @@ extern struct task_group root_task_group#define INIT_TASK_COMM "swapper" +#ifdef CONFIG_SCHED_NUMA +# define INIT_TASK_NUMA (tsk) \ + .node = -1, +#else +# define INIT_TASK_NUMA (tsk) +#endif +/* * INIT_TASK is used to set up the first task table, touch at * your own risk!. Base=0, limit=0x1fffff (=2MB)
@@ -210,6 +217,7 @@ extern struct task_group root_task_group INIT_TRACE_RECURSION \ INIT_TASK_RCU_PREEMPT(tsk) \ INIT_CPUSET_SEQ \ + INIT_TASK_NUMA(tsk) \ }
include/linux/sched.h +12 -0
@@ -1479,6 +1479,9 @@ struct task_struct {short il_next;short pref_node_fork;#endif +#ifdef CONFIG_SCHED_NUMA +int node; +#endif struct rcu_head rcu;/*
@@ -1553,6 +1556,15 @@ struct task_struct {/* Future-safe accessor for struct task_struct's cpus_allowed. */ #define tsk_cpus_allowed (tsk) (&(tsk)->cpus_allowed) +static inline int tsk_home_node (struct task_struct *p) +{ +#ifdef CONFIG_SCHED_NUMA +return p->node; +#else +return -1 ; +#endif +} +/* * Priority of a process goes from 0..MAX_PRIO-1, valid RT * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
init/Kconfig +14 -0
@@ -696,6 +696,20 @@ config LOG_BUF_SHIFT config HAVE_UNSTABLE_SCHED_CLOCK bool +# +# For architectures that (ab)use NUMA to represent different memory regions +# all cpu-local but of different latencies, such as SuperH. +# +config EMBEDDED_NUMA + bool + +config SCHED_NUMA + bool "Memory placement aware NUMA scheduler" + default n + depends on SMP && NUMA && MIGRATION && !EMBEDDED_NUMA + help + This option adds support for automatic NUMA aware memory/task placement. + menuconfig CGROUPS boolean "Control Group support" depends on EVENTFD
kernel/sched/core.c +36 -0
@@ -5959,6 +5959,42 @@ static struct sched_domain_topology_levestatic struct sched_domain_topology_level *sched_domain_topology = default_topology; +#ifdef CONFIG_SCHED_NUMA + +/* +* Requeues a task ensuring its on the right load-balance list so +* that it might get migrated to its new home. +* +* Note that we cannot actively migrate ourselves since our callers +* can be from atomic context. We rely on the regular load-balance +* mechanisms to move us around -- its all preference anyway. +*/ +void sched_setnode (struct task_struct *p,int node) +{ +unsigned long flags; +int on_rq, running; +struct rq *rq; + + rq =task_rq_lock (p, &flags); + on_rq = p->on_rq; + running =task_current (rq, p); + +if (on_rq) +dequeue_task (rq, p,0 ); +if (running) + p->sched_class->put_prev_task (rq, p); + + p->node = node; + +if (running) + p->sched_class->set_curr_task (rq); +if (on_rq) +enqueue_task (rq, p,0 ); +task_rq_unlock (rq, p, &flags); +} + +#endif /* CONFIG_SCHED_NUMA */ +#ifdef CONFIG_NUMA static int sched_domains_numa_levels;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 19/31] sched, numa, mm: Introduce tsk_home_node()
Quoted 5 lines · Peter Zijlstra
Introduce the home-node concept for tasks. In order to keep memory locality we need to have a something to stay local to, we define the home-node of a task as the node we prefer to allocate memory from and prefer to execute on.
That implies that at some point or the other we must be hooking into alloc_pages_current() and modifying where it calls numa_node_id() to take the home node into account. Otherwise a process that faults while running temporarily off the home node will allocate a page in the wrong node forcing a migration later.
If we don't do that, why not and how do we cope with a task being temporarily scheduled on a CPU that is not on the home node?
Quoted 8 lines
These are no hard guarantees, merely soft preferences. This allows for optimal resource usage, we can run a task away from the home-node, the remote memory hit -- while expensive -- is less expensive than not running at all, or very little, due to severe cpu overload.
Similarly, we can allocate memory from another node if our home-node is depleted, again, some memory is better than no memory.
Yes.
Quoted 8 lines
This patch merely introduces the basic infrastructure, all policy comes later.
NOTE: we introduce the concept of
EMBEDDED_NUMA, these are architectures where the memory access cost doesn't depend on the cpu but purely on the physical address -- embedded boards with cheap (slow) and expensive (fast) memory banks.
This is a bit left-of-center. Is it necessary to deal with this now?
The name EMBEDDED here sucks a bit too as it has nothing to do with whether the machine is embedded or not. Based on the description NUMA_LATENCY_VARIABLE or something might have been a better name with a desription saying that. Not sure as it's not obvious yet how it gets used.
Quoted 57 lines
Signed-off-by Peter Zijlstra <[email protected]>Cc Lee Schermerhorn <[email protected]>Cc Rik van Riel <[email protected]>Cc Andrew Morton <[email protected]>Cc Linus Torvalds <[email protected]>Signed-off-by Ingo Molnar <[email protected]>--- arch/sh/mm/Kconfig | 1 + include/linux/init_task.h | 8 ++++++++ include/linux/sched.h | 12 ++++++++++++ init/Kconfig | 14 ++++++++++++++ kernel/sched/core.c | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+)Index: tip/arch/sh/mm/Kconfig
===================================================================arch/sh/mm/Kconfig +1
-0@@ -111,6 +111,7 @@ config VSYSCALL config NUMA bool "Non Uniform Memory Access (NUMA) Support" depends on MMU && SYS_SUPPORTS_NUMA && EXPERIMENTAL + select EMBEDDED_NUMA default n help Some SH systems have many various memories scattered aroundIndex:
tip/include/linux/init_task.h
===================================================================include/linux/init_task.h +8
-0@@ -143,6 +143,13 @@ extern struct task_group root_task_group#define INIT_TASK_COMM "swapper" +#ifdef CONFIG_SCHED_NUMA +# define INIT_TASK_NUMA (tsk) \ + .node = -1, +#else +# define INIT_TASK_NUMA (tsk) +#endif +/* * INIT_TASK is used to set up the first task table, touch at * your own risk!. Base=0, limit=0x1fffff (=2MB) @@ -210,6 +217,7 @@ extern struct task_group root_task_group INIT_TRACE_RECURSION \ INIT_TASK_RCU_PREEMPT(tsk) \ INIT_CPUSET_SEQ \ + INIT_TASK_NUMA(tsk) \ }Index:
tip/include/linux/sched.h
===================================================================
include/linux/sched.h struct task_struct { · line 1484
Quoted 6 lines
include/linux/sched.h +3
-0@@ -1479,6 +1479,9 @@ struct task_struct {short il_next;short pref_node_fork;#endif +#ifdef CONFIG_SCHED_NUMA +int node; +#endif
int home_node and a comment. node might be ok in parts of the VM where it is clear from context what it means but in task_struct, "node" gives very little hint as to what it is for.
Quoted 31 lines
include/linux/sched.h +9
-0struct rcu_head rcu;/* @@ -1553,6 +1556,15 @@ struct task_struct {/* Future-safe accessor for struct task_struct's cpus_allowed. */ #define tsk_cpus_allowed (tsk) (&(tsk)->cpus_allowed) +static inline int tsk_home_node (struct task_struct *p) +{ +#ifdef CONFIG_SCHED_NUMA +return p->node; +#else +return -1 ; +#endif +} +/* * Priority of a process goes from 0..MAX_PRIO-1, valid RT * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH Index: tip/init/Kconfig
===================================================================init/Kconfig +4
-0@@ -696,6 +696,20 @@ config LOG_BUF_SHIFT config HAVE_UNSTABLE_SCHED_CLOCK bool +# +# For architectures that (ab)use NUMA to represent different memory regions +# all cpu-local but of different latencies, such as SuperH. +#
init/Kconfig config LOG_BUF_SHIFT · line 712
Quoted 10 lines
init/Kconfig +10
-0+config EMBEDDED_NUMA + bool + +config SCHED_NUMA + bool "Memory placement aware NUMA scheduler" + default n + depends on SMP && NUMA && MIGRATION && !EMBEDDED_NUMA + help + This option adds support for automatic NUMA aware memory/task placement. +
I see why you introduce EMBEDDED_NUMA now. This should have been a separate patch though explaining why when NUMA is abused like this that automatic NUMA placement is the wrong thing to do because presumably the lower latency regions are being manually managed and should not be interfered with. That, or such architectures need to add a pgdat field that excludes such nodes from automatic migration.
Quoted 35 lines
init/Kconfig +0
-0menuconfig CGROUPS boolean "Control Group support" depends on EVENTFDIndex:
tip/kernel/sched/core.c
===================================================================kernel/sched/core.c +24
-0@@ -5959,6 +5959,42 @@ static struct sched_domain_topology_levestatic struct sched_domain_topology_level *sched_domain_topology = default_topology; +#ifdef CONFIG_SCHED_NUMA + +/* +* Requeues a task ensuring its on the right load-balance list so +* that it might get migrated to its new home. +* +* Note that we cannot actively migrate ourselves since our callers +* can be from atomic context. We rely on the regular load-balance +* mechanisms to move us around -- its all preference anyway. +*/ +void sched_setnode (struct task_struct *p,int node) +{ +unsigned long flags; +int on_rq, running; +struct rq *rq; + + rq =task_rq_lock (p, &flags); + on_rq = p->on_rq; + running =task_current (rq, p); + +if (on_rq) +dequeue_task (rq, p,0 ); +if (running) + p->sched_class->put_prev_task (rq, p);
kernel/sched/core.c static struct sched_domain_topology_leve · line 5995
Quoted 10 lines
kernel/sched/core.c +10
-0+ + p->node = node; + +if (running) + p->sched_class->set_curr_task (rq); +if (on_rq) +enqueue_task (rq, p,0 ); +task_rq_unlock (rq, p, &flags); +} +
Presumably this thing is called rare enough that rq lock contention will not be a problem. If it is, it'll be quickly obvious.
Quoted 7 lines
kernel/sched/core.c +2
-0+#endif /* CONFIG_SCHED_NUMA */ +#ifdef CONFIG_NUMA static int sched_domains_numa_levels;
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 20/31 sched, numa, mm/mpol: Make mempolicy home-node aware
In reply to Peter ZijlstraAdd another layer of fallback policy to make the home node concept useful from a memory allocation PoV.
This changes the mpol order to:
- vma->vm_ops->get_policy [if applicable]
- vma->vm_policy [if applicable]
- task->mempolicy
- tsk_home_node() preferred [NEW]
- default_policy
Note that the tsk_home_node() policy has Migrate-on-Fault enabled to facilitate efficient on-demand memory migration.
--- mm/mempolicy.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-)
mm/mempolicy.c +27 -2
@@ -117,6 +117,22 @@ static struct mempolicy default_policy = .flags = MPOL_F_LOCAL, }; +static struct mempolicy preferred_node_policy[MAX_NUMNODES ]; + +static struct mempolicy *get_task_policy (struct task_struct *p) +{ +struct mempolicy *pol = p->mempolicy; +int node; + +if (!pol) { + node =tsk_home_node (p); +if (node !=-1 ) + pol = &preferred_node_policy[node]; + } + +return pol; +} + static const struct mempolicy_operations { int (*create)(struct mempolicy *pol, const nodemask_t *nodes); /*
@@ -1565,7 +1581,7 @@ asmlinkage long compat_sys_mbind(compat_struct mempolicy *get_vma_policy (struct task_struct *task,struct vm_area_struct *vma,unsigned long addr) { -struct mempolicy *pol = task->mempolicy; +struct mempolicy *pol =get_task_policy (task);if (vma) {if (vma->vm_ops && vma->vm_ops->get_policy) {
@@ -1965,7 +1981,7 @@ retry_cpuset:*/ struct page *alloc_pages_current (gfp_t gfp,unsigned order) { -struct mempolicy *pol = current->mempolicy; +struct mempolicy *pol =get_task_policy (current);struct page *page;unsigned int cpuset_mems_cookie;
@@ -2424,6 +2440,15 @@ void __init numa_policy_init(void)sizeof (struct sp_node ), 0, SLAB_PANIC, NULL); +for_each_node (nid) { + preferred_node_policy[nid] = (struct mempolicy ) { + .refcnt =ATOMIC_INIT (1 ), + .mode =MPOL_PREFERRED , + .flags =MPOL_F_MOF , + .v = { .preferred_node = nid, }, + }; + } +/* * Set interleaving policy for system init. Interleaving is only * enabled across suitably sized nodes (default is >= 16MB), or
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 20/31] sched, numa, mm/mpol: Make mempolicy home-node aware
Quoted 5 lines · Peter Zijlstra
Add another layer of fallback policy to make the home node concept useful from a memory allocation PoV.
This changes the mpol order to:
Quoted 9 lines
-
vma->vm_ops->get_policy[if applicable]
-vma->vm_policy[if applicable]
-task->mempolicy
-tsk_home_node()preferred [NEW]
-default_policyNote that the
tsk_home_node()policy has Migrate-on-Fault enabled to facilitate efficient on-demand memory migration.
Makes sense and it looks like a VMA policy, if set, will still override the home_node policy as you'd expect. At some point this may need to cope with node hot-remove. Also, at some point this must be dealing with the case where mbind() is called but the home_node is not in the nodemask. Does that happen somewhere else in the series? (maybe I'll see it later)
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 20/31] sched, numa, mm/mpol: Make mempolicy home-node aware
Quoted 16 lines · Mel Gorman
Quoted 5 lines · Peter Zijlstra
Add another layer of fallback policy to make the home node concept useful from a memory allocation PoV.
This changes the mpol order to:
Quoted 9 lines
-
vma->vm_ops->get_policy[if applicable]
-vma->vm_policy[if applicable]
-task->mempolicy
-tsk_home_node()preferred [NEW]
-default_policyNote that the
tsk_home_node()policy has Migrate-on-Fault enabled to facilitate efficient on-demand memory migration.
Quoted 6 lines
Makes sense and it looks like a VMA policy, if set, will still override the
home_nodepolicy as you'd expect. At some point this may need to cope with node hot-remove. Also, at some point this must be dealing with the case wherembind()is called but thehome_nodeis not in the nodemask. Does that happen somewhere else in the series? (maybe I'll see it later)
I'd expect one of the first things to be done in the sequence of hot-removing a node would be to take the cpus offline (at least out of being schedulable). Hence the tasks would be migrated to other nodes/processors, which should result in a home node update the same as if the scheduler had simply chosen a better home for them anyway. The memory would then migrate either via the home node change by the tasks themselves or via migration to evacuate the outgoing node (with the preferred migration target using the new home node).
As long as no one wants to do something crazy like offline a node before taking the resources away from the scheduler and memory management, it should all work out.
Don Morris
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 21/31 sched, numa, mm: Introduce sched_feat_numa()
In reply to Peter ZijlstraAvoid a few #ifdef's later on.
--- kernel/sched/sched.h | 6 ++++++ 1 file changed, 6 insertions(+)
kernel/sched/sched.h +6 -0
@@ -648,6 +648,12 @@ extern struct static_key sched_feat_keys#define sched_feat (x) (sysctl_sched_features & (1UL << __SCHED_FEAT_##x))#endif /* SCHED_DEBUG && HAVE_JUMP_LABEL */ +#ifdef CONFIG_SCHED_NUMA +#define sched_feat_numa (x) sched_feat(x) +#else +#define sched_feat_numa (x) (0) +#endif +static inline u64 global_rt_period (void ) {return (u64 )sysctl_sched_rt_period *NSEC_PER_USEC ;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 21/31] sched, numa, mm: Introduce sched_feat_numa()
Quoted 2 lines · Peter Zijlstra
Avoid a few #ifdef's later on.
It does mean that schednuma cannot be enabled or disabled from the command line (or similarly easy mechanism) and that debugfs must be mounted to control it. This would be awkward from an admin perspective if they wanted to force disable schednuma because it hurt their workload for whatever reason. Yes, they can disable it with an init script of some sort but there will be some moaning.
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 22/31 sched, numa, mm: Implement THP migration
In reply to Peter ZijlstraAdd THP migration for the NUMA working set scanning fault case.
It uses the page lock to serialize. No migration pte dance is necessary because the pte is already unmapped when we decide to migrate.
--- mm/huge_memory.c | 133 ++++++++++++++++++++++++++++++++++++++++++------------- mm/migrate.c | 2 2 files changed, 104 insertions(+), 31 deletions(-)
mm/huge_memory.c +103 -30
@@ -742,12 +742,13 @@ void do_huge_pmd_numa_page(struct mm_str unsigned int flags, pmd_t entry) {unsigned long haddr = address &HPAGE_PMD_MASK ; +struct page *new_page =NULL ;struct page *page =NULL ; -int node; +int node, lru;spin_lock (&mm->page_table_lock);if (unlikely (!pmd_same (*pmd, entry))) - goto out_unlock; + goto unlock;if (unlikely (pmd_trans_splitting (entry))) {spin_unlock (&mm->page_table_lock);
@@ -755,45 +756,117 @@ void do_huge_pmd_numa_page(struct mm_strreturn ; } -#ifdef CONFIG_NUMA page =pmd_page (entry); -VM_BUG_ON (!PageCompound (page) || !PageHead (page)); +if (page) { +VM_BUG_ON (!PageCompound (page) || !PageHead (page)); -get_page (page); +get_page (page); + node =mpol_misplaced (page, vma, haddr); +if (node !=-1 ) + goto migrate; + } + +fixup: +/* change back to regular protection */ + entry =pmd_modify (entry, vma->vm_page_prot); +set_pmd_at (mm, haddr, pmd, entry); +update_mmu_cache_pmd (vma, address, entry); + +unlock:spin_unlock (&mm->page_table_lock); +if (page) +put_page (page); -/* -* XXX should we serialize against split_huge_page ? -*/ - - node =mpol_misplaced (page, vma, haddr); -if (node ==-1 ) - goto do_fixup; - -/* -* Due to lacking code to migrate thp pages, we'll split -* (which preserves the special PROT_NONE) and re-take the -* fault on the normal pages. -*/ -split_huge_page (page); -put_page (page);return ; -do_fixup: +migrate: +spin_unlock (&mm->page_table_lock); + +lock_page (page);spin_lock (&mm->page_table_lock); -if (unlikely (!pmd_same (*pmd, entry))) - goto out_unlock; -#endif +if (unlikely (!pmd_same (*pmd, entry))) { +spin_unlock (&mm->page_table_lock); +unlock_page (page); +put_page (page); +return ; + } +spin_unlock (&mm->page_table_lock); -/* change back to regular protection */ - entry =pmd_modify (entry, vma->vm_page_prot); -if (pmdp_set_access_flags (vma, haddr, pmd, entry,1 )) -update_mmu_cache_pmd (vma, address, entry); + new_page =alloc_pages_node (node, + (GFP_TRANSHUGE |GFP_THISNODE ) & ~__GFP_WAIT, +HPAGE_PMD_ORDER ); + +if (!new_page) + goto alloc_fail; + + lru =PageLRU (page); + +if (lru &&isolate_lru_page (page))/* does an implicit get_page() */ + goto alloc_fail; + +if (!trylock_page (new_page)) +BUG (); + +/* anon mapping, we can simply copy page->mapping to the new page: */ + new_page->mapping = page->mapping; + new_page->index = page->index; -out_unlock: +migrate_page_copy (new_page, page); + +WARN_ON (PageLRU (new_page)); + +spin_lock (&mm->page_table_lock); +if (unlikely (!pmd_same (*pmd, entry))) { +spin_unlock (&mm->page_table_lock); +if (lru) +putback_lru_page (page); + +unlock_page (new_page); +ClearPageActive (new_page);/* Set by migrate_page_copy() */ + new_page->mapping =NULL ; +put_page (new_page);/* Free it */ + +unlock_page (page); +put_page (page);/* Drop the local reference */ + +return ; + } + + entry =mk_pmd (new_page, vma->vm_page_prot); + entry =maybe_pmd_mkwrite (pmd_mkdirty (entry), vma); + entry =pmd_mkhuge (entry); + +page_add_new_anon_rmap (new_page, vma, haddr); + +set_pmd_at (mm, haddr, pmd, entry); +update_mmu_cache_pmd (vma, address, entry); +page_remove_rmap (page);spin_unlock (&mm->page_table_lock); -if (page) + +put_page (page);/* Drop the rmap reference */ + +if (lru) +put_page (page);/* drop the LRU isolation reference */ + +unlock_page (new_page); +unlock_page (page); +put_page (page);/* Drop the local reference */ + +return ; + +alloc_fail: +if (new_page) +put_page (new_page); + +unlock_page (page); + +spin_lock (&mm->page_table_lock); +if (unlikely (!pmd_same (*pmd, entry))) {put_page (page); + page =NULL ; + goto unlock; + } + goto fixup; } int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
mm/migrate.c +1 -1
@@ -417,7 +417,7 @@ int migrate_huge_page_move_mapping(struc*/ void migrate_page_copy (struct page *newpage,struct page *page) { -if (PageHuge (page)) +if (PageHuge (page) ||PageTransHuge (page))copy_huge_page (newpage, page);else copy_highpage (newpage, page);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 22/31] sched, numa, mm: Implement THP migration
Quoted 3 lines · Peter Zijlstra
Add THP migration for the NUMA working set scanning fault case.
It uses the page lock to serialize.
Serialize against what?
Quoted 4 lines
No migration pte dance is
necessary because the pte is already unmapped when we decide to migrate.
Without the migration PTE dance it does mean that parallel faults could attempt to migrate at the same time and do a lot of busy work. Is this what the page lock is meant to serialise against?
Either way, this feels like an optimisation that should have appeared later in the series because if there is any bug due to this patch it'll be a bitch to debug. The bisection will point to where schednuma finally comes into play and not this patch where the actual bug is (if any, maybe this is perfect).
Also, I'm slightly confused by this comment because we have this
page = pmd_page(entry);
if (page) {
VM_BUG_ON(!PageCompound(page) || !PageHead(page));
get_page(page);
node = mpol_misplaced(page, vma, haddr);
if (node != -1)
goto migrate;It's not obvious at all why the "pte is already unmapped when we decide to migrate".
Quoted 115 lines
Signed-off-by Peter Zijlstra <[email protected]>Cc Johannes Weiner <[email protected]>Cc Mel Gorman <[email protected]>Cc Andrea Arcangeli <[email protected]>Cc Andrew Morton <[email protected]>Cc Linus Torvalds <[email protected]>[ Significant fixes and changelog. ]Signed-off-by Ingo Molnar <[email protected]>--- mm/huge_memory.c | 133 ++++++++++++++++++++++++++++++++++++++++++------------- mm/migrate.c | 2 2 files changed, 104 insertions(+), 31 deletions(-)Index:
tip/mm/huge_memory.c
===================================================================mm/huge_memory.c +47
-28@@ -742,12 +742,13 @@ void do_huge_pmd_numa_page(struct mm_str unsigned int flags, pmd_t entry) {unsigned long haddr = address &HPAGE_PMD_MASK ; +struct page *new_page =NULL ;struct page *page =NULL ; -int node; +int node, lru;spin_lock (&mm->page_table_lock);if (unlikely (!pmd_same (*pmd, entry))) - goto out_unlock; + goto unlock;if (unlikely (pmd_trans_splitting (entry))) {spin_unlock (&mm->page_table_lock);@@ -755,45 +756,117 @@ void do_huge_pmd_numa_page(struct mm_strreturn ; } -#ifdef CONFIG_NUMA page =pmd_page (entry); -VM_BUG_ON (!PageCompound (page) || !PageHead (page)); +if (page) { +VM_BUG_ON (!PageCompound (page) || !PageHead (page)); -get_page (page); +get_page (page); + node =mpol_misplaced (page, vma, haddr); +if (node !=-1 ) + goto migrate; + } + +fixup: +/* change back to regular protection */ + entry =pmd_modify (entry, vma->vm_page_prot); +set_pmd_at (mm, haddr, pmd, entry); +update_mmu_cache_pmd (vma, address, entry); + +unlock:spin_unlock (&mm->page_table_lock); +if (page) +put_page (page); -/* -* XXX should we serialize against split_huge_page ? -*/ - - node =mpol_misplaced (page, vma, haddr); -if (node ==-1 ) - goto do_fixup; - -/* -* Due to lacking code to migrate thp pages, we'll split -* (which preserves the special PROT_NONE) and re-take the -* fault on the normal pages. -*/ -split_huge_page (page); -put_page (page);return ; -do_fixup: +migrate: +spin_unlock (&mm->page_table_lock); + +lock_page (page);spin_lock (&mm->page_table_lock); -if (unlikely (!pmd_same (*pmd, entry))) - goto out_unlock; -#endif +if (unlikely (!pmd_same (*pmd, entry))) { +spin_unlock (&mm->page_table_lock); +unlock_page (page); +put_page (page); +return ; + } +spin_unlock (&mm->page_table_lock); -/* change back to regular protection */ - entry =pmd_modify (entry, vma->vm_page_prot); -if (pmdp_set_access_flags (vma, haddr, pmd, entry,1 )) -update_mmu_cache_pmd (vma, address, entry); + new_page =alloc_pages_node (node, + (GFP_TRANSHUGE |GFP_THISNODE ) & ~__GFP_WAIT, +HPAGE_PMD_ORDER ); + +if (!new_page) + goto alloc_fail; + + lru =PageLRU (page); + +if (lru &&isolate_lru_page (page))/* does an implicit get_page() */ + goto alloc_fail; + +if (!trylock_page (new_page)) +BUG (); + +/* anon mapping, we can simply copy page->mapping to the new page: */
mm/huge_memory.c void do_huge_pmd_numa_page(struct mm_str · line 819
Quoted 10 lines
mm/huge_memory.c +8
-1+ new_page->mapping = page->mapping; + new_page->index = page->index; -out_unlock: +migrate_page_copy (new_page, page); + +WARN_ON (PageLRU (new_page)); + +spin_lock (&mm->page_table_lock); +if (unlikely (!pmd_same (*pmd, entry))) {
So the page lock serialises against parallel faults by the looks of things but where does it serialise against the transhuge page being split underneath you and turning it into a regular pmd? I guess the pmd_same check sortof catches that but it feels like it is caught by accident instead of on purpose.
Quoted 69 lines
mm/huge_memory.c +48
-1+spin_unlock (&mm->page_table_lock); +if (lru) +putback_lru_page (page); + +unlock_page (new_page); +ClearPageActive (new_page);/* Set by migrate_page_copy() */ + new_page->mapping =NULL ; +put_page (new_page);/* Free it */ + +unlock_page (page); +put_page (page);/* Drop the local reference */ + +return ; + } + + entry =mk_pmd (new_page, vma->vm_page_prot); + entry =maybe_pmd_mkwrite (pmd_mkdirty (entry), vma); + entry =pmd_mkhuge (entry); + +page_add_new_anon_rmap (new_page, vma, haddr); + +set_pmd_at (mm, haddr, pmd, entry); +update_mmu_cache_pmd (vma, address, entry); +page_remove_rmap (page);spin_unlock (&mm->page_table_lock); -if (page) + +put_page (page);/* Drop the rmap reference */ + +if (lru) +put_page (page);/* drop the LRU isolation reference */ + +unlock_page (new_page); +unlock_page (page); +put_page (page);/* Drop the local reference */ + +return ; + +alloc_fail: +if (new_page) +put_page (new_page); + +unlock_page (page); + +spin_lock (&mm->page_table_lock); +if (unlikely (!pmd_same (*pmd, entry))) {put_page (page); + page =NULL ; + goto unlock; + } + goto fixup; } int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,Index:
tip/mm/migrate.c
===================================================================mm/migrate.c +1
-1@@ -417,7 +417,7 @@ int migrate_huge_page_move_mapping(struc*/ void migrate_page_copy (struct page *newpage,struct page *page) { -if (PageHuge (page)) +if (PageHuge (page) ||PageTransHuge (page))copy_huge_page (newpage, page);else copy_highpage (newpage, page);
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 23/31 sched, numa, mm: Implement home-node awareness
In reply to Peter ZijlstraImplement home node preference in the scheduler's load-balancer.
This is done in four pieces:
- task_numa_hot(); make it harder to migrate tasks away from their home-node, controlled using the NUMA_HOT feature flag.
- select_task_rq_fair(); prefer placing the task in their home-node, controlled using the NUMA_TTWU_BIAS feature flag. Disabled by default for we found this to be far too agressive.
- load_balance(); during the regular pull load-balance pass, try pulling tasks that are on the wrong node first with a preference of moving them nearer to their home-node through task_numa_hot(), controlled through the NUMA_PULL feature flag.
- load_balance(); when the balancer finds no imbalance, introduce some such that it still prefers to move tasks towards their home-node, using active load-balance if needed, controlled through the NUMA_PULL_BIAS feature flag.
In particular, only introduce this BIAS if the system is otherwise properly (weight) balanced and we either have an offnode or !numa task to trade for it.
In order to easily find off-node tasks, split the per-cpu task list into two parts.
--- include/linux/sched.h | 3 kernel/sched/core.c | 28 +++ kernel/sched/debug.c | 3 kernel/sched/fair.c | 349 +++++++++++++++++++++++++++++++++++++++++++++--- kernel/sched/features.h | 10 + kernel/sched/sched.h | 17 ++ 6 files changed, 384 insertions(+), 26 deletions(-)
include/linux/sched.h +3 -0
@@ -823,6 +823,7 @@ enum cpu_idle_type {#define SD_ASYM_PACKING 0x0800/* Place busy groups earlier in the domain */ #define SD_PREFER_SIBLING 0x1000/* Prefer to place tasks in a sibling domain */ #define SD_OVERLAP 0x2000/* sched_domains of this level overlap */ +#define SD_NUMA 0x4000/* cross-node balancing */ extern int __weak arch_sd_sibiling_asym_packing (void );
@@ -1481,6 +1482,7 @@ struct task_struct {#endif #ifdef CONFIG_SCHED_NUMA int node; +unsigned long numa_contrib;#endif struct rcu_head rcu;
@@ -2084,6 +2086,7 @@ extern int sched_setscheduler(struct tas const struct sched_param *);extern int sched_setscheduler_nocheck (struct task_struct *,int ,const struct sched_param *); +extern void sched_setnode (struct task_struct *p,int node);extern struct task_struct *idle_task (int cpu);/** * is_idle_task - is the specified task an idle task?
kernel/sched/core.c +23 -5
@@ -5484,7 +5484,9 @@ static void destroy_sched_domains(struct DEFINE_PER_CPU(struct sched_domain *, sd_llc);DEFINE_PER_CPU (int, sd_llc_id); -static void update_top_cache_domain (int cpu) +DEFINE_PER_CPU(struct sched_domain *, sd_node); + +static void update_domain_cache (int cpu) {struct sched_domain *sd;int id = cpu;
@@ -5495,6 +5497,15 @@ static void update_top_cache_domain(intrcu_assign_pointer (per_cpu (sd_llc, cpu), sd);per_cpu (sd_llc_id, cpu) = id; + +for_each_domain (cpu, sd) { +if (cpumask_equal (sched_domain_span (sd), +cpumask_of_node (cpu_to_node (cpu)))) + goto got_node; + } + sd =NULL ; +got_node: +rcu_assign_pointer (per_cpu (sd_node, cpu), sd); }/*
@@ -5537,7 +5548,7 @@ cpu_attach_domain(struct sched_domain *srcu_assign_pointer (rq->sd, sd);destroy_sched_domains (tmp, cpu); -update_top_cache_domain (cpu); +update_domain_cache (cpu); }/* cpus with isolated domains */
@@ -5965,9 +5976,9 @@ static struct sched_domain_topology_leve* Requeues a task ensuring its on the right load-balance list so * that it might get migrated to its new home. * -* Note that we cannot actively migrate ourselves since our callers -* can be from atomic context. We rely on the regular load-balance -* mechanisms to move us around -- its all preference anyway. +* Since home-node is pure preference there's no hard migrate to force +* us anywhere, this also allows us to call this from atomic context if +* required. */ void sched_setnode (struct task_struct *p,int node) {
@@ -6040,6 +6051,7 @@ sd_numa_init(struct sched_domain_topolog | 0*SD_SHARE_PKG_RESOURCES |1 *SD_SERIALIZE |0 *SD_PREFER_SIBLING + |1 *SD_NUMA |sd_local_flags (level) , .last_balance = jiffies,
@@ -6901,6 +6913,12 @@ void __init sched_init(void) rq->avg_idle =2 *sysctl_sched_migration_cost;INIT_LIST_HEAD (&rq->cfs_tasks); +#ifdef CONFIG_SCHED_NUMA +INIT_LIST_HEAD (&rq->offnode_tasks); + rq->onnode_running =0 ; + rq->offnode_running =0 ; + rq->offnode_weight =0 ; +#endif rq_attach_root (rq, &def_root_domain);#ifdef CONFIG_NO_HZ
kernel/sched/debug.c +3 -0
@@ -132,6 +132,9 @@ print_task(struct seq_file *m, struct rqSEQ_printf (m,"%15Ld %15Ld %15Ld.%06ld %15Ld.%06ld %15Ld.%06ld" ,0LL ,0LL ,0LL ,0L ,0LL ,0L ,0LL ,0L );#endif +#ifdef CONFIG_SCHED_NUMA +SEQ_printf (m," %d/%d" , p->node,cpu_to_node (task_cpu (p))); +#endif #ifdef CONFIG_CGROUP_SCHED SEQ_printf (m," %s" ,task_group_path (task_group (p)));#endif
kernel/sched/fair.c +328 -21
559 lines not on this page · raw message
kernel/sched/features.h +10 -0
@@ -61,3 +61,13 @@ SCHED_FEAT(TTWU_QUEUE, true) SCHED_FEAT(FORCE_SD_OVERLAP, false) SCHED_FEAT(RT_RUNTIME_SHARE, true) SCHED_FEAT(LB_MIN, false) + +#ifdef CONFIG_SCHED_NUMA +SCHED_FEAT(NUMA, true) +SCHED_FEAT(NUMA_HOT, true) +SCHED_FEAT(NUMA_TTWU_BIAS, false) +SCHED_FEAT(NUMA_TTWU_TO, false) +SCHED_FEAT(NUMA_PULL, true) +SCHED_FEAT(NUMA_PULL_BIAS, true) +#endif +
kernel/sched/sched.h +17 -0
@@ -418,6 +418,13 @@ struct rq {struct list_head cfs_tasks; +#ifdef CONFIG_SCHED_NUMA +unsigned long onnode_running; +unsigned long offnode_running; +unsigned long offnode_weight; +struct list_head offnode_tasks; +#endif +u64 rt_avg;u64 age_stamp;u64 idle_stamp;
@@ -469,6 +476,15 @@ struct rq {#endif }; +static inline struct list_head *offnode_tasks (struct rq *rq) +{ +#ifdef CONFIG_SCHED_NUMA +return &rq->offnode_tasks; +#else +return NULL ; +#endif +} +static inline int cpu_of (struct rq *rq) {#ifdef CONFIG_SMP
@@ -529,6 +545,7 @@ static inline struct sched_domain *highe DECLARE_PER_CPU(struct sched_domain *, sd_llc);DECLARE_PER_CPU (int, sd_llc_id); +DECLARE_PER_CPU(struct sched_domain *, sd_node);extern int group_balance_cpu (struct sched_group *sg);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 23/31] sched, numa, mm: Implement home-node awareness
Quoted 7 lines · Peter Zijlstra
Implement home node preference in the scheduler's load-balancer.
This is done in four pieces:
-
task_numa_hot(); make it harder to migrate tasks away from their home-node, controlled using theNUMA_HOTfeature flag.
We don't actually know if it's hotm we're guessing. task_numa_stick()?
Quoted 4 lines
-
select_task_rq_fair(); prefer placing the task in their home-node, controlled using theNUMA_TTWU_BIASfeature flag. Disabled by default for we found this to be far too agressive.
Separate patch then?
Quoted 5 lines
-
load_balance(); during the regular pull load-balance pass, try pulling tasks that are on the wrong node first with a preference of moving them nearer to their home-node throughtask_numa_hot(), controlled through theNUMA_PULLfeature flag.
Sounds sensible.
Quoted 9 lines
-
load_balance(); when the balancer finds no imbalance, introduce some such that it still prefers to move tasks towards their home-node, using active load-balance if needed, controlled through theNUMA_PULL_BIASfeature flag.In particular, only introduce this BIAS if the system is otherwise properly (weight) balanced and we either have an offnode or !numa task to trade for it.
Again, sounds reasonable.
Quoted 33 lines
In order to easily find off-node tasks, split the per-cpu task list into two parts.
Signed-off-by Peter Zijlstra <[email protected]>Cc Paul Turner <[email protected]>Cc Lee Schermerhorn <[email protected]>Cc Christoph Lameter <[email protected]>Cc Rik van Riel <[email protected]>Cc Andrew Morton <[email protected]>Cc Linus Torvalds <[email protected]>Signed-off-by Ingo Molnar <[email protected]>--- include/linux/sched.h | 3 kernel/sched/core.c | 28 +++ kernel/sched/debug.c | 3 kernel/sched/fair.c | 349 +++++++++++++++++++++++++++++++++++++++++++++--- kernel/sched/features.h | 10 + kernel/sched/sched.h | 17 ++ 6 files changed, 384 insertions(+), 26 deletions(-)Index:
tip/include/linux/sched.h
===================================================================include/linux/sched.h +1
-0@@ -823,6 +823,7 @@ enum cpu_idle_type {#define SD_ASYM_PACKING 0x0800/* Place busy groups earlier in the domain */ #define SD_PREFER_SIBLING 0x1000/* Prefer to place tasks in a sibling domain */ #define SD_OVERLAP 0x2000/* sched_domains of this level overlap */ +#define SD_NUMA 0x4000/* cross-node balancing */ extern int __weak arch_sd_sibiling_asym_packing (void );
include/linux/sched.h struct task_struct { · line 1485
Quoted 4 lines
include/linux/sched.h +1
-0@@ -1481,6 +1482,7 @@ struct task_struct {#endif #ifdef CONFIG_SCHED_NUMA int node; +unsigned long numa_contrib;
comment!
/*
* numa_contrib records how much of this tasks load factor was due to
* running away from its homoe node
*/
It contributes to numa_offnode_weight but where do we make any decisions based on it? Superficially this is for stats but it gets bubbled all the way up to the sched domain where the actual decisions are made. The comment could be a lot more helpful in spelling this out.
Quoted 30 lines
include/linux/sched.h +1
-0#endif struct rcu_head rcu;@@ -2084,6 +2086,7 @@ extern int sched_setscheduler(struct tas const struct sched_param *);extern int sched_setscheduler_nocheck (struct task_struct *,int ,const struct sched_param *); +extern void sched_setnode (struct task_struct *p,int node);extern struct task_struct *idle_task (int cpu);/** * is_idle_task - is the specified task an idle task? Index:
tip/kernel/sched/core.c
===================================================================kernel/sched/core.c +3
-1@@ -5484,7 +5484,9 @@ static void destroy_sched_domains(struct DEFINE_PER_CPU(struct sched_domain *, sd_llc);DEFINE_PER_CPU (int, sd_llc_id); -static void update_top_cache_domain (int cpu) +DEFINE_PER_CPU(struct sched_domain *, sd_node); + +static void update_domain_cache (int cpu) {struct sched_domain *sd;int id = cpu;@@ -5495,6 +5497,15 @@ static void update_top_cache_domain(intrcu_assign_pointer (per_cpu (sd_llc, cpu), sd);per_cpu (sd_llc_id, cpu) = id;
kernel/sched/core.c static void update_top_cache_domain(int · line 5509
Quoted 10 lines
kernel/sched/core.c +9
-0+ +for_each_domain (cpu, sd) { +if (cpumask_equal (sched_domain_span (sd), +cpumask_of_node (cpu_to_node (cpu)))) + goto got_node; + } + sd =NULL ; +got_node: +rcu_assign_pointer (per_cpu (sd_node, cpu), sd); }
Not obvious how this connects to the rest of the patch at all.
Quoted 161 lines
kernel/sched/core.c +11
-4/* @@ -5537,7 +5548,7 @@ cpu_attach_domain(struct sched_domain *srcu_assign_pointer (rq->sd, sd);destroy_sched_domains (tmp, cpu); -update_top_cache_domain (cpu); +update_domain_cache (cpu); }/* cpus with isolated domains */ @@ -5965,9 +5976,9 @@ static struct sched_domain_topology_leve* Requeues a task ensuring its on the right load-balance list so * that it might get migrated to its new home. * -* Note that we cannot actively migrate ourselves since our callers -* can be from atomic context. We rely on the regular load-balance -* mechanisms to move us around -- its all preference anyway. +* Since home-node is pure preference there's no hard migrate to force +* us anywhere, this also allows us to call this from atomic context if +* required. */ void sched_setnode (struct task_struct *p,int node) {@@ -6040,6 +6051,7 @@ sd_numa_init(struct sched_domain_topolog | 0*SD_SHARE_PKG_RESOURCES |1 *SD_SERIALIZE |0 *SD_PREFER_SIBLING + |1 *SD_NUMA |sd_local_flags (level) , .last_balance = jiffies,@@ -6901,6 +6913,12 @@ void __init sched_init(void) rq->avg_idle =2 *sysctl_sched_migration_cost;INIT_LIST_HEAD (&rq->cfs_tasks); +#ifdef CONFIG_SCHED_NUMA +INIT_LIST_HEAD (&rq->offnode_tasks); + rq->onnode_running =0 ; + rq->offnode_running =0 ; + rq->offnode_weight =0 ; +#endif rq_attach_root (rq, &def_root_domain);#ifdef CONFIG_NO_HZ Index:
tip/kernel/sched/debug.c
===================================================================kernel/sched/debug.c +3
-0@@ -132,6 +132,9 @@ print_task(struct seq_file *m, struct rqSEQ_printf (m,"%15Ld %15Ld %15Ld.%06ld %15Ld.%06ld %15Ld.%06ld" ,0LL ,0LL ,0LL ,0L ,0LL ,0L ,0LL ,0L );#endif +#ifdef CONFIG_SCHED_NUMA +SEQ_printf (m," %d/%d" , p->node,cpu_to_node (task_cpu (p))); +#endif #ifdef CONFIG_CGROUP_SCHED SEQ_printf (m," %s" ,task_group_path (task_group (p)));#endif Index:
tip/kernel/sched/fair.c
===================================================================kernel/sched/fair.c +64
-4@@ -26,6 +26,7 @@#include <linux/slab.h> #include <linux/profile.h> #include <linux/interrupt.h> +#include <linux/random.h> #include <trace/events/sched.h> @@ -773,6 +774,51 @@ update_stats_curr_start(struct cfs_rq *c }/************************************************** +* Scheduling class numa methods. +*/ + +#ifdef CONFIG_SMP +static unsigned long task_h_load (struct task_struct *p); +#endif + +#ifdef CONFIG_SCHED_NUMA +static struct list_head *account_numa_enqueue (struct rq *rq,struct task_struct *p) +{ +struct list_head *tasks = &rq->cfs_tasks; + +if (tsk_home_node (p) !=cpu_to_node (task_cpu (p))) { + p->numa_contrib =task_h_load (p); + rq->offnode_weight += p->numa_contrib; + rq->offnode_running++; + tasks = &rq->offnode_tasks; + }else + rq->onnode_running++; + +return tasks; +} + +static void account_numa_dequeue (struct rq *rq,struct task_struct *p) +{ +if (tsk_home_node (p) !=cpu_to_node (task_cpu (p))) { + rq->offnode_weight -= p->numa_contrib; + rq->offnode_running--; + }else + rq->onnode_running--; +} +#else +#ifdef CONFIG_SMP +static struct list_head *account_numa_enqueue (struct rq *rq,struct task_struct *p) +{ +return NULL ; +} +#endif + +static void account_numa_dequeue (struct rq *rq,struct task_struct *p) +{ +} +#endif /* CONFIG_SCHED_NUMA */ + +/************************************************** * Scheduling class queueing methods: */ @@ -783,9 +829,17 @@ account_entity_enqueue(struct cfs_rq *cfif (!parent_entity (se))update_load_add (&rq_of (cfs_rq)->load, se->load.weight);#ifdef CONFIG_SMP -if (entity_is_task (se)) -list_add (&se->group_node, &rq_of (cfs_rq)->cfs_tasks); -#endif +if (entity_is_task (se)) { +struct rq *rq =rq_of (cfs_rq); +struct task_struct *p =task_of (se); +struct list_head *tasks = &rq->cfs_tasks; + +if (tsk_home_node (p) !=-1 ) + tasks =account_numa_enqueue (rq, p); + +list_add (&se->group_node, tasks); + } +#endif /* CONFIG_SMP */ cfs_rq->nr_running++; }@@ -795,8 +849,14 @@ account_entity_dequeue(struct cfs_rq *cfupdate_load_sub (&cfs_rq->load, se->load.weight);if (!parent_entity (se))update_load_sub (&rq_of (cfs_rq)->load, se->load.weight); -if (entity_is_task (se)) +if (entity_is_task (se)) { +struct task_struct *p =task_of (se); +list_del_init (&se->group_node); + +if (tsk_home_node (p) !=-1 ) +account_numa_dequeue (rq_of (cfs_rq), p); + } cfs_rq->nr_running--; }
kernel/sched/fair.c done: · line 2749
Quoted 9 lines
kernel/sched/fair.c +6
-0@@ -2681,6 +2741,35 @@ done:return target; } +#ifdef CONFIG_SCHED_NUMA +static inline bool pick_numa_rand (int n) +{ +return !(get_random_int () % n); +} +
"return get_random_int() % n" I could understand but this thing looks like it only returns 1 if the random number is 0 or some multiple of n. Hard to see how this is going to randomly select a node as such.
Quoted 89 lines
kernel/sched/fair.c +57
-0+/* +* Pick a random elegible CPU in the target node, hopefully faster +* than doing a least-loaded scan. +*/ +static int numa_select_node_cpu (struct task_struct *p,int node) +{ +int weight =cpumask_weight (cpumask_of_node (node)); +int i, cpu =-1 ; + +for_each_cpu_and (i,cpumask_of_node (node),tsk_cpus_allowed (p)) { +if (cpu <0 ||pick_numa_rand (weight)) + cpu = i; + } + +return cpu; +} +#else +static int numa_select_node_cpu (struct task_struct *p,int node) +{ +return -1 ; +} +#endif /* CONFIG_SCHED_NUMA */ +/* * sched_balance_self: balance the current task (running on cpu) in domains * that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and @@ -2701,6 +2790,7 @@ select_task_rq_fair(struct task_struct *int new_cpu = cpu;int want_affine =0 ;int sync = wake_flags &WF_SYNC ; +int node =tsk_home_node (p);if (p->nr_cpus_allowed ==1 )return prev_cpu;@@ -2712,6 +2802,36 @@ select_task_rq_fair(struct task_struct * }rcu_read_lock (); +if (sched_feat_numa (NUMA_TTWU_BIAS ) && node !=-1 ) { +/* +* For fork,exec find the idlest cpu in the home-node. +*/ +if (sd_flag & (SD_BALANCE_FORK |SD_BALANCE_EXEC )) { +int node_cpu =numa_select_node_cpu (p, node); +if (node_cpu <0 ) + goto find_sd; + + new_cpu = cpu = node_cpu; + sd =per_cpu (sd_node, cpu); + goto pick_idlest; + } + +/* +* For wake, pretend we were running in the home-node. +*/ +if (cpu_to_node (prev_cpu) != node) { +int node_cpu =numa_select_node_cpu (p, node); +if (node_cpu <0 ) + goto find_sd; + +if (sched_feat_numa (NUMA_TTWU_TO )) + cpu = node_cpu; +else + prev_cpu = node_cpu; + } + } + +find_sd:for_each_domain (cpu, tmp) {if (!(tmp->flags &SD_LOAD_BALANCE ))continue ;@@ -2738,6 +2858,7 @@ select_task_rq_fair(struct task_struct * goto unlock; } +pick_idlest:while (sd) {int load_idx = sd->forkexec_idx;struct sched_group *group;@@ -3060,6 +3181,8 @@ struct lb_env {unsigned int flags; +struct list_head *tasks; +unsigned int loop;unsigned int loop_break;unsigned int loop_max;
kernel/sched/fair.c static void move_task(struct task_struct · line 3207
Quoted 5 lines
kernel/sched/fair.c +2
-0@@ -3080,11 +3203,28 @@ static void move_task(struct task_structcheck_preempt_curr (env->dst_rq, p,0 ); } +static int task_numa_hot (struct task_struct *p,struct lb_env *env) +{
bool
document return value.
It's not actually returning if the node is "hot" or "cold", it's returning if it should stick with the current node or not.
Quoted 5 lines
kernel/sched/fair.c +5
-0+int from_dist, to_dist; +int node =tsk_home_node (p); + +if (!sched_feat_numa (NUMA_HOT ) || node ==-1 ) +return 0 ;/* no node preference */
kernel/sched/fair.c static void move_task(struct task_struct · line 3222
Quoted 10 lines
kernel/sched/fair.c +10
-0+ + from_dist =node_distance (cpu_to_node (env->src_cpu), node); + to_dist =node_distance (cpu_to_node (env->dst_cpu), node); + +if (to_dist < from_dist) +return 0 ;/* getting closer is ok */ + +return 1 ;/* stick to where we are */ +} +
Ok.
Quoted 10 lines
kernel/sched/fair.c +1
-1/* * Is this task likely cache-hot: */ static int -task_hot (struct task_struct *p,u64 now,struct sched_domain *sd) +task_hot (struct task_struct *p,struct lb_env *env) {s64 delta;
kernel/sched/fair.c task_hot(struct task_struct *p, u64 now, · line 3251
Quoted 6 lines
kernel/sched/fair.c +1
-1@@ -3107,7 +3247,7 @@ task_hot(struct task_struct *p, u64 now,if (sysctl_sched_migration_cost ==0 )return 0 ; - delta = now - p->se.exec_start; + delta = env->src_rq->clock_task - p->se.exec_start;
This looks like a cleanup. Not obviously connected with the rest of the patch.
Quoted 28 lines
kernel/sched/fair.c +5
-3return delta < (s64 )sysctl_sched_migration_cost; }@@ -3164,7 +3304,9 @@ int can_migrate_task(struct task_struct* 2) too many balance attempts have failed. */ - tsk_cache_hot =task_hot (p, env->src_rq->clock_task, env->sd); + tsk_cache_hot =task_hot (p, env); +if (env->idle ==CPU_NOT_IDLE ) + tsk_cache_hot |=task_numa_hot (p, env);if (!tsk_cache_hot || env->sd->nr_balance_failed > env->sd->cache_nice_tries) {#ifdef CONFIG_SCHEDSTATS @@ -3190,11 +3332,11 @@ int can_migrate_task(struct task_struct* * Called with both runqueues locked. */ -static int move_one_task (struct lb_env *env) +static int __move_one_task (struct lb_env *env) {struct task_struct *p, *n; -list_for_each_entry_safe (p, n, &env->src_rq->cfs_tasks, se.group_node) { +list_for_each_entry_safe (p, n, env->tasks, se.group_node) {if (throttled_lb_pair (task_group (p), env->src_rq->cpu, env->dst_cpu))continue ;
kernel/sched/fair.c static int move_one_task(struct lb_env * · line 3359
Quoted 6 lines
kernel/sched/fair.c +2
-1@@ -3213,7 +3355,20 @@ static int move_one_task(struct lb_env *return 0 ; } -static unsigned long task_h_load (struct task_struct *p); +static int move_one_task (struct lb_env *env) +{
This function is not actually used in this patch. Glancing forward I see that you later call this from the load balancer which makes sense but overall this patch is hard to follow because it's not clear which parts are relevant and which are not as this hunk is not critical to the concept of home-node awareness. It's part of the CPU migration policy when schednuma is enabled.
Quoted 93 lines
kernel/sched/fair.c +28
-8+if (sched_feat_numa (NUMA_PULL )) { + env->tasks =offnode_tasks (env->src_rq); +if (__move_one_task (env)) +return 1 ; + } + + env->tasks = &env->src_rq->cfs_tasks; +if (__move_one_task (env)) +return 1 ; + +return 0 ; +}static const unsigned int sched_nr_migrate_break =32 ;@@ -3226,7 +3381,6 @@ static const unsigned int sched_nr_migra*/ static int move_tasks (struct lb_env *env) { -struct list_head *tasks = &env->src_rq->cfs_tasks;struct task_struct *p;unsigned long load;int pulled =0 ;@@ -3234,8 +3388,9 @@ static int move_tasks(struct lb_env *envif (env->imbalance <=0 )return 0 ; -while (!list_empty (tasks)) { - p = list_first_entry(tasks, struct task_struct, se.group_node); +again: +while (!list_empty (env->tasks)) { + p = list_first_entry(env->tasks, struct task_struct, se.group_node); env->loop++;/* We've more or less seen every task there is, call it quits */ @@ -3246,7 +3401,7 @@ static int move_tasks(struct lb_env *envif (env->loop > env->loop_break) { env->loop_break += sched_nr_migrate_break; env->flags |=LBF_NEED_BREAK ; -break ; + goto out; }if (throttled_lb_pair (task_group (p), env->src_cpu, env->dst_cpu))@@ -3274,7 +3429,7 @@ static int move_tasks(struct lb_env *env* the critical section. */ if (env->idle ==CPU_NEWLY_IDLE ) -break ; + goto out;#endif /* @@ -3282,13 +3437,20 @@ static int move_tasks(struct lb_env *env* weighted load. */ if (env->imbalance <=0 ) -break ; + goto out;continue ; next: -list_move_tail (&p->se.group_node, tasks); +list_move_tail (&p->se.group_node, env->tasks); + } + +if (env->tasks ==offnode_tasks (env->src_rq)) { + env->tasks = &env->src_rq->cfs_tasks; + env->loop =0 ; + goto again; } +out:/* * Right now, this is one of only two places move_task() is called, * so we can safely collect move_task() stats here rather than @@ -3407,12 +3569,13 @@ static inline void update_shares(int cpustatic inline void update_h_load (long cpu) { } - +#ifdef CONFIG_SMP static unsigned long task_h_load (struct task_struct *p) {return p->se.load.weight; }#endif +#endif /********** Helpers for find_busiest_group ************************/ /* @@ -3443,6 +3606,14 @@ struct sd_lb_stats {unsigned int busiest_group_weight;
kernel/sched/fair.c struct sd_lb_stats { · line 3616
Quoted 10 lines
kernel/sched/fair.c +8
-0int group_imb;/* Is there imbalance in this sd */ +#ifdef CONFIG_SCHED_NUMA +struct sched_group *numa_group;/* group which has offnode_tasks */ +unsigned long numa_group_weight; +unsigned long numa_group_running; + +unsigned long this_offnode_running; +unsigned long this_onnode_running; +#endif
So from here is where the actual home-node awareness part kicks in.
Quoted 25 lines
kernel/sched/fair.c +11
-0};/* @@ -3458,6 +3629,11 @@ struct sg_lb_stats {unsigned long group_weight;int group_imb;/* Is there an imbalance in the group ? */ int group_has_capacity;/* Is there extra capacity in the group? */ +#ifdef CONFIG_SCHED_NUMA +unsigned long numa_offnode_weight; +unsigned long numa_offnode_running; +unsigned long numa_onnode_running; +#endif };/** @@ -3486,6 +3662,121 @@ static inline int get_sd_load_idx(structreturn load_idx; } +#ifdef CONFIG_SCHED_NUMA +static inline void update_sg_numa_stats (struct sg_lb_stats *sgs,struct rq *rq) +{ + sgs->numa_offnode_weight += rq->offnode_weight; + sgs->numa_offnode_running += rq->offnode_running; + sgs->numa_onnode_running += rq->onnode_running;
kernel/sched/fair.c static inline int get_sd_load_idx(struct · line 3680
Quoted 10 lines
kernel/sched/fair.c +10
-0+} + +/* +* Since the offnode lists are indiscriminate (they contain tasks for all other +* nodes) it is impossible to say if there's any task on there that wants to +* move towards the pulling cpu. Therefore select a random offnode list to pull +* from such that eventually we'll try them all. +* +* Select a random group that has offnode tasks as sds->numa_group +*/
The comment says we select a random group but this thing returns void. We're not selecting anything.
Quoted 7 lines
kernel/sched/fair.c +7
-0+static inline void update_sd_numa_stats (struct sched_domain *sd, +struct sched_group *group,struct sd_lb_stats *sds, +int local_group,struct sg_lb_stats *sgs) +{ +if (!(sd->flags &SD_NUMA )) +return ; +
kernel/sched/fair.c static inline int get_sd_load_idx(struct · line 3697
Quoted 10 lines
kernel/sched/fair.c +10
-0+if (local_group) { + sds->this_offnode_running = sgs->numa_offnode_running; + sds->this_onnode_running = sgs->numa_onnode_running; +return ; + } + +if (!sgs->numa_offnode_running) +return ; + +if (!sds->numa_group ||pick_numa_rand (sd->span_weight / group->group_weight)) {
What does passing in sd->span_weight / group->group_weight) mean?
Quoted 15 lines
kernel/sched/fair.c +15
-0+ sds->numa_group = group; + sds->numa_group_weight = sgs->numa_offnode_weight; + sds->numa_group_running = sgs->numa_offnode_running; + } +} + +/* +* Pick a random queue from the group that has offnode tasks. +*/ +static struct rq *find_busiest_numa_queue (struct lb_env *env, +struct sched_group *group) +{ +struct rq *busiest =NULL , *rq; +int cpu; +
kernel/sched/fair.c static inline int get_sd_load_idx(struct · line 3722
Quoted 10 lines
kernel/sched/fair.c +10
-0+for_each_cpu_and (cpu,sched_group_cpus (group), env->cpus) { + rq =cpu_rq (cpu); +if (!rq->offnode_running) +continue ; +if (!busiest ||pick_numa_rand (group->group_weight)) + busiest = rq; + } + +return busiest; +}
So if the random number if 0 or group_weight it will be randomly considered the busiest runqueue. Any idea how often that happens? I have a suspicion that the random perturb logic to avoid worst-case scenarios may not be operating as expected.
Quoted 151 lines
kernel/sched/fair.c +76
-3+ +/* +* Called in case of no other imbalance, if there is a queue running offnode +* tasksk we'll say we're imbalanced anyway to nudge these tasks towards their +* proper node. +*/ +static inline int check_numa_busiest_group (struct lb_env *env,struct sd_lb_stats *sds) +{ +if (!sched_feat (NUMA_PULL_BIAS )) +return 0 ; + +if (!sds->numa_group) +return 0 ; + +/* +* Only pull an offnode task home if we've got offnode or !numa tasks to trade for it. +*/ +if (!sds->this_offnode_running && + !(sds->this_nr_running - sds->this_onnode_running - sds->this_offnode_running)) +return 0 ; + + env->imbalance = sds->numa_group_weight / sds->numa_group_running; + sds->busiest = sds->numa_group; + env->find_busiest_queue = find_busiest_numa_queue; +return 1 ; +} + +static inline bool need_active_numa_balance (struct lb_env *env) +{ +return env->find_busiest_queue == find_busiest_numa_queue && + env->src_rq->offnode_running ==1 && + env->src_rq->nr_running ==1 ; +} + +#else /* CONFIG_SCHED_NUMA */ + +static inline void update_sg_numa_stats (struct sg_lb_stats *sgs,struct rq *rq) +{ +} + +static inline void update_sd_numa_stats (struct sched_domain *sd, +struct sched_group *group,struct sd_lb_stats *sds, +int local_group,struct sg_lb_stats *sgs) +{ +} + +static inline int check_numa_busiest_group (struct lb_env *env,struct sd_lb_stats *sds) +{ +return 0 ; +} + +static inline bool need_active_numa_balance (struct lb_env *env) +{ +return false; +} +#endif /* CONFIG_SCHED_NUMA */ +unsigned long default_scale_freq_power (struct sched_domain *sd,int cpu) {return SCHED_POWER_SCALE ;@@ -3701,6 +3992,8 @@ static inline void update_sg_lb_stats(st sgs->sum_weighted_load +=weighted_cpuload (i);if (idle_cpu (i)) sgs->idle_cpus++; + +update_sg_numa_stats (sgs, rq); }/* @@ -3854,6 +4147,8 @@ static inline void update_sd_lb_stats(st sds->group_imb = sgs.group_imb; } +update_sd_numa_stats (env->sd, sg, sds, local_group, &sgs); + sg = sg->next; }while (sg != env->sd->groups); }@@ -4084,7 +4379,7 @@ find_busiest_group(struct lb_env *env, i/* There is no busy sibling group to pull tasks from */ if (!sds.busiest || sds.busiest_nr_running ==0 ) - goto out_balanced; + goto ret; sds.avg_load = (SCHED_POWER_SCALE * sds.total_load) / sds.total_pwr;@@ -4106,14 +4401,14 @@ find_busiest_group(struct lb_env *env, i* don't try and pull any tasks. */ if (sds.this_load >= sds.max_load) - goto out_balanced; + goto ret;/* * Don't pull any tasks if this group is already above the domain * average load. */ if (sds.this_load >= sds.avg_load) - goto out_balanced; + goto ret;if (env->idle ==CPU_IDLE ) {/* @@ -4140,6 +4435,9 @@ force_balance:return sds.busiest; out_balanced: +if (check_numa_busiest_group (env, &sds)) +return sds.busiest; + ret: env->imbalance =0 ;return NULL ;@@ -4218,6 +4516,9 @@ static int need_active_balance(struct lbreturn 1 ; } +if (need_active_numa_balance (env)) +return 1 ; +return unlikely (sd->nr_balance_failed > sd->cache_nice_tries+2 ); }@@ -4270,6 +4571,8 @@ redo:schedstat_inc (sd, lb_nobusyq[idle]); goto out_balanced; } + env.src_rq = busiest; + env.src_cpu = busiest->cpu;BUG_ON (busiest == env.dst_rq);@@ -4288,6 +4591,10 @@ redo: env.src_cpu = busiest->cpu; env.src_rq = busiest; env.loop_max =min (sysctl_sched_nr_migrate, busiest->nr_running); +if (sched_feat_numa (NUMA_PULL )) + env.tasks =offnode_tasks (busiest); +else + env.tasks = &busiest->cfs_tasks;update_h_load (env.src_cpu); more_balance:Index:
tip/kernel/sched/features.h
===================================================================kernel/sched/features.h +0
-0@@ -61,3 +61,13 @@ SCHED_FEAT(TTWU_QUEUE, true) SCHED_FEAT(FORCE_SD_OVERLAP, false)SCHED_FEAT (RT_RUNTIME_SHARE , true)
kernel/sched/features.h SCHED_FEAT(TTWU_QUEUE, true) · line 72
Quoted 10 lines
kernel/sched/features.h +9
-0SCHED_FEAT(LB_MIN, false) + +#ifdef CONFIG_SCHED_NUMA +SCHED_FEAT(NUMA, true) +SCHED_FEAT(NUMA_HOT, true) +SCHED_FEAT(NUMA_TTWU_BIAS, false) +SCHED_FEAT(NUMA_TTWU_TO, false) +SCHED_FEAT(NUMA_PULL, true) +SCHED_FEAT(NUMA_PULL_BIAS, true) +#endif
Many of the other SCHED_FEAT flags got a nice explanation.
Quoted 45 lines
kernel/sched/features.h +1
-0+Index:
tip/kernel/sched/sched.h
===================================================================kernel/sched/sched.h +17
-0@@ -418,6 +418,13 @@ struct rq {struct list_head cfs_tasks; +#ifdef CONFIG_SCHED_NUMA +unsigned long onnode_running; +unsigned long offnode_running; +unsigned long offnode_weight; +struct list_head offnode_tasks; +#endif +u64 rt_avg;u64 age_stamp;u64 idle_stamp;@@ -469,6 +476,15 @@ struct rq {#endif }; +static inline struct list_head *offnode_tasks (struct rq *rq) +{ +#ifdef CONFIG_SCHED_NUMA +return &rq->offnode_tasks; +#else +return NULL ; +#endif +} +static inline int cpu_of (struct rq *rq) {#ifdef CONFIG_SMP @@ -529,6 +545,7 @@ static inline struct sched_domain *highe DECLARE_PER_CPU(struct sched_domain *, sd_llc);DECLARE_PER_CPU (int, sd_llc_id); +DECLARE_PER_CPU(struct sched_domain *, sd_node);extern int group_balance_cpu (struct sched_group *sg);
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 24/31 sched, numa, mm: Introduce last_nid in the pageframe
In reply to Peter ZijlstraIntroduce a per-page last_nid field, fold this into the struct page::flags field whenever possible.
The unlikely/rare 32bit NUMA configs will likely grow the page-frame.
Completely dropping 32bit support for CONFIG_SCHED_NUMA would simplify things, but it would also remove the warning if we grow enough 64bit only page-flags to push the last-nid out.
--- include/linux/mm.h | 90 ++++++++++++++++++++------------------ include/linux/mm_types.h | 5 ++ include/linux/mmzone.h | 14 ----- include/linux/page-flags-layout.h | 83 +++++++++++++++++++++++++++++++++++ mm/huge_memory.c | 1 mm/memory.c | 4 + 6 files changed, 143 insertions(+), 54 deletions(-) create mode 100644 include/linux/page-flags-layout.h
include/linux/mm.h +49 -41
@@ -594,50 +594,11 @@ static inline pte_t maybe_mkwrite(pte_t* sets it, so none of the operations on it need to be atomic. */ - -/* -* page->flags layout: -* -* There are three possibilities for how page->flags get -* laid out. The first is for the normal case, without -* sparsemem. The second is for sparsemem when there is -* plenty of space for node and section. The last is when -* we have run out of space and have to fall back to an -* alternate (slower) way of determining the node. -* -* No sparsemem or sparsemem vmemmap: | NODE | ZONE | ... | FLAGS | -* classic sparse with space for node:| SECTION | NODE | ZONE | ... | FLAGS | -* classic sparse no space for node: | SECTION | ZONE | ... | FLAGS | -*/ -#if defined(CONFIG_SPARSEMEM ) && !defined(CONFIG_SPARSEMEM_VMEMMAP ) -#define SECTIONS_WIDTH SECTIONS_SHIFT -#else -#define SECTIONS_WIDTH 0 -#endif - -#define ZONES_WIDTH ZONES_SHIFT - -#if SECTIONS_WIDTH +ZONES_WIDTH +NODES_SHIFT <=BITS_PER_LONG -NR_PAGEFLAGS -#define NODES_WIDTH NODES_SHIFT -#else -#ifdef CONFIG_SPARSEMEM_VMEMMAP -#error "Vmemmap: No space for nodes field in page flags" -#endif -#define NODES_WIDTH 0 -#endif - -/* Page flags: | [SECTION] | [NODE] | ZONE | ... | FLAGS | */ +/* Page flags: | [SECTION] | [NODE] | ZONE | [LAST_NID] | ... | FLAGS | */ #define SECTIONS_PGOFF ((sizeof(unsigned long)*8) - SECTIONS_WIDTH)#define NODES_PGOFF (SECTIONS_PGOFF - NODES_WIDTH)#define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH) - -/* -* We are going to use the flags for the page to node mapping if its in -* there. This includes the case where there is no node, so it is implicit. -*/ -#if !(NODES_WIDTH >0 ||NODES_SHIFT ==0 ) -#define NODE_NOT_IN_PAGE_FLAGS -#endif +#define LAST_NID_PGOFF (ZONES_PGOFF - LAST_NID_WIDTH)/* * Define the bit shifts to access each section. For non-existent
@@ -647,6 +608,7 @@ static inline pte_t maybe_mkwrite(pte_t#define SECTIONS_PGSHIFT (SECTIONS_PGOFF * (SECTIONS_WIDTH != 0))#define NODES_PGSHIFT (NODES_PGOFF * (NODES_WIDTH != 0))#define ZONES_PGSHIFT (ZONES_PGOFF * (ZONES_WIDTH != 0)) +#define LAST_NID_PGSHIFT (LAST_NID_PGOFF * (LAST_NID_WIDTH != 0))/* NODE:ZONE or SECTION:ZONE is used to ID a zone for the buddy allocator */ #ifdef NODE_NOT_IN_PAGE_FLAGS
@@ -668,6 +630,7 @@ static inline pte_t maybe_mkwrite(pte_t#define ZONES_MASK ((1UL << ZONES_WIDTH) - 1)#define NODES_MASK ((1UL << NODES_WIDTH) - 1)#define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) +#define LAST_NID_MASK ((1UL << LAST_NID_WIDTH) - 1)#define ZONEID_MASK ((1UL << ZONEID_SHIFT) - 1)static inline enum zone_type page_zonenum (const struct page *page)
@@ -706,6 +669,51 @@ static inline int page_to_nid(const stru }#endif +#ifdef CONFIG_SCHED_NUMA +#ifdef LAST_NID_NOT_IN_PAGE_FLAGS +static inline int page_xchg_last_nid (struct page *page,int nid) +{ +return xchg (&page->_last_nid, nid); +} + +static inline int page_last_nid (struct page *page) +{ +return page->_last_nid; +} +#else +static inline int page_xchg_last_nid (struct page *page,int nid) +{ +unsigned long old_flags, flags; +int last_nid; + +do { + old_flags = flags = page->flags; + last_nid = (flags >>LAST_NID_PGSHIFT ) &LAST_NID_MASK ; + + flags &= ~(LAST_NID_MASK <<LAST_NID_PGSHIFT ); + flags |= (nid &LAST_NID_MASK ) <<LAST_NID_PGSHIFT ; + }while (unlikely (cmpxchg (&page->flags, old_flags, flags) != old_flags)); + +return last_nid; +} + +static inline int page_last_nid (struct page *page) +{ +return (page->flags >>LAST_NID_PGSHIFT ) &LAST_NID_MASK ; +} +#endif /* LAST_NID_NOT_IN_PAGE_FLAGS */ +#else /* CONFIG_SCHED_NUMA */ +static inline int page_xchg_last_nid (struct page *page,int nid) +{ +return page_to_nid (page); +} + +static inline int page_last_nid (struct page *page) +{ +return page_to_nid (page); +} +#endif /* CONFIG_SCHED_NUMA */ +static inline struct zone *page_zone (const struct page *page) {return &NODE_DATA (page_to_nid (page))->node_zones[page_zonenum (page)];
include/linux/mm_types.h +5 -0
@@ -12,6 +12,7 @@#include <linux/cpumask.h> #include <linux/page-debug-flags.h> #include <linux/uprobes.h> +#include <linux/page-flags-layout.h> #include <asm/page.h> #include <asm/mmu.h>
@@ -175,6 +176,10 @@ struct page {*/ void *shadow;#endif + +#ifdef LAST_NID_NOT_IN_PAGE_FLAGS +int _last_nid; +#endif }/* * The struct page can be forced to be double word aligned so that atomic ops
include/linux/mmzone.h +1 -13
@@ -15,7 +15,7 @@#include <linux/seqlock.h> #include <linux/nodemask.h> #include <linux/pageblock-flags.h> -#include <generated/bounds.h> +#include <linux/page-flags-layout.h> #include <linux/atomic.h> #include <asm/page.h>
@@ -317,16 +317,6 @@ enum zone_type {* match the requested limits. See gfp_zone() in include/linux/gfp.h */ -#if MAX_NR_ZONES <2 -#define ZONES_SHIFT 0 -#elif MAX_NR_ZONES <=2 -#define ZONES_SHIFT 1 -#elif MAX_NR_ZONES <=4 -#define ZONES_SHIFT 2 -#else -#error ZONES_SHIFT -- too many zones configured adjust calculation -#endif -struct zone {/* Fields commonly accessed by the page allocator */
@@ -1029,8 +1019,6 @@ static inline unsigned long early_pfn_to* PA_SECTION_SHIFT physical address to/from section number * PFN_SECTION_SHIFT pfn to/from section number */ -#define SECTIONS_SHIFT (MAX_PHYSMEM_BITS - SECTION_SIZE_BITS) -#define PA_SECTION_SHIFT (SECTION_SIZE_BITS)#define PFN_SECTION_SHIFT (SECTION_SIZE_BITS - PAGE_SHIFT)
include/linux/page-flags-layout.h new file +83 -0
83 lines not on this page · raw message
mm/huge_memory.c +1 -0
@@ -1440,6 +1440,7 @@ static void __split_huge_page_refcount(s page_tail->mapping = page->mapping; page_tail->index = page->index + i; +page_xchg_last_nid (page,page_last_nid (page_tail));BUG_ON (!PageAnon (page_tail));BUG_ON (!PageUptodate (page_tail));
mm/memory.c +4 -0
@@ -68,6 +68,10 @@#include "internal.h" +#ifdef LAST_NID_NOT_IN_PAGE_FLAGS +#warning Unfortunate NUMA config, growing page-frame for last_nid. +#endif +#ifndef CONFIG_NEED_MULTIPLE_NODES /* use the per-pgdat data instead for discontigmem - mbligh */ unsigned long max_mapnr;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 24/31] sched, numa, mm: Introduce last_nid in the pageframe
Quoted 3 lines · Peter Zijlstra
Introduce a per-page
last_nidfield, fold this into the structpage::flagsfield whenever possible.
This is used later in the series.
Quoted 2 lines
The unlikely/rare 32bit NUMA configs will likely grow the page-frame.
If someone files a bug report that lowmem pressure is higher on their 32-bit NUMA machine I would be a bit surprised. Maybe abusers of NUMA care but screw it.
Quoted 34 lines
Completely dropping 32bit support for
CONFIG_SCHED_NUMAwould simplify things, but it would also remove the warning if we grow enough 64bit only page-flags to push the last-nid out.Suggested-by Rik van Riel <[email protected]>Signed-off-by Peter Zijlstra <[email protected]>Cc Linus Torvalds <[email protected]>Cc Andrew Morton <[email protected]>Cc Rik van Riel <[email protected]>Cc Andrea Arcangeli <[email protected]>Signed-off-by Ingo Molnar <[email protected]>--- include/linux/mm.h | 90 ++++++++++++++++++++------------------ include/linux/mm_types.h | 5 ++ include/linux/mmzone.h | 14 ----- include/linux/page-flags-layout.h | 83 +++++++++++++++++++++++++++++++++++ mm/huge_memory.c | 1 mm/memory.c | 4 + 6 files changed, 143 insertions(+), 54 deletions(-) create mode 100644 include/linux/page-flags-layout.hIndex:
tip/include/linux/mm.h
===================================================================include/linux/mm.h +0
-5@@ -594,50 +594,11 @@ static inline pte_t maybe_mkwrite(pte_t* sets it, so none of the operations on it need to be atomic. */ - -/* -* page->flags layout: -* -* There are three possibilities for how page->flags get
include/linux/mm.h static inline pte_t maybe_mkwrite(pte_t · line 611
Quoted 10 lines
include/linux/mm.h +0
-10-* laid out. The first is for the normal case, without -* sparsemem. The second is for sparsemem when there is -* plenty of space for node and section. The last is when -* we have run out of space and have to fall back to an -* alternate (slower) way of determining the node. -* -* No sparsemem or sparsemem vmemmap: | NODE | ZONE | ... | FLAGS | -* classic sparse with space for node:| SECTION | NODE | ZONE | ... | FLAGS | -* classic sparse no space for node: | SECTION | ZONE | ... | FLAGS | -*/
The move to page-flags-layout.h should have been a separate patch! Figuring out what you actually added to the layout is going to be a complete headache (headache was not the first word I was going to use).
In other words I did not try very hard and I'll just be scanning for something obvious.
Quoted 35 lines
include/linux/mm.h +2
-26-#if defined(CONFIG_SPARSEMEM ) && !defined(CONFIG_SPARSEMEM_VMEMMAP ) -#define SECTIONS_WIDTH SECTIONS_SHIFT -#else -#define SECTIONS_WIDTH 0 -#endif - -#define ZONES_WIDTH ZONES_SHIFT - -#if SECTIONS_WIDTH +ZONES_WIDTH +NODES_SHIFT <=BITS_PER_LONG -NR_PAGEFLAGS -#define NODES_WIDTH NODES_SHIFT -#else -#ifdef CONFIG_SPARSEMEM_VMEMMAP -#error "Vmemmap: No space for nodes field in page flags" -#endif -#define NODES_WIDTH 0 -#endif - -/* Page flags: | [SECTION] | [NODE] | ZONE | ... | FLAGS | */ +/* Page flags: | [SECTION] | [NODE] | ZONE | [LAST_NID] | ... | FLAGS | */ #define SECTIONS_PGOFF ((sizeof(unsigned long)*8) - SECTIONS_WIDTH)#define NODES_PGOFF (SECTIONS_PGOFF - NODES_WIDTH)#define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH) - -/* -* We are going to use the flags for the page to node mapping if its in -* there. This includes the case where there is no node, so it is implicit. -*/ -#if !(NODES_WIDTH >0 ||NODES_SHIFT ==0 ) -#define NODE_NOT_IN_PAGE_FLAGS -#endif +#define LAST_NID_PGOFF (ZONES_PGOFF - LAST_NID_WIDTH)/* * Define the bit shifts to access each section. For non-existent
include/linux/mm.h static inline pte_t maybe_mkwrite(pte_t · line 612
Quoted 5 lines
include/linux/mm.h +1
-0@@ -647,6 +608,7 @@ static inline pte_t maybe_mkwrite(pte_t#define SECTIONS_PGSHIFT (SECTIONS_PGOFF * (SECTIONS_WIDTH != 0))#define NODES_PGSHIFT (NODES_PGOFF * (NODES_WIDTH != 0))#define ZONES_PGSHIFT (ZONES_PGOFF * (ZONES_WIDTH != 0)) +#define LAST_NID_PGSHIFT (LAST_NID_PGOFF * (LAST_NID_WIDTH != 0))
Why is LAST_NID_PGSHIFT != NODES_PGSHIFT?
Oh, it more or less is but it's hidden. Screw that, get rid of LAST_NIFT_SHIFT WIDTH and express this entirely in terms of NODES_PFSHIFT and friends.
Quoted 29 lines
include/linux/mm.h +16
-0/* NODE:ZONE or SECTION:ZONE is used to ID a zone for the buddy allocator */ #ifdef NODE_NOT_IN_PAGE_FLAGS @@ -668,6 +630,7 @@ static inline pte_t maybe_mkwrite(pte_t#define ZONES_MASK ((1UL << ZONES_WIDTH) - 1)#define NODES_MASK ((1UL << NODES_WIDTH) - 1)#define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) +#define LAST_NID_MASK ((1UL << LAST_NID_WIDTH) - 1)#define ZONEID_MASK ((1UL << ZONEID_SHIFT) - 1)static inline enum zone_type page_zonenum (const struct page *page)@@ -706,6 +669,51 @@ static inline int page_to_nid(const stru }#endif +#ifdef CONFIG_SCHED_NUMA +#ifdef LAST_NID_NOT_IN_PAGE_FLAGS +static inline int page_xchg_last_nid(struct page *page, int nid) +{ + return xchg(&page->_last_nid, nid); +} + +static inline int page_last_nid(struct page *page) +{ + return page->_last_nid; +} +#else +static inline int page_xchg_last_nid(struct page *page, int nid) +{ + unsigned long old_flags, flags;
include/linux/mm.h static inline int page_to_nid(const stru · line 696
Quoted 10 lines
include/linux/mm.h +10
-0+int last_nid; + +do { + old_flags = flags = page->flags; + last_nid = (flags >>LAST_NID_PGSHIFT ) &LAST_NID_MASK ; + + flags &= ~(LAST_NID_MASK <<LAST_NID_PGSHIFT ); + flags |= (nid &LAST_NID_MASK ) <<LAST_NID_PGSHIFT ; + }while (unlikely (cmpxchg (&page->flags, old_flags, flags) != old_flags)); +
This opens a very small window where this function messed up the flags and fixes them up very shortly afterwards. For most page flags it will not matter but potentially causes weirdness with the extended page flags or are we protected by something else?
Quoted 202 lines
include/linux/mm.h +20
-0+return last_nid; +} + +static inline int page_last_nid (struct page *page) +{ +return (page->flags >>LAST_NID_PGSHIFT ) &LAST_NID_MASK ; +} +#endif /* LAST_NID_NOT_IN_PAGE_FLAGS */ +#else /* CONFIG_SCHED_NUMA */ +static inline int page_xchg_last_nid (struct page *page,int nid) +{ +return page_to_nid (page); +} + +static inline int page_last_nid (struct page *page) +{ +return page_to_nid (page); +} +#endif /* CONFIG_SCHED_NUMA */ +static inline struct zone *page_zone (const struct page *page) {return &NODE_DATA (page_to_nid (page))->node_zones[page_zonenum (page)];Index:
tip/include/linux/mm_types.h
===================================================================include/linux/mm_types.h +5
-0@@ -12,6 +12,7 @@#include <linux/cpumask.h> #include <linux/page-debug-flags.h> #include <linux/uprobes.h> +#include <linux/page-flags-layout.h> #include <asm/page.h> #include <asm/mmu.h> @@ -175,6 +176,10 @@ struct page {*/ void *shadow;#endif + +#ifdef LAST_NID_NOT_IN_PAGE_FLAGS +int _last_nid; +#endif }/* * The struct page can be forced to be double word aligned so that atomic ops Index:
tip/include/linux/mmzone.h
===================================================================include/linux/mmzone.h +1
-13@@ -15,7 +15,7 @@#include <linux/seqlock.h> #include <linux/nodemask.h> #include <linux/pageblock-flags.h> -#include <generated/bounds.h> +#include <linux/page-flags-layout.h> #include <linux/atomic.h> #include <asm/page.h> @@ -317,16 +317,6 @@ enum zone_type {* match the requested limits. See gfp_zone() in include/linux/gfp.h */ -#if MAX_NR_ZONES <2 -#define ZONES_SHIFT 0 -#elif MAX_NR_ZONES <=2 -#define ZONES_SHIFT 1 -#elif MAX_NR_ZONES <=4 -#define ZONES_SHIFT 2 -#else -#error ZONES_SHIFT -- too many zones configured adjust calculation -#endif -struct zone {/* Fields commonly accessed by the page allocator */ @@ -1029,8 +1019,6 @@ static inline unsigned long early_pfn_to* PA_SECTION_SHIFT physical address to/from section number * PFN_SECTION_SHIFT pfn to/from section number */ -#define SECTIONS_SHIFT (MAX_PHYSMEM_BITS - SECTION_SIZE_BITS) -#define PA_SECTION_SHIFT (SECTION_SIZE_BITS)#define PFN_SECTION_SHIFT (SECTION_SIZE_BITS - PAGE_SHIFT)Index:
tip/include/linux/page-flags-layout.h
===================================================================include/linux/page-flags-layout.h new file +83
-0@@ -0,0 +1,83 @@ +#ifndef _LINUX_PAGE_FLAGS_LAYOUT +#define _LINUX_PAGE_FLAGS_LAYOUT + +#include <linux/numa.h> +#include <generated/bounds.h> + +#if MAX_NR_ZONES <2 +#define ZONES_SHIFT 0 +#elif MAX_NR_ZONES <=2 +#define ZONES_SHIFT 1 +#elif MAX_NR_ZONES <=4 +#define ZONES_SHIFT 2 +#else +#error ZONES_SHIFT -- too many zones configured adjust calculation +#endif + +#ifdef CONFIG_SPARSEMEM +#include <asm/sparsemem.h> + +/* +* SECTION_SHIFT #bits space required to store a section # +*/ +#define SECTIONS_SHIFT (MAX_PHYSMEM_BITS - SECTION_SIZE_BITS) +#endif + +/* +* page->flags layout: +* +* There are five possibilities for how page->flags get laid out. The first +* (and second) is for the normal case, without sparsemem. The third is for +* sparsemem when there is plenty of space for node and section. The last is +* when we have run out of space and have to fall back to an alternate (slower) +* way of determining the node. +* +* No sparsemem or sparsemem vmemmap: | NODE | ZONE | ... | FLAGS | +* " plus space for last_nid:| NODE | ZONE | LAST_NID | ... | FLAGS | +* classic sparse with space for node:| SECTION | NODE | ZONE | ... | FLAGS | +* " plus space for last_nid:| SECTION | NODE | ZONE | LAST_NID | ... | FLAGS | +* classic sparse no space for node: | SECTION | ZONE | ... | FLAGS | +*/ +#if defined(CONFIG_SPARSEMEM ) && !defined(CONFIG_SPARSEMEM_VMEMMAP ) + +#define SECTIONS_WIDTH SECTIONS_SHIFT +#else +#define SECTIONS_WIDTH 0 +#endif + +#define ZONES_WIDTH ZONES_SHIFT + +#if SECTIONS_WIDTH +ZONES_WIDTH +NODES_SHIFT <=BITS_PER_LONG -NR_PAGEFLAGS +#define NODES_WIDTH NODES_SHIFT +#else +#ifdef CONFIG_SPARSEMEM_VMEMMAP +#error "Vmemmap: No space for nodes field in page flags" +#endif +#define NODES_WIDTH 0 +#endif + +#ifdef CONFIG_SCHED_NUMA +#define LAST_NID_SHIFT NODES_SHIFT +#else +#define LAST_NID_SHIFT 0 +#endif + +#if SECTIONS_WIDTH +ZONES_WIDTH +NODES_SHIFT +LAST_NID_SHIFT <=BITS_PER_LONG -NR_PAGEFLAGS +#define LAST_NID_WIDTH LAST_NID_SHIFT +#else +#define LAST_NID_WIDTH 0 +#endif + +/* +* We are going to use the flags for the page to node mapping if its in +* there. This includes the case where there is no node, so it is implicit. +*/ +#if !(NODES_WIDTH >0 ||NODES_SHIFT ==0 ) +#define NODE_NOT_IN_PAGE_FLAGS +#endif + +#if defined(CONFIG_SCHED_NUMA ) &&LAST_NID_WIDTH ==0 +#define LAST_NID_NOT_IN_PAGE_FLAGS +#endif + +#endif /* _LINUX_PAGE_FLAGS_LAYOUT */ Index:
tip/mm/huge_memory.c
===================================================================mm/huge_memory.c +1
-0@@ -1440,6 +1440,7 @@ static void __split_huge_page_refcount(s page_tail->mapping = page->mapping; page_tail->index = page->index + i; +page_xchg_last_nid (page,page_last_nid (page_tail));BUG_ON (!PageAnon (page_tail));BUG_ON (!PageUptodate (page_tail));Index:
tip/mm/memory.c
===================================================================mm/memory.c +4
-0@@ -68,6 +68,10 @@#include "internal.h" +#ifdef LAST_NID_NOT_IN_PAGE_FLAGS +#warning Unfortunate NUMA config, growing page-frame for last_nid. +#endif +#ifndef CONFIG_NEED_MULTIPLE_NODES /* use the per-pgdat data instead for discontigmem - mbligh */ unsigned long max_mapnr;
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 25/31 sched, numa, mm/mpol: Add_MPOL_F_HOME
In reply to Peter ZijlstraAdd MPOL_F_HOME, to implement multi-stage home node binding.
--- include/uapi/linux/mempolicy.h | 1 + mm/mempolicy.c | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-)
include/uapi/linux/mempolicy.h +1 -0
@@ -69,6 +69,7 @@ enum mpol_rebind_step {#define MPOL_F_LOCAL (1 << 1)/* preferred local allocation */ #define MPOL_F_REBINDING (1 << 2)/* identify policies in rebinding */ #define MPOL_F_MOF (1 << 3)/* this policy wants migrate on fault */ +#define MPOL_F_HOME (1 << 4)/* this is the home-node policy */ #endif /* _UAPI_LINUX_MEMPOLICY_H */
mm/mempolicy.c +33 -1
@@ -2190,6 +2190,7 @@ static void sp_free(struct sp_node *n)* @page - page to be checked * @vma - vm area where page mapped * @addr - virtual address where page mapped +* @multi - use multi-stage node binding * * Lookup current policy node id for vma,addr and "compare to" page's * node id.
@@ -2252,6 +2253,37 @@ int mpol_misplaced(struct page *page, stdefault :BUG (); } + +/* +* Multi-stage node selection is used in conjunction with a periodic +* migration fault to build a temporal task<->page relation. By +* using a two-stage filter we remove short/unlikely relations. +* +* Using P(p) ~ n_p / n_t as per frequentist probability, we can +* equate a task's usage of a particular page (n_p) per total usage +* of this page (n_t) (in a given time-span) to a probability. +* +* Our periodic faults will then sample this probability and getting +* the same result twice in a row, given these samples are fully +* independent, is then given by P(n)^2, provided our sample period +* is sufficiently short compared to the usage pattern. +* +* This quadric squishes small probabilities, making it less likely +* we act on an unlikely task<->page relation. +*/ +if (pol->flags &MPOL_F_HOME ) { +int last_nid; + +/* +* Migrate towards the current node, depends on +* task_numa_placement() details. +*/ + polnid =numa_node_id (); + last_nid =page_xchg_last_nid (page, polnid); +if (last_nid != polnid) + goto out; + } +if (curnid != polnid) ret = polnid; out:
@@ -2444,7 +2476,7 @@ void __init numa_policy_init(void) preferred_node_policy[nid] = (struct mempolicy ) { .refcnt =ATOMIC_INIT (1 ), .mode =MPOL_PREFERRED , - .flags =MPOL_F_MOF , + .flags =MPOL_F_MOF |MPOL_F_HOME , .v = { .preferred_node = nid, }, }; }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 26/31 sched, numa, mm: Add fault driven placement and migration policy
In reply to Peter ZijlstraAs per the problem/design document Documentation/scheduler/numa-problem.txt implement 3ac & 4.
( A pure 3a was found too unstable, I did briefly try 3bc
but found no significant improvement. )
Implement a per-task memory placement scheme relying on a regular PROT_NONE 'migration' fault to scan the memory space of the procress and uses a two stage migration scheme to reduce the invluence of unlikely usage relations.
It relies on the assumption that the compute part is tied to a paticular task and builds a task<->page relation set to model the compute<->data relation.
In the previous patch we made memory migrate towards where the task is running, here we select the node on which most memory is located as the preferred node to run on.
This creates a feed-back control loop between trying to schedule a task on a node and migrating memory towards the node the task is scheduled on.
--- include/linux/mm_types.h | 4 + include/linux/sched.h | 35 +++++++-- kernel/sched/core.c | 16 ++++ kernel/sched/fair.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++ kernel/sched/features.h | 1 kernel/sched/sched.h | 31 +++++--- kernel/sysctl.c | 31 +++++++- mm/huge_memory.c | 7 + mm/memory.c | 4 - 9 files changed, 282 insertions(+), 22 deletions(-)
include/linux/mm_types.h +4 -0
@@ -403,6 +403,10 @@ struct mm_struct {#ifdef CONFIG_CPUMASK_OFFSTACK struct cpumask cpumask_allocation;#endif +#ifdef CONFIG_SCHED_NUMA +unsigned long numa_next_scan; +int numa_scan_seq; +#endif struct uprobes_state uprobes_state; };
include/linux/sched.h +27 -8
@@ -1481,9 +1481,16 @@ struct task_struct {short pref_node_fork;#endif #ifdef CONFIG_SCHED_NUMA -int node; +int node;/* task home node */ +int numa_scan_seq; +int numa_migrate_seq; +unsigned int numa_scan_period; +u64 node_stamp;/* migration stamp */ unsigned long numa_contrib; -#endif +unsigned long *numa_faults; +struct callback_head numa_work; +#endif /* CONFIG_SCHED_NUMA */ +struct rcu_head rcu;/*
@@ -1558,15 +1565,24 @@ struct task_struct {/* Future-safe accessor for struct task_struct's cpus_allowed. */ #define tsk_cpus_allowed (tsk) (&(tsk)->cpus_allowed) +#ifdef CONFIG_SCHED_NUMA static inline int tsk_home_node (struct task_struct *p) { -#ifdef CONFIG_SCHED_NUMA return p->node; +} + +extern void task_numa_fault (int node,int pages);#else +static inline int tsk_home_node (struct task_struct *p) +{return -1 ; -#endif } +static inline void task_numa_fault (int node,int pages) +{ +} +#endif /* CONFIG_SCHED_NUMA */ +/* * Priority of a process goes from 0..MAX_PRIO-1, valid RT * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
@@ -2004,6 +2020,10 @@ enum sched_tunable_scaling { };extern enum sched_tunable_scaling sysctl_sched_tunable_scaling; +extern unsigned int sysctl_sched_numa_scan_period_min; +extern unsigned int sysctl_sched_numa_scan_period_max; +extern unsigned int sysctl_sched_numa_settle_count; +#ifdef CONFIG_SCHED_DEBUG extern unsigned int sysctl_sched_migration_cost;extern unsigned int sysctl_sched_nr_migrate;
@@ -2014,18 +2034,17 @@ extern unsigned int sysctl_sched_shares_int sched_proc_update_handler (struct ctl_table *table,int write,void __user *buffer,size_t *length,loff_t *ppos); -#endif -#ifdef CONFIG_SCHED_DEBUG +static inline unsigned int get_sysctl_timer_migration (void ) {return sysctl_timer_migration; } -#else +#else /* CONFIG_SCHED_DEBUG */ static inline unsigned int get_sysctl_timer_migration (void ) {return 1 ; } -#endif +#endif /* CONFIG_SCHED_DEBUG */ extern unsigned int sysctl_sched_rt_period;extern int sysctl_sched_rt_runtime;
kernel/sched/core.c +16 -0
@@ -1533,6 +1533,21 @@ static void __sched_fork(struct task_str#ifdef CONFIG_PREEMPT_NOTIFIERS INIT_HLIST_HEAD (&p->preempt_notifiers);#endif + +#ifdef CONFIG_SCHED_NUMA +if (p->mm &&atomic_read (&p->mm->mm_users) ==1 ) { + p->mm->numa_next_scan = jiffies; + p->mm->numa_scan_seq =0 ; + } + + p->node =-1 ; + p->node_stamp =0ULL ; + p->numa_scan_seq = p->mm ? p->mm->numa_scan_seq :0 ; + p->numa_migrate_seq = p->mm ? p->mm->numa_scan_seq -1 :0 ; + p->numa_faults =NULL ; + p->numa_scan_period = sysctl_sched_numa_scan_period_min; + p->numa_work.next = &p->numa_work; +#endif /* CONFIG_SCHED_NUMA */ }/*
@@ -1774,6 +1789,7 @@ static void finish_task_switch(struct rqif (mm)mmdrop (mm);if (unlikely (prev_state ==TASK_DEAD )) { +task_numa_free (prev);/* * Remove function-return probe instances associated with this * task and put them back on the free list.
kernel/sched/fair.c +175 -0
205 lines not on this page · raw message
kernel/sched/features.h +1 -0
@@ -69,5 +69,6 @@ SCHED_FEAT(NUMA_TTWU_BIAS, false) SCHED_FEAT(NUMA_TTWU_TO, false) SCHED_FEAT(NUMA_PULL, true) SCHED_FEAT(NUMA_PULL_BIAS, true) +SCHED_FEAT(NUMA_SETTLE, true)#endif
kernel/sched/sched.h +22 -9
@@ -3,6 +3,7 @@#include <linux/mutex.h> #include <linux/spinlock.h> #include <linux/stop_machine.h> +#include <linux/slab.h> #include "cpupri.h"
@@ -476,15 +477,6 @@ struct rq {#endif }; -static inline struct list_head *offnode_tasks (struct rq *rq) -{ -#ifdef CONFIG_SCHED_NUMA -return &rq->offnode_tasks; -#else -return NULL ; -#endif -} -static inline int cpu_of (struct rq *rq) {#ifdef CONFIG_SMP
@@ -502,6 +494,27 @@ DECLARE_PER_CPU(struct rq, runqueues);#define cpu_curr (cpu) (cpu_rq(cpu)->curr)#define raw_rq () (&__raw_get_cpu_var(runqueues)) +#ifdef CONFIG_SCHED_NUMA +static inline struct list_head *offnode_tasks (struct rq *rq) +{ +return &rq->offnode_tasks; +} + +static inline void task_numa_free (struct task_struct *p) +{ +kfree (p->numa_faults); +} +#else /* CONFIG_SCHED_NUMA */ +static inline struct list_head *offnode_tasks (struct rq *rq) +{ +return NULL ; +} + +static inline void task_numa_free (struct task_struct *p) +{ +} +#endif /* CONFIG_SCHED_NUMA */ +#ifdef CONFIG_SMP #define rcu_dereference_check_sched_domain (p) \
kernel/sysctl.c +29 -2
@@ -256,9 +256,11 @@ static int min_sched_granularity_ns = 10static int max_sched_granularity_ns =NSEC_PER_SEC ;/* 1 second */ static int min_wakeup_granularity_ns;/* 0 usecs */ static int max_wakeup_granularity_ns =NSEC_PER_SEC ;/* 1 second */ +#ifdef CONFIG_SMP static int min_sched_tunable_scaling =SCHED_TUNABLESCALING_NONE ;static int max_sched_tunable_scaling =SCHED_TUNABLESCALING_END -1 ; -#endif +#endif /* CONFIG_SMP */ +#endif /* CONFIG_SCHED_DEBUG */ #ifdef CONFIG_COMPACTION static int min_extfrag_threshold;
@@ -301,6 +303,7 @@ static struct ctl_table kern_table[] = { .extra1 = &min_wakeup_granularity_ns, .extra2 = &max_wakeup_granularity_ns, }, +#ifdef CONFIG_SMP { .procname = "sched_tunable_scaling", .data = &sysctl_sched_tunable_scaling,
@@ -347,7 +350,31 @@ static struct ctl_table kern_table[] = { .extra1 = &zero, .extra2 = &one, }, -#endif +#endif /* CONFIG_SMP */ +#ifdef CONFIG_SCHED_NUMA + { + .procname = "sched_numa_scan_period_min_ms", + .data = &sysctl_sched_numa_scan_period_min, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { + .procname = "sched_numa_scan_period_max_ms", + .data = &sysctl_sched_numa_scan_period_max, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { + .procname = "sched_numa_settle_count", + .data = &sysctl_sched_numa_settle_count, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, +#endif /* CONFIG_SCHED_NUMA */ +#endif /* CONFIG_SCHED_DEBUG */ { .procname = "sched_rt_period_us", .data = &sysctl_sched_rt_period,
mm/huge_memory.c +5 -2
@@ -774,9 +774,10 @@ fixup: unlock:spin_unlock (&mm->page_table_lock); -if (page) +if (page) { +task_numa_fault (page_to_nid (page),HPAGE_PMD_NR );put_page (page); - + }return ; migrate:
@@ -845,6 +846,8 @@ migrate:put_page (page);/* Drop the rmap reference */ +task_numa_fault (node,HPAGE_PMD_NR ); +if (lru)put_page (page);/* drop the LRU isolation reference */
mm/memory.c +3 -1
@@ -3512,8 +3512,10 @@ out_pte_upgrade_unlock: out_unlock:pte_unmap_unlock (ptep, ptl); out: -if (page) +if (page) { +task_numa_fault (page_nid,1 );put_page (page); + }return 0 ;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 26/31] sched, numa, mm: Add fault driven placement and migration policy
kernel/sched/fair.c static void account_numa_dequeue(struct · line 963
Quoted 6 lines · Peter Zijlstra
kernel/sched/fair.c +6
-0+/* +* Using runtime rather than walltime has the dual advantage that +* we (mostly) drive the selection from busy threads and that the +* task needs to have done some actual work before we bother with +* NUMA placement. +*/
That explanation makes sense..
kernel/sched/fair.c static void account_numa_dequeue(struct · line 970
Quoted 7 lines
kernel/sched/fair.c +7
-0+ now = curr->se.sum_exec_runtime; + period = (u64 )curr->numa_scan_period *NSEC_PER_MSEC ; + +if (now - curr->node_stamp > period) { + curr->node_stamp = now; + +if (!time_before (jiffies, curr->mm->numa_next_scan)) {
.. but then the whole "numa_next_scan" thing ends up being about real-time anyway?
So 'numa_scan_period' in in CPU time (msec, converted to nsec at runtime rather than when setting it), but 'numa_next_scan' is in wallclock time (jiffies)?
But *both* of them are based on the same 'numa_scan_period' thing that the user sets in ms.
So numa_scan_period is interpreted as both wallclock *and* as runtime?
Maybe this works, but it doesn't really make much sense. And what is the impact of this on machines that run lots of loads with delays (whether due to IO or timers)?
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 26/31] sched, numa, mm: Add fault driven placement and migration policy
Quoted 25 lines · Linus Torvalds
kernel/sched/fair.c static void account_numa_dequeue(struct · line 963
Quoted 6 lines · Peter Zijlstra
kernel/sched/fair.c +6
-0+/* +* Using runtime rather than walltime has the dual advantage that +* we (mostly) drive the selection from busy threads and that the +* task needs to have done some actual work before we bother with +* NUMA placement. +*/ That explanation makes sense..
kernel/sched/fair.c static void account_numa_dequeue(struct · line 970
Quoted 7 lines
kernel/sched/fair.c +7
-0+ now = curr->se.sum_exec_runtime; + period = (u64 )curr->numa_scan_period *NSEC_PER_MSEC ; + +if (now - curr->node_stamp > period) { + curr->node_stamp = now; + +if (!time_before (jiffies, curr->mm->numa_next_scan)) {.. but then the whole "
numa_next_scan" thing ends up being about real-time anyway?So '
numa_scan_period' in in CPU time (msec, converted to nsec at runtime rather than when setting it), but 'numa_next_scan' is in wallclock time (jiffies)?
Quoted 7 lines
But *both* of them are based on the same '
numa_scan_period' thing that the user sets in ms.So
numa_scan_periodis interpreted as both wallclock *and* as runtime?Maybe this works, but it doesn't really make much sense.
So, the relationship between wall clock time and execution runtime is that on the limit they run at the same speed: when there's a single task running. In any other case execution runtime can only run slower than wall time.
So the bit you found weird:
Quoted 1 line
Quoted 1 line
+ if (!time_before(jiffies,
curr->mm->numa_next_scan)) {
together with the task_numa_work() frequency limit:
/*
* Enforce maximal scan/migration frequency..
*/
migrate = mm->numa_next_scan;
if (time_before(now, migrate))
return;
next_scan = now + 2*msecs_to_jiffies(sysctl_sched_numa_scan_period_min);
if (cmpxchg(&mm->numa_next_scan, migrate, next_scan) != migrate)
return;puts an upper limit on the per mm scanning frequency.
This filters us from over-sampling if there are many threads: if all threads happen to come in at the same time we don't create a spike in overhead.
We also avoid multiple threads scanning at once in parallel to each other. Faults are nicely parallel, especially with all the preparatory patches in place, so the distributed nature of the faults itself is not a problem.
So we have to conflicting goals here: on one hand we have a quality of sampling goal which asks for per task runtime proportional scanning on all threads, but we also have a performance goal and don't actually want all threads running at the same time. This frequency limit avoids the over-sampling scenario while still fulfilling the per task sampling property, statistically on average.
If you agree that we should do it like that and if the implementation is correct and optimal, I will put a better explanation into the code.
[
task_numa_work() performance side note:
We are also *very* close to be able to use down_read() instead of down_write() in the sampling-unmap code in task_numa_work(), as it should be safe in theory to call change_protection(PROT_NONE) in parallel - but there's one regression that disagrees with this theory so we use down_write() at the moment.
Maybe you could help us there: can you see a reason why the change_prot_none()->change_protection() call in task_numa_work() can not occur in parallel to a page fault in another thread on another CPU? It should be safe - yet if we change it I can see occasional corruption of user-space state:
segfaults and register corruption.
]
Quoted 2 lines
[...] And what is the impact of this on machines that run lots of loads with delays (whether due to IO or timers)?
I've done sysbench OLTP measurements which showed no apparent regressions:
#
# Comparing { res-schednuma-NO_NUMA.txt } to { res-schednuma-+NUMA.txt }:
#
# threads improvement % SysBench OLTP transactions/second
#-------------------------------------------------------------------
2: 2.11 % # 2160.20 vs. 2205.80
4: -5.52 % # 4202.04 vs. 3969.97
8: 0.01 % # 6894.45 vs. 6895.45
16: -0.31 % # 11840.77 vs. 11804.30
24: -0.56 % # 15053.98 vs. 14969.14
30: 0.56 % # 17043.23 vs. 17138.21
32: -1.08 % # 17797.04 vs. 17604.67
34: 1.04 % # 18158.10 vs. 18347.22
36: -0.16 % # 18125.42 vs. 18096.68
40: 0.45 % # 18218.73 vs. 18300.59
48: -0.39 % # 18266.91 vs. 18195.26
56: -0.11 % # 18285.56 vs. 18265.74
64: 0.23 % # 18304.74 vs. 18347.51
96: 0.18 % # 18268.44 vs. 18302.04
128: 0.22 % # 18058.92 vs. 18099.34
256: 1.63 % # 17068.55 vs. 17347.14
512: 6.86 % # 13452.18 vs. 14375.08No regression is the best we can hope for I think, given that OLTP typically has huge global caches and global serialization, so any NUMA conscious will at most be a nuisance.
We've also done kbuild measurements - which too is a pretty sleepy workload that is too fast for any migration techniques to help.
But even sysbench isn't doing very long delays, so I will do more IO delay targeted measurements.
So I've been actively looking for and checking the worst-case loads for this feature. The feature obviously helps long-run, CPU-intense workloads, but those aren't the challenging ones really IMO: I spent 70% of the time analyzing workloads that are not expected to be friends with this feature.
We are also keeping CONFIG_SCHED_NUMA off by default for good measure.
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 26/31] sched, numa, mm: Add fault driven placement and migration policy
Quoted 10 lines · Ingo Molnar
[
task_numa_work()performance side note:We are also *very* close to be able to use
down_read()instead ofdown_write()in the sampling-unmap code intask_numa_work(), as it should be safe in theory to callchange_protection(PROT_NONE)in parallel - but there's one regression that disagrees with this theory so we usedown_write()at the moment.
Quoted 7 lines
Maybe you could help us there: can you see a reason why the change_prot_none()->change_protection() call in
task_numa_work()can not occur in parallel to a page fault in another thread on another CPU? It should be safe - yet if we change it I can see occasional corruption of user-space state:
segfaults and register corruption.
]
Oh, just found the reason:
the ptep_modify_prot_start()/modify()/commit() sequence is SMP-unsafe - it has to be done under the mmap_sem write-locked.
It is safe against *hardware* updates to the PTE, but not safe against itself.
This is apparently a hidden cost of paravirt, it is forcing that weird sequence and thus the down_write() ...
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 26/31] sched, numa, mm: Add fault driven placement and migration policy
Quoted 8 lines · Ingo Molnar
Oh, just found the reason:
the ptep_modify_prot_start()/modify()/commit() sequence is SMP-unsafe - it has to be done under the
mmap_semwrite-locked.It is safe against *hardware* updates to the PTE, but not safe against itself.
Shouldn't the pte_lock serialize all that still? All sites that modify PTE contents should hold the pte_lock (and do afaict).
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 26/31] sched, numa, mm: Add fault driven placement and migration policy
Quoted 8 lines · Peter Zijlstra
Quoted 7 lines · Ingo Molnar
Oh, just found the reason:
the ptep_modify_prot_start()/modify()/commit() sequence is SMP-unsafe - it has to be done under the
mmap_semwrite-locked.
Quoted 6 lines
Quoted 2 lines
It is safe against *hardware* updates to the PTE, but not safe against itself.
Shouldn't the
pte_lockserialize all that still? All sites that modify PTE contents should hold thepte_lock(and do afaict).
Hm, indeed.
Is there no code under down_read() (in the page fault path) that modifies the pte via just pure atomics?
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 26/31] sched, numa, mm: Add fault driven placement and migration policy
Quoted 11 lines · Ingo Molnar
Quoted 4 lines · Peter Zijlstra
Shouldn't the
pte_lockserialize all that still? All sites that modify PTE contents should hold thepte_lock(and do afaict).Hm, indeed.
Is there no code under
down_read()(in the page fault path) that modifies the pte via just pure atomics?
Well, the ptep_set_access_flags() thing modifies the pte under down_read(). Not using atomics, though. If it races with itself or with a hardware page walk, that's fine, but if it races with something changing other bits than A/D, that would be horribly horribly bad - it could undo any other bit changes exactly because it's a unlocked read-do-other-things-write sequence.
But it's always run under the page table lock - as should all other SW page table modifications - so it *should* be fine. The down_read() is for protecting other VM data structures (notably the vma lists etc), not the page table bit-twiddling.
In fact, the whole SW page table modification scheme *depends* on the page table lock, because the ptep_modify_prot_start/commit thing does a "atomically clear the page table pointer to protect against hardware walkers". And if another software walker were to see that cleared state, it would do bad things (the exception, as usual, is the GUP code, which does the optimistic unlocked accesses and conceptually emulates a hardware page table walk)
So I really think that the mmap_sem should be entirely a non-issue for this kind of code.
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 26/31] sched, numa, mm: Add fault driven placement and migration policy
In reply to Peter Zijlstrakernel/sched/fair.c static void account_numa_dequeue(struct · line 956
Quoted 13 lines · Peter Zijlstra
kernel/sched/fair.c +13
-0+/* +* Drive the periodic memory faults.. +*/ +void task_tick_numa (struct rq *rq,struct task_struct *curr) +{ +struct callback_head *work = &curr->numa_work; +u64 period, now; + +/* +* We don't care about NUMA placement if we don't have memory. +*/ +if (!curr->mm || (curr->flags &PF_EXITING ) || work->next != work) +return ;
We should probably skip the whole unmap-and-refault business if we are running on a system that is not NUMA. Ie. a system with just one node...
kernel/sched/fair.c static void account_numa_dequeue(struct · line 966
Quoted 9 lines
kernel/sched/fair.c +9
-0+/* +* Using runtime rather than walltime has the dual advantage that +* we (mostly) drive the selection from busy threads and that the +* task needs to have done some actual work before we bother with +* NUMA placement. +*/ + now = curr->se.sum_exec_runtime; + period = (u64 )curr->numa_scan_period *NSEC_PER_MSEC ; +
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 26/31] sched, numa, mm: Add fault driven placement and migration policy
In reply to Peter ZijlstraQuoted 15 lines · Peter Zijlstra
As per the problem/design document
Documentation/scheduler/numa-problem.txtimplement 3ac & 4.( A pure 3a was found too unstable, I did briefly try 3bc
but found no significant improvement. )Implement a per-task memory placement scheme relying on a regular
PROT_NONE'migration' fault to scan the memory space of the procress and uses a two stage migration scheme to reduce the invluence of unlikely usage relations.It relies on the assumption that the compute part is tied to a paticular task and builds a task<->page relation set to model the compute<->data relation.
Quoted 8 lines
In the previous patch we made memory migrate towards where the task is running, here we select the node on which most memory is located as the preferred node to run on.
This creates a feed-back control loop between trying to schedule a task on a node and migrating memory towards the node the task is scheduled on.
Ok.
Quoted 23 lines
Suggested-by Andrea Arcangeli <[email protected]>Suggested-by Rik van Riel <[email protected]>Fixes-by David Rientjes <[email protected]>Cc Linus Torvalds <[email protected]>Cc Andrew Morton <[email protected]>Signed-off-by Peter Zijlstra <[email protected]>Signed-off-by Ingo Molnar <[email protected]>--- include/linux/mm_types.h | 4 + include/linux/sched.h | 35 +++++++-- kernel/sched/core.c | 16 ++++ kernel/sched/fair.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++ kernel/sched/features.h | 1 kernel/sched/sched.h | 31 +++++--- kernel/sysctl.c | 31 +++++++- mm/huge_memory.c | 7 + mm/memory.c | 4 - 9 files changed, 282 insertions(+), 22 deletions(-)Index:
tip/include/linux/mm_types.h
===================================================================
include/linux/mm_types.h struct mm_struct { · line 407
Quoted 5 lines
include/linux/mm_types.h +2
-0@@ -403,6 +403,10 @@ struct mm_struct {#ifdef CONFIG_CPUMASK_OFFSTACK struct cpumask cpumask_allocation;#endif +#ifdef CONFIG_SCHED_NUMA +unsigned long numa_next_scan;
comment.
include/linux/mm_types.h struct mm_struct { · line 408
Quoted 1 line
include/linux/mm_types.h +1
-0+int numa_scan_seq;
comment! at least the other one is easy to guess. This thing looks like it's preventing multiple threads in a process space scanning and updating PTEs at the same time. Effectively it's a type of barrier but without a comment I'm not sure if what it's doing is what you expect it to be doing or something else entirely.
Quoted 183 lines
include/linux/mm_types.h +1
-0+#endif struct uprobes_state uprobes_state; };Index:
tip/include/linux/sched.h
===================================================================include/linux/sched.h +27
-8@@ -1481,9 +1481,16 @@ struct task_struct {short pref_node_fork;#endif #ifdef CONFIG_SCHED_NUMA -int node; +int node;/* task home node */ +int numa_scan_seq; +int numa_migrate_seq; +unsigned int numa_scan_period; +u64 node_stamp;/* migration stamp */ unsigned long numa_contrib; -#endif +unsigned long *numa_faults; +struct callback_head numa_work; +#endif /* CONFIG_SCHED_NUMA */ +struct rcu_head rcu;/* @@ -1558,15 +1565,24 @@ struct task_struct {/* Future-safe accessor for struct task_struct's cpus_allowed. */ #define tsk_cpus_allowed (tsk) (&(tsk)->cpus_allowed) +#ifdef CONFIG_SCHED_NUMA static inline int tsk_home_node (struct task_struct *p) { -#ifdef CONFIG_SCHED_NUMA return p->node; +} + +extern void task_numa_fault (int node,int pages);#else +static inline int tsk_home_node (struct task_struct *p) +{return -1 ; -#endif } +static inline void task_numa_fault (int node,int pages) +{ +} +#endif /* CONFIG_SCHED_NUMA */ +/* * Priority of a process goes from 0..MAX_PRIO-1, valid RT * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH @@ -2004,6 +2020,10 @@ enum sched_tunable_scaling { };extern enum sched_tunable_scaling sysctl_sched_tunable_scaling; +extern unsigned int sysctl_sched_numa_scan_period_min; +extern unsigned int sysctl_sched_numa_scan_period_max; +extern unsigned int sysctl_sched_numa_settle_count; +#ifdef CONFIG_SCHED_DEBUG extern unsigned int sysctl_sched_migration_cost;extern unsigned int sysctl_sched_nr_migrate;@@ -2014,18 +2034,17 @@ extern unsigned int sysctl_sched_shares_int sched_proc_update_handler (struct ctl_table *table,int write,void __user *buffer,size_t *length,loff_t *ppos); -#endif -#ifdef CONFIG_SCHED_DEBUG +static inline unsigned int get_sysctl_timer_migration (void ) {return sysctl_timer_migration; } -#else +#else /* CONFIG_SCHED_DEBUG */ static inline unsigned int get_sysctl_timer_migration (void ) {return 1 ; } -#endif +#endif /* CONFIG_SCHED_DEBUG */ extern unsigned int sysctl_sched_rt_period;extern int sysctl_sched_rt_runtime;Index:
tip/kernel/sched/core.c
===================================================================kernel/sched/core.c +16
-0@@ -1533,6 +1533,21 @@ static void __sched_fork(struct task_str#ifdef CONFIG_PREEMPT_NOTIFIERS INIT_HLIST_HEAD (&p->preempt_notifiers);#endif + +#ifdef CONFIG_SCHED_NUMA +if (p->mm &&atomic_read (&p->mm->mm_users) ==1 ) { + p->mm->numa_next_scan = jiffies; + p->mm->numa_scan_seq =0 ; + } + + p->node =-1 ; + p->node_stamp =0ULL ; + p->numa_scan_seq = p->mm ? p->mm->numa_scan_seq :0 ; + p->numa_migrate_seq = p->mm ? p->mm->numa_scan_seq -1 :0 ; + p->numa_faults =NULL ; + p->numa_scan_period = sysctl_sched_numa_scan_period_min; + p->numa_work.next = &p->numa_work; +#endif /* CONFIG_SCHED_NUMA */ }/* @@ -1774,6 +1789,7 @@ static void finish_task_switch(struct rqif (mm)mmdrop (mm);if (unlikely (prev_state ==TASK_DEAD )) { +task_numa_free (prev);/* * Remove function-return probe instances associated with this * task and put them back on the free list. Index:
tip/kernel/sched/fair.c
===================================================================kernel/sched/fair.c +40
-0@@ -27,6 +27,8 @@#include <linux/profile.h> #include <linux/interrupt.h> #include <linux/random.h> +#include <linux/mempolicy.h> +#include <linux/task_work.h> #include <trace/events/sched.h> @@ -775,6 +777,21 @@ update_stats_curr_start(struct cfs_rq *c/************************************************** * Scheduling class numa methods. +* +* The purpose of the NUMA bits are to maintain compute (task) and data +* (memory) locality. We try and achieve this by making tasks stick to +* a particular node (their home node) but if fairness mandates they run +* elsewhere for long enough, we let the memory follow them. +* +* Tasks start out with their home-node unset (-1) this effectively means +* they act !NUMA until we've established the task is busy enough to bother +* with placement. +* +* We keep a home-node per task and use periodic fault scans to try and +* estalish a task<->page relation. This assumes the task<->page relation is a +* compute<->data relation, this is false for things like virt. and n:m +* threading solutions but its the best we can do given the information we +* have. */ #ifdef CONFIG_SMP @@ -805,6 +822,157 @@ static void account_numa_dequeue(struct }else rq->onnode_running--; } + +/* +* numa task sample period in ms: 5s +*/ +unsigned int sysctl_sched_numa_scan_period_min =5000 ; +unsigned int sysctl_sched_numa_scan_period_max =5000 *16 ; + +/* +* Wait for the 2-sample stuff to settle before migrating again +*/ +unsigned int sysctl_sched_numa_settle_count =2 ; + +static void task_numa_placement (struct task_struct *p) +{ +unsigned long faults, max_faults =0 ; +int node, max_node =-1 ; +int seq =ACCESS_ONCE (p->mm->numa_scan_seq); + +if (p->numa_scan_seq == seq) +return ; + + p->numa_scan_seq = seq; +
kernel/sched/fair.c static void account_numa_dequeue(struct · line 857
Quoted 10 lines
kernel/sched/fair.c +10
-0+for (node =0 ; node < nr_node_ids; node++) { + faults = p->numa_faults[node]; + +if (faults > max_faults) { + max_faults = faults; + max_node = node; + } + + p->numa_faults[node] /=2 ; + }
No comments explaining the logic behind the decaying average. It can be inferred if someone reads Documentation/scheduler/numa-problem.txt and point 3c carefully enough. At the very least point them at it.
kernel/sched/fair.c static void account_numa_dequeue(struct · line 868
Quoted 11 lines
kernel/sched/fair.c +11
-0+ +if (max_node ==-1 ) +return ; + +if (p->node != max_node) { + p->numa_scan_period = sysctl_sched_numa_scan_period_min; +if (sched_feat (NUMA_SETTLE ) && + (seq - p->numa_migrate_seq) <= (int )sysctl_sched_numa_settle_count) +return ; + p->numa_migrate_seq = seq; +sched_setnode (p, max_node);
Ok, so at a guess even if we do ping-pong it will only take effect every 10 seconds which could be far worse.
Quoted 11 lines
kernel/sched/fair.c +11
-0+ }else { + p->numa_scan_period =min (sysctl_sched_numa_scan_period_max, + p->numa_scan_period *2 ); + } +} + +/* +* Got a PROT_NONE fault for a page on @node. +*/ +void task_numa_fault (int node,int pages) +{
kernel/sched/fair.c static void account_numa_dequeue(struct · line 889
Quoted 10 lines
kernel/sched/fair.c +10
-0+struct task_struct *p = current; + +if (unlikely (!p->numa_faults)) { +int size =sizeof (unsigned long ) * nr_node_ids; + + p->numa_faults =kzalloc (size,GFP_KERNEL ); +if (!p->numa_faults) +return ; + } +
On a maximally configured machine this will be an order-4 allocation and you need at least 512 nodes before it's an order-1 allocation. As unlikely as it is, should this be GFP_NOWARN?
Quoted 43 lines
kernel/sched/fair.c +43
-0+task_numa_placement (p); + + p->numa_faults[node] += pages; +} + +/* +* The expensive part of numa migration is done from task_work context. +* Triggered from task_tick_numa(). +*/ +void task_numa_work (struct callback_head *work) +{ +unsigned long migrate, next_scan, now = jiffies; +struct task_struct *p = current; +struct mm_struct *mm = p->mm; + + WARN_ON_ONCE(p != container_of(work, struct task_struct, numa_work)); + + work->next = work;/* protect against double add */ +/* +* Who cares about NUMA placement when they're dying. +* +* NOTE: make sure not to dereference p->mm before this check, +* exit_task_work() happens _after_ exit_mm() so we could be called +* without p->mm even though we still had it when we enqueued this +* work. +*/ +if (p->flags &PF_EXITING ) +return ; + +/* +* Enforce maximal scan/migration frequency.. +*/ + migrate = mm->numa_next_scan; +if (time_before (now, migrate)) +return ; + + next_scan = now +2 *msecs_to_jiffies (sysctl_sched_numa_scan_period_min); +if (cmpxchg (&mm->numa_next_scan, migrate, next_scan) != migrate) +return ; + +ACCESS_ONCE (mm->numa_scan_seq)++; + { +struct vm_area_struct *vma;
kernel/sched/fair.c static void account_numa_dequeue(struct · line 942
Quoted 10 lines
kernel/sched/fair.c +10
-0+ +down_write (&mm->mmap_sem); +for (vma = mm->mmap; vma; vma = vma->vm_next) { +if (!vma_migratable (vma)) +continue ; +change_protection (vma, vma->vm_start, vma->vm_end,vma_prot_none (vma),0 ); + } +up_write (&mm->mmap_sem); + } +}
Ok, I like the idea of the scanning cost being incurred by the process. I was going to complain though that for very large processes that the length time it takes to complete this scan could be considerable. However, a quick glance forward indicates that you cope with this problem later by limiting how much is scanned each time.
Quoted 11 lines
kernel/sched/fair.c +11
-0+ +/* +* Drive the periodic memory faults.. +*/ +void task_tick_numa (struct rq *rq,struct task_struct *curr) +{ +struct callback_head *work = &curr->numa_work; +u64 period, now; + +/* +* We don't care about NUMA placement if we don't have memory.
kernel/sched/fair.c static void account_numa_dequeue(struct · line 963
Quoted 10 lines
kernel/sched/fair.c +10
-0+*/ +if (!curr->mm || (curr->flags &PF_EXITING ) || work->next != work) +return ; + +/* +* Using runtime rather than walltime has the dual advantage that +* we (mostly) drive the selection from busy threads and that the +* task needs to have done some actual work before we bother with +* NUMA placement. +*/
Makes sense.
Quoted 205 lines
kernel/sched/fair.c +19
-0+ now = curr->se.sum_exec_runtime; + period = (u64 )curr->numa_scan_period *NSEC_PER_MSEC ; + +if (now - curr->node_stamp > period) { + curr->node_stamp = now; + +if (!time_before (jiffies, curr->mm->numa_next_scan)) { +init_task_work (work, task_numa_work);/* TODO: move this into sched_fork() */ +task_work_add (curr, work, true); + } + } +}#else #ifdef CONFIG_SMP static struct list_head *account_numa_enqueue (struct rq *rq,struct task_struct *p)@@ -816,6 +984,10 @@ static struct list_head *account_numa_enstatic void account_numa_dequeue (struct rq *rq,struct task_struct *p) { } + +static void task_tick_numa (struct rq *rq,struct task_struct *curr) +{ +}#endif /* CONFIG_SCHED_NUMA */ /************************************************** @@ -5265,6 +5437,9 @@ static void task_tick_fair(struct rq *rq cfs_rq =cfs_rq_of (se);entity_tick (cfs_rq, se, queued); } + +if (sched_feat_numa (NUMA )) +task_tick_numa (rq, curr); }/* Index:
tip/kernel/sched/features.h
===================================================================kernel/sched/features.h +1
-0@@ -69,5 +69,6 @@ SCHED_FEAT(NUMA_TTWU_BIAS, false) SCHED_FEAT(NUMA_TTWU_TO, false) SCHED_FEAT(NUMA_PULL, true) SCHED_FEAT(NUMA_PULL_BIAS, true) +SCHED_FEAT(NUMA_SETTLE, true)#endif Index:
tip/kernel/sched/sched.h
===================================================================kernel/sched/sched.h +22
-9@@ -3,6 +3,7 @@#include <linux/mutex.h> #include <linux/spinlock.h> #include <linux/stop_machine.h> +#include <linux/slab.h> #include "cpupri.h" @@ -476,15 +477,6 @@ struct rq {#endif }; -static inline struct list_head *offnode_tasks (struct rq *rq) -{ -#ifdef CONFIG_SCHED_NUMA -return &rq->offnode_tasks; -#else -return NULL ; -#endif -} -static inline int cpu_of (struct rq *rq) {#ifdef CONFIG_SMP @@ -502,6 +494,27 @@ DECLARE_PER_CPU(struct rq, runqueues);#define cpu_curr (cpu) (cpu_rq(cpu)->curr)#define raw_rq () (&__raw_get_cpu_var(runqueues)) +#ifdef CONFIG_SCHED_NUMA +static inline struct list_head *offnode_tasks (struct rq *rq) +{ +return &rq->offnode_tasks; +} + +static inline void task_numa_free (struct task_struct *p) +{ +kfree (p->numa_faults); +} +#else /* CONFIG_SCHED_NUMA */ +static inline struct list_head *offnode_tasks (struct rq *rq) +{ +return NULL ; +} + +static inline void task_numa_free (struct task_struct *p) +{ +} +#endif /* CONFIG_SCHED_NUMA */ +#ifdef CONFIG_SMP #define rcu_dereference_check_sched_domain (p) \Index:
tip/kernel/sysctl.c
===================================================================kernel/sysctl.c +29
-2@@ -256,9 +256,11 @@ static int min_sched_granularity_ns = 10static int max_sched_granularity_ns =NSEC_PER_SEC ;/* 1 second */ static int min_wakeup_granularity_ns;/* 0 usecs */ static int max_wakeup_granularity_ns =NSEC_PER_SEC ;/* 1 second */ +#ifdef CONFIG_SMP static int min_sched_tunable_scaling =SCHED_TUNABLESCALING_NONE ;static int max_sched_tunable_scaling =SCHED_TUNABLESCALING_END -1 ; -#endif +#endif /* CONFIG_SMP */ +#endif /* CONFIG_SCHED_DEBUG */ #ifdef CONFIG_COMPACTION static int min_extfrag_threshold;@@ -301,6 +303,7 @@ static struct ctl_table kern_table[] = { .extra1 = &min_wakeup_granularity_ns, .extra2 = &max_wakeup_granularity_ns, }, +#ifdef CONFIG_SMP { .procname = "sched_tunable_scaling", .data = &sysctl_sched_tunable_scaling,@@ -347,7 +350,31 @@ static struct ctl_table kern_table[] = { .extra1 = &zero, .extra2 = &one, }, -#endif +#endif /* CONFIG_SMP */ +#ifdef CONFIG_SCHED_NUMA + { + .procname = "sched_numa_scan_period_min_ms", + .data = &sysctl_sched_numa_scan_period_min, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { + .procname = "sched_numa_scan_period_max_ms", + .data = &sysctl_sched_numa_scan_period_max, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { + .procname = "sched_numa_settle_count", + .data = &sysctl_sched_numa_settle_count, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, +#endif /* CONFIG_SCHED_NUMA */ +#endif /* CONFIG_SCHED_DEBUG */ { .procname = "sched_rt_period_us", .data = &sysctl_sched_rt_period,Index:
tip/mm/huge_memory.c
===================================================================mm/huge_memory.c +5
-2@@ -774,9 +774,10 @@ fixup: unlock:spin_unlock (&mm->page_table_lock); -if (page) +if (page) { +task_numa_fault (page_to_nid (page),HPAGE_PMD_NR );put_page (page); - + }return ; migrate:@@ -845,6 +846,8 @@ migrate:put_page (page);/* Drop the rmap reference */ +task_numa_fault (node,HPAGE_PMD_NR ); +if (lru)put_page (page);/* drop the LRU isolation reference */ Index:
tip/mm/memory.c
===================================================================mm/memory.c +3
-1@@ -3512,8 +3512,10 @@ out_pte_upgrade_unlock: out_unlock:pte_unmap_unlock (ptep, ptl); out: -if (page) +if (page) { +task_numa_fault (page_nid,1 );put_page (page); + }return 0 ;
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 27/31 sched, numa, mm: Add credits for NUMA placement
In reply to Peter ZijlstraFrom: Rik van Riel <[email protected]>
The NUMA placement code has been rewritten several times, but the basic ideas took a lot of work to develop. The people who put in the work deserve credit for it. Thanks Andrea & Peter :)
[ The Documentation/scheduler/numa-problem.txt file should
probably be rewritten once we figure out the final details of what the NUMA code needs to do, and why. ]
----
This is against tip.git numa/core
--- CREDITS | 1 + kernel/sched/fair.c | 3 +++ mm/memory.c | 2 ++ 3 files changed, 6 insertions(+)
CREDITS +1 -0
@@ -125,6 +125,7 @@ D: Author of pscan that helps to fix lp/ D: Author of lil (Linux Interrupt Latency benchmark) D: Fixed the shm swap deallocation at swapoff time (try_to_unuse message) D: VM hacker +D: NUMA task placement D: Various other kernel hacks S: Imola 40026 S: Italy
kernel/sched/fair.c +3 -0
@@ -18,6 +18,9 @@* * Adaptive scheduling granularity, math enhancements by Peter Zijlstra * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra <[email protected]> +* +* NUMA placement, statistics and algorithm by Andrea Arcangeli, +* CFS balancing changes by Peter Zijlstra. Copyright (C) 2012 Red Hat, Inc. */ #include <linux/latencytop.h>
mm/memory.c +2 -0
@@ -36,6 +36,8 @@* ([email protected]) * * Aug/Sep 2004 Changed to four level page tables (Andi Kleen) +* +* 2012 - NUMA placement page faults (Andrea Arcangeli, Peter Zijlstra) */ #include <linux/kernel_stat.h>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 28/31 sched, numa, mm: Implement constant, per task Working Set Sampling (WSS) rate
In reply to Peter ZijlstraPreviously, to probe the working set of a task, we'd use a very simple and crude method: mark all of its address space PROT_NONE.
That method has various (obvious) disadvantages:
- it samples the working set at dissimilar rates, giving some tasks a sampling quality advantage over others.
- creates performance problems for tasks with very large working sets
- over-samples processes with large address spaces but which only very rarely execute
Improve that method by keeping a rotating offset into the address space that marks the current position of the scan, and advance it by a constant rate (in a CPU cycles execution proportional manner). If the offset reaches the last mapped address of the mm then it then it starts over at the first address.
The per-task nature of the working set sampling functionality in this tree allows such constant rate, per task, execution-weight proportional sampling of the working set, with an adaptive sampling interval/frequency that goes from once per 100 msecs up to just once per 1.6 seconds. The current sampling volume is 256 MB per interval.
As tasks mature and converge their working set, so does the sampling rate slow down to just a trickle, 256 MB per 1.6 seconds of CPU time executed.
This, beyond being adaptive, also rate-limits rarely executing systems and does not over-sample on overloaded systems.
[ In AutoNUMA speak, this patch deals with the effective sampling
rate of the 'hinting page fault'. AutoNUMA's scanning is currently rate-limited, but it is also fundamentally single-threaded, executing in the knuma_scand kernel thread, so the limit in AutoNUMA is global and does not scale up with the number of CPUs, nor does it scan tasks in an execution proportional manner.
So the idea of rate-limiting the scanning was first implemented in the AutoNUMA tree via a global rate limit. This patch goes beyond that by implementing an execution rate proportional working set sampling rate that is not implemented via a single global scanning daemon. ]
[ Dan Carpenter pointed out a possible NULL pointer dereference in the
first version of this patch. ]
--- include/linux/mm_types.h | 1 + include/linux/sched.h | 1 + kernel/sched/fair.c | 43 ++++++++++++++++++++++++++++++------------- kernel/sysctl.c | 7 +++++++ 4 files changed, 39 insertions(+), 13 deletions(-)
include/linux/mm_types.h +1 -0
@@ -405,6 +405,7 @@ struct mm_struct {#endif #ifdef CONFIG_SCHED_NUMA unsigned long numa_next_scan; +unsigned long numa_scan_offset;int numa_scan_seq;#endif struct uprobes_state uprobes_state;
include/linux/sched.h +1 -0
@@ -2022,6 +2022,7 @@ extern enum sched_tunable_scaling sysctlextern unsigned int sysctl_sched_numa_scan_period_min;extern unsigned int sysctl_sched_numa_scan_period_max; +extern unsigned int sysctl_sched_numa_scan_size;extern unsigned int sysctl_sched_numa_settle_count;#ifdef CONFIG_SCHED_DEBUG
kernel/sched/fair.c +30 -13
62 lines not on this page · raw message
kernel/sysctl.c +7 -0
@@ -367,6 +367,13 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec, }, { + .procname = "sched_numa_scan_size_mb", + .data = &sysctl_sched_numa_scan_size, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { .procname = "sched_numa_settle_count", .data = &sysctl_sched_numa_settle_count, .maxlen = sizeof(unsigned int),
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 28/31] sched, numa, mm: Implement constant, per task Working Set Sampling (WSS) rate
Quoted 132 lines · Peter Zijlstra
Previously, to probe the working set of a task, we'd use a very simple and crude method: mark all of its address space
PROT_NONE.That method has various (obvious) disadvantages:
- it samples the working set at dissimilar rates, giving some tasks a sampling quality advantage over others.
- creates performance problems for tasks with very large working sets
- over-samples processes with large address spaces but which only very rarely execute
Improve that method by keeping a rotating offset into the address space that marks the current position of the scan, and advance it by a constant rate (in a CPU cycles execution proportional manner). If the offset reaches the last mapped address of the mm then it then it starts over at the first address.
The per-task nature of the working set sampling functionality in this tree allows such constant rate, per task, execution-weight proportional sampling of the working set, with an adaptive sampling interval/frequency that goes from once per 100 msecs up to just once per 1.6 seconds. The current sampling volume is 256 MB per interval.
As tasks mature and converge their working set, so does the sampling rate slow down to just a trickle, 256 MB per 1.6 seconds of CPU time executed.
This, beyond being adaptive, also rate-limits rarely executing systems and does not over-sample on overloaded systems.
[ In AutoNUMA speak, this patch deals with the effective sampling
rate of the 'hinting page fault'. AutoNUMA's scanning is currently rate-limited, but it is also fundamentally single-threaded, executing in theknuma_scandkernel thread, so the limit in AutoNUMA is global and does not scale up with the number of CPUs, nor does it scan tasks in an execution proportional manner.So the idea of rate-limiting the scanning was first implemented in the AutoNUMA tree via a global rate limit. This patch goes beyond that by implementing an execution rate proportional working set sampling rate that is not implemented via a single global scanning daemon. ]
[ Dan Carpenter pointed out a possible NULL pointer dereference in the
first version of this patch. ]Based-on-idea-by Andrea Arcangeli <[email protected]>Bug-Found-By Dan Carpenter <[email protected]>Signed-off-by Peter Zijlstra <[email protected]>Cc Linus Torvalds <[email protected]>Cc Andrew Morton <[email protected]>Cc Peter Zijlstra <[email protected]>Cc Andrea Arcangeli <[email protected]>Cc Rik van Riel <[email protected]>[ Wrote changelog and fixed bug. ]Signed-off-by Ingo Molnar <[email protected]>--- include/linux/mm_types.h | 1 + include/linux/sched.h | 1 + kernel/sched/fair.c | 43 ++++++++++++++++++++++++++++++------------- kernel/sysctl.c | 7 +++++++ 4 files changed, 39 insertions(+), 13 deletions(-)Index:
tip/include/linux/mm_types.h
===================================================================include/linux/mm_types.h +1
-0@@ -405,6 +405,7 @@ struct mm_struct {#endif #ifdef CONFIG_SCHED_NUMA unsigned long numa_next_scan; +unsigned long numa_scan_offset;int numa_scan_seq;#endif struct uprobes_state uprobes_state;Index:
tip/include/linux/sched.h
===================================================================include/linux/sched.h +1
-0@@ -2022,6 +2022,7 @@ extern enum sched_tunable_scaling sysctlextern unsigned int sysctl_sched_numa_scan_period_min;extern unsigned int sysctl_sched_numa_scan_period_max; +extern unsigned int sysctl_sched_numa_scan_size;extern unsigned int sysctl_sched_numa_settle_count;#ifdef CONFIG_SCHED_DEBUG Index:
tip/kernel/sched/fair.c
===================================================================kernel/sched/fair.c +6
-8@@ -829,8 +829,9 @@ static void account_numa_dequeue(struct/* * numa task sample period in ms: 5s */ -unsigned int sysctl_sched_numa_scan_period_min =5000 ; -unsigned int sysctl_sched_numa_scan_period_max =5000 *16 ; +unsigned int sysctl_sched_numa_scan_period_min =100 ; +unsigned int sysctl_sched_numa_scan_period_max =100 *16 ; +unsigned int sysctl_sched_numa_scan_size =256 ;/* MB */ /* * Wait for the 2-sample stuff to settle before migrating again @@ -904,6 +905,9 @@ void task_numa_work(struct callback_headunsigned long migrate, next_scan, now = jiffies;struct task_struct *p = current;struct mm_struct *mm = p->mm; +struct vm_area_struct *vma; +unsigned long offset, end; +long length; WARN_ON_ONCE(p != container_of(work, struct task_struct, numa_work));@@ -930,18 +934,31 @@ void task_numa_work(struct callback_headif (cmpxchg (&mm->numa_next_scan, migrate, next_scan) != migrate)return ; -ACCESS_ONCE (mm->numa_scan_seq)++; - { -struct vm_area_struct *vma; - -down_write (&mm->mmap_sem); -for (vma = mm->mmap; vma; vma = vma->vm_next) {
kernel/sched/fair.c void task_numa_work(struct callback_head · line 941
Quoted 10 lines
kernel/sched/fair.c +5
-5-if (!vma_migratable (vma)) -continue ; -change_protection (vma, vma->vm_start, vma->vm_end,vma_prot_none (vma),0 ); - } -up_write (&mm->mmap_sem); + offset = mm->numa_scan_offset; + length = sysctl_sched_numa_scan_size; + length <<=20 ; + +down_write (&mm->mmap_sem);
I should have spotted this during the last patch but we have to take mmap_sem for write?!? Why? Parallel mmap and fault performance is potentially mutilated by this depending on how often this task_numa_work thing is running.
kernel/sched/fair.c void task_numa_work(struct callback_head · line 942
Quoted 1 line
kernel/sched/fair.c +1
-0+ vma =find_vma (mm, offset);
and a find_vma every scan restart. That sucks too.
Cache the vma as well as the offset. Compare vma->mm under mmap_sem held for read and that the offset still matches. Will that avoid the expense of the lookup?
Quoted 27 lines
kernel/sched/fair.c +18
-0+if (!vma) { +ACCESS_ONCE (mm->numa_scan_seq)++; + offset =0 ; + vma = mm->mmap; + } +for (; vma && length >0 ; vma = vma->vm_next) { +if (!vma_migratable (vma)) +continue ; + + offset =max (offset, vma->vm_start); + end =min (ALIGN (offset + length,HPAGE_SIZE ), vma->vm_end); + length -= end - offset; + +change_prot_none (vma, offset, end); + + offset = end; } + mm->numa_scan_offset = offset; +up_write (&mm->mmap_sem); }/* Index:
tip/kernel/sysctl.c
===================================================================
kernel/sysctl.c static struct ctl_table kern_table[] = { · line 376
Quoted 10 lines
kernel/sysctl.c +7
-0@@ -367,6 +367,13 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec, }, { + .procname = "sched_numa_scan_size_mb", + .data = &sysctl_sched_numa_scan_size, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + {
If some muppet writes 0 into this, it effectively disables scanning. I guess who cares, but maybe a minimum value of a a hugepage size would make some sort of sense.
Quoted 5 lines
kernel/sysctl.c +0
-0.procname = "sched_numa_settle_count", .data = &sysctl_sched_numa_settle_count, .maxlen = sizeof(unsigned int),
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 29/31 sched, numa, mm: Add NUMA_MIGRATION feature flag
In reply to Peter ZijlstraFrom: Ingo Molnar <[email protected]>
After this patch, doing:
# echo NO_NUMA_MIGRATION > /sys/kernel/debug/sched_features
Will turn off the NUMA placement logic/policy - but keeps the working set sampling faults in place.
This allows the debugging of the WSS facility, by using it but keeping vanilla, non-NUMA CPU and memory placement policies.
Default enabled. Generates on extra code on !CONFIG_SCHED_DEBUG.
--- kernel/sched/core.c | 3 +++ kernel/sched/features.h | 3 +++ 2 files changed, 6 insertions(+)
kernel/sched/core.c +3 -0
@@ -6002,6 +6002,9 @@ void sched_setnode(struct task_struct *pint on_rq, running;struct rq *rq; +if (!sched_feat (NUMA_MIGRATION )) +return ; + rq =task_rq_lock (p, &flags); on_rq = p->on_rq; running =task_current (rq, p);
kernel/sched/features.h +3 -0
@@ -63,7 +63,10 @@ SCHED_FEAT(RT_RUNTIME_SHARE, true) SCHED_FEAT(LB_MIN, false)#ifdef CONFIG_SCHED_NUMA +/* Do the working set probing faults: */ SCHED_FEAT (NUMA , true) +/* Do actual migration/placement based on the working set information: */ +SCHED_FEAT(NUMA_MIGRATION, true) SCHED_FEAT(NUMA_HOT, true) SCHED_FEAT(NUMA_TTWU_BIAS, false)SCHED_FEAT (NUMA_TTWU_TO , false)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 30/31 sched, numa, mm: Implement slow start for working set sampling
In reply to Peter ZijlstraAdd a 1 second delay before starting to scan the working set of a task and starting to balance it amongst nodes.
[ note that before the constant per task WSS sampling rate patch
the initial scan would happen much later still, in effect that patch caused this regression. ]
The theory is that short-run tasks benefit very little from NUMA
placement: they come and go, and they better stick to the node they were started on. As tasks mature and rebalance to other CPUs and nodes, so does their NUMA placement have to change and so does it start to matter more and more.
In practice this change fixes an observable kbuild regression:
# [ a perf stat --null --repeat 10 test of ten bzImage builds to /dev/shm ]
!NUMA:
45.291088843 seconds time elapsed ( +- 0.40% ) 45.154231752 seconds time elapsed ( +- 0.36% )
+NUMA, no slow start:
46.172308123 seconds time elapsed ( +- 0.30% ) 46.343168745 seconds time elapsed ( +- 0.25% )
+NUMA, 1 sec slow start:
45.224189155 seconds time elapsed ( +- 0.25% ) 45.160866532 seconds time elapsed ( +- 0.17% )
and it also fixes an observable perf bench (hackbench) regression:
# perf stat --null --repeat 10 perf bench sched messaging
-NUMA:
-NUMA: 0.246225691 seconds time elapsed ( +- 1.31% ) +NUMA no slow start: 0.252620063 seconds time elapsed ( +- 1.13% )
+NUMA 1sec delay: 0.248076230 seconds time elapsed ( +- 1.35% )
The implementation is simple and straightforward, most of the patch deals with adding the /proc/sys/kernel/sched_numa_scan_delay_ms tunable knob.
--- include/linux/sched.h | 1 + kernel/sched/core.c | 2 +- kernel/sched/fair.c | 11 +++++++---- kernel/sysctl.c | 7 +++++++ 4 files changed, 16 insertions(+), 5 deletions(-)
include/linux/sched.h +1 -0
@@ -2020,6 +2020,7 @@ enum sched_tunable_scaling { };extern enum sched_tunable_scaling sysctl_sched_tunable_scaling; +extern unsigned int sysctl_sched_numa_scan_delay;extern unsigned int sysctl_sched_numa_scan_period_min;extern unsigned int sysctl_sched_numa_scan_period_max;extern unsigned int sysctl_sched_numa_scan_size;
kernel/sched/core.c +1 -1
@@ -1545,7 +1545,7 @@ static void __sched_fork(struct task_str p->numa_scan_seq = p->mm ? p->mm->numa_scan_seq :0 ; p->numa_migrate_seq = p->mm ? p->mm->numa_scan_seq -1 :0 ; p->numa_faults =NULL ; - p->numa_scan_period = sysctl_sched_numa_scan_period_min; + p->numa_scan_period = sysctl_sched_numa_scan_delay; p->numa_work.next = &p->numa_work;#endif /* CONFIG_SCHED_NUMA */ }
kernel/sched/fair.c +7 -4
@@ -827,11 +827,12 @@ static void account_numa_dequeue(struct }/* -* numa task sample period in ms: 5s +* Scan @scan_size MB every @scan_period after an initial @scan_delay. */ -unsigned int sysctl_sched_numa_scan_period_min =100 ; -unsigned int sysctl_sched_numa_scan_period_max =100 *16 ; -unsigned int sysctl_sched_numa_scan_size =256 ;/* MB */ +unsigned int sysctl_sched_numa_scan_delay =1000 ;/* ms */ +unsigned int sysctl_sched_numa_scan_period_min =100 ;/* ms */ +unsigned int sysctl_sched_numa_scan_period_max =100 *16 ;/* ms */ +unsigned int sysctl_sched_numa_scan_size =256 ;/* MB */ /* * Wait for the 2-sample stuff to settle before migrating again
@@ -985,6 +986,8 @@ void task_tick_numa(struct rq *rq, struc period = (u64 )curr->numa_scan_period *NSEC_PER_MSEC ;if (now - curr->node_stamp > period) { +if (!curr->node_stamp) + curr->numa_scan_period = sysctl_sched_numa_scan_period_min; curr->node_stamp = now;if (!time_before (jiffies, curr->mm->numa_next_scan)) {
kernel/sysctl.c +7 -0
@@ -353,6 +353,13 @@ static struct ctl_table kern_table[] = {#endif /* CONFIG_SMP */ #ifdef CONFIG_SCHED_NUMA { + .procname = "sched_numa_scan_delay_ms", + .data = &sysctl_sched_numa_scan_delay, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { .procname = "sched_numa_scan_period_min_ms", .data = &sysctl_sched_numa_scan_period_min, .maxlen = sizeof(unsigned int),
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Mel Gorman
reviewerRe: [PATCH 30/31] sched, numa, mm: Implement slow start for working set sampling
Quoted 7 lines · Peter Zijlstra
Add a 1 second delay before starting to scan the working set of a task and starting to balance it amongst nodes.
[ note that before the constant per task WSS sampling rate patch
the initial scan would happen much later still, in effect that patch caused this regression. ]
Quoted 6 lines
The theory is that short-run tasks benefit very little from NUMA
placement: they come and go, and they better stick to the node they were started on. As tasks mature and rebalance to other CPUs and nodes, so does their NUMA placement have to change and so does it start to matter more and more.
Yeah, ok. It's done by wall time, right? Should it be CPU time in case it spent the first second asleep?
Signature · 8 lines
Mel Gorman SUSE Labs -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 31/31 sched, numa, mm: Add memcg support to do_huge_pmd_numa_page()
In reply to Peter ZijlstraFrom: Johannes Weiner <[email protected]>
--- mm/huge_memory.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
mm/huge_memory.c +9 -1
@@ -742,6 +742,7 @@ void do_huge_pmd_numa_page(struct mm_str unsigned int flags, pmd_t entry) {unsigned long haddr = address &HPAGE_PMD_MASK ; +struct mem_cgroup *memcg =NULL ;struct page *new_page =NULL ;struct page *page =NULL ;int node, lru;
@@ -800,6 +801,8 @@ migrate:if (!new_page) goto alloc_fail; +mem_cgroup_prepare_migration (page, new_page, &memcg); + lru =PageLRU (page);if (lru &&isolate_lru_page (page))/* does an implicit get_page() */
@@ -852,14 +855,19 @@ migrate:put_page (page);/* drop the LRU isolation reference */ unlock_page (new_page); + +mem_cgroup_end_migration (memcg, page, new_page, true); +unlock_page (page);put_page (page);/* Drop the local reference */ return ; alloc_fail: -if (new_page) +if (new_page) { +mem_cgroup_end_migration (memcg, page, new_page, false);put_page (new_page); + }unlock_page (page);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 18 lines · Peter Zijlstra
Hi all,
Here's a re-post of the NUMA scheduling and migration improvement patches that we are working on. These include techniques from AutoNUMA and the sched/numa tree and form a unified basis - it has got all the bits that look good and mergeable.
With these patches applied, the mbind system calls expand to new modes of lazy-migration binding, and if the
CONFIG_SCHED_NUMA=y.config option is enabled the scheduler will automatically sample the working set of tasks via page faults. Based on that information the scheduler then tries to balance smartly, put tasks on a home node and migrate CPU work and memory on the same node.They are functional in their current state and have had testing on a variety of x86 NUMA hardware.
Quoted 7 lines
These patches will continue their life in tip:numa/core and unless there are major showstoppers they are intended for the v3.8 merge window.
We believe that they provide a solid basis for future work.
Please review .. once again and holler if you see anything funny! :-)
Hi,
I tested the patch set, but there's one issues blocked me:
kernel BUG at mm/memcontrol.c:3263!
--------- snip -----------------
[ 179.804754] kernel BUG at mm/memcontrol.c:3263! [ 179.874356] invalid opcode: 0000 [#1] SMP [ 179.939377] Modules linked in: fuse ip6table_filter ip6_tables ebtable_nat ebtables bnep bluetooth rfkill iptable_mangle nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack be2iscsi iscsi_boot_sysfs bnx2i cnic uio cxgb4i cxgb4 cxgb3i cxgb3 mdio libcxgbi ib_iser rdma_cm ib_addr iw_cm ib_cm ib_sa ib_mad ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi vfat fat iTCO_wdt cdc_ether coretemp iTCO_vendor_support usbnet mii ioatdma lpc_ich crc32c_intel bnx2 shpchp i7core_edac pcspkr tpm_tis tpm i2c_i801 mfd_core tpm_bios edac_core dca serio_raw microcode vhost_net tun macvtap macvlan kvm_intel kvm uinput mgag200 i2c_algo_bit drm_kms_helper ttm drm megaraid_sas i2c_core [ 180.737647] CPU 7 [ 180.759586] Pid: 1316, comm: X Not tainted 3.7.0-rc2+ #3 IBM IBM System x3400 M3 Server -[7379I08]-/69Y4356 [ 180.918591] RIP: 0010:[<ffffffff8118c39a>] [<ffffffff8118c39a>] mem_cgroup_prepare_migration+0xba/0xd0 [ 181.047572] RSP: 0000:ffff880179113d38 EFLAGS: 00013202 [ 181.127009] RAX: 0040100000084069 RBX: ffffea0005b28000 RCX: ffffea00099a805c [ 181.228674] RDX: ffff880179113d90 RSI: ffffea00099a8000 RDI: ffffea0005b28000 [ 181.331080] RBP: ffff880179113d58 R08: 0000000000280000 R09: ffff88027fffff80 [ 181.433163] R10: 00000000000000d4 R11: 00000037e9f7bd90 R12: ffff880179113d90 [ 181.533866] R13: 00007fc5ffa00000 R14: ffff880178001fe8 R15: 000000016ca001e0 [ 181.635264] FS: 00007fc600ddb940(0000) GS:ffff88027fc60000(0000) knlGS:0000000000000000 [ 181.753726] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 181.842013] CR2: 00007fc5ffa00000 CR3: 00000001779d2000 CR4: 00000000000007e0 [ 181.945346] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 182.049416] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 182.153796] Process X (pid: 1316, threadinfo ffff880179112000, task ffff880179364620) [ 182.266464] Stack: [ 182.309943] ffff880177d2c980 00007fc5ffa00000 ffffea0005b28000 ffff880177d2c980 [ 182.418164] ffff880179113dc8 ffffffff81183b60 ffff880177d2c9dc 0000000178001fe0 [ 182.526366] ffff880177856a50 ffffea00099a8000 ffff880177d2cc38 0000000000000000 [ 182.633709] Call Trace: [ 182.681450] [<ffffffff81183b60>] do_huge_pmd_numa_page+0x180/0x500 [ 182.775090] [<ffffffff811585c9>] handle_mm_fault+0x1e9/0x360 [ 182.863038] [<ffffffff81632b62>] __do_page_fault+0x172/0x4e0 [ 182.950574] [<ffffffff8101c283>] ? __switch_to_xtra+0x163/0x1a0 [ 183.041512] [<ffffffff8101281e>] ? __switch_to+0x3ce/0x4a0 [ 183.126832] [<ffffffff8162d686>] ? __schedule+0x3c6/0x7a0 [ 183.211216] [<ffffffff81632ede>] do_page_fault+0xe/0x10 [ 183.293705] [<ffffffff8162f518>] page_fault+0x28/0x30 [ 183.373909] Code: 00 48 8b 78 08 48 8b 57 10 83 e2 01 75 05 f0 83 47 08 01 f6 43 08 01 74 bb f0 80 08 04 eb b5 f3 90 48 8b 10 80 e2 01 75 f6 eb 94 <0f> 0b 0f 1f 40 00 e8 9c b4 49 00 66 66 2e 0f 1f 84 00 00 00 00 [ 183.651946] RIP [<ffffffff8118c39a>] mem_cgroup_prepare_migration+0xba/0xd0 [ 183.760378] RSP <ffff880179113d38>
===========================================================================
my system has two numa nodes.
There are two methods can reproduce the bug on my machine.
1. start X server:
# startx it's 100% to reproduce it, and which can crash the system.
2. Compiling kernel source using multi-threads:
# make -j N this action can produce such similar above Call Trace, but it *didn't* crash the system
The whole dmesg log and config file are attached.
Also I have tested the mainline kernel un-patched sched/numa patch set, there's no such issues.
please let me know if you need more info.
Thanks,
Zhouping
Quoted 7 lines
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86_64 3.7.0-rc2 Kernel Configuration
#CONFIG_64BIT=yCONFIG_X86_64=yCONFIG_X86=yCONFIG_INSTRUCTION_DECODER=yCONFIG_OUTPUT_FORMAT="elf64-x86-64"CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"CONFIG_LOCKDEP_SUPPORT=yCONFIG_STACKTRACE_SUPPORT=yCONFIG_HAVE_LATENCYTOP_SUPPORT=yCONFIG_MMU=yCONFIG_NEED_DMA_MAP_STATE=yCONFIG_NEED_SG_DMA_LENGTH=yCONFIG_GENERIC_ISA_DMA=yCONFIG_GENERIC_BUG=yCONFIG_GENERIC_BUG_RELATIVE_POINTERS=yCONFIG_GENERIC_HWEIGHT=yCONFIG_ARCH_MAY_HAVE_PC_FDC=yCONFIG_RWSEM_XCHGADD_ALGORITHM=yCONFIG_GENERIC_CALIBRATE_DELAY=yCONFIG_ARCH_HAS_CPU_RELAX=yCONFIG_ARCH_HAS_DEFAULT_IDLE=yCONFIG_ARCH_HAS_CACHE_LINE_SIZE=yCONFIG_ARCH_HAS_CPU_AUTOPROBE=yCONFIG_HAVE_SETUP_PER_CPU_AREA=yCONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=yCONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=yCONFIG_ARCH_HIBERNATION_POSSIBLE=yCONFIG_ARCH_SUSPEND_POSSIBLE=yCONFIG_ZONE_DMA32=yCONFIG_AUDIT_ARCH=yCONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=yCONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=yCONFIG_HAVE_INTEL_TXT=yCONFIG_X86_64_SMP=yCONFIG_X86_HT=yCONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" CONFIG_ARCH_CPU_PROBE_RELEASE=yCONFIG_ARCH_SUPPORTS_UPROBES=yCONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"CONFIG_HAVE_IRQ_WORK=yCONFIG_IRQ_WORK=yCONFIG_BUILDTIME_EXTABLE_SORT=y
#
# General setup
#CONFIG_EXPERIMENTAL=yCONFIG_INIT_ENV_ARG_LIMIT=32CONFIG_CROSS_COMPILE=""CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not setCONFIG_HAVE_KERNEL_GZIP=yCONFIG_HAVE_KERNEL_BZIP2=yCONFIG_HAVE_KERNEL_LZMA=yCONFIG_HAVE_KERNEL_XZ=yCONFIG_HAVE_KERNEL_LZO=yCONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not setCONFIG_DEFAULT_HOSTNAME="(none)"CONFIG_SWAP=yCONFIG_SYSVIPC=yCONFIG_SYSVIPC_SYSCTL=yCONFIG_POSIX_MQUEUE=yCONFIG_POSIX_MQUEUE_SYSCTL=yCONFIG_FHANDLE=yCONFIG_AUDIT=yCONFIG_AUDITSYSCALL=yCONFIG_AUDIT_WATCH=yCONFIG_AUDIT_TREE=y
# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not setCONFIG_HAVE_GENERIC_HARDIRQS=y
#
# IRQ subsystem
#CONFIG_GENERIC_HARDIRQS=yCONFIG_GENERIC_IRQ_PROBE=yCONFIG_GENERIC_IRQ_SHOW=yCONFIG_GENERIC_PENDING_IRQ=yCONFIG_IRQ_DOMAIN=y
# CONFIG_IRQ_DOMAIN_DEBUG is not setCONFIG_IRQ_FORCED_THREADING=yCONFIG_SPARSE_IRQ=yCONFIG_CLOCKSOURCE_WATCHDOG=yCONFIG_ARCH_CLOCKSOURCE_DATA=yCONFIG_GENERIC_TIME_VSYSCALL=yCONFIG_GENERIC_CLOCKEVENTS=yCONFIG_GENERIC_CLOCKEVENTS_BUILD=yCONFIG_GENERIC_CLOCKEVENTS_BROADCAST=yCONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=yCONFIG_GENERIC_CMOS_UPDATE=y
#
# Timers subsystem
#CONFIG_TICK_ONESHOT=yCONFIG_NO_HZ=yCONFIG_HIGH_RES_TIMERS=y
#
# CPU/Task time and stats accounting
#
# CONFIG_TICK_CPU_ACCOUNTING is not setCONFIG_IRQ_TIME_ACCOUNTING=yCONFIG_BSD_PROCESS_ACCT=yCONFIG_BSD_PROCESS_ACCT_V3=yCONFIG_TASKSTATS=yCONFIG_TASK_DELAY_ACCT=yCONFIG_TASK_XACCT=yCONFIG_TASK_IO_ACCOUNTING=y
#
# RCU Subsystem
#CONFIG_TREE_RCU=y
# CONFIG_PREEMPT_RCU is not set
# CONFIG_RCU_USER_QS is not setCONFIG_RCU_FANOUT=64CONFIG_RCU_FANOUT_LEAF=16
# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_RCU_FAST_NO_HZ is not set
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not setCONFIG_LOG_BUF_SHIFT=18CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=yCONFIG_SCHED_NUMA=yCONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not setCONFIG_CGROUP_FREEZER=yCONFIG_CGROUP_DEVICE=yCONFIG_CPUSETS=yCONFIG_PROC_PID_CPUSET=yCONFIG_CGROUP_CPUACCT=yCONFIG_RESOURCE_COUNTERS=yCONFIG_MEMCG=yCONFIG_MEMCG_SWAP=y
# CONFIG_MEMCG_SWAP_ENABLED is not setCONFIG_MEMCG_KMEM=y
# CONFIG_CGROUP_HUGETLB is not setCONFIG_CGROUP_PERF=yCONFIG_CGROUP_SCHED=yCONFIG_FAIR_GROUP_SCHED=yCONFIG_CFS_BANDWIDTH=yCONFIG_RT_GROUP_SCHED=yCONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
# CONFIG_CHECKPOINT_RESTORE is not setCONFIG_NAMESPACES=yCONFIG_UTS_NS=yCONFIG_IPC_NS=yCONFIG_PID_NS=yCONFIG_NET_NS=yCONFIG_SCHED_AUTOGROUP=yCONFIG_MM_OWNER=y
# CONFIG_SYSFS_DEPRECATED is not setCONFIG_RELAY=yCONFIG_BLK_DEV_INITRD=yCONFIG_INITRAMFS_SOURCE=""CONFIG_RD_GZIP=yCONFIG_RD_BZIP2=yCONFIG_RD_LZMA=yCONFIG_RD_XZ=yCONFIG_RD_LZO=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not setCONFIG_SYSCTL=yCONFIG_ANON_INODES=y
# CONFIG_EXPERT is not setCONFIG_HAVE_UID16=yCONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not setCONFIG_SYSCTL_EXCEPTION_TRACE=yCONFIG_KALLSYMS=yCONFIG_KALLSYMS_ALL=yCONFIG_HOTPLUG=yCONFIG_PRINTK=yCONFIG_BUG=yCONFIG_ELF_CORE=yCONFIG_PCSPKR_PLATFORM=yCONFIG_HAVE_PCSPKR_PLATFORM=yCONFIG_BASE_FULL=yCONFIG_FUTEX=yCONFIG_EPOLL=yCONFIG_SIGNALFD=yCONFIG_TIMERFD=yCONFIG_EVENTFD=yCONFIG_SHMEM=yCONFIG_AIO=y
# CONFIG_EMBEDDED is not setCONFIG_HAVE_PERF_EVENTS=y
#
# Kernel Performance Events And Counters
#CONFIG_PERF_EVENTS=y
# CONFIG_DEBUG_PERF_USE_VMALLOC is not setCONFIG_VM_EVENT_COUNTERS=yCONFIG_PCI_QUIRKS=yCONFIG_SLUB_DEBUG=y
# CONFIG_COMPAT_BRK is not set
# CONFIG_SLAB is not setCONFIG_SLUB=yCONFIG_PROFILING=yCONFIG_TRACEPOINTS=yCONFIG_OPROFILE=mCONFIG_OPROFILE_EVENT_MULTIPLEX=yCONFIG_HAVE_OPROFILE=yCONFIG_OPROFILE_NMI_TIMER=yCONFIG_KPROBES=yCONFIG_JUMP_LABEL=yCONFIG_OPTPROBES=yCONFIG_UPROBES=yCONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=yCONFIG_KRETPROBES=yCONFIG_USER_RETURN_NOTIFIER=yCONFIG_HAVE_IOREMAP_PROT=yCONFIG_HAVE_KPROBES=yCONFIG_HAVE_KRETPROBES=yCONFIG_HAVE_OPTPROBES=yCONFIG_HAVE_ARCH_TRACEHOOK=yCONFIG_HAVE_DMA_ATTRS=yCONFIG_USE_GENERIC_SMP_HELPERS=yCONFIG_GENERIC_SMP_IDLE_THREAD=yCONFIG_HAVE_REGS_AND_STACK_ACCESS_API=yCONFIG_HAVE_DMA_API_DEBUG=yCONFIG_HAVE_HW_BREAKPOINT=yCONFIG_HAVE_MIXED_BREAKPOINTS_REGS=yCONFIG_HAVE_USER_RETURN_NOTIFIER=yCONFIG_HAVE_PERF_EVENTS_NMI=yCONFIG_HAVE_PERF_REGS=yCONFIG_HAVE_PERF_USER_STACK_DUMP=yCONFIG_HAVE_ARCH_JUMP_LABEL=yCONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=yCONFIG_HAVE_ALIGNED_STRUCT_PAGE=yCONFIG_HAVE_CMPXCHG_LOCAL=yCONFIG_HAVE_CMPXCHG_DOUBLE=yCONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=yCONFIG_ARCH_WANT_OLD_COMPAT_IPC=yCONFIG_GENERIC_KERNEL_THREAD=yCONFIG_GENERIC_KERNEL_EXECVE=yCONFIG_HAVE_ARCH_SECCOMP_FILTER=yCONFIG_SECCOMP_FILTER=yCONFIG_HAVE_RCU_USER_QS=yCONFIG_HAVE_IRQ_TIME_ACCOUNTING=yCONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=yCONFIG_MODULES_USE_ELF_RELA=y
#
# GCOV-based kernel profiling
#
# CONFIG_GCOV_KERNEL is not set
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not setCONFIG_SLABINFO=yCONFIG_RT_MUTEXES=yCONFIG_BASE_SMALL=0CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not setCONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not setCONFIG_MODULE_SIG=y
# CONFIG_MODULE_SIG_FORCE is not set
# CONFIG_MODULE_SIG_SHA1 is not set
# CONFIG_MODULE_SIG_SHA224 is not setCONFIG_MODULE_SIG_SHA256=y
# CONFIG_MODULE_SIG_SHA384 is not set
# CONFIG_MODULE_SIG_SHA512 is not setCONFIG_STOP_MACHINE=yCONFIG_BLOCK=yCONFIG_BLK_DEV_BSG=yCONFIG_BLK_DEV_BSGLIB=yCONFIG_BLK_DEV_INTEGRITY=yCONFIG_BLK_DEV_THROTTLING=y
#
# Partition Types
#CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not setCONFIG_OSF_PARTITION=yCONFIG_AMIGA_PARTITION=y
# CONFIG_ATARI_PARTITION is not setCONFIG_MAC_PARTITION=yCONFIG_MSDOS_PARTITION=yCONFIG_BSD_DISKLABEL=yCONFIG_MINIX_SUBPARTITION=yCONFIG_SOLARIS_X86_PARTITION=yCONFIG_UNIXWARE_DISKLABEL=y
# CONFIG_LDM_PARTITION is not setCONFIG_SGI_PARTITION=y
# CONFIG_ULTRIX_PARTITION is not setCONFIG_SUN_PARTITION=yCONFIG_KARMA_PARTITION=yCONFIG_EFI_PARTITION=y
# CONFIG_SYSV68_PARTITION is not setCONFIG_BLOCK_COMPAT=y
#
# IO Schedulers
#CONFIG_IOSCHED_NOOP=yCONFIG_IOSCHED_DEADLINE=yCONFIG_IOSCHED_CFQ=yCONFIG_CFQ_GROUP_IOSCHED=y
# CONFIG_DEFAULT_DEADLINE is not setCONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not setCONFIG_DEFAULT_IOSCHED="cfq"CONFIG_PREEMPT_NOTIFIERS=yCONFIG_PADATA=yCONFIG_ASN1=yCONFIG_INLINE_SPIN_UNLOCK_IRQ=yCONFIG_INLINE_READ_UNLOCK=yCONFIG_INLINE_READ_UNLOCK_IRQ=yCONFIG_INLINE_WRITE_UNLOCK=yCONFIG_INLINE_WRITE_UNLOCK_IRQ=yCONFIG_MUTEX_SPIN_ON_OWNER=yCONFIG_FREEZER=y
#
# Processor type and features
#CONFIG_ZONE_DMA=yCONFIG_SMP=yCONFIG_X86_X2APIC=yCONFIG_X86_MPPARSE=y CONFIG_X86_EXTENDED_PLATFORM=y
# CONFIG_X86_NUMACHIP is not set
# CONFIG_X86_VSMP is not set
# CONFIG_X86_UV is not set CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_PARAVIRT_GUEST=y CONFIG_PARAVIRT_TIME_ACCOUNTING=yCONFIG_XEN=yCONFIG_XEN_DOM0=yCONFIG_XEN_PRIVILEGED_GUEST=yCONFIG_XEN_PVHVM=y CONFIG_XEN_MAX_DOMAIN_MEMORY=500 CONFIG_XEN_SAVE_RESTORE=yCONFIG_XEN_DEBUG_FS=yCONFIG_KVM_GUEST=yCONFIG_PARAVIRT=y
# CONFIG_PARAVIRT_SPINLOCKS is not set CONFIG_PARAVIRT_CLOCK=y
# CONFIG_PARAVIRT_DEBUG is not set CONFIG_NO_BOOTMEM=y
# CONFIG_MEMTEST is not set
# CONFIG_MK8 is not set
# CONFIG_MPSC is not set
# CONFIG_MCORE2 is not set
# CONFIG_MATOM is not setCONFIG_GENERIC_CPU=y CONFIG_X86_INTERNODE_CACHE_SHIFT=6 CONFIG_X86_CMPXCHG=yCONFIG_X86_L1_CACHE_SHIFT=6CONFIG_X86_XADD=yCONFIG_X86_WP_WORKS_OK=yCONFIG_X86_TSC=yCONFIG_X86_CMPXCHG64=yCONFIG_X86_CMOV=y CONFIG_X86_MINIMUM_CPU_FAMILY=64 CONFIG_X86_DEBUGCTLMSR=yCONFIG_CPU_SUP_INTEL=yCONFIG_CPU_SUP_AMD=yCONFIG_CPU_SUP_CENTAUR=yCONFIG_HPET_TIMER=yCONFIG_HPET_EMULATE_RTC=yCONFIG_DMI=yCONFIG_GART_IOMMU=y
# CONFIG_CALGARY_IOMMU is not set CONFIG_SWIOTLB=yCONFIG_IOMMU_HELPER=y
# CONFIG_MAXSMP is not setCONFIG_NR_CPUS=128CONFIG_SCHED_SMT=yCONFIG_SCHED_MC=y
# CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=yCONFIG_X86_IO_APIC=y CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y CONFIG_X86_MCE=yCONFIG_X86_MCE_INTEL=yCONFIG_X86_MCE_AMD=yCONFIG_X86_MCE_THRESHOLD=y
# CONFIG_X86_MCE_INJECT is not set CONFIG_X86_THERMAL_VECTOR=yCONFIG_I8K=mCONFIG_MICROCODE=mCONFIG_MICROCODE_INTEL=yCONFIG_MICROCODE_AMD=y CONFIG_MICROCODE_OLD_INTERFACE=y CONFIG_X86_MSR=yCONFIG_X86_CPUID=y CONFIG_ARCH_PHYS_ADDR_T_64BIT=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_DIRECT_GBPAGES=yCONFIG_NUMA=yCONFIG_AMD_NUMA=yCONFIG_X86_64_ACPI_NUMA=y CONFIG_NODES_SPAN_OTHER_NODES=y
# CONFIG_NUMA_EMU is not set CONFIG_NODES_SHIFT=9 CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_PROC_KCORE_TEXT=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_SELECT_MEMORY_MODEL=y CONFIG_SPARSEMEM_MANUAL=yCONFIG_SPARSEMEM=yCONFIG_NEED_MULTIPLE_NODES=y CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_HAVE_MEMBLOCK=y CONFIG_HAVE_MEMBLOCK_NODE_MAP=y CONFIG_ARCH_DISCARD_MEMBLOCK=y CONFIG_MEMORY_ISOLATION=y
# CONFIG_MEMORY_HOTPLUG is not set CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4CONFIG_COMPACTION=yCONFIG_MIGRATION=yCONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=1CONFIG_BOUNCE=yCONFIG_VIRT_TO_BUS=yCONFIG_MMU_NOTIFIER=yCONFIG_KSM=yCONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y CONFIG_MEMORY_FAILURE=yCONFIG_HWPOISON_INJECT=m CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set CONFIG_CROSS_MEMORY_ATTACH=yCONFIG_CLEANCACHE=yCONFIG_FRONTSWAP=y CONFIG_X86_CHECK_BIOS_CORRUPTION=y
# CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK is not set CONFIG_X86_RESERVE_LOW=64CONFIG_MTRR=yCONFIG_MTRR_SANITIZER=y CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=1 CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 CONFIG_X86_PAT=yCONFIG_ARCH_USES_PG_UNCACHED=y CONFIG_ARCH_RANDOM=yCONFIG_X86_SMAP=yCONFIG_EFI=yCONFIG_EFI_STUB=yCONFIG_SECCOMP=yCONFIG_CC_STACKPROTECTOR=y
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not setCONFIG_HZ_1000=yCONFIG_HZ=1000CONFIG_SCHED_HRTICK=yCONFIG_KEXEC=yCONFIG_CRASH_DUMP=yCONFIG_KEXEC_JUMP=y CONFIG_PHYSICAL_START=0x1000000 CONFIG_RELOCATABLE=y CONFIG_PHYSICAL_ALIGN=0x1000000 CONFIG_HOTPLUG_CPU=y
# CONFIG_COMPAT_VDSO is not set
# CONFIG_CMDLINE_BOOL is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_USE_PERCPU_NUMA_NODE_ID=y
#
# Power management and ACPI options
#CONFIG_ARCH_HIBERNATION_HEADER=yCONFIG_SUSPEND=yCONFIG_SUSPEND_FREEZER=yCONFIG_HIBERNATE_CALLBACKS=yCONFIG_HIBERNATION=yCONFIG_PM_STD_PARTITION=""CONFIG_PM_SLEEP=yCONFIG_PM_SLEEP_SMP=y
# CONFIG_PM_AUTOSLEEP is not set
# CONFIG_PM_WAKELOCKS is not setCONFIG_PM_RUNTIME=yCONFIG_PM=yCONFIG_PM_DEBUG=yCONFIG_PM_ADVANCED_DEBUG=y
# CONFIG_PM_TEST_SUSPEND is not setCONFIG_PM_SLEEP_DEBUG=yCONFIG_PM_TRACE=yCONFIG_PM_TRACE_RTC=yCONFIG_ACPI=yCONFIG_ACPI_SLEEP=yCONFIG_ACPI_PROCFS=y
# CONFIG_ACPI_PROCFS_POWER is not setCONFIG_ACPI_EC_DEBUGFS=m
# CONFIG_ACPI_PROC_EVENT is not setCONFIG_ACPI_AC=yCONFIG_ACPI_BATTERY=yCONFIG_ACPI_BUTTON=yCONFIG_ACPI_VIDEO=mCONFIG_ACPI_FAN=yCONFIG_ACPI_DOCK=yCONFIG_ACPI_PROCESSOR=yCONFIG_ACPI_IPMI=mCONFIG_ACPI_HOTPLUG_CPU=yCONFIG_ACPI_PROCESSOR_AGGREGATOR=mCONFIG_ACPI_THERMAL=yCONFIG_ACPI_NUMA=y
# CONFIG_ACPI_CUSTOM_DSDT is not setCONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not setCONFIG_ACPI_PCI_SLOT=yCONFIG_X86_PM_TIMER=yCONFIG_ACPI_CONTAINER=yCONFIG_ACPI_SBS=mCONFIG_ACPI_HED=yCONFIG_ACPI_CUSTOM_METHOD=m
# CONFIG_ACPI_BGRT is not setCONFIG_ACPI_APEI=yCONFIG_ACPI_APEI_GHES=yCONFIG_ACPI_APEI_PCIEAER=yCONFIG_ACPI_APEI_MEMORY_FAILURE=y
# CONFIG_ACPI_APEI_EINJ is not set
# CONFIG_ACPI_APEI_ERST_DEBUG is not setCONFIG_SFI=y
#
# CPU Frequency scaling
#CONFIG_CPU_FREQ=yCONFIG_CPU_FREQ_TABLE=y CONFIG_CPU_FREQ_STAT=m CONFIG_CPU_FREQ_STAT_DETAILS=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
#
# x86 CPU frequency scaling drivers # CONFIG_X86_PCC_CPUFREQ=y CONFIG_X86_ACPI_CPUFREQ=y CONFIG_X86_ACPI_CPUFREQ_CPB=y CONFIG_X86_POWERNOW_K8=y # CONFIG_X86_SPEEDSTEP_CENTRINO is not set CONFIG_X86_P4_CLOCKMOD=y
#
# shared options # CONFIG_X86_SPEEDSTEP_LIB=y CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y # CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set CONFIG_INTEL_IDLE=y
#
# Memory power savings
#CONFIG_I7300_IDLE_IOAT_CHANNEL=yCONFIG_I7300_IDLE=m
#
# Bus options (PCI etc.)
#CONFIG_PCI=yCONFIG_PCI_DIRECT=yCONFIG_PCI_MMCONFIG=yCONFIG_PCI_XEN=yCONFIG_PCI_DOMAINS=yCONFIG_PCIEPORTBUS=yCONFIG_HOTPLUG_PCI_PCIE=yCONFIG_PCIEAER=yCONFIG_PCIE_ECRC=yCONFIG_PCIEAER_INJECT=mCONFIG_PCIEASPM=y
# CONFIG_PCIEASPM_DEBUG is not setCONFIG_PCIEASPM_DEFAULT=y
# CONFIG_PCIEASPM_POWERSAVE is not set
# CONFIG_PCIEASPM_PERFORMANCE is not setCONFIG_PCIE_PME=yCONFIG_ARCH_SUPPORTS_MSI=yCONFIG_PCI_MSI=y
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_REALLOC_ENABLE_AUTO is not setCONFIG_PCI_STUB=yCONFIG_XEN_PCIDEV_FRONTEND=mCONFIG_HT_IRQ=yCONFIG_PCI_ATS=yCONFIG_PCI_IOV=yCONFIG_PCI_PRI=yCONFIG_PCI_PASID=yCONFIG_PCI_IOAPIC=yCONFIG_PCI_LABEL=yCONFIG_ISA_DMA_API=yCONFIG_AMD_NB=yCONFIG_PCCARD=yCONFIG_PCMCIA=yCONFIG_PCMCIA_LOAD_CIS=yCONFIG_CARDBUS=y
#
# PC-card bridges
#CONFIG_YENTA=mCONFIG_YENTA_O2=yCONFIG_YENTA_RICOH=yCONFIG_YENTA_TI=yCONFIG_YENTA_ENE_TUNE=yCONFIG_YENTA_TOSHIBA=yCONFIG_PD6729=mCONFIG_I82092=mCONFIG_PCCARD_NONSTATIC=yCONFIG_HOTPLUG_PCI=yCONFIG_HOTPLUG_PCI_ACPI=yCONFIG_HOTPLUG_PCI_ACPI_IBM=m
# CONFIG_HOTPLUG_PCI_CPCI is not setCONFIG_HOTPLUG_PCI_SHPC=m
# CONFIG_RAPIDIO is not set
#
# Executable file formats / Emulations
#CONFIG_BINFMT_ELF=yCONFIG_COMPAT_BINFMT_ELF=yCONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=yCONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
# CONFIG_HAVE_AOUT is not setCONFIG_BINFMT_MISC=mCONFIG_COREDUMP=yCONFIG_IA32_EMULATION=y
# CONFIG_IA32_AOUT is not set
# CONFIG_X86_X32 is not setCONFIG_COMPAT=yCONFIG_COMPAT_FOR_U64_ALIGNMENT=yCONFIG_SYSVIPC_COMPAT=yCONFIG_KEYS_COMPAT=yCONFIG_HAVE_TEXT_POKE_SMP=yCONFIG_X86_DEV_DMA_OPS=yCONFIG_NET=yCONFIG_COMPAT_NETLINK_MESSAGES=y
#
# Networking options
#CONFIG_PACKET=y
# CONFIG_PACKET_DIAG is not setCONFIG_UNIX=yCONFIG_UNIX_DIAG=mCONFIG_XFRM=yCONFIG_XFRM_ALGO=yCONFIG_XFRM_USER=yCONFIG_XFRM_SUB_POLICY=yCONFIG_XFRM_MIGRATE=yCONFIG_XFRM_STATISTICS=yCONFIG_XFRM_IPCOMP=mCONFIG_NET_KEY=mCONFIG_NET_KEY_MIGRATE=yCONFIG_INET=yCONFIG_IP_MULTICAST=yCONFIG_IP_ADVANCED_ROUTER=yCONFIG_IP_FIB_TRIE_STATS=yCONFIG_IP_MULTIPLE_TABLES=yCONFIG_IP_ROUTE_MULTIPATH=yCONFIG_IP_ROUTE_VERBOSE=yCONFIG_IP_ROUTE_CLASSID=y
# CONFIG_IP_PNP is not setCONFIG_NET_IPIP=mCONFIG_NET_IPGRE_DEMUX=mCONFIG_NET_IPGRE=mCONFIG_NET_IPGRE_BROADCAST=yCONFIG_IP_MROUTE=yCONFIG_IP_MROUTE_MULTIPLE_TABLES=yCONFIG_IP_PIMSM_V1=yCONFIG_IP_PIMSM_V2=yCONFIG_ARPD=yCONFIG_SYN_COOKIES=yCONFIG_NET_IPVTI=mCONFIG_INET_AH=mCONFIG_INET_ESP=mCONFIG_INET_IPCOMP=mCONFIG_INET_XFRM_TUNNEL=mCONFIG_INET_TUNNEL=mCONFIG_INET_XFRM_MODE_TRANSPORT=mCONFIG_INET_XFRM_MODE_TUNNEL=mCONFIG_INET_XFRM_MODE_BEET=mCONFIG_INET_LRO=yCONFIG_INET_DIAG=mCONFIG_INET_TCP_DIAG=mCONFIG_INET_UDP_DIAG=mCONFIG_TCP_CONG_ADVANCED=yCONFIG_TCP_CONG_BIC=mCONFIG_TCP_CONG_CUBIC=yCONFIG_TCP_CONG_WESTWOOD=mCONFIG_TCP_CONG_HTCP=mCONFIG_TCP_CONG_HSTCP=mCONFIG_TCP_CONG_HYBLA=mCONFIG_TCP_CONG_VEGAS=mCONFIG_TCP_CONG_SCALABLE=mCONFIG_TCP_CONG_LP=mCONFIG_TCP_CONG_VENO=mCONFIG_TCP_CONG_YEAH=mCONFIG_TCP_CONG_ILLINOIS=mCONFIG_DEFAULT_CUBIC=y
# CONFIG_DEFAULT_RENO is not setCONFIG_DEFAULT_TCP_CONG="cubic"CONFIG_TCP_MD5SIG=yCONFIG_IPV6=yCONFIG_IPV6_PRIVACY=yCONFIG_IPV6_ROUTER_PREF=yCONFIG_IPV6_ROUTE_INFO=yCONFIG_IPV6_OPTIMISTIC_DAD=yCONFIG_INET6_AH=mCONFIG_INET6_ESP=mCONFIG_INET6_IPCOMP=mCONFIG_IPV6_MIP6=yCONFIG_INET6_XFRM_TUNNEL=mCONFIG_INET6_TUNNEL=mCONFIG_INET6_XFRM_MODE_TRANSPORT=mCONFIG_INET6_XFRM_MODE_TUNNEL=mCONFIG_INET6_XFRM_MODE_BEET=mCONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=mCONFIG_IPV6_SIT=mCONFIG_IPV6_SIT_6RD=yCONFIG_IPV6_NDISC_NODETYPE=yCONFIG_IPV6_TUNNEL=m
# CONFIG_IPV6_GRE is not setCONFIG_IPV6_MULTIPLE_TABLES=yCONFIG_IPV6_SUBTREES=yCONFIG_IPV6_MROUTE=yCONFIG_IPV6_MROUTE_MULTIPLE_TABLES=yCONFIG_IPV6_PIMSM_V2=yCONFIG_NETLABEL=yCONFIG_NETWORK_SECMARK=yCONFIG_NETWORK_PHY_TIMESTAMPING=yCONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not setCONFIG_NETFILTER_ADVANCED=yCONFIG_BRIDGE_NETFILTER=y
#
# Core Netfilter Configuration
#CONFIG_NETFILTER_NETLINK=mCONFIG_NETFILTER_NETLINK_ACCT=mCONFIG_NETFILTER_NETLINK_QUEUE=mCONFIG_NETFILTER_NETLINK_LOG=mCONFIG_NF_CONNTRACK=mCONFIG_NF_CONNTRACK_MARK=yCONFIG_NF_CONNTRACK_SECMARK=yCONFIG_NF_CONNTRACK_ZONES=yCONFIG_NF_CONNTRACK_PROCFS=yCONFIG_NF_CONNTRACK_EVENTS=y
# CONFIG_NF_CONNTRACK_TIMEOUT is not setCONFIG_NF_CONNTRACK_TIMESTAMP=yCONFIG_NF_CT_PROTO_DCCP=mCONFIG_NF_CT_PROTO_GRE=mCONFIG_NF_CT_PROTO_SCTP=mCONFIG_NF_CT_PROTO_UDPLITE=mCONFIG_NF_CONNTRACK_AMANDA=mCONFIG_NF_CONNTRACK_FTP=mCONFIG_NF_CONNTRACK_H323=mCONFIG_NF_CONNTRACK_IRC=mCONFIG_NF_CONNTRACK_BROADCAST=mCONFIG_NF_CONNTRACK_NETBIOS_NS=mCONFIG_NF_CONNTRACK_SNMP=mCONFIG_NF_CONNTRACK_PPTP=mCONFIG_NF_CONNTRACK_SANE=mCONFIG_NF_CONNTRACK_SIP=mCONFIG_NF_CONNTRACK_TFTP=mCONFIG_NF_CT_NETLINK=m
# CONFIG_NF_CT_NETLINK_TIMEOUT is not setCONFIG_NF_CT_NETLINK_HELPER=mCONFIG_NETFILTER_NETLINK_QUEUE_CT=yCONFIG_NETFILTER_TPROXY=mCONFIG_NETFILTER_XTABLES=y
#
# Xtables combined modules
#CONFIG_NETFILTER_XT_MARK=mCONFIG_NETFILTER_XT_CONNMARK=mCONFIG_NETFILTER_XT_SET=m
#
# Xtables targets
#CONFIG_NETFILTER_XT_TARGET_AUDIT=mCONFIG_NETFILTER_XT_TARGET_CHECKSUM=mCONFIG_NETFILTER_XT_TARGET_CLASSIFY=mCONFIG_NETFILTER_XT_TARGET_CONNMARK=mCONFIG_NETFILTER_XT_TARGET_CONNSECMARK=mCONFIG_NETFILTER_XT_TARGET_CT=mCONFIG_NETFILTER_XT_TARGET_DSCP=mCONFIG_NETFILTER_XT_TARGET_HL=mCONFIG_NETFILTER_XT_TARGET_HMARK=mCONFIG_NETFILTER_XT_TARGET_IDLETIMER=mCONFIG_NETFILTER_XT_TARGET_LED=mCONFIG_NETFILTER_XT_TARGET_LOG=mCONFIG_NETFILTER_XT_TARGET_MARK=mCONFIG_NETFILTER_XT_TARGET_NFLOG=mCONFIG_NETFILTER_XT_TARGET_NFQUEUE=mCONFIG_NETFILTER_XT_TARGET_RATEEST=mCONFIG_NETFILTER_XT_TARGET_TEE=mCONFIG_NETFILTER_XT_TARGET_TPROXY=mCONFIG_NETFILTER_XT_TARGET_TRACE=mCONFIG_NETFILTER_XT_TARGET_SECMARK=mCONFIG_NETFILTER_XT_TARGET_TCPMSS=mCONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
#
# Xtables matches
#CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=mCONFIG_NETFILTER_XT_MATCH_CLUSTER=mCONFIG_NETFILTER_XT_MATCH_COMMENT=mCONFIG_NETFILTER_XT_MATCH_CONNBYTES=mCONFIG_NETFILTER_XT_MATCH_CONNLIMIT=mCONFIG_NETFILTER_XT_MATCH_CONNMARK=mCONFIG_NETFILTER_XT_MATCH_CONNTRACK=mCONFIG_NETFILTER_XT_MATCH_CPU=mCONFIG_NETFILTER_XT_MATCH_DCCP=mCONFIG_NETFILTER_XT_MATCH_DEVGROUP=mCONFIG_NETFILTER_XT_MATCH_DSCP=mCONFIG_NETFILTER_XT_MATCH_ECN=mCONFIG_NETFILTER_XT_MATCH_ESP=mCONFIG_NETFILTER_XT_MATCH_HASHLIMIT=mCONFIG_NETFILTER_XT_MATCH_HELPER=mCONFIG_NETFILTER_XT_MATCH_HL=mCONFIG_NETFILTER_XT_MATCH_IPRANGE=mCONFIG_NETFILTER_XT_MATCH_IPVS=mCONFIG_NETFILTER_XT_MATCH_LENGTH=mCONFIG_NETFILTER_XT_MATCH_LIMIT=mCONFIG_NETFILTER_XT_MATCH_MAC=mCONFIG_NETFILTER_XT_MATCH_MARK=mCONFIG_NETFILTER_XT_MATCH_MULTIPORT=mCONFIG_NETFILTER_XT_MATCH_NFACCT=mCONFIG_NETFILTER_XT_MATCH_OSF=mCONFIG_NETFILTER_XT_MATCH_OWNER=mCONFIG_NETFILTER_XT_MATCH_POLICY=mCONFIG_NETFILTER_XT_MATCH_PHYSDEV=mCONFIG_NETFILTER_XT_MATCH_PKTTYPE=mCONFIG_NETFILTER_XT_MATCH_QUOTA=mCONFIG_NETFILTER_XT_MATCH_RATEEST=mCONFIG_NETFILTER_XT_MATCH_REALM=mCONFIG_NETFILTER_XT_MATCH_RECENT=mCONFIG_NETFILTER_XT_MATCH_SCTP=mCONFIG_NETFILTER_XT_MATCH_SOCKET=mCONFIG_NETFILTER_XT_MATCH_STATE=mCONFIG_NETFILTER_XT_MATCH_STATISTIC=mCONFIG_NETFILTER_XT_MATCH_STRING=mCONFIG_NETFILTER_XT_MATCH_TCPMSS=mCONFIG_NETFILTER_XT_MATCH_TIME=mCONFIG_NETFILTER_XT_MATCH_U32=mCONFIG_IP_SET=mCONFIG_IP_SET_MAX=256CONFIG_IP_SET_BITMAP_IP=mCONFIG_IP_SET_BITMAP_IPMAC=mCONFIG_IP_SET_BITMAP_PORT=mCONFIG_IP_SET_HASH_IP=mCONFIG_IP_SET_HASH_IPPORT=mCONFIG_IP_SET_HASH_IPPORTIP=mCONFIG_IP_SET_HASH_IPPORTNET=mCONFIG_IP_SET_HASH_NET=mCONFIG_IP_SET_HASH_NETPORT=mCONFIG_IP_SET_HASH_NETIFACE=mCONFIG_IP_SET_LIST_SET=mCONFIG_IP_VS=mCONFIG_IP_VS_IPV6=y
# CONFIG_IP_VS_DEBUG is not setCONFIG_IP_VS_TAB_BITS=12
#
# IPVS transport protocol load balancing support
#CONFIG_IP_VS_PROTO_TCP=yCONFIG_IP_VS_PROTO_UDP=yCONFIG_IP_VS_PROTO_AH_ESP=yCONFIG_IP_VS_PROTO_ESP=yCONFIG_IP_VS_PROTO_AH=yCONFIG_IP_VS_PROTO_SCTP=y
#
# IPVS scheduler
#CONFIG_IP_VS_RR=mCONFIG_IP_VS_WRR=mCONFIG_IP_VS_LC=mCONFIG_IP_VS_WLC=mCONFIG_IP_VS_LBLC=mCONFIG_IP_VS_LBLCR=mCONFIG_IP_VS_DH=mCONFIG_IP_VS_SH=mCONFIG_IP_VS_SED=mCONFIG_IP_VS_NQ=m
#
# IPVS SH scheduler
#CONFIG_IP_VS_SH_TAB_BITS=8
#
# IPVS application helper
#CONFIG_IP_VS_NFCT=yCONFIG_IP_VS_PE_SIP=m
#
# IP: Netfilter Configuration
#CONFIG_NF_DEFRAG_IPV4=mCONFIG_NF_CONNTRACK_IPV4=m
# CONFIG_NF_CONNTRACK_PROC_COMPAT is not setCONFIG_IP_NF_QUEUE=mCONFIG_IP_NF_IPTABLES=yCONFIG_IP_NF_MATCH_AH=mCONFIG_IP_NF_MATCH_ECN=mCONFIG_IP_NF_MATCH_RPFILTER=mCONFIG_IP_NF_MATCH_TTL=mCONFIG_IP_NF_FILTER=yCONFIG_IP_NF_TARGET_REJECT=yCONFIG_IP_NF_TARGET_ULOG=m
# CONFIG_NF_NAT_IPV4 is not setCONFIG_IP_NF_MANGLE=mCONFIG_IP_NF_TARGET_CLUSTERIP=mCONFIG_IP_NF_TARGET_ECN=mCONFIG_IP_NF_TARGET_TTL=mCONFIG_IP_NF_RAW=mCONFIG_IP_NF_SECURITY=mCONFIG_IP_NF_ARPTABLES=mCONFIG_IP_NF_ARPFILTER=mCONFIG_IP_NF_ARP_MANGLE=m
#
# IPv6: Netfilter Configuration
#CONFIG_NF_DEFRAG_IPV6=mCONFIG_NF_CONNTRACK_IPV6=mCONFIG_IP6_NF_IPTABLES=mCONFIG_IP6_NF_MATCH_AH=mCONFIG_IP6_NF_MATCH_EUI64=mCONFIG_IP6_NF_MATCH_FRAG=mCONFIG_IP6_NF_MATCH_OPTS=mCONFIG_IP6_NF_MATCH_HL=mCONFIG_IP6_NF_MATCH_IPV6HEADER=mCONFIG_IP6_NF_MATCH_MH=mCONFIG_IP6_NF_MATCH_RPFILTER=mCONFIG_IP6_NF_MATCH_RT=mCONFIG_IP6_NF_TARGET_HL=mCONFIG_IP6_NF_FILTER=mCONFIG_IP6_NF_TARGET_REJECT=mCONFIG_IP6_NF_MANGLE=mCONFIG_IP6_NF_RAW=mCONFIG_IP6_NF_SECURITY=m
# CONFIG_NF_NAT_IPV6 is not setCONFIG_BRIDGE_NF_EBTABLES=mCONFIG_BRIDGE_EBT_BROUTE=mCONFIG_BRIDGE_EBT_T_FILTER=mCONFIG_BRIDGE_EBT_T_NAT=mCONFIG_BRIDGE_EBT_802_3=mCONFIG_BRIDGE_EBT_AMONG=mCONFIG_BRIDGE_EBT_ARP=mCONFIG_BRIDGE_EBT_IP=mCONFIG_BRIDGE_EBT_IP6=mCONFIG_BRIDGE_EBT_LIMIT=mCONFIG_BRIDGE_EBT_MARK=mCONFIG_BRIDGE_EBT_PKTTYPE=mCONFIG_BRIDGE_EBT_STP=mCONFIG_BRIDGE_EBT_VLAN=mCONFIG_BRIDGE_EBT_ARPREPLY=mCONFIG_BRIDGE_EBT_DNAT=mCONFIG_BRIDGE_EBT_MARK_T=mCONFIG_BRIDGE_EBT_REDIRECT=mCONFIG_BRIDGE_EBT_SNAT=mCONFIG_BRIDGE_EBT_LOG=mCONFIG_BRIDGE_EBT_ULOG=mCONFIG_BRIDGE_EBT_NFLOG=mCONFIG_IP_DCCP=mCONFIG_INET_DCCP_DIAG=m
#
# DCCP CCIDs Configuration (EXPERIMENTAL)
#
# CONFIG_IP_DCCP_CCID2_DEBUG is not setCONFIG_IP_DCCP_CCID3=y
# CONFIG_IP_DCCP_CCID3_DEBUG is not setCONFIG_IP_DCCP_TFRC_LIB=y
#
# DCCP Kernel Hacking
#
# CONFIG_IP_DCCP_DEBUG is not set
# CONFIG_NET_DCCPPROBE is not setCONFIG_IP_SCTP=mCONFIG_NET_SCTPPROBE=m
# CONFIG_SCTP_DBG_MSG is not set
# CONFIG_SCTP_DBG_OBJCNT is not set
# CONFIG_SCTP_HMAC_NONE is not setCONFIG_SCTP_HMAC_SHA1=y
# CONFIG_SCTP_HMAC_MD5 is not setCONFIG_RDS=mCONFIG_RDS_RDMA=mCONFIG_RDS_TCP=m
# CONFIG_RDS_DEBUG is not set
# CONFIG_TIPC is not setCONFIG_ATM=mCONFIG_ATM_CLIP=m
# CONFIG_ATM_CLIP_NO_ICMP is not setCONFIG_ATM_LANE=m
# CONFIG_ATM_MPOA is not setCONFIG_ATM_BR2684=m
# CONFIG_ATM_BR2684_IPFILTER is not setCONFIG_L2TP=mCONFIG_L2TP_DEBUGFS=mCONFIG_L2TP_V3=yCONFIG_L2TP_IP=mCONFIG_L2TP_ETH=mCONFIG_STP=mCONFIG_GARP=mCONFIG_BRIDGE=mCONFIG_BRIDGE_IGMP_SNOOPING=yCONFIG_NET_DSA=mCONFIG_NET_DSA_TAG_DSA=yCONFIG_NET_DSA_TAG_EDSA=yCONFIG_NET_DSA_TAG_TRAILER=yCONFIG_VLAN_8021Q=mCONFIG_VLAN_8021Q_GVRP=y
# CONFIG_DECNET is not setCONFIG_LLC=m
# CONFIG_LLC2 is not setCONFIG_IPX=m
# CONFIG_IPX_INTERN is not setCONFIG_ATALK=mCONFIG_DEV_APPLETALK=mCONFIG_IPDDP=mCONFIG_IPDDP_ENCAP=yCONFIG_IPDDP_DECAP=y
# CONFIG_X25 is not set
# CONFIG_LAPB is not setCONFIG_WAN_ROUTER=m
# CONFIG_PHONET is not setCONFIG_IEEE802154=mCONFIG_IEEE802154_6LOWPAN=mCONFIG_MAC802154=mCONFIG_NET_SCHED=y
#
# Queueing/Scheduling
#CONFIG_NET_SCH_CBQ=mCONFIG_NET_SCH_HTB=mCONFIG_NET_SCH_HFSC=mCONFIG_NET_SCH_ATM=mCONFIG_NET_SCH_PRIO=mCONFIG_NET_SCH_MULTIQ=mCONFIG_NET_SCH_RED=mCONFIG_NET_SCH_SFB=mCONFIG_NET_SCH_SFQ=mCONFIG_NET_SCH_TEQL=mCONFIG_NET_SCH_TBF=mCONFIG_NET_SCH_GRED=mCONFIG_NET_SCH_DSMARK=mCONFIG_NET_SCH_NETEM=mCONFIG_NET_SCH_DRR=mCONFIG_NET_SCH_MQPRIO=mCONFIG_NET_SCH_CHOKE=mCONFIG_NET_SCH_QFQ=mCONFIG_NET_SCH_CODEL=mCONFIG_NET_SCH_FQ_CODEL=mCONFIG_NET_SCH_INGRESS=mCONFIG_NET_SCH_PLUG=m
#
# Classification
#CONFIG_NET_CLS=yCONFIG_NET_CLS_BASIC=mCONFIG_NET_CLS_TCINDEX=mCONFIG_NET_CLS_ROUTE4=mCONFIG_NET_CLS_FW=mCONFIG_NET_CLS_U32=mCONFIG_CLS_U32_PERF=yCONFIG_CLS_U32_MARK=yCONFIG_NET_CLS_RSVP=mCONFIG_NET_CLS_RSVP6=mCONFIG_NET_CLS_FLOW=mCONFIG_NET_CLS_CGROUP=yCONFIG_NET_EMATCH=yCONFIG_NET_EMATCH_STACK=32CONFIG_NET_EMATCH_CMP=mCONFIG_NET_EMATCH_NBYTE=mCONFIG_NET_EMATCH_U32=mCONFIG_NET_EMATCH_META=mCONFIG_NET_EMATCH_TEXT=mCONFIG_NET_EMATCH_IPSET=mCONFIG_NET_CLS_ACT=yCONFIG_NET_ACT_POLICE=mCONFIG_NET_ACT_GACT=mCONFIG_GACT_PROB=yCONFIG_NET_ACT_MIRRED=mCONFIG_NET_ACT_IPT=mCONFIG_NET_ACT_NAT=mCONFIG_NET_ACT_PEDIT=mCONFIG_NET_ACT_SIMP=mCONFIG_NET_ACT_SKBEDIT=mCONFIG_NET_ACT_CSUM=mCONFIG_NET_CLS_IND=yCONFIG_NET_SCH_FIFO=yCONFIG_DCB=yCONFIG_DNS_RESOLVER=mCONFIG_BATMAN_ADV=mCONFIG_BATMAN_ADV_BLA=y
# CONFIG_BATMAN_ADV_DEBUG is not setCONFIG_OPENVSWITCH=mCONFIG_RPS=yCONFIG_RFS_ACCEL=yCONFIG_XPS=yCONFIG_NETPRIO_CGROUP=mCONFIG_BQL=yCONFIG_BPF_JIT=y
#
# Network testing
#CONFIG_NET_PKTGEN=m
# CONFIG_NET_TCPPROBE is not setCONFIG_NET_DROP_MONITOR=yCONFIG_HAMRADIO=y
#
# Packet Radio protocols
#CONFIG_AX25=mCONFIG_AX25_DAMA_SLAVE=yCONFIG_NETROM=mCONFIG_ROSE=m
#
# AX.25 network device drivers
#CONFIG_MKISS=mCONFIG_6PACK=mCONFIG_BPQETHER=mCONFIG_BAYCOM_SER_FDX=mCONFIG_BAYCOM_SER_HDX=mCONFIG_BAYCOM_PAR=mCONFIG_YAM=m
# CONFIG_CAN is not setCONFIG_IRDA=m
#
# IrDA protocols
#CONFIG_IRLAN=mCONFIG_IRNET=mCONFIG_IRCOMM=m
# CONFIG_IRDA_ULTRA is not set
#
# IrDA options
#CONFIG_IRDA_CACHE_LAST_LSAP=yCONFIG_IRDA_FAST_RR=y
# CONFIG_IRDA_DEBUG is not set
#
# Infrared-port device drivers
#
#
# SIR device drivers
#CONFIG_IRTTY_SIR=m
#
# Dongle support
#CONFIG_DONGLE=yCONFIG_ESI_DONGLE=mCONFIG_ACTISYS_DONGLE=mCONFIG_TEKRAM_DONGLE=mCONFIG_TOIM3232_DONGLE=mCONFIG_LITELINK_DONGLE=mCONFIG_MA600_DONGLE=mCONFIG_GIRBIL_DONGLE=mCONFIG_MCP2120_DONGLE=mCONFIG_OLD_BELKIN_DONGLE=mCONFIG_ACT200L_DONGLE=mCONFIG_KINGSUN_DONGLE=mCONFIG_KSDAZZLE_DONGLE=mCONFIG_KS959_DONGLE=m
#
# FIR device drivers
#CONFIG_USB_IRDA=mCONFIG_SIGMATEL_FIR=mCONFIG_NSC_FIR=mCONFIG_WINBOND_FIR=mCONFIG_SMC_IRCC_FIR=mCONFIG_ALI_FIR=mCONFIG_VLSI_FIR=mCONFIG_VIA_FIR=mCONFIG_MCS_FIR=mCONFIG_BT=mCONFIG_BT_RFCOMM=mCONFIG_BT_RFCOMM_TTY=yCONFIG_BT_BNEP=mCONFIG_BT_BNEP_MC_FILTER=yCONFIG_BT_BNEP_PROTO_FILTER=yCONFIG_BT_CMTP=mCONFIG_BT_HIDP=m
#
# Bluetooth device drivers
#CONFIG_BT_HCIBTUSB=mCONFIG_BT_HCIBTSDIO=mCONFIG_BT_HCIUART=mCONFIG_BT_HCIUART_H4=yCONFIG_BT_HCIUART_BCSP=yCONFIG_BT_HCIUART_ATH3K=yCONFIG_BT_HCIUART_LL=yCONFIG_BT_HCIUART_3WIRE=yCONFIG_BT_HCIBCM203X=mCONFIG_BT_HCIBPA10X=mCONFIG_BT_HCIBFUSB=mCONFIG_BT_HCIDTL1=mCONFIG_BT_HCIBT3C=mCONFIG_BT_HCIBLUECARD=mCONFIG_BT_HCIBTUART=mCONFIG_BT_HCIVHCI=mCONFIG_BT_MRVL=mCONFIG_BT_MRVL_SDIO=mCONFIG_BT_ATH3K=m
# CONFIG_AF_RXRPC is not setCONFIG_FIB_RULES=yCONFIG_WIRELESS=yCONFIG_WIRELESS_EXT=yCONFIG_WEXT_CORE=yCONFIG_WEXT_PROC=yCONFIG_WEXT_SPY=yCONFIG_WEXT_PRIV=yCONFIG_CFG80211=m
# CONFIG_NL80211_TESTMODE is not set
# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
# CONFIG_CFG80211_REG_DEBUG is not setCONFIG_CFG80211_DEFAULT_PS=yCONFIG_CFG80211_DEBUGFS=y
# CONFIG_CFG80211_INTERNAL_REGDB is not setCONFIG_CFG80211_WEXT=yCONFIG_LIB80211=mCONFIG_LIB80211_CRYPT_WEP=mCONFIG_LIB80211_CRYPT_CCMP=mCONFIG_LIB80211_CRYPT_TKIP=m
# CONFIG_LIB80211_DEBUG is not setCONFIG_MAC80211=mCONFIG_MAC80211_HAS_RC=yCONFIG_MAC80211_RC_MINSTREL=yCONFIG_MAC80211_RC_MINSTREL_HT=yCONFIG_MAC80211_RC_DEFAULT_MINSTREL=yCONFIG_MAC80211_RC_DEFAULT="minstrel_ht"CONFIG_MAC80211_MESH=yCONFIG_MAC80211_LEDS=yCONFIG_MAC80211_DEBUGFS=y
# CONFIG_MAC80211_MESSAGE_TRACING is not set
# CONFIG_MAC80211_DEBUG_MENU is not setCONFIG_WIMAX=mCONFIG_WIMAX_DEBUG_LEVEL=8CONFIG_RFKILL=mCONFIG_RFKILL_LEDS=yCONFIG_RFKILL_INPUT=yCONFIG_NET_9P=mCONFIG_NET_9P_VIRTIO=mCONFIG_NET_9P_RDMA=m
# CONFIG_NET_9P_DEBUG is not set
# CONFIG_CAIF is not setCONFIG_CEPH_LIB=m
# CONFIG_CEPH_LIB_PRETTYDEBUG is not set
# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not setCONFIG_NFC=mCONFIG_NFC_NCI=mCONFIG_NFC_HCI=mCONFIG_NFC_SHDLC=yCONFIG_NFC_LLCP=y
#
# Near Field Communication (NFC) devices
#CONFIG_PN544_HCI_NFC=mCONFIG_NFC_PN533=mCONFIG_HAVE_BPF_JIT=y
#
# Device Drivers
#
#
# Generic Driver Options
#CONFIG_UEVENT_HELPER_PATH=""CONFIG_DEVTMPFS=yCONFIG_DEVTMPFS_MOUNT=yCONFIG_STANDALONE=yCONFIG_PREVENT_FIRMWARE_BUILD=yCONFIG_FW_LOADER=y
# CONFIG_FIRMWARE_IN_KERNEL is not setCONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not setCONFIG_DEBUG_DEVRES=yCONFIG_SYS_HYPERVISOR=y
# CONFIG_GENERIC_CPU_DEVICES is not setCONFIG_REGMAP=yCONFIG_REGMAP_I2C=mCONFIG_DMA_SHARED_BUFFER=y
#
# Bus devices
#
# CONFIG_OMAP_OCP2SCP is not setCONFIG_CONNECTOR=yCONFIG_PROC_EVENTS=yCONFIG_MTD=m
# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
#
# User Modules And Translation Layers
#
# CONFIG_MTD_CHAR is not set
# CONFIG_MTD_BLKDEVS is not set
# CONFIG_MTD_BLOCK is not set
# CONFIG_MTD_BLOCK_RO is not set
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
# CONFIG_SM_FTL is not set
# CONFIG_MTD_OOPS is not set
# CONFIG_MTD_SWAP is not set
#
# RAM/ROM/Flash chip drivers
#
# CONFIG_MTD_CFI is not set
# CONFIG_MTD_JEDECPROBE is not setCONFIG_MTD_MAP_BANK_WIDTH_1=yCONFIG_MTD_MAP_BANK_WIDTH_2=yCONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not setCONFIG_MTD_CFI_I1=yCONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_TS5500 is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLOCK2MTD is not set
#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOCG3 is not set
# CONFIG_MTD_NAND is not set
# CONFIG_MTD_ONENAND is not set
#
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not setCONFIG_MTD_UBI=mCONFIG_MTD_UBI_WL_THRESHOLD=4096CONFIG_MTD_UBI_BEB_LIMIT=20
# CONFIG_MTD_UBI_FASTMAP is not set
# CONFIG_MTD_UBI_GLUEBI is not setCONFIG_PARPORT=mCONFIG_PARPORT_PC=mCONFIG_PARPORT_SERIAL=m
# CONFIG_PARPORT_PC_FIFO is not set
# CONFIG_PARPORT_PC_SUPERIO is not setCONFIG_PARPORT_PC_PCMCIA=m
# CONFIG_PARPORT_GSC is not set
# CONFIG_PARPORT_AX88796 is not setCONFIG_PARPORT_1284=yCONFIG_PARPORT_NOT_PC=yCONFIG_PNP=y
# CONFIG_PNP_DEBUG_MESSAGES is not set
#
# Protocols
#CONFIG_PNPACPI=yCONFIG_BLK_DEV=yCONFIG_BLK_DEV_FD=m
# CONFIG_PARIDE is not setCONFIG_BLK_DEV_PCIESSD_MTIP32XX=mCONFIG_BLK_CPQ_DA=mCONFIG_BLK_CPQ_CISS_DA=mCONFIG_CISS_SCSI_TAPE=yCONFIG_BLK_DEV_DAC960=mCONFIG_BLK_DEV_UMEM=m
# CONFIG_BLK_DEV_COW_COMMON is not setCONFIG_BLK_DEV_LOOP=yCONFIG_BLK_DEV_LOOP_MIN_COUNT=8CONFIG_BLK_DEV_CRYPTOLOOP=mCONFIG_BLK_DEV_DRBD=m
# CONFIG_DRBD_FAULT_INJECTION is not setCONFIG_BLK_DEV_NBD=mCONFIG_BLK_DEV_NVME=mCONFIG_BLK_DEV_OSD=mCONFIG_BLK_DEV_SX8=mCONFIG_BLK_DEV_RAM=mCONFIG_BLK_DEV_RAM_COUNT=16CONFIG_BLK_DEV_RAM_SIZE=16384
# CONFIG_BLK_DEV_XIP is not setCONFIG_CDROM_PKTCDVD=mCONFIG_CDROM_PKTCDVD_BUFFERS=8
# CONFIG_CDROM_PKTCDVD_WCACHE is not setCONFIG_ATA_OVER_ETH=mCONFIG_XEN_BLKDEV_FRONTEND=mCONFIG_XEN_BLKDEV_BACKEND=mCONFIG_VIRTIO_BLK=m
# CONFIG_BLK_DEV_HD is not setCONFIG_BLK_DEV_RBD=m
#
# Misc devices
#CONFIG_SENSORS_LIS3LV02D=m
# CONFIG_AD525X_DPOT is not set
# CONFIG_IBM_ASM is not set
# CONFIG_PHANTOM is not set
# CONFIG_INTEL_MID_PTI is not setCONFIG_SGI_IOC4=mCONFIG_TIFM_CORE=mCONFIG_TIFM_7XX1=m
# CONFIG_ICS932S401 is not setCONFIG_ENCLOSURE_SERVICES=mCONFIG_HP_ILO=mCONFIG_APDS9802ALS=mCONFIG_ISL29003=mCONFIG_ISL29020=mCONFIG_SENSORS_TSL2550=m
# CONFIG_SENSORS_BH1780 is not setCONFIG_SENSORS_BH1770=mCONFIG_SENSORS_APDS990X=m
# CONFIG_HMC6352 is not set
# CONFIG_DS1682 is not setCONFIG_VMWARE_BALLOON=m
# CONFIG_BMP085_I2C is not setCONFIG_PCH_PHUB=m
# CONFIG_USB_SWITCH_FSA9480 is not set
# CONFIG_C2PORT is not set
#
# EEPROM support
#CONFIG_EEPROM_AT24=mCONFIG_EEPROM_LEGACY=mCONFIG_EEPROM_MAX6875=mCONFIG_EEPROM_93CX6=mCONFIG_CB710_CORE=m
# CONFIG_CB710_DEBUG is not setCONFIG_CB710_DEBUG_ASSUMPTIONS=y
#
# Texas Instruments shared transport line discipline #CONFIG_SENSORS_LIS3_I2C=m
#
# Altera FPGA firmware download module
#CONFIG_ALTERA_STAPL=mCONFIG_INTEL_MEI=mCONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
# SCSI device support
#CONFIG_SCSI_MOD=yCONFIG_RAID_ATTRS=mCONFIG_SCSI=yCONFIG_SCSI_DMA=yCONFIG_SCSI_TGT=mCONFIG_SCSI_NETLINK=yCONFIG_SCSI_PROC_FS=y
#
# SCSI support type (disk, tape, CD-ROM)
#CONFIG_BLK_DEV_SD=yCONFIG_CHR_DEV_ST=mCONFIG_CHR_DEV_OSST=mCONFIG_BLK_DEV_SR=yCONFIG_BLK_DEV_SR_VENDOR=yCONFIG_CHR_DEV_SG=yCONFIG_CHR_DEV_SCH=mCONFIG_SCSI_ENCLOSURE=mCONFIG_SCSI_MULTI_LUN=yCONFIG_SCSI_CONSTANTS=yCONFIG_SCSI_LOGGING=yCONFIG_SCSI_SCAN_ASYNC=y
#
# SCSI Transports
#CONFIG_SCSI_SPI_ATTRS=mCONFIG_SCSI_FC_ATTRS=mCONFIG_SCSI_FC_TGT_ATTRS=yCONFIG_SCSI_ISCSI_ATTRS=mCONFIG_SCSI_SAS_ATTRS=mCONFIG_SCSI_SAS_LIBSAS=mCONFIG_SCSI_SAS_ATA=yCONFIG_SCSI_SAS_HOST_SMP=yCONFIG_SCSI_SRP_ATTRS=mCONFIG_SCSI_SRP_TGT_ATTRS=yCONFIG_SCSI_LOWLEVEL=yCONFIG_ISCSI_TCP=mCONFIG_ISCSI_BOOT_SYSFS=mCONFIG_SCSI_CXGB3_ISCSI=mCONFIG_SCSI_CXGB4_ISCSI=mCONFIG_SCSI_BNX2_ISCSI=mCONFIG_SCSI_BNX2X_FCOE=mCONFIG_BE2ISCSI=mCONFIG_BLK_DEV_3W_XXXX_RAID=mCONFIG_SCSI_HPSA=mCONFIG_SCSI_3W_9XXX=mCONFIG_SCSI_3W_SAS=mCONFIG_SCSI_ACARD=mCONFIG_SCSI_AACRAID=mCONFIG_SCSI_AIC7XXX=mCONFIG_AIC7XXX_CMDS_PER_DEVICE=4CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_DEBUG_ENABLE is not setCONFIG_AIC7XXX_DEBUG_MASK=0
# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not setCONFIG_SCSI_AIC7XXX_OLD=mCONFIG_SCSI_AIC79XX=mCONFIG_AIC79XX_CMDS_PER_DEVICE=4CONFIG_AIC79XX_RESET_DELAY_MS=15000
# CONFIG_AIC79XX_DEBUG_ENABLE is not setCONFIG_AIC79XX_DEBUG_MASK=0
# CONFIG_AIC79XX_REG_PRETTY_PRINT is not setCONFIG_SCSI_AIC94XX=m
# CONFIG_AIC94XX_DEBUG is not setCONFIG_SCSI_MVSAS=m
# CONFIG_SCSI_MVSAS_DEBUG is not setCONFIG_SCSI_MVSAS_TASKLET=yCONFIG_SCSI_MVUMI=m
# CONFIG_SCSI_DPT_I2O is not setCONFIG_SCSI_ADVANSYS=mCONFIG_SCSI_ARCMSR=mCONFIG_MEGARAID_NEWGEN=yCONFIG_MEGARAID_MM=mCONFIG_MEGARAID_MAILBOX=mCONFIG_MEGARAID_LEGACY=mCONFIG_MEGARAID_SAS=mCONFIG_SCSI_MPT2SAS=mCONFIG_SCSI_MPT2SAS_MAX_SGE=128CONFIG_SCSI_MPT2SAS_LOGGING=yCONFIG_SCSI_UFSHCD=mCONFIG_SCSI_HPTIOP=mCONFIG_SCSI_BUSLOGIC=mCONFIG_VMWARE_PVSCSI=mCONFIG_HYPERV_STORAGE=mCONFIG_LIBFC=mCONFIG_LIBFCOE=mCONFIG_FCOE=mCONFIG_FCOE_FNIC=m
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not setCONFIG_SCSI_GDTH=mCONFIG_SCSI_ISCI=mCONFIG_SCSI_IPS=mCONFIG_SCSI_INITIO=mCONFIG_SCSI_INIA100=m
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not setCONFIG_SCSI_STEX=mCONFIG_SCSI_SYM53C8XX_2=mCONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64CONFIG_SCSI_SYM53C8XX_MMIO=y
# CONFIG_SCSI_IPR is not setCONFIG_SCSI_QLOGIC_1280=mCONFIG_SCSI_QLA_FC=mCONFIG_TCM_QLA2XXX=mCONFIG_SCSI_QLA_ISCSI=mCONFIG_SCSI_LPFC=m
# CONFIG_SCSI_LPFC_DEBUG_FS is not set
CONFIG_SCSI_DC395x=mCONFIG_SCSI_DC390T=mCONFIG_SCSI_DEBUG=mCONFIG_SCSI_PMCRAID=mCONFIG_SCSI_PM8001=mCONFIG_SCSI_SRP=mCONFIG_SCSI_BFA_FC=mCONFIG_SCSI_VIRTIO=m
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not setCONFIG_SCSI_DH=yCONFIG_SCSI_DH_RDAC=mCONFIG_SCSI_DH_HP_SW=mCONFIG_SCSI_DH_EMC=mCONFIG_SCSI_DH_ALUA=mCONFIG_SCSI_OSD_INITIATOR=mCONFIG_SCSI_OSD_ULD=mCONFIG_SCSI_OSD_DPRINT_SENSE=1
# CONFIG_SCSI_OSD_DEBUG is not setCONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not setCONFIG_ATA_VERBOSE_ERROR=yCONFIG_ATA_ACPI=yCONFIG_SATA_PMP=y
#
# Controllers with non-SFF native interface
#CONFIG_SATA_AHCI=yCONFIG_SATA_AHCI_PLATFORM=mCONFIG_SATA_INIC162X=mCONFIG_SATA_ACARD_AHCI=mCONFIG_SATA_SIL24=mCONFIG_ATA_SFF=y
#
# SFF controllers with custom DMA interface
#CONFIG_PDC_ADMA=mCONFIG_SATA_QSTOR=mCONFIG_SATA_SX4=mCONFIG_ATA_BMDMA=y
#
# SATA SFF controllers with BMDMA
#CONFIG_ATA_PIIX=y
# CONFIG_SATA_HIGHBANK is not setCONFIG_SATA_MV=mCONFIG_SATA_NV=mCONFIG_SATA_PROMISE=mCONFIG_SATA_SIL=mCONFIG_SATA_SIS=mCONFIG_SATA_SVW=mCONFIG_SATA_ULI=mCONFIG_SATA_VIA=mCONFIG_SATA_VITESSE=m
#
# PATA SFF controllers with BMDMA
#CONFIG_PATA_ALI=mCONFIG_PATA_AMD=mCONFIG_PATA_ARASAN_CF=mCONFIG_PATA_ARTOP=mCONFIG_PATA_ATIIXP=mCONFIG_PATA_ATP867X=mCONFIG_PATA_CMD64X=mCONFIG_PATA_CS5520=mCONFIG_PATA_CS5530=mCONFIG_PATA_CS5536=mCONFIG_PATA_CYPRESS=mCONFIG_PATA_EFAR=mCONFIG_PATA_HPT366=mCONFIG_PATA_HPT37X=mCONFIG_PATA_HPT3X2N=mCONFIG_PATA_HPT3X3=m
# CONFIG_PATA_HPT3X3_DMA is not setCONFIG_PATA_IT8213=mCONFIG_PATA_IT821X=mCONFIG_PATA_JMICRON=mCONFIG_PATA_MARVELL=mCONFIG_PATA_NETCELL=mCONFIG_PATA_NINJA32=mCONFIG_PATA_NS87415=mCONFIG_PATA_OLDPIIX=mCONFIG_PATA_OPTIDMA=mCONFIG_PATA_PDC2027X=mCONFIG_PATA_PDC_OLD=m
# CONFIG_PATA_RADISYS is not setCONFIG_PATA_RDC=m
# CONFIG_PATA_SC1200 is not setCONFIG_PATA_SCH=mCONFIG_PATA_SERVERWORKS=mCONFIG_PATA_SIL680=mCONFIG_PATA_SIS=mCONFIG_PATA_TOSHIBA=mCONFIG_PATA_TRIFLEX=mCONFIG_PATA_VIA=mCONFIG_PATA_WINBOND=m
#
# PIO-only SFF controllers
#CONFIG_PATA_CMD640_PCI=mCONFIG_PATA_MPIIX=mCONFIG_PATA_NS87410=mCONFIG_PATA_OPTI=mCONFIG_PATA_PCMCIA=m
# CONFIG_PATA_RZ1000 is not set
#
# Generic fallback / legacy drivers
#CONFIG_PATA_ACPI=mCONFIG_ATA_GENERIC=m
# CONFIG_PATA_LEGACY is not setCONFIG_MD=yCONFIG_BLK_DEV_MD=yCONFIG_MD_AUTODETECT=yCONFIG_MD_LINEAR=mCONFIG_MD_RAID0=mCONFIG_MD_RAID1=mCONFIG_MD_RAID10=mCONFIG_MD_RAID456=m
# CONFIG_MULTICORE_RAID456 is not setCONFIG_MD_MULTIPATH=mCONFIG_MD_FAULTY=mCONFIG_BLK_DEV_DM=yCONFIG_DM_DEBUG=yCONFIG_DM_BUFIO=mCONFIG_DM_BIO_PRISON=mCONFIG_DM_PERSISTENT_DATA=mCONFIG_DM_CRYPT=mCONFIG_DM_SNAPSHOT=yCONFIG_DM_THIN_PROVISIONING=m
# CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not setCONFIG_DM_MIRROR=yCONFIG_DM_RAID=mCONFIG_DM_LOG_USERSPACE=mCONFIG_DM_ZERO=yCONFIG_DM_MULTIPATH=mCONFIG_DM_MULTIPATH_QL=mCONFIG_DM_MULTIPATH_ST=m
# CONFIG_DM_DELAY is not setCONFIG_DM_UEVENT=yCONFIG_DM_FLAKEY=mCONFIG_DM_VERITY=mCONFIG_TARGET_CORE=mCONFIG_TCM_IBLOCK=mCONFIG_TCM_FILEIO=mCONFIG_TCM_PSCSI=mCONFIG_LOOPBACK_TARGET=mCONFIG_TCM_FC=mCONFIG_ISCSI_TARGET=mCONFIG_SBP_TARGET=mCONFIG_FUSION=yCONFIG_FUSION_SPI=mCONFIG_FUSION_FC=mCONFIG_FUSION_SAS=mCONFIG_FUSION_MAX_SGE=40CONFIG_FUSION_CTL=mCONFIG_FUSION_LAN=mCONFIG_FUSION_LOGGING=y
#
# IEEE 1394 (FireWire) support
#CONFIG_FIREWIRE=mCONFIG_FIREWIRE_OHCI=mCONFIG_FIREWIRE_SBP2=mCONFIG_FIREWIRE_NET=mCONFIG_FIREWIRE_NOSY=m
# CONFIG_I2O is not setCONFIG_MACINTOSH_DRIVERS=yCONFIG_MAC_EMUMOUSEBTN=yCONFIG_NETDEVICES=yCONFIG_NET_CORE=yCONFIG_BONDING=mCONFIG_DUMMY=mCONFIG_EQUALIZER=mCONFIG_NET_FC=yCONFIG_MII=mCONFIG_IFB=mCONFIG_NET_TEAM=mCONFIG_NET_TEAM_MODE_BROADCAST=mCONFIG_NET_TEAM_MODE_ROUNDROBIN=mCONFIG_NET_TEAM_MODE_ACTIVEBACKUP=mCONFIG_NET_TEAM_MODE_LOADBALANCE=mCONFIG_MACVLAN=mCONFIG_MACVTAP=m
# CONFIG_VXLAN is not setCONFIG_NETCONSOLE=mCONFIG_NETCONSOLE_DYNAMIC=yCONFIG_NETPOLL=yCONFIG_NETPOLL_TRAP=yCONFIG_NET_POLL_CONTROLLER=yCONFIG_TUN=mCONFIG_VETH=mCONFIG_VIRTIO_NET=mCONFIG_SUNGEM_PHY=m
# CONFIG_ARCNET is not setCONFIG_ATM_DRIVERS=y
# CONFIG_ATM_DUMMY is not setCONFIG_ATM_TCP=m
# CONFIG_ATM_LANAI is not setCONFIG_ATM_ENI=m
# CONFIG_ATM_ENI_DEBUG is not set
# CONFIG_ATM_ENI_TUNE_BURST is not setCONFIG_ATM_FIRESTREAM=m
# CONFIG_ATM_ZATM is not setCONFIG_ATM_NICSTAR=m
# CONFIG_ATM_NICSTAR_USE_SUNI is not set
# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
# CONFIG_ATM_IDT77252 is not set
# CONFIG_ATM_AMBASSADOR is not set
# CONFIG_ATM_HORIZON is not set
# CONFIG_ATM_IA is not set
# CONFIG_ATM_FORE200E is not setCONFIG_ATM_HE=m
# CONFIG_ATM_HE_USE_SUNI is not setCONFIG_ATM_SOLOS=m
#
# CAIF transport drivers
#
#
# Distributed Switch Architecture drivers
#CONFIG_NET_DSA_MV88E6XXX=mCONFIG_NET_DSA_MV88E6060=mCONFIG_NET_DSA_MV88E6XXX_NEED_PPU=yCONFIG_NET_DSA_MV88E6131=mCONFIG_NET_DSA_MV88E6123_61_65=mCONFIG_ETHERNET=yCONFIG_MDIO=mCONFIG_NET_VENDOR_3COM=yCONFIG_PCMCIA_3C574=mCONFIG_PCMCIA_3C589=mCONFIG_VORTEX=mCONFIG_TYPHOON=mCONFIG_NET_VENDOR_ADAPTEC=yCONFIG_ADAPTEC_STARFIRE=mCONFIG_NET_VENDOR_ALTEON=yCONFIG_ACENIC=m
# CONFIG_ACENIC_OMIT_TIGON_I is not setCONFIG_NET_VENDOR_AMD=yCONFIG_AMD8111_ETH=mCONFIG_PCNET32=mCONFIG_PCMCIA_NMCLAN=mCONFIG_NET_VENDOR_ATHEROS=yCONFIG_ATL2=mCONFIG_ATL1=mCONFIG_ATL1E=mCONFIG_ATL1C=mCONFIG_NET_VENDOR_BROADCOM=yCONFIG_B44=mCONFIG_B44_PCI_AUTOSELECT=yCONFIG_B44_PCICORE_AUTOSELECT=yCONFIG_B44_PCI=yCONFIG_BNX2=mCONFIG_CNIC=mCONFIG_TIGON3=mCONFIG_BNX2X=mCONFIG_NET_VENDOR_BROCADE=yCONFIG_BNA=mCONFIG_NET_CALXEDA_XGMAC=mCONFIG_NET_VENDOR_CHELSIO=yCONFIG_CHELSIO_T1=mCONFIG_CHELSIO_T1_1G=yCONFIG_CHELSIO_T3=mCONFIG_CHELSIO_T4=mCONFIG_CHELSIO_T4VF=mCONFIG_NET_VENDOR_CISCO=yCONFIG_ENIC=mCONFIG_DNET=mCONFIG_NET_VENDOR_DEC=yCONFIG_NET_TULIP=yCONFIG_DE2104X=mCONFIG_DE2104X_DSL=0CONFIG_TULIP=m
# CONFIG_TULIP_MWI is not setCONFIG_TULIP_MMIO=y
# CONFIG_TULIP_NAPI is not setCONFIG_DE4X5=mCONFIG_WINBOND_840=mCONFIG_DM9102=mCONFIG_ULI526X=mCONFIG_PCMCIA_XIRCOM=mCONFIG_NET_VENDOR_DLINK=yCONFIG_DE600=mCONFIG_DE620=mCONFIG_DL2K=mCONFIG_SUNDANCE=m
# CONFIG_SUNDANCE_MMIO is not setCONFIG_NET_VENDOR_EMULEX=yCONFIG_BE2NET=mCONFIG_NET_VENDOR_EXAR=yCONFIG_S2IO=mCONFIG_VXGE=m
# CONFIG_VXGE_DEBUG_TRACE_ALL is not set
# CONFIG_NET_VENDOR_FUJITSU is not set
# CONFIG_NET_VENDOR_HP is not setCONFIG_NET_VENDOR_INTEL=yCONFIG_E100=mCONFIG_E1000=mCONFIG_E1000E=mCONFIG_IGB=mCONFIG_IGB_DCA=yCONFIG_IGB_PTP=yCONFIG_IGBVF=mCONFIG_IXGB=mCONFIG_IXGBE=mCONFIG_IXGBE_HWMON=yCONFIG_IXGBE_DCA=yCONFIG_IXGBE_DCB=yCONFIG_IXGBE_PTP=yCONFIG_IXGBEVF=m
# CONFIG_NET_VENDOR_I825XX is not setCONFIG_IP1000=mCONFIG_JME=mCONFIG_NET_VENDOR_MARVELL=yCONFIG_SKGE=m
# CONFIG_SKGE_DEBUG is not setCONFIG_SKGE_GENESIS=yCONFIG_SKY2=m
# CONFIG_SKY2_DEBUG is not setCONFIG_NET_VENDOR_MELLANOX=yCONFIG_MLX4_EN=mCONFIG_MLX4_EN_DCB=yCONFIG_MLX4_CORE=mCONFIG_MLX4_DEBUG=yCONFIG_NET_VENDOR_MICREL=y
# CONFIG_KS8842 is not set
# CONFIG_KS8851_MLL is not setCONFIG_KSZ884X_PCI=mCONFIG_NET_VENDOR_MYRI=yCONFIG_MYRI10GE=mCONFIG_MYRI10GE_DCA=yCONFIG_FEALNX=mCONFIG_NET_VENDOR_NATSEMI=yCONFIG_NATSEMI=mCONFIG_NS83820=mCONFIG_NET_VENDOR_8390=yCONFIG_PCMCIA_AXNET=mCONFIG_NE2K_PCI=mCONFIG_PCMCIA_PCNET=mCONFIG_NET_VENDOR_NVIDIA=yCONFIG_FORCEDETH=mCONFIG_NET_VENDOR_OKI=yCONFIG_PCH_GBE=m
# CONFIG_PCH_PTP is not setCONFIG_ETHOC=mCONFIG_NET_PACKET_ENGINE=yCONFIG_HAMACHI=mCONFIG_YELLOWFIN=mCONFIG_NET_VENDOR_QLOGIC=yCONFIG_QLA3XXX=mCONFIG_QLCNIC=mCONFIG_QLGE=mCONFIG_NETXEN_NIC=mCONFIG_NET_VENDOR_REALTEK=yCONFIG_ATP=mCONFIG_8139CP=mCONFIG_8139TOO=m
# CONFIG_8139TOO_PIO is not set
# CONFIG_8139TOO_TUNE_TWISTER is not setCONFIG_8139TOO_8129=y
# CONFIG_8139_OLD_RX_RESET is not setCONFIG_R8169=mCONFIG_NET_VENDOR_RDC=yCONFIG_R6040=m
# CONFIG_NET_VENDOR_SEEQ is not setCONFIG_NET_VENDOR_SILAN=yCONFIG_SC92031=mCONFIG_NET_VENDOR_SIS=yCONFIG_SIS900=mCONFIG_SIS190=mCONFIG_SFC=m
# CONFIG_SFC_MTD is not setCONFIG_SFC_MCDI_MON=yCONFIG_SFC_SRIOV=yCONFIG_SFC_PTP=yCONFIG_NET_VENDOR_SMSC=yCONFIG_PCMCIA_SMC91C92=mCONFIG_EPIC100=mCONFIG_SMSC9420=mCONFIG_NET_VENDOR_STMICRO=yCONFIG_STMMAC_ETH=m
# CONFIG_STMMAC_PLATFORM is not set
# CONFIG_STMMAC_PCI is not set
# CONFIG_STMMAC_DEBUG_FS is not set
# CONFIG_STMMAC_DA is not setCONFIG_STMMAC_RING=y
# CONFIG_STMMAC_CHAINED is not setCONFIG_NET_VENDOR_SUN=yCONFIG_HAPPYMEAL=mCONFIG_SUNGEM=mCONFIG_CASSINI=mCONFIG_NIU=mCONFIG_NET_VENDOR_TEHUTI=yCONFIG_TEHUTI=mCONFIG_NET_VENDOR_TI=yCONFIG_TLAN=mCONFIG_NET_VENDOR_VIA=yCONFIG_VIA_RHINE=mCONFIG_VIA_RHINE_MMIO=yCONFIG_VIA_VELOCITY=mCONFIG_NET_VENDOR_WIZNET=yCONFIG_WIZNET_W5100=mCONFIG_WIZNET_W5300=m
# CONFIG_WIZNET_BUS_DIRECT is not set
# CONFIG_WIZNET_BUS_INDIRECT is not setCONFIG_WIZNET_BUS_ANY=yCONFIG_NET_VENDOR_XIRCOM=yCONFIG_PCMCIA_XIRC2PS=m
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_NET_SB1000 is not setCONFIG_PHYLIB=y
#
# MII PHY device drivers
#CONFIG_AMD_PHY=mCONFIG_MARVELL_PHY=mCONFIG_DAVICOM_PHY=mCONFIG_QSEMI_PHY=mCONFIG_LXT_PHY=mCONFIG_CICADA_PHY=mCONFIG_VITESSE_PHY=mCONFIG_SMSC_PHY=mCONFIG_BROADCOM_PHY=mCONFIG_BCM87XX_PHY=mCONFIG_ICPLUS_PHY=mCONFIG_REALTEK_PHY=mCONFIG_NATIONAL_PHY=mCONFIG_STE10XP=mCONFIG_LSI_ET1011C_PHY=mCONFIG_MICREL_PHY=mCONFIG_FIXED_PHY=yCONFIG_MDIO_BITBANG=m
# CONFIG_PLIP is not setCONFIG_PPP=mCONFIG_PPP_BSDCOMP=mCONFIG_PPP_DEFLATE=mCONFIG_PPP_FILTER=yCONFIG_PPP_MPPE=mCONFIG_PPP_MULTILINK=yCONFIG_PPPOATM=mCONFIG_PPPOE=mCONFIG_PPTP=mCONFIG_PPPOL2TP=mCONFIG_PPP_ASYNC=mCONFIG_PPP_SYNC_TTY=mCONFIG_SLIP=mCONFIG_SLHC=mCONFIG_SLIP_COMPRESSED=yCONFIG_SLIP_SMART=y
# CONFIG_SLIP_MODE_SLIP6 is not set
#
# USB Network Adapters
#CONFIG_USB_CATC=mCONFIG_USB_KAWETH=mCONFIG_USB_PEGASUS=mCONFIG_USB_RTL8150=mCONFIG_USB_USBNET=mCONFIG_USB_NET_AX8817X=mCONFIG_USB_NET_CDCETHER=mCONFIG_USB_NET_CDC_EEM=mCONFIG_USB_NET_CDC_NCM=mCONFIG_USB_NET_DM9601=mCONFIG_USB_NET_SMSC75XX=mCONFIG_USB_NET_SMSC95XX=mCONFIG_USB_NET_GL620A=mCONFIG_USB_NET_NET1080=mCONFIG_USB_NET_PLUSB=mCONFIG_USB_NET_MCS7830=mCONFIG_USB_NET_RNDIS_HOST=mCONFIG_USB_NET_CDC_SUBSET=mCONFIG_USB_ALI_M5632=yCONFIG_USB_AN2720=yCONFIG_USB_BELKIN=yCONFIG_USB_ARMLINUX=yCONFIG_USB_EPSON2888=yCONFIG_USB_KC2190=yCONFIG_USB_NET_ZAURUS=mCONFIG_USB_NET_CX82310_ETH=mCONFIG_USB_NET_KALMIA=mCONFIG_USB_NET_QMI_WWAN=mCONFIG_USB_HSO=mCONFIG_USB_NET_INT51X1=mCONFIG_USB_IPHETH=mCONFIG_USB_SIERRA_NET=mCONFIG_USB_VL600=mCONFIG_WLAN=y
# CONFIG_PCMCIA_RAYCS is not set
# CONFIG_LIBERTAS_THINFIRM is not set
# CONFIG_AIRO is not set
# CONFIG_ATMEL is not setCONFIG_AT76C50X_USB=m
# CONFIG_AIRO_CS is not set
# CONFIG_PCMCIA_WL3501 is not set
# CONFIG_PRISM54 is not set
# CONFIG_USB_ZD1201 is not setCONFIG_USB_NET_RNDIS_WLAN=mCONFIG_RTL8180=mCONFIG_RTL8187=mCONFIG_RTL8187_LEDS=y
# CONFIG_ADM8211 is not setCONFIG_MAC80211_HWSIM=mCONFIG_MWL8K=mCONFIG_ATH_COMMON=m
# CONFIG_ATH_DEBUG is not setCONFIG_ATH5K=mCONFIG_ATH5K_DEBUG=y
# CONFIG_ATH5K_TRACER is not setCONFIG_ATH5K_PCI=yCONFIG_ATH9K_HW=mCONFIG_ATH9K_COMMON=mCONFIG_ATH9K_BTCOEX_SUPPORT=yCONFIG_ATH9K=mCONFIG_ATH9K_PCI=yCONFIG_ATH9K_AHB=yCONFIG_ATH9K_DEBUGFS=y
# CONFIG_ATH9K_MAC_DEBUG is not setCONFIG_ATH9K_RATE_CONTROL=yCONFIG_ATH9K_HTC=m
# CONFIG_ATH9K_HTC_DEBUGFS is not setCONFIG_CARL9170=mCONFIG_CARL9170_LEDS=y
# CONFIG_CARL9170_DEBUGFS is not setCONFIG_CARL9170_WPC=y
# CONFIG_CARL9170_HWRNG is not setCONFIG_ATH6KL=mCONFIG_ATH6KL_SDIO=mCONFIG_ATH6KL_USB=mCONFIG_ATH6KL_DEBUG=yCONFIG_B43=mCONFIG_B43_BCMA=y
# CONFIG_B43_BCMA_EXTRA is not setCONFIG_B43_SSB=yCONFIG_B43_PCI_AUTOSELECT=yCONFIG_B43_PCICORE_AUTOSELECT=yCONFIG_B43_PCMCIA=yCONFIG_B43_SDIO=yCONFIG_B43_BCMA_PIO=yCONFIG_B43_PIO=yCONFIG_B43_PHY_N=yCONFIG_B43_PHY_LP=yCONFIG_B43_PHY_HT=yCONFIG_B43_LEDS=yCONFIG_B43_HWRNG=y
# CONFIG_B43_DEBUG is not setCONFIG_B43LEGACY=mCONFIG_B43LEGACY_PCI_AUTOSELECT=yCONFIG_B43LEGACY_PCICORE_AUTOSELECT=yCONFIG_B43LEGACY_LEDS=yCONFIG_B43LEGACY_HWRNG=y
# CONFIG_B43LEGACY_DEBUG is not setCONFIG_B43LEGACY_DMA=yCONFIG_B43LEGACY_PIO=yCONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
# CONFIG_B43LEGACY_DMA_MODE is not set
# CONFIG_B43LEGACY_PIO_MODE is not setCONFIG_BRCMUTIL=mCONFIG_BRCMSMAC=mCONFIG_BRCMFMAC=mCONFIG_BRCMFMAC_SDIO=yCONFIG_BRCMFMAC_SDIO_OOB=yCONFIG_BRCMFMAC_USB=y
# CONFIG_BRCMISCAN is not set
# CONFIG_BRCMDBG is not set
# CONFIG_HOSTAP is not setCONFIG_IPW2100=mCONFIG_IPW2100_MONITOR=y
# CONFIG_IPW2100_DEBUG is not setCONFIG_IPW2200=mCONFIG_IPW2200_MONITOR=yCONFIG_IPW2200_RADIOTAP=yCONFIG_IPW2200_PROMISCUOUS=yCONFIG_IPW2200_QOS=y
# CONFIG_IPW2200_DEBUG is not setCONFIG_LIBIPW=m
# CONFIG_LIBIPW_DEBUG is not setCONFIG_IWLWIFI=mCONFIG_IWLDVM=m
#
# Debugging Options
#CONFIG_IWLWIFI_DEBUG=y CONFIG_IWLWIFI_DEBUGFS=y
# CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE is not set # CONFIG_IWLWIFI_DEVICE_TRACING is not set
# CONFIG_IWLWIFI_P2P is not set
# CONFIG_IWLWIFI_EXPERIMENTAL_MFP is not set CONFIG_IWLEGACY=mCONFIG_IWL4965=mCONFIG_IWL3945=m
#
# iwl3945 / iwl4965 Debugging Options # CONFIG_IWLEGACY_DEBUG=y CONFIG_IWLEGACY_DEBUGFS=y CONFIG_LIBERTAS=m CONFIG_LIBERTAS_USB=m CONFIG_LIBERTAS_CS=m CONFIG_LIBERTAS_SDIO=m # CONFIG_LIBERTAS_DEBUG is not set CONFIG_LIBERTAS_MESH=y # CONFIG_HERMES is not set CONFIG_P54_COMMON=m CONFIG_P54_USB=m CONFIG_P54_PCI=m CONFIG_P54_LEDS=y CONFIG_RT2X00=m CONFIG_RT2400PCI=m CONFIG_RT2500PCI=m CONFIG_RT61PCI=m CONFIG_RT2800PCI=m CONFIG_RT2800PCI_RT33XX=y CONFIG_RT2800PCI_RT35XX=y CONFIG_RT2800PCI_RT53XX=y CONFIG_RT2800PCI_RT3290=y CONFIG_RT2500USB=m CONFIG_RT73USB=m CONFIG_RT2800USB=m CONFIG_RT2800USB_RT33XX=y CONFIG_RT2800USB_RT35XX=y CONFIG_RT2800USB_RT53XX=y CONFIG_RT2800USB_UNKNOWN=y CONFIG_RT2800_LIB=m CONFIG_RT2X00_LIB_PCI=m CONFIG_RT2X00_LIB_USB=m CONFIG_RT2X00_LIB=m CONFIG_RT2X00_LIB_FIRMWARE=y CONFIG_RT2X00_LIB_CRYPTO=y CONFIG_RT2X00_LIB_LEDS=y CONFIG_RT2X00_LIB_DEBUGFS=y # CONFIG_RT2X00_DEBUG is not set CONFIG_RTL8192CE=m CONFIG_RTL8192SE=m CONFIG_RTL8192DE=m CONFIG_RTL8192CU=m CONFIG_RTLWIFI=m # CONFIG_RTLWIFI_DEBUG is not set CONFIG_RTL8192C_COMMON=m # CONFIG_WL_TI is not set CONFIG_ZD1211RW=m # CONFIG_ZD1211RW_DEBUG is not set CONFIG_MWIFIEX=m CONFIG_MWIFIEX_SDIO=m CONFIG_MWIFIEX_PCIE=m CONFIG_MWIFIEX_USB=m
#
# WiMAX Wireless Broadband devices
#CONFIG_WIMAX_I2400M=mCONFIG_WIMAX_I2400M_USB=mCONFIG_WIMAX_I2400M_DEBUG_LEVEL=8
# CONFIG_WAN is not setCONFIG_IEEE802154_DRIVERS=mCONFIG_IEEE802154_FAKEHARD=mCONFIG_IEEE802154_FAKELB=mCONFIG_XEN_NETDEV_FRONTEND=mCONFIG_XEN_NETDEV_BACKEND=mCONFIG_VMXNET3=mCONFIG_HYPERV_NET=mCONFIG_ISDN=yCONFIG_ISDN_I4L=mCONFIG_ISDN_PPP=yCONFIG_ISDN_PPP_VJ=yCONFIG_ISDN_MPP=yCONFIG_IPPP_FILTER=y
# CONFIG_ISDN_PPP_BSDCOMP is not setCONFIG_ISDN_AUDIO=yCONFIG_ISDN_TTY_FAX=y
#
# ISDN feature submodules
#CONFIG_ISDN_DIVERSION=m
#
# ISDN4Linux hardware drivers
#
#
# Passive cards
#CONFIG_ISDN_DRV_HISAX=m
#
# D-channel protocol features
#CONFIG_HISAX_EURO=yCONFIG_DE_AOC=yCONFIG_HISAX_NO_SENDCOMPLETE=yCONFIG_HISAX_NO_LLC=yCONFIG_HISAX_NO_KEYPAD=yCONFIG_HISAX_1TR6=yCONFIG_HISAX_NI1=yCONFIG_HISAX_MAX_CARDS=8
#
# HiSax supported cards
#CONFIG_HISAX_16_3=yCONFIG_HISAX_TELESPCI=yCONFIG_HISAX_S0BOX=yCONFIG_HISAX_FRITZPCI=yCONFIG_HISAX_AVM_A1_PCMCIA=yCONFIG_HISAX_ELSA=yCONFIG_HISAX_DIEHLDIVA=yCONFIG_HISAX_SEDLBAUER=yCONFIG_HISAX_NETJET=yCONFIG_HISAX_NETJET_U=yCONFIG_HISAX_NICCY=yCONFIG_HISAX_BKM_A4T=yCONFIG_HISAX_SCT_QUADRO=yCONFIG_HISAX_GAZEL=yCONFIG_HISAX_HFC_PCI=yCONFIG_HISAX_W6692=yCONFIG_HISAX_HFC_SX=yCONFIG_HISAX_ENTERNOW_PCI=y
# CONFIG_HISAX_DEBUG is not set
#
# HiSax PCMCIA card service modules
#CONFIG_HISAX_SEDLBAUER_CS=mCONFIG_HISAX_ELSA_CS=mCONFIG_HISAX_AVM_A1_CS=mCONFIG_HISAX_TELES_CS=m
#
# HiSax sub driver modules
#CONFIG_HISAX_ST5481=m
# CONFIG_HISAX_HFCUSB is not setCONFIG_HISAX_HFC4S8S=mCONFIG_HISAX_FRITZ_PCIPNP=m
#
# Active cards
#CONFIG_ISDN_CAPI=mCONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
# CONFIG_CAPI_TRACE is not setCONFIG_ISDN_CAPI_MIDDLEWARE=yCONFIG_ISDN_CAPI_CAPI20=mCONFIG_ISDN_CAPI_CAPIDRV=m
#
# CAPI hardware drivers
#CONFIG_CAPI_AVM=yCONFIG_ISDN_DRV_AVMB1_B1PCI=mCONFIG_ISDN_DRV_AVMB1_B1PCIV4=yCONFIG_ISDN_DRV_AVMB1_B1PCMCIA=mCONFIG_ISDN_DRV_AVMB1_AVM_CS=mCONFIG_ISDN_DRV_AVMB1_T1PCI=mCONFIG_ISDN_DRV_AVMB1_C4=mCONFIG_CAPI_EICON=yCONFIG_ISDN_DIVAS=mCONFIG_ISDN_DIVAS_BRIPCI=yCONFIG_ISDN_DIVAS_PRIPCI=yCONFIG_ISDN_DIVAS_DIVACAPI=mCONFIG_ISDN_DIVAS_USERIDI=mCONFIG_ISDN_DIVAS_MAINT=mCONFIG_ISDN_DRV_GIGASET=mCONFIG_GIGASET_CAPI=y
# CONFIG_GIGASET_I4L is not set
# CONFIG_GIGASET_DUMMYLL is not setCONFIG_GIGASET_BASE=mCONFIG_GIGASET_M105=mCONFIG_GIGASET_M101=m
# CONFIG_GIGASET_DEBUG is not setCONFIG_HYSDN=mCONFIG_HYSDN_CAPI=yCONFIG_MISDN=mCONFIG_MISDN_DSP=mCONFIG_MISDN_L1OIP=m
#
# mISDN hardware drivers
#CONFIG_MISDN_HFCPCI=mCONFIG_MISDN_HFCMULTI=mCONFIG_MISDN_HFCUSB=mCONFIG_MISDN_AVMFRITZ=mCONFIG_MISDN_SPEEDFAX=mCONFIG_MISDN_INFINEON=mCONFIG_MISDN_W6692=mCONFIG_MISDN_NETJET=mCONFIG_MISDN_IPAC=mCONFIG_MISDN_ISAR=mCONFIG_ISDN_HDLC=m
#
# Input device support
#CONFIG_INPUT=yCONFIG_INPUT_FF_MEMLESS=yCONFIG_INPUT_POLLDEV=mCONFIG_INPUT_SPARSEKMAP=m
# CONFIG_INPUT_MATRIXKMAP is not set
#
# Userland interfaces
#CONFIG_INPUT_MOUSEDEV=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not setCONFIG_INPUT_MOUSEDEV_SCREEN_X=1024CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768CONFIG_INPUT_JOYDEV=mCONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
# Input Device Drivers
#CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_ADP5588 is not set
# CONFIG_KEYBOARD_ADP5589 is not setCONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_QT1070 is not set
# CONFIG_KEYBOARD_QT2160 is not set
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_TCA6416 is not set
# CONFIG_KEYBOARD_TCA8418 is not set
# CONFIG_KEYBOARD_LM8323 is not set
# CONFIG_KEYBOARD_LM8333 is not set
# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_MCS is not set
# CONFIG_KEYBOARD_MPR121 is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_OPENCORES is not set
# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_OMAP4 is not set
# CONFIG_KEYBOARD_XTKBD is not setCONFIG_INPUT_MOUSE=yCONFIG_MOUSE_PS2=yCONFIG_MOUSE_PS2_ALPS=yCONFIG_MOUSE_PS2_LOGIPS2PP=yCONFIG_MOUSE_PS2_SYNAPTICS=yCONFIG_MOUSE_PS2_LIFEBOOK=yCONFIG_MOUSE_PS2_TRACKPOINT=yCONFIG_MOUSE_PS2_ELANTECH=yCONFIG_MOUSE_PS2_SENTELIC=y
# CONFIG_MOUSE_PS2_TOUCHKIT is not setCONFIG_MOUSE_SERIAL=mCONFIG_MOUSE_APPLETOUCH=mCONFIG_MOUSE_BCM5974=mCONFIG_MOUSE_VSXXXAA=mCONFIG_MOUSE_SYNAPTICS_I2C=mCONFIG_MOUSE_SYNAPTICS_USB=mCONFIG_INPUT_JOYSTICK=yCONFIG_JOYSTICK_ANALOG=mCONFIG_JOYSTICK_A3D=mCONFIG_JOYSTICK_ADI=mCONFIG_JOYSTICK_COBRA=mCONFIG_JOYSTICK_GF2K=mCONFIG_JOYSTICK_GRIP=mCONFIG_JOYSTICK_GRIP_MP=mCONFIG_JOYSTICK_GUILLEMOT=mCONFIG_JOYSTICK_INTERACT=mCONFIG_JOYSTICK_SIDEWINDER=mCONFIG_JOYSTICK_TMDC=mCONFIG_JOYSTICK_IFORCE=mCONFIG_JOYSTICK_IFORCE_USB=yCONFIG_JOYSTICK_IFORCE_232=yCONFIG_JOYSTICK_WARRIOR=mCONFIG_JOYSTICK_MAGELLAN=mCONFIG_JOYSTICK_SPACEORB=mCONFIG_JOYSTICK_SPACEBALL=mCONFIG_JOYSTICK_STINGER=mCONFIG_JOYSTICK_TWIDJOY=mCONFIG_JOYSTICK_ZHENHUA=mCONFIG_JOYSTICK_DB9=mCONFIG_JOYSTICK_GAMECON=mCONFIG_JOYSTICK_TURBOGRAFX=m
# CONFIG_JOYSTICK_AS5011 is not setCONFIG_JOYSTICK_JOYDUMP=mCONFIG_JOYSTICK_XPAD=mCONFIG_JOYSTICK_XPAD_FF=yCONFIG_JOYSTICK_XPAD_LEDS=yCONFIG_JOYSTICK_WALKERA0701=mCONFIG_INPUT_TABLET=yCONFIG_TABLET_USB_ACECAD=mCONFIG_TABLET_USB_AIPTEK=mCONFIG_TABLET_USB_GTCO=mCONFIG_TABLET_USB_HANWANG=mCONFIG_TABLET_USB_KBTAB=mCONFIG_TABLET_USB_WACOM=mCONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_AD7879 is not setCONFIG_TOUCHSCREEN_ATMEL_MXT=m
# CONFIG_TOUCHSCREEN_BU21013 is not set
# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not setCONFIG_TOUCHSCREEN_DYNAPRO=m
# CONFIG_TOUCHSCREEN_HAMPSHIRE is not setCONFIG_TOUCHSCREEN_EETI=mCONFIG_TOUCHSCREEN_EGALAX=mCONFIG_TOUCHSCREEN_FUJITSU=mCONFIG_TOUCHSCREEN_ILI210X=mCONFIG_TOUCHSCREEN_GUNZE=mCONFIG_TOUCHSCREEN_ELO=mCONFIG_TOUCHSCREEN_WACOM_W8001=mCONFIG_TOUCHSCREEN_WACOM_I2C=m
# CONFIG_TOUCHSCREEN_MAX11801 is not setCONFIG_TOUCHSCREEN_MCS5000=mCONFIG_TOUCHSCREEN_MMS114=mCONFIG_TOUCHSCREEN_MTOUCH=mCONFIG_TOUCHSCREEN_INEXIO=mCONFIG_TOUCHSCREEN_MK712=mCONFIG_TOUCHSCREEN_PENMOUNT=mCONFIG_TOUCHSCREEN_EDT_FT5X06=mCONFIG_TOUCHSCREEN_TOUCHRIGHT=mCONFIG_TOUCHSCREEN_TOUCHWIN=mCONFIG_TOUCHSCREEN_PIXCIR=m
# CONFIG_TOUCHSCREEN_WM97XX is not setCONFIG_TOUCHSCREEN_USB_COMPOSITE=mCONFIG_TOUCHSCREEN_USB_EGALAX=yCONFIG_TOUCHSCREEN_USB_PANJIT=yCONFIG_TOUCHSCREEN_USB_3M=yCONFIG_TOUCHSCREEN_USB_ITM=yCONFIG_TOUCHSCREEN_USB_ETURBO=yCONFIG_TOUCHSCREEN_USB_GUNZE=yCONFIG_TOUCHSCREEN_USB_DMC_TSC10=yCONFIG_TOUCHSCREEN_USB_IRTOUCH=yCONFIG_TOUCHSCREEN_USB_IDEALTEK=yCONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=yCONFIG_TOUCHSCREEN_USB_GOTOP=yCONFIG_TOUCHSCREEN_USB_JASTEC=yCONFIG_TOUCHSCREEN_USB_ELO=yCONFIG_TOUCHSCREEN_USB_E2I=yCONFIG_TOUCHSCREEN_USB_ZYTRONIC=yCONFIG_TOUCHSCREEN_USB_ETT_TC45USB=yCONFIG_TOUCHSCREEN_USB_NEXIO=yCONFIG_TOUCHSCREEN_USB_EASYTOUCH=yCONFIG_TOUCHSCREEN_TOUCHIT213=mCONFIG_TOUCHSCREEN_TSC_SERIO=mCONFIG_TOUCHSCREEN_TSC2007=mCONFIG_TOUCHSCREEN_ST1232=m
# CONFIG_TOUCHSCREEN_TPS6507X is not setCONFIG_INPUT_MISC=y
# CONFIG_INPUT_AD714X is not set
# CONFIG_INPUT_BMA150 is not setCONFIG_INPUT_PCSPKR=mCONFIG_INPUT_MMA8450=mCONFIG_INPUT_MPU3050=mCONFIG_INPUT_APANEL=mCONFIG_INPUT_ATLAS_BTNS=mCONFIG_INPUT_ATI_REMOTE2=mCONFIG_INPUT_KEYSPAN_REMOTE=mCONFIG_INPUT_KXTJ9=m
# CONFIG_INPUT_KXTJ9_POLLED_MODE is not setCONFIG_INPUT_POWERMATE=mCONFIG_INPUT_YEALINK=mCONFIG_INPUT_CM109=mCONFIG_INPUT_UINPUT=m
# CONFIG_INPUT_PCF8574 is not set
# CONFIG_INPUT_ADXL34X is not setCONFIG_INPUT_CMA3000=mCONFIG_INPUT_CMA3000_I2C=mCONFIG_INPUT_XEN_KBDDEV_FRONTEND=y
#
# Hardware I/O ports
#CONFIG_SERIO=yCONFIG_SERIO_I8042=yCONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PARKBD is not set
# CONFIG_SERIO_PCIPS2 is not setCONFIG_SERIO_LIBPS2=yCONFIG_SERIO_RAW=mCONFIG_SERIO_ALTERA_PS2=m
# CONFIG_SERIO_PS2MULT is not setCONFIG_GAMEPORT=mCONFIG_GAMEPORT_NS558=mCONFIG_GAMEPORT_L4=mCONFIG_GAMEPORT_EMU10K1=mCONFIG_GAMEPORT_FM801=m
#
# Character devices
#CONFIG_VT=yCONFIG_CONSOLE_TRANSLATIONS=yCONFIG_VT_CONSOLE=yCONFIG_VT_CONSOLE_SLEEP=yCONFIG_HW_CONSOLE=yCONFIG_VT_HW_CONSOLE_BINDING=yCONFIG_UNIX98_PTYS=yCONFIG_DEVPTS_MULTIPLE_INSTANCES=y
# CONFIG_LEGACY_PTYS is not setCONFIG_SERIAL_NONSTANDARD=yCONFIG_ROCKETPORT=mCONFIG_CYCLADES=m
# CONFIG_CYZ_INTR is not set
# CONFIG_MOXA_INTELLIO is not set
# CONFIG_MOXA_SMARTIO is not setCONFIG_SYNCLINK=mCONFIG_SYNCLINKMP=mCONFIG_SYNCLINK_GT=mCONFIG_NOZOMI=m
# CONFIG_ISI is not setCONFIG_N_HDLC=mCONFIG_N_GSM=m
# CONFIG_TRACE_SINK is not set
# CONFIG_DEVKMEM is not set
# CONFIG_STALDRV is not set
#
# Serial drivers
#CONFIG_SERIAL_8250=yCONFIG_SERIAL_8250_PNP=yCONFIG_SERIAL_8250_CONSOLE=yCONFIG_FIX_EARLYCON_MEM=yCONFIG_SERIAL_8250_PCI=yCONFIG_SERIAL_8250_CS=mCONFIG_SERIAL_8250_NR_UARTS=32CONFIG_SERIAL_8250_RUNTIME_UARTS=4CONFIG_SERIAL_8250_EXTENDED=yCONFIG_SERIAL_8250_MANY_PORTS=yCONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not setCONFIG_SERIAL_8250_RSA=y
#
# Non-8250 serial port support
#
# CONFIG_SERIAL_KGDB_NMI is not set
# CONFIG_SERIAL_MFD_HSU is not setCONFIG_SERIAL_CORE=yCONFIG_SERIAL_CORE_CONSOLE=yCONFIG_CONSOLE_POLL=yCONFIG_SERIAL_JSM=m
# CONFIG_SERIAL_SCCNXP is not set
# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
# CONFIG_SERIAL_PCH_UART is not set
# CONFIG_SERIAL_XILINX_PS_UART is not setCONFIG_PRINTER=mCONFIG_LP_CONSOLE=yCONFIG_PPDEV=mCONFIG_HVC_DRIVER=yCONFIG_HVC_IRQ=yCONFIG_HVC_XEN=yCONFIG_HVC_XEN_FRONTEND=yCONFIG_VIRTIO_CONSOLE=yCONFIG_IPMI_HANDLER=m
# CONFIG_IPMI_PANIC_EVENT is not setCONFIG_IPMI_DEVICE_INTERFACE=mCONFIG_IPMI_SI=mCONFIG_IPMI_WATCHDOG=mCONFIG_IPMI_POWEROFF=mCONFIG_HW_RANDOM=yCONFIG_HW_RANDOM_TIMERIOMEM=mCONFIG_HW_RANDOM_INTEL=mCONFIG_HW_RANDOM_AMD=mCONFIG_HW_RANDOM_VIA=mCONFIG_HW_RANDOM_VIRTIO=mCONFIG_HW_RANDOM_TPM=mCONFIG_NVRAM=yCONFIG_R3964=m
# CONFIG_APPLICOM is not set
#
# PCMCIA character devices
#
# CONFIG_SYNCLINK_CS is not setCONFIG_CARDMAN_4000=mCONFIG_CARDMAN_4040=mCONFIG_IPWIRELESS=mCONFIG_MWAVE=mCONFIG_RAW_DRIVER=yCONFIG_MAX_RAW_DEVS=8192CONFIG_HPET=y
# CONFIG_HPET_MMAP is not setCONFIG_HANGCHECK_TIMER=mCONFIG_TCG_TPM=mCONFIG_TCG_TIS=m
# CONFIG_TCG_TIS_I2C_INFINEON is not setCONFIG_TCG_NSC=mCONFIG_TCG_ATMEL=mCONFIG_TCG_INFINEON=mCONFIG_TELCLOCK=mCONFIG_DEVPORT=yCONFIG_I2C=mCONFIG_I2C_BOARDINFO=yCONFIG_I2C_COMPAT=yCONFIG_I2C_CHARDEV=m
# CONFIG_I2C_MUX is not setCONFIG_I2C_HELPER_AUTO=yCONFIG_I2C_SMBUS=mCONFIG_I2C_ALGOBIT=mCONFIG_I2C_ALGOPCA=m
#
# I2C Hardware Bus support
#
#
# PC SMBus host controller drivers
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not setCONFIG_I2C_AMD756=mCONFIG_I2C_AMD756_S4882=mCONFIG_I2C_AMD8111=mCONFIG_I2C_I801=mCONFIG_I2C_ISCH=mCONFIG_I2C_PIIX4=mCONFIG_I2C_NFORCE2=mCONFIG_I2C_NFORCE2_S4985=m
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not setCONFIG_I2C_SIS96X=mCONFIG_I2C_VIA=mCONFIG_I2C_VIAPRO=m
#
# ACPI drivers
#CONFIG_I2C_SCMI=m
#
# I2C system bus drivers (mostly embedded / system-on-chip) #
# CONFIG_I2C_DESIGNWARE_PCI is not set
# CONFIG_I2C_EG20T is not set
# CONFIG_I2C_INTEL_MID is not set
# CONFIG_I2C_OCORES is not set CONFIG_I2C_PCA_PLATFORM=m
# CONFIG_I2C_PXA_PCI is not set CONFIG_I2C_SIMTEC=m
# CONFIG_I2C_XILINX is not set
#
# External I2C/SMBus adapter drivers
#CONFIG_I2C_DIOLAN_U2C=mCONFIG_I2C_PARPORT=mCONFIG_I2C_PARPORT_LIGHT=m
# CONFIG_I2C_TAOS_EVM is not setCONFIG_I2C_TINY_USB=m
#
# Other I2C/SMBus bus drivers
#CONFIG_I2C_STUB=m
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_SPI is not set
# CONFIG_HSI is not set
#
# PPS support
#CONFIG_PPS=m
# CONFIG_PPS_DEBUG is not set
#
# PPS clients support
#
# CONFIG_PPS_CLIENT_KTIMER is not setCONFIG_PPS_CLIENT_LDISC=mCONFIG_PPS_CLIENT_PARPORT=mCONFIG_PPS_CLIENT_GPIO=m
#
# PPS generators support
#
#
# PTP clock support
#CONFIG_PTP_1588_CLOCK=mCONFIG_DP83640_PHY=mCONFIG_PTP_1588_CLOCK_PCH=mCONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not setCONFIG_W1=mCONFIG_W1_CON=y
#
# 1-wire Bus Masters
#
# CONFIG_W1_MASTER_MATROX is not setCONFIG_W1_MASTER_DS2490=mCONFIG_W1_MASTER_DS2482=mCONFIG_W1_MASTER_DS1WM=m
# CONFIG_HDQ_MASTER_OMAP is not set
#
# 1-wire Slaves
#CONFIG_W1_SLAVE_THERM=mCONFIG_W1_SLAVE_SMEM=mCONFIG_W1_SLAVE_DS2408=mCONFIG_W1_SLAVE_DS2423=mCONFIG_W1_SLAVE_DS2431=mCONFIG_W1_SLAVE_DS2433=mCONFIG_W1_SLAVE_DS2433_CRC=yCONFIG_W1_SLAVE_DS2760=mCONFIG_W1_SLAVE_DS2780=mCONFIG_W1_SLAVE_DS2781=mCONFIG_W1_SLAVE_DS28E04=mCONFIG_W1_SLAVE_BQ27000=mCONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
# CONFIG_PDA_POWER is not set
# CONFIG_TEST_POWER is not set
# CONFIG_BATTERY_DS2760 is not set
# CONFIG_BATTERY_DS2780 is not set
# CONFIG_BATTERY_DS2781 is not set
# CONFIG_BATTERY_DS2782 is not set
# CONFIG_BATTERY_SBS is not set
# CONFIG_BATTERY_BQ27x00 is not set
# CONFIG_BATTERY_MAX17040 is not set
# CONFIG_BATTERY_MAX17042 is not set
# CONFIG_CHARGER_ISP1704 is not set
# CONFIG_CHARGER_MAX8903 is not set
# CONFIG_CHARGER_LP8727 is not setCONFIG_CHARGER_SMB347=m
# CONFIG_POWER_AVS is not setCONFIG_HWMON=yCONFIG_HWMON_VID=m
# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Native drivers
#CONFIG_SENSORS_ABITUGURU=mCONFIG_SENSORS_ABITUGURU3=mCONFIG_SENSORS_AD7414=mCONFIG_SENSORS_AD7418=mCONFIG_SENSORS_ADM1021=mCONFIG_SENSORS_ADM1025=mCONFIG_SENSORS_ADM1026=mCONFIG_SENSORS_ADM1029=mCONFIG_SENSORS_ADM1031=mCONFIG_SENSORS_ADM9240=m
# CONFIG_SENSORS_ADT7410 is not setCONFIG_SENSORS_ADT7411=mCONFIG_SENSORS_ADT7462=mCONFIG_SENSORS_ADT7470=mCONFIG_SENSORS_ADT7475=mCONFIG_SENSORS_ASC7621=mCONFIG_SENSORS_K8TEMP=mCONFIG_SENSORS_K10TEMP=mCONFIG_SENSORS_FAM15H_POWER=mCONFIG_SENSORS_ASB100=mCONFIG_SENSORS_ATXP1=mCONFIG_SENSORS_DS620=mCONFIG_SENSORS_DS1621=mCONFIG_SENSORS_I5K_AMB=mCONFIG_SENSORS_F71805F=mCONFIG_SENSORS_F71882FG=mCONFIG_SENSORS_F75375S=mCONFIG_SENSORS_FSCHMD=mCONFIG_SENSORS_G760A=mCONFIG_SENSORS_GL518SM=mCONFIG_SENSORS_GL520SM=m
# CONFIG_SENSORS_HIH6130 is not setCONFIG_SENSORS_CORETEMP=mCONFIG_SENSORS_IBMAEM=mCONFIG_SENSORS_IBMPEX=mCONFIG_SENSORS_IT87=m
# CONFIG_SENSORS_JC42 is not setCONFIG_SENSORS_LINEAGE=mCONFIG_SENSORS_LM63=mCONFIG_SENSORS_LM73=mCONFIG_SENSORS_LM75=mCONFIG_SENSORS_LM77=mCONFIG_SENSORS_LM78=mCONFIG_SENSORS_LM80=mCONFIG_SENSORS_LM83=mCONFIG_SENSORS_LM85=mCONFIG_SENSORS_LM87=mCONFIG_SENSORS_LM90=mCONFIG_SENSORS_LM92=mCONFIG_SENSORS_LM93=mCONFIG_SENSORS_LTC4151=mCONFIG_SENSORS_LTC4215=mCONFIG_SENSORS_LTC4245=mCONFIG_SENSORS_LTC4261=mCONFIG_SENSORS_LM95241=mCONFIG_SENSORS_LM95245=mCONFIG_SENSORS_MAX16065=mCONFIG_SENSORS_MAX1619=mCONFIG_SENSORS_MAX1668=m
# CONFIG_SENSORS_MAX197 is not setCONFIG_SENSORS_MAX6639=mCONFIG_SENSORS_MAX6642=mCONFIG_SENSORS_MAX6650=mCONFIG_SENSORS_MCP3021=mCONFIG_SENSORS_NTC_THERMISTOR=mCONFIG_SENSORS_PC87360=mCONFIG_SENSORS_PC87427=mCONFIG_SENSORS_PCF8591=mCONFIG_PMBUS=mCONFIG_SENSORS_PMBUS=mCONFIG_SENSORS_ADM1275=mCONFIG_SENSORS_LM25066=mCONFIG_SENSORS_LTC2978=mCONFIG_SENSORS_MAX16064=mCONFIG_SENSORS_MAX34440=mCONFIG_SENSORS_MAX8688=mCONFIG_SENSORS_UCD9000=mCONFIG_SENSORS_UCD9200=mCONFIG_SENSORS_ZL6100=mCONFIG_SENSORS_SHT21=mCONFIG_SENSORS_SIS5595=m
# CONFIG_SENSORS_SMM665 is not setCONFIG_SENSORS_DME1737=mCONFIG_SENSORS_EMC1403=m
# CONFIG_SENSORS_EMC2103 is not setCONFIG_SENSORS_EMC6W201=mCONFIG_SENSORS_SMSC47M1=mCONFIG_SENSORS_SMSC47M192=mCONFIG_SENSORS_SMSC47B397=mCONFIG_SENSORS_SCH56XX_COMMON=mCONFIG_SENSORS_SCH5627=mCONFIG_SENSORS_SCH5636=mCONFIG_SENSORS_ADS1015=mCONFIG_SENSORS_ADS7828=mCONFIG_SENSORS_AMC6821=mCONFIG_SENSORS_INA2XX=mCONFIG_SENSORS_THMC50=mCONFIG_SENSORS_TMP102=mCONFIG_SENSORS_TMP401=mCONFIG_SENSORS_TMP421=mCONFIG_SENSORS_VIA_CPUTEMP=mCONFIG_SENSORS_VIA686A=mCONFIG_SENSORS_VT1211=mCONFIG_SENSORS_VT8231=mCONFIG_SENSORS_W83781D=mCONFIG_SENSORS_W83791D=mCONFIG_SENSORS_W83792D=mCONFIG_SENSORS_W83793=mCONFIG_SENSORS_W83795=m
# CONFIG_SENSORS_W83795_FANCTRL is not setCONFIG_SENSORS_W83L785TS=mCONFIG_SENSORS_W83L786NG=mCONFIG_SENSORS_W83627HF=mCONFIG_SENSORS_W83627EHF=mCONFIG_SENSORS_APPLESMC=m
#
# ACPI drivers
#CONFIG_SENSORS_ACPI_POWER=mCONFIG_SENSORS_ATK0110=mCONFIG_THERMAL=yCONFIG_THERMAL_HWMON=y
# CONFIG_CPU_THERMAL is not setCONFIG_WATCHDOG=yCONFIG_WATCHDOG_CORE=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
#
# Watchdog Device Drivers
#CONFIG_SOFT_WATCHDOG=m
# CONFIG_ACQUIRE_WDT is not set
# CONFIG_ADVANTECH_WDT is not setCONFIG_ALIM1535_WDT=mCONFIG_ALIM7101_WDT=mCONFIG_F71808E_WDT=mCONFIG_SP5100_TCO=m
# CONFIG_SC520_WDT is not setCONFIG_SBC_FITPC2_WATCHDOG=m
# CONFIG_EUROTECH_WDT is not setCONFIG_IB700_WDT=mCONFIG_IBMASR=m
# CONFIG_WAFER_WDT is not setCONFIG_I6300ESB_WDT=mCONFIG_IE6XX_WDT=mCONFIG_ITCO_WDT=mCONFIG_ITCO_VENDOR_SUPPORT=yCONFIG_IT8712F_WDT=mCONFIG_IT87_WDT=mCONFIG_HP_WATCHDOG=mCONFIG_HPWDT_NMI_DECODING=y
# CONFIG_SC1200_WDT is not set
# CONFIG_PC87413_WDT is not setCONFIG_NV_TCO=m
# CONFIG_60XX_WDT is not set
# CONFIG_SBC8360_WDT is not set
# CONFIG_CPU5_WDT is not setCONFIG_SMSC_SCH311X_WDT=m
# CONFIG_SMSC37B787_WDT is not setCONFIG_VIA_WDT=mCONFIG_W83627HF_WDT=mCONFIG_W83697HF_WDT=mCONFIG_W83697UG_WDT=mCONFIG_W83877F_WDT=mCONFIG_W83977F_WDT=mCONFIG_MACHZ_WDT=m
# CONFIG_SBC_EPX_C3_WATCHDOG is not setCONFIG_XEN_WDT=m
#
# PCI-based Watchdog Cards
#CONFIG_PCIPCWATCHDOG=mCONFIG_WDTPCI=m
#
# USB-based Watchdog Cards
#CONFIG_USBPCWATCHDOG=mCONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#CONFIG_SSB=mCONFIG_SSB_SPROM=yCONFIG_SSB_BLOCKIO=yCONFIG_SSB_PCIHOST_POSSIBLE=yCONFIG_SSB_PCIHOST=yCONFIG_SSB_B43_PCI_BRIDGE=yCONFIG_SSB_PCMCIAHOST_POSSIBLE=yCONFIG_SSB_PCMCIAHOST=yCONFIG_SSB_SDIOHOST_POSSIBLE=yCONFIG_SSB_SDIOHOST=y
# CONFIG_SSB_DEBUG is not setCONFIG_SSB_DRIVER_PCICORE_POSSIBLE=yCONFIG_SSB_DRIVER_PCICORE=yCONFIG_BCMA_POSSIBLE=y
#
# Broadcom specific AMBA
#CONFIG_BCMA=mCONFIG_BCMA_BLOCKIO=yCONFIG_BCMA_HOST_PCI_POSSIBLE=yCONFIG_BCMA_HOST_PCI=yCONFIG_BCMA_DRIVER_GMAC_CMN=y
# CONFIG_BCMA_DEBUG is not set
#
# Multifunction device drivers
#CONFIG_MFD_CORE=mCONFIG_MFD_SM501=m
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_LM3533 is not set
# CONFIG_TPS6105X is not set
# CONFIG_TPS6507X is not set
# CONFIG_MFD_TPS65217 is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_ARIZONA_I2C is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_MFD_MC13XXX_I2C is not set
# CONFIG_ABX500_CORE is not set
# CONFIG_MFD_CS5535 is not setCONFIG_LPC_SCH=mCONFIG_LPC_ICH=m
# CONFIG_MFD_RDC321X is not set
# CONFIG_MFD_JANZ_CMODIO is not setCONFIG_MFD_VX855=mCONFIG_MFD_WL1273_CORE=m
# CONFIG_REGULATOR is not setCONFIG_MEDIA_SUPPORT=m
#
# Multimedia core support
#CONFIG_MEDIA_CAMERA_SUPPORT=yCONFIG_MEDIA_ANALOG_TV_SUPPORT=yCONFIG_MEDIA_DIGITAL_TV_SUPPORT=yCONFIG_MEDIA_RADIO_SUPPORT=yCONFIG_MEDIA_RC_SUPPORT=yCONFIG_MEDIA_CONTROLLER=yCONFIG_VIDEO_DEV=mCONFIG_VIDEO_V4L2_SUBDEV_API=yCONFIG_VIDEO_V4L2=m
# CONFIG_VIDEO_ADV_DEBUG is not set
# CONFIG_VIDEO_FIXED_MINOR_RANGES is not setCONFIG_DVB_CORE=mCONFIG_DVB_NET=yCONFIG_DVB_MAX_ADAPTERS=8CONFIG_DVB_DYNAMIC_MINORS=y
#
# Media drivers
#CONFIG_RC_CORE=mCONFIG_RC_MAP=mCONFIG_RC_DECODERS=yCONFIG_LIRC=mCONFIG_IR_LIRC_CODEC=mCONFIG_IR_NEC_DECODER=mCONFIG_IR_RC5_DECODER=mCONFIG_IR_RC6_DECODER=mCONFIG_IR_JVC_DECODER=mCONFIG_IR_SONY_DECODER=mCONFIG_IR_RC5_SZ_DECODER=mCONFIG_IR_SANYO_DECODER=mCONFIG_IR_MCE_KBD_DECODER=mCONFIG_RC_DEVICES=yCONFIG_RC_ATI_REMOTE=mCONFIG_IR_ENE=mCONFIG_IR_IMON=mCONFIG_IR_MCEUSB=mCONFIG_IR_ITE_CIR=mCONFIG_IR_FINTEK=mCONFIG_IR_NUVOTON=mCONFIG_IR_REDRAT3=mCONFIG_IR_STREAMZAP=mCONFIG_IR_WINBOND_CIR=mCONFIG_IR_IGUANA=m
# CONFIG_IR_TTUSBIR is not setCONFIG_RC_LOOPBACK=mCONFIG_IR_GPIO_CIR=m
# CONFIG_MEDIA_USB_SUPPORT is not set
# CONFIG_MEDIA_PCI_SUPPORT is not set
# CONFIG_V4L_PLATFORM_DRIVERS is not setCONFIG_V4L_MEM2MEM_DRIVERS=y
# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set
# CONFIG_V4L_TEST_DRIVERS is not set
#
# Supported MMC/SDIO adapters
#CONFIG_SMS_SDIO_DRV=m
# CONFIG_MEDIA_PARPORT_SUPPORT is not setCONFIG_RADIO_ADAPTERS=yCONFIG_RADIO_SI470X=yCONFIG_USB_SI470X=mCONFIG_I2C_SI470X=mCONFIG_USB_MR800=mCONFIG_USB_DSBR=mCONFIG_RADIO_MAXIRADIO=mCONFIG_RADIO_SHARK=mCONFIG_RADIO_SHARK2=mCONFIG_I2C_SI4713=mCONFIG_RADIO_SI4713=mCONFIG_USB_KEENE=mCONFIG_RADIO_TEA5764=mCONFIG_RADIO_SAA7706H=m
# CONFIG_RADIO_TEF6862 is not setCONFIG_RADIO_WL1273=m
#
# Texas Instruments WL128x FM driver (ST based)
#
#
# Supported FireWire (IEEE 1394) Adapters
#CONFIG_DVB_FIREDTV=mCONFIG_DVB_FIREDTV_INPUT=yCONFIG_SMS_SIANO_MDTV=mCONFIG_MEDIA_SUBDRV_AUTOSELECT=y
#
# Media ancillary drivers (tuners, sensors, i2c, frontends) #CONFIG_VIDEO_IR_I2C=m
#
# Audio decoders, processors and mixers
#
#
# RDS decoders
#
#
# Video decoders
#
#
# Video and audio decoders
#
#
# MPEG video encoders
#
#
# Video encoders
#
#
# Camera sensor devices
#
#
# Flash devices
#
#
# Video improvement chips
#
#
# Miscelaneous helper chips
#
#
# Sensors used on soc_camera driver
#CONFIG_MEDIA_ATTACH=yCONFIG_MEDIA_TUNER=mCONFIG_MEDIA_TUNER_SIMPLE=mCONFIG_MEDIA_TUNER_TDA8290=mCONFIG_MEDIA_TUNER_TDA827X=mCONFIG_MEDIA_TUNER_TDA18271=mCONFIG_MEDIA_TUNER_TDA9887=mCONFIG_MEDIA_TUNER_TEA5761=mCONFIG_MEDIA_TUNER_TEA5767=mCONFIG_MEDIA_TUNER_MT20XX=mCONFIG_MEDIA_TUNER_XC2028=mCONFIG_MEDIA_TUNER_XC5000=mCONFIG_MEDIA_TUNER_XC4000=mCONFIG_MEDIA_TUNER_MC44S803=m
#
# Multistandard (satellite) frontends
#
#
# Multistandard (cable + terrestrial) frontends
#
#
# DVB-S (satellite) frontends
#
#
# DVB-T (terrestrial) frontends
#
#
# DVB-C (cable) frontends
#
#
# ATSC (North American/Korean Terrestrial/Cable DTV) frontends #
#
# ISDB-T (terrestrial) frontends
#
#
# Digital terrestrial only tuners/PLL
#
#
# SEC control devices for DVB-S
#
#
# Tools to develop new frontends
#
# CONFIG_DVB_DUMMY_FE is not set
#
# Graphics support
#CONFIG_AGP=yCONFIG_AGP_AMD64=yCONFIG_AGP_INTEL=yCONFIG_AGP_SIS=yCONFIG_AGP_VIA=yCONFIG_VGA_ARB=yCONFIG_VGA_ARB_MAX_GPUS=16CONFIG_VGA_SWITCHEROO=yCONFIG_DRM=mCONFIG_DRM_USB=mCONFIG_DRM_KMS_HELPER=mCONFIG_DRM_LOAD_EDID_FIRMWARE=yCONFIG_DRM_TTM=m
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not setCONFIG_DRM_RADEON=mCONFIG_DRM_RADEON_KMS=yCONFIG_DRM_NOUVEAU=mCONFIG_NOUVEAU_DEBUG=5CONFIG_NOUVEAU_DEBUG_DEFAULT=3CONFIG_DRM_NOUVEAU_BACKLIGHT=y
#
# I2C encoder or helper chips
#CONFIG_DRM_I2C_CH7006=mCONFIG_DRM_I2C_SIL164=m
# CONFIG_DRM_I810 is not setCONFIG_DRM_I915=mCONFIG_DRM_I915_KMS=y
# CONFIG_DRM_MGA is not set
# CONFIG_DRM_SIS is not setCONFIG_DRM_VIA=m
# CONFIG_DRM_SAVAGE is not setCONFIG_DRM_VMWGFX=m
# CONFIG_DRM_VMWGFX_FBCON is not setCONFIG_DRM_GMA500=m
# CONFIG_DRM_GMA600 is not setCONFIG_DRM_GMA3600=yCONFIG_DRM_UDL=mCONFIG_DRM_AST=mCONFIG_DRM_MGAG200=mCONFIG_DRM_CIRRUS_QEMU=m
# CONFIG_STUB_POULSBO is not setCONFIG_VGASTATE=mCONFIG_VIDEO_OUTPUT_CONTROL=mCONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not setCONFIG_FB_BOOT_VESA_SUPPORT=yCONFIG_FB_CFB_FILLRECT=yCONFIG_FB_CFB_COPYAREA=yCONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not setCONFIG_FB_SYS_FILLRECT=yCONFIG_FB_SYS_COPYAREA=yCONFIG_FB_SYS_IMAGEBLIT=y
# CONFIG_FB_FOREIGN_ENDIAN is not setCONFIG_FB_SYS_FOPS=y
# CONFIG_FB_WMT_GE_ROPS is not setCONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not setCONFIG_FB_BACKLIGHT=y
# CONFIG_FB_MODE_HELPERS is not setCONFIG_FB_TILEBLITTING=y
#
# Frame buffer hardware drivers
#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ARC is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not setCONFIG_FB_VGA16=m
# CONFIG_FB_UVESA is not setCONFIG_FB_VESA=yCONFIG_FB_EFI=y
# CONFIG_FB_N411 is not set
# CONFIG_FB_HGA is not set
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_I740 is not set
# CONFIG_FB_LE80578 is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_VIA is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not setCONFIG_FB_VOODOO1=m
# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_ARK is not set
# CONFIG_FB_PM3 is not set
# CONFIG_FB_CARMINE is not set
# CONFIG_FB_GEODE is not set
# CONFIG_FB_TMIO is not set
# CONFIG_FB_SM501 is not set
# CONFIG_FB_SMSCUFX is not set
# CONFIG_FB_UDL is not setCONFIG_FB_VIRTUAL=mCONFIG_XEN_FBDEV_FRONTEND=y
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
# CONFIG_FB_BROADSHEET is not set
# CONFIG_FB_AUO_K190X is not set
# CONFIG_EXYNOS_VIDEO is not setCONFIG_BACKLIGHT_LCD_SUPPORT=yCONFIG_LCD_CLASS_DEVICE=mCONFIG_LCD_PLATFORM=mCONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_GENERIC is not setCONFIG_BACKLIGHT_APPLE=m
# CONFIG_BACKLIGHT_SAHARA is not set
# CONFIG_BACKLIGHT_ADP8860 is not set
# CONFIG_BACKLIGHT_ADP8870 is not set
# CONFIG_BACKLIGHT_LM3630 is not set
# CONFIG_BACKLIGHT_LM3639 is not setCONFIG_BACKLIGHT_LP855X=m
#
# Console display driver support
#CONFIG_VGA_CONSOLE=yCONFIG_VGACON_SOFT_SCROLLBACK=yCONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64CONFIG_DUMMY_CONSOLE=yCONFIG_FRAMEBUFFER_CONSOLE=yCONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=yCONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=yCONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not setCONFIG_LOGO_LINUX_CLUT224=yCONFIG_SOUND=mCONFIG_SOUND_OSS_CORE=yCONFIG_SOUND_OSS_CORE_PRECLAIM=yCONFIG_SND=mCONFIG_SND_TIMER=mCONFIG_SND_PCM=mCONFIG_SND_HWDEP=mCONFIG_SND_RAWMIDI=mCONFIG_SND_JACK=yCONFIG_SND_SEQUENCER=mCONFIG_SND_SEQ_DUMMY=mCONFIG_SND_OSSEMUL=yCONFIG_SND_MIXER_OSS=mCONFIG_SND_PCM_OSS=mCONFIG_SND_PCM_OSS_PLUGINS=yCONFIG_SND_SEQUENCER_OSS=yCONFIG_SND_HRTIMER=mCONFIG_SND_SEQ_HRTIMER_DEFAULT=yCONFIG_SND_DYNAMIC_MINORS=y
# CONFIG_SND_SUPPORT_OLD_API is not setCONFIG_SND_VERBOSE_PROCFS=yCONFIG_SND_VERBOSE_PRINTK=yCONFIG_SND_DEBUG=y
# CONFIG_SND_DEBUG_VERBOSE is not setCONFIG_SND_PCM_XRUN_DEBUG=yCONFIG_SND_VMASTER=yCONFIG_SND_KCTL_JACK=yCONFIG_SND_DMA_SGBUF=yCONFIG_SND_RAWMIDI_SEQ=mCONFIG_SND_OPL3_LIB_SEQ=m
# CONFIG_SND_OPL4_LIB_SEQ is not set
# CONFIG_SND_SBAWE_SEQ is not setCONFIG_SND_EMU10K1_SEQ=mCONFIG_SND_MPU401_UART=mCONFIG_SND_OPL3_LIB=mCONFIG_SND_VX_LIB=mCONFIG_SND_AC97_CODEC=mCONFIG_SND_DRIVERS=yCONFIG_SND_PCSP=mCONFIG_SND_DUMMY=mCONFIG_SND_ALOOP=mCONFIG_SND_VIRMIDI=mCONFIG_SND_MTPAV=mCONFIG_SND_MTS64=mCONFIG_SND_SERIAL_U16550=mCONFIG_SND_MPU401=mCONFIG_SND_PORTMAN2X4=mCONFIG_SND_AC97_POWER_SAVE=yCONFIG_SND_AC97_POWER_SAVE_DEFAULT=0CONFIG_SND_SB_COMMON=mCONFIG_SND_SB16_DSP=mCONFIG_SND_TEA575X=mCONFIG_SND_PCI=yCONFIG_SND_AD1889=mCONFIG_SND_ALS300=mCONFIG_SND_ALS4000=mCONFIG_SND_ALI5451=mCONFIG_SND_ASIHPI=mCONFIG_SND_ATIIXP=mCONFIG_SND_ATIIXP_MODEM=mCONFIG_SND_AU8810=mCONFIG_SND_AU8820=mCONFIG_SND_AU8830=m
# CONFIG_SND_AW2 is not setCONFIG_SND_AZT3328=mCONFIG_SND_BT87X=m
# CONFIG_SND_BT87X_OVERCLOCK is not setCONFIG_SND_CA0106=mCONFIG_SND_CMIPCI=mCONFIG_SND_OXYGEN_LIB=mCONFIG_SND_OXYGEN=mCONFIG_SND_CS4281=mCONFIG_SND_CS46XX=mCONFIG_SND_CS46XX_NEW_DSP=yCONFIG_SND_CS5530=mCONFIG_SND_CS5535AUDIO=mCONFIG_SND_CTXFI=mCONFIG_SND_DARLA20=mCONFIG_SND_GINA20=mCONFIG_SND_LAYLA20=mCONFIG_SND_DARLA24=mCONFIG_SND_GINA24=mCONFIG_SND_LAYLA24=mCONFIG_SND_MONA=mCONFIG_SND_MIA=mCONFIG_SND_ECHO3G=mCONFIG_SND_INDIGO=mCONFIG_SND_INDIGOIO=mCONFIG_SND_INDIGODJ=mCONFIG_SND_INDIGOIOX=mCONFIG_SND_INDIGODJX=mCONFIG_SND_EMU10K1=mCONFIG_SND_EMU10K1X=mCONFIG_SND_ENS1370=mCONFIG_SND_ENS1371=mCONFIG_SND_ES1938=mCONFIG_SND_ES1968=mCONFIG_SND_ES1968_INPUT=yCONFIG_SND_ES1968_RADIO=yCONFIG_SND_FM801=mCONFIG_SND_FM801_TEA575X_BOOL=yCONFIG_SND_HDA_INTEL=mCONFIG_SND_HDA_PREALLOC_SIZE=4096CONFIG_SND_HDA_HWDEP=yCONFIG_SND_HDA_RECONFIG=yCONFIG_SND_HDA_INPUT_BEEP=yCONFIG_SND_HDA_INPUT_BEEP_MODE=0CONFIG_SND_HDA_INPUT_JACK=yCONFIG_SND_HDA_PATCH_LOADER=yCONFIG_SND_HDA_CODEC_REALTEK=yCONFIG_SND_HDA_CODEC_ANALOG=yCONFIG_SND_HDA_CODEC_SIGMATEL=yCONFIG_SND_HDA_CODEC_VIA=yCONFIG_SND_HDA_CODEC_HDMI=yCONFIG_SND_HDA_CODEC_CIRRUS=yCONFIG_SND_HDA_CODEC_CONEXANT=yCONFIG_SND_HDA_CODEC_CA0110=yCONFIG_SND_HDA_CODEC_CA0132=yCONFIG_SND_HDA_CODEC_CMEDIA=yCONFIG_SND_HDA_CODEC_SI3054=yCONFIG_SND_HDA_GENERIC=yCONFIG_SND_HDA_POWER_SAVE_DEFAULT=0CONFIG_SND_HDSP=mCONFIG_SND_HDSPM=mCONFIG_SND_ICE1712=mCONFIG_SND_ICE1724=mCONFIG_SND_INTEL8X0=mCONFIG_SND_INTEL8X0M=mCONFIG_SND_KORG1212=mCONFIG_SND_LOLA=mCONFIG_SND_LX6464ES=mCONFIG_SND_MAESTRO3=mCONFIG_SND_MAESTRO3_INPUT=yCONFIG_SND_MIXART=mCONFIG_SND_NM256=mCONFIG_SND_PCXHR=mCONFIG_SND_RIPTIDE=mCONFIG_SND_RME32=mCONFIG_SND_RME96=mCONFIG_SND_RME9652=mCONFIG_SND_SONICVIBES=mCONFIG_SND_TRIDENT=mCONFIG_SND_VIA82XX=mCONFIG_SND_VIA82XX_MODEM=mCONFIG_SND_VIRTUOSO=mCONFIG_SND_VX222=mCONFIG_SND_YMFPCI=mCONFIG_SND_USB=yCONFIG_SND_USB_AUDIO=mCONFIG_SND_USB_UA101=mCONFIG_SND_USB_USX2Y=mCONFIG_SND_USB_CAIAQ=mCONFIG_SND_USB_CAIAQ_INPUT=yCONFIG_SND_USB_US122L=mCONFIG_SND_USB_6FIRE=mCONFIG_SND_FIREWIRE=yCONFIG_SND_FIREWIRE_LIB=mCONFIG_SND_FIREWIRE_SPEAKERS=mCONFIG_SND_ISIGHT=m
# CONFIG_SND_PCMCIA is not set
# CONFIG_SND_SOC is not set
# CONFIG_SOUND_PRIME is not setCONFIG_AC97_BUS=m
#
# HID support
#CONFIG_HID=yCONFIG_HID_BATTERY_STRENGTH=yCONFIG_HIDRAW=yCONFIG_UHID=mCONFIG_HID_GENERIC=y
#
# Special HID drivers
#CONFIG_HID_A4TECH=yCONFIG_HID_ACRUX=mCONFIG_HID_ACRUX_FF=yCONFIG_HID_APPLE=yCONFIG_HID_AUREAL=mCONFIG_HID_BELKIN=yCONFIG_HID_CHERRY=yCONFIG_HID_CHICONY=yCONFIG_HID_PRODIKEYS=mCONFIG_HID_CYPRESS=yCONFIG_HID_DRAGONRISE=mCONFIG_DRAGONRISE_FF=yCONFIG_HID_EMS_FF=mCONFIG_HID_ELECOM=mCONFIG_HID_EZKEY=yCONFIG_HID_HOLTEK=mCONFIG_HOLTEK_FF=yCONFIG_HID_KEYTOUCH=mCONFIG_HID_KYE=mCONFIG_HID_UCLOGIC=mCONFIG_HID_WALTOP=mCONFIG_HID_GYRATION=mCONFIG_HID_TWINHAN=mCONFIG_HID_KENSINGTON=yCONFIG_HID_LCPOWER=mCONFIG_HID_LENOVO_TPKBD=mCONFIG_HID_LOGITECH=yCONFIG_HID_LOGITECH_DJ=mCONFIG_LOGITECH_FF=yCONFIG_LOGIRUMBLEPAD2_FF=yCONFIG_LOGIG940_FF=yCONFIG_LOGIWHEELS_FF=yCONFIG_HID_MAGICMOUSE=mCONFIG_HID_MICROSOFT=yCONFIG_HID_MONTEREY=yCONFIG_HID_MULTITOUCH=mCONFIG_HID_NTRIG=yCONFIG_HID_ORTEK=mCONFIG_HID_PANTHERLORD=mCONFIG_PANTHERLORD_FF=yCONFIG_HID_PETALYNX=mCONFIG_HID_PICOLCD=mCONFIG_HID_PICOLCD_FB=yCONFIG_HID_PICOLCD_BACKLIGHT=yCONFIG_HID_PICOLCD_LCD=yCONFIG_HID_PICOLCD_LEDS=yCONFIG_HID_PICOLCD_CIR=yCONFIG_HID_PRIMAX=m
# CONFIG_HID_PS3REMOTE is not setCONFIG_HID_ROCCAT=mCONFIG_HID_SAITEK=mCONFIG_HID_SAMSUNG=mCONFIG_HID_SONY=mCONFIG_HID_SPEEDLINK=mCONFIG_HID_SUNPLUS=mCONFIG_HID_GREENASIA=mCONFIG_GREENASIA_FF=yCONFIG_HID_HYPERV_MOUSE=mCONFIG_HID_SMARTJOYPLUS=mCONFIG_SMARTJOYPLUS_FF=yCONFIG_HID_TIVO=mCONFIG_HID_TOPSEED=mCONFIG_HID_THRUSTMASTER=mCONFIG_THRUSTMASTER_FF=yCONFIG_HID_WACOM=mCONFIG_HID_WIIMOTE=mCONFIG_HID_WIIMOTE_EXT=yCONFIG_HID_ZEROPLUS=mCONFIG_ZEROPLUS_FF=yCONFIG_HID_ZYDACRON=m
# CONFIG_HID_SENSOR_HUB is not set
#
# USB HID support
#CONFIG_USB_HID=yCONFIG_HID_PID=yCONFIG_USB_HIDDEV=yCONFIG_USB_ARCH_HAS_OHCI=yCONFIG_USB_ARCH_HAS_EHCI=yCONFIG_USB_ARCH_HAS_XHCI=yCONFIG_USB_SUPPORT=yCONFIG_USB_COMMON=yCONFIG_USB_ARCH_HAS_HCD=yCONFIG_USB=y
# CONFIG_USB_DEBUG is not setCONFIG_USB_ANNOUNCE_NEW_DEVICES=y
#
# Miscellaneous USB options
#
# CONFIG_USB_DYNAMIC_MINORS is not setCONFIG_USB_SUSPEND=y
# CONFIG_USB_OTG is not setCONFIG_USB_MON=yCONFIG_USB_WUSB=mCONFIG_USB_WUSB_CBAF=m
# CONFIG_USB_WUSB_CBAF_DEBUG is not set
#
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not setCONFIG_USB_XHCI_HCD=y
# CONFIG_USB_XHCI_HCD_DEBUGGING is not setCONFIG_USB_EHCI_HCD=yCONFIG_USB_EHCI_ROOT_HUB_TT=yCONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not setCONFIG_USB_ISP1362_HCD=mCONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_HCD_PLATFORM is not set
# CONFIG_USB_EHCI_HCD_PLATFORM is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not setCONFIG_USB_OHCI_LITTLE_ENDIAN=yCONFIG_USB_UHCI_HCD=yCONFIG_USB_U132_HCD=mCONFIG_USB_SL811_HCD=mCONFIG_USB_SL811_HCD_ISO=y
# CONFIG_USB_SL811_CS is not set
# CONFIG_USB_R8A66597_HCD is not setCONFIG_USB_WHCI_HCD=mCONFIG_USB_HWA_HCD=m
# CONFIG_USB_HCD_BCMA is not set
# CONFIG_USB_HCD_SSB is not set
# CONFIG_USB_CHIPIDEA is not set
#
# USB Device Class drivers
#CONFIG_USB_ACM=mCONFIG_USB_PRINTER=mCONFIG_USB_WDM=mCONFIG_USB_TMC=m
#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may #
#
# also be needed; see USB_STORAGE Help for more info # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set CONFIG_USB_STORAGE_REALTEK=m CONFIG_REALTEK_AUTOPM=y CONFIG_USB_STORAGE_DATAFAB=m CONFIG_USB_STORAGE_FREECOM=m CONFIG_USB_STORAGE_ISD200=m CONFIG_USB_STORAGE_USBAT=m CONFIG_USB_STORAGE_SDDR09=m CONFIG_USB_STORAGE_SDDR55=m CONFIG_USB_STORAGE_JUMPSHOT=m CONFIG_USB_STORAGE_ALAUDA=m CONFIG_USB_STORAGE_ONETOUCH=m CONFIG_USB_STORAGE_KARMA=m CONFIG_USB_STORAGE_CYPRESS_ATACB=m CONFIG_USB_STORAGE_ENE_UB6250=m # CONFIG_USB_UAS is not set
#
# USB Imaging devices
#CONFIG_USB_MDC800=mCONFIG_USB_MICROTEK=m
#
# USB port drivers
#CONFIG_USB_USS720=mCONFIG_USB_SERIAL=yCONFIG_USB_SERIAL_CONSOLE=yCONFIG_USB_SERIAL_GENERIC=yCONFIG_USB_SERIAL_AIRCABLE=mCONFIG_USB_SERIAL_ARK3116=mCONFIG_USB_SERIAL_BELKIN=mCONFIG_USB_SERIAL_CH341=mCONFIG_USB_SERIAL_WHITEHEAT=mCONFIG_USB_SERIAL_DIGI_ACCELEPORT=mCONFIG_USB_SERIAL_CP210X=mCONFIG_USB_SERIAL_CYPRESS_M8=mCONFIG_USB_SERIAL_EMPEG=mCONFIG_USB_SERIAL_FTDI_SIO=mCONFIG_USB_SERIAL_FUNSOFT=mCONFIG_USB_SERIAL_VISOR=mCONFIG_USB_SERIAL_IPAQ=mCONFIG_USB_SERIAL_IR=mCONFIG_USB_SERIAL_EDGEPORT=mCONFIG_USB_SERIAL_EDGEPORT_TI=m
# CONFIG_USB_SERIAL_F81232 is not setCONFIG_USB_SERIAL_GARMIN=mCONFIG_USB_SERIAL_IPW=mCONFIG_USB_SERIAL_IUU=mCONFIG_USB_SERIAL_KEYSPAN_PDA=mCONFIG_USB_SERIAL_KEYSPAN=mCONFIG_USB_SERIAL_KLSI=mCONFIG_USB_SERIAL_KOBIL_SCT=mCONFIG_USB_SERIAL_MCT_U232=m
# CONFIG_USB_SERIAL_METRO is not setCONFIG_USB_SERIAL_MOS7720=mCONFIG_USB_SERIAL_MOS7715_PARPORT=yCONFIG_USB_SERIAL_MOS7840=mCONFIG_USB_SERIAL_MOTOROLA=mCONFIG_USB_SERIAL_NAVMAN=mCONFIG_USB_SERIAL_PL2303=mCONFIG_USB_SERIAL_OTI6858=mCONFIG_USB_SERIAL_QCAUX=mCONFIG_USB_SERIAL_QUALCOMM=mCONFIG_USB_SERIAL_SPCP8X5=mCONFIG_USB_SERIAL_HP4X=mCONFIG_USB_SERIAL_SAFE=mCONFIG_USB_SERIAL_SAFE_PADDED=yCONFIG_USB_SERIAL_SIEMENS_MPI=mCONFIG_USB_SERIAL_SIERRAWIRELESS=mCONFIG_USB_SERIAL_SYMBOL=mCONFIG_USB_SERIAL_TI=mCONFIG_USB_SERIAL_CYBERJACK=mCONFIG_USB_SERIAL_XIRCOM=mCONFIG_USB_SERIAL_WWAN=mCONFIG_USB_SERIAL_OPTION=mCONFIG_USB_SERIAL_OMNINET=mCONFIG_USB_SERIAL_OPTICON=mCONFIG_USB_SERIAL_VIVOPAY_SERIAL=m
# CONFIG_USB_SERIAL_ZIO is not set
# CONFIG_USB_SERIAL_ZTE is not setCONFIG_USB_SERIAL_SSU100=mCONFIG_USB_SERIAL_QT2=mCONFIG_USB_SERIAL_DEBUG=m
#
# USB Miscellaneous drivers
#CONFIG_USB_EMI62=mCONFIG_USB_EMI26=mCONFIG_USB_ADUTUX=mCONFIG_USB_SEVSEG=m
# CONFIG_USB_RIO500 is not setCONFIG_USB_LEGOTOWER=mCONFIG_USB_LCD=mCONFIG_USB_LED=m
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not setCONFIG_USB_IDMOUSE=mCONFIG_USB_FTDI_ELAN=mCONFIG_USB_APPLEDISPLAY=mCONFIG_USB_SISUSBVGA=mCONFIG_USB_SISUSBVGA_CON=yCONFIG_USB_LD=mCONFIG_USB_TRANCEVIBRATOR=mCONFIG_USB_IOWARRIOR=m
# CONFIG_USB_TEST is not setCONFIG_USB_ISIGHTFW=mCONFIG_USB_YUREX=mCONFIG_USB_EZUSB_FX2=m
#
# USB Physical Layer drivers
#
# CONFIG_OMAP_USB2 is not set
# CONFIG_USB_ISP1301 is not setCONFIG_USB_ATM=mCONFIG_USB_SPEEDTOUCH=mCONFIG_USB_CXACRU=mCONFIG_USB_UEAGLEATM=mCONFIG_USB_XUSBATM=m
# CONFIG_USB_GADGET is not set
#
# OTG and related infrastructure
#CONFIG_USB_OTG_UTILS=yCONFIG_NOP_USB_XCEIV=mCONFIG_UWB=mCONFIG_UWB_HWA=mCONFIG_UWB_WHCI=mCONFIG_UWB_I1480U=mCONFIG_MMC=m
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
# CONFIG_MMC_CLKGATE is not set
#
# MMC/SD/SDIO Card Drivers
#CONFIG_MMC_BLOCK=mCONFIG_MMC_BLOCK_MINORS=8CONFIG_MMC_BLOCK_BOUNCE=yCONFIG_SDIO_UART=m
# CONFIG_MMC_TEST is not set
#
# MMC/SD/SDIO Host Controller Drivers
#CONFIG_MMC_SDHCI=mCONFIG_MMC_SDHCI_PCI=mCONFIG_MMC_RICOH_MMC=yCONFIG_MMC_SDHCI_PLTFM=mCONFIG_MMC_WBSD=mCONFIG_MMC_TIFM_SD=mCONFIG_MMC_SDRICOH_CS=mCONFIG_MMC_CB710=mCONFIG_MMC_VIA_SDMMC=mCONFIG_MMC_VUB300=mCONFIG_MMC_USHC=mCONFIG_MEMSTICK=m
# CONFIG_MEMSTICK_DEBUG is not set
#
# MemoryStick drivers
#
# CONFIG_MEMSTICK_UNSAFE_RESUME is not setCONFIG_MSPRO_BLOCK=m
#
# MemoryStick Host Controller Drivers
#CONFIG_MEMSTICK_TIFM_MS=mCONFIG_MEMSTICK_JMICRON_38X=mCONFIG_MEMSTICK_R592=mCONFIG_NEW_LEDS=yCONFIG_LEDS_CLASS=y
#
# LED drivers
#CONFIG_LEDS_LM3530=m
# CONFIG_LEDS_LM3642 is not set
# CONFIG_LEDS_PCA9532 is not setCONFIG_LEDS_LP3944=mCONFIG_LEDS_LP5521=mCONFIG_LEDS_LP5523=mCONFIG_LEDS_CLEVO_MAIL=m
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_PCA9633 is not set
# CONFIG_LEDS_BD2802 is not setCONFIG_LEDS_INTEL_SS4200=mCONFIG_LEDS_DELL_NETBOOKS=m
# CONFIG_LEDS_TCA6507 is not set
# CONFIG_LEDS_LM355x is not set
# CONFIG_LEDS_OT200 is not setCONFIG_LEDS_BLINKM=mCONFIG_LEDS_TRIGGERS=y
#
# LED Triggers
#CONFIG_LEDS_TRIGGER_TIMER=mCONFIG_LEDS_TRIGGER_ONESHOT=mCONFIG_LEDS_TRIGGER_HEARTBEAT=mCONFIG_LEDS_TRIGGER_BACKLIGHT=m
# CONFIG_LEDS_TRIGGER_CPU is not setCONFIG_LEDS_TRIGGER_DEFAULT_ON=m
#
# iptables trigger is under Netfilter config (LED target) # CONFIG_LEDS_TRIGGER_TRANSIENT=m CONFIG_ACCESSIBILITY=y CONFIG_A11Y_BRAILLE_CONSOLE=y CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_MAD=m CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_INFINIBAND_USER_MEM=y CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_MTHCA_DEBUG=y CONFIG_INFINIBAND_IPATH=m CONFIG_INFINIBAND_QIB=m CONFIG_INFINIBAND_AMSO1100=m # CONFIG_INFINIBAND_AMSO1100_DEBUG is not set CONFIG_INFINIBAND_CXGB3=m # CONFIG_INFINIBAND_CXGB3_DEBUG is not set CONFIG_INFINIBAND_CXGB4=m CONFIG_MLX4_INFINIBAND=m CONFIG_INFINIBAND_NES=m # CONFIG_INFINIBAND_NES_DEBUG is not set # CONFIG_INFINIBAND_OCRDMA is not set CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_IPOIB_CM=y CONFIG_INFINIBAND_IPOIB_DEBUG=y CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y CONFIG_INFINIBAND_SRP=m CONFIG_INFINIBAND_SRPT=m CONFIG_INFINIBAND_ISER=m CONFIG_EDAC=y
#
# Reporting subsystems
#CONFIG_EDAC_LEGACY_SYSFS=y
# CONFIG_EDAC_DEBUG is not setCONFIG_EDAC_DECODE_MCE=mCONFIG_EDAC_MCE_INJ=mCONFIG_EDAC_MM_EDAC=mCONFIG_EDAC_AMD64=m
# CONFIG_EDAC_AMD64_ERROR_INJECTION is not setCONFIG_EDAC_E752X=mCONFIG_EDAC_I82975X=mCONFIG_EDAC_I3000=mCONFIG_EDAC_I3200=mCONFIG_EDAC_X38=mCONFIG_EDAC_I5400=mCONFIG_EDAC_I7CORE=mCONFIG_EDAC_I5000=mCONFIG_EDAC_I5100=mCONFIG_EDAC_I7300=mCONFIG_EDAC_SBRIDGE=mCONFIG_RTC_LIB=yCONFIG_RTC_CLASS=yCONFIG_RTC_HCTOSYS=yCONFIG_RTC_HCTOSYS_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set
#
# RTC interfaces
#CONFIG_RTC_INTF_SYSFS=yCONFIG_RTC_INTF_PROC=yCONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
# CONFIG_RTC_DRV_TEST is not set
#
# I2C RTC drivers
#CONFIG_RTC_DRV_DS1307=mCONFIG_RTC_DRV_DS1374=mCONFIG_RTC_DRV_DS1672=mCONFIG_RTC_DRV_DS3232=mCONFIG_RTC_DRV_MAX6900=mCONFIG_RTC_DRV_RS5C372=mCONFIG_RTC_DRV_ISL1208=mCONFIG_RTC_DRV_ISL12022=mCONFIG_RTC_DRV_X1205=mCONFIG_RTC_DRV_PCF8563=mCONFIG_RTC_DRV_PCF8583=mCONFIG_RTC_DRV_M41T80=mCONFIG_RTC_DRV_M41T80_WDT=yCONFIG_RTC_DRV_BQ32K=m
# CONFIG_RTC_DRV_S35390A is not setCONFIG_RTC_DRV_FM3130=mCONFIG_RTC_DRV_RX8581=mCONFIG_RTC_DRV_RX8025=mCONFIG_RTC_DRV_EM3027=mCONFIG_RTC_DRV_RV3029C2=m
#
# SPI RTC drivers
#
#
# Platform RTC drivers
#CONFIG_RTC_DRV_CMOS=yCONFIG_RTC_DRV_DS1286=mCONFIG_RTC_DRV_DS1511=mCONFIG_RTC_DRV_DS1553=mCONFIG_RTC_DRV_DS1742=mCONFIG_RTC_DRV_STK17TA8=m
# CONFIG_RTC_DRV_M48T86 is not setCONFIG_RTC_DRV_M48T35=mCONFIG_RTC_DRV_M48T59=mCONFIG_RTC_DRV_MSM6242=mCONFIG_RTC_DRV_BQ4802=mCONFIG_RTC_DRV_RP5C01=mCONFIG_RTC_DRV_V3020=m
# CONFIG_RTC_DRV_DS2404 is not set
#
# on-CPU RTC drivers
#CONFIG_DMADEVICES=y
# CONFIG_DMADEVICES_DEBUG is not set
#
# DMA Devices
#
# CONFIG_INTEL_MID_DMAC is not setCONFIG_INTEL_IOATDMA=m
# CONFIG_TIMB_DMA is not setCONFIG_PCH_DMA=mCONFIG_DMA_ENGINE=y
#
# DMA Clients
#CONFIG_NET_DMA=yCONFIG_ASYNC_TX_DMA=y
# CONFIG_DMATEST is not setCONFIG_DCA=mCONFIG_AUXDISPLAY=yCONFIG_KS0108=mCONFIG_KS0108_PORT=0x378CONFIG_KS0108_DELAY=2CONFIG_CFAG12864B=mCONFIG_CFAG12864B_RATE=20CONFIG_UIO=mCONFIG_UIO_CIF=m
# CONFIG_UIO_PDRV is not set
# CONFIG_UIO_PDRV_GENIRQ is not setCONFIG_UIO_AEC=mCONFIG_UIO_SERCOS3=mCONFIG_UIO_PCI_GENERIC=m
# CONFIG_UIO_NETX is not set
# CONFIG_VFIO is not setCONFIG_VIRTIO=y
#
# Virtio drivers
#CONFIG_VIRTIO_PCI=yCONFIG_VIRTIO_BALLOON=mCONFIG_VIRTIO_MMIO=m
# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
#
# Microsoft Hyper-V guest support
#CONFIG_HYPERV=mCONFIG_HYPERV_UTILS=m
#
# Xen driver support
#CONFIG_XEN_BALLOON=yCONFIG_XEN_SELFBALLOONING=yCONFIG_XEN_SCRUB_PAGES=yCONFIG_XEN_DEV_EVTCHN=mCONFIG_XEN_BACKEND=yCONFIG_XENFS=mCONFIG_XEN_COMPAT_XENFS=yCONFIG_XEN_SYS_HYPERVISOR=yCONFIG_XEN_XENBUS_FRONTEND=yCONFIG_XEN_GNTDEV=mCONFIG_XEN_GRANT_DEV_ALLOC=mCONFIG_SWIOTLB_XEN=yCONFIG_XEN_TMEM=yCONFIG_XEN_PCIDEV_BACKEND=mCONFIG_XEN_PRIVCMD=mCONFIG_XEN_ACPI_PROCESSOR=m
# CONFIG_XEN_MCE_LOG is not setCONFIG_STAGING=y
# CONFIG_ET131X is not set
# CONFIG_SLICOSS is not set
# CONFIG_USBIP_CORE is not set
# CONFIG_W35UND is not set
# CONFIG_PRISM2_USB is not set
# CONFIG_ECHO is not set
# CONFIG_COMEDI is not set
# CONFIG_ASUS_OLED is not set
# CONFIG_PANEL is not set
# CONFIG_R8187SE is not set
# CONFIG_RTL8192U is not set
# CONFIG_RTLLIB is not setCONFIG_R8712U=m
# CONFIG_RTS_PSTOR is not set
# CONFIG_RTS5139 is not set
# CONFIG_TRANZPORT is not set
# CONFIG_IDE_PHISON is not set
# CONFIG_LINE6_USB is not set
# CONFIG_USB_SERIAL_QUATECH2 is not set
# CONFIG_VT6655 is not set
# CONFIG_VT6656 is not set
# CONFIG_DX_SEP is not set
# CONFIG_ZSMALLOC is not set
# CONFIG_WLAGS49_H2 is not set
# CONFIG_WLAGS49_H25 is not set
# CONFIG_FB_SM7XX is not setCONFIG_CRYSTALHD=m
# CONFIG_FB_XGI is not set
# CONFIG_ACPI_QUICKSTART is not set
# CONFIG_USB_ENESTORAGE is not set
# CONFIG_BCM_WIMAX is not set
# CONFIG_FT1000 is not set
#
# Speakup console speech
#
# CONFIG_SPEAKUP is not set
# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set CONFIG_STAGING_MEDIA=y
# CONFIG_DVB_AS102 is not set
# CONFIG_DVB_CXD2099 is not set
# CONFIG_VIDEO_DT3155 is not set
# CONFIG_VIDEO_GO7007 is not set
# CONFIG_SOLO6X10 is not set CONFIG_LIRC_STAGING=yCONFIG_LIRC_BT829=m CONFIG_LIRC_IGORPLUGUSB=m CONFIG_LIRC_IMON=mCONFIG_LIRC_PARALLEL=mCONFIG_LIRC_SASEM=mCONFIG_LIRC_SERIAL=m CONFIG_LIRC_SERIAL_TRANSMITTER=y CONFIG_LIRC_SIR=mCONFIG_LIRC_ZILOG=m
#
# Android
#
# CONFIG_ANDROID is not set
# CONFIG_PHONE is not set
# CONFIG_USB_WPAN_HCD is not set
# CONFIG_IPACK_BUS is not set
# CONFIG_WIMAX_GDM72XX is not set
# CONFIG_CSR_WIFI is not set
# CONFIG_ZCACHE2 is not setCONFIG_NET_VENDOR_SILICOM=y
# CONFIG_SBYPASS is not set
# CONFIG_BPCTL is not set
# CONFIG_CED1401 is not set
# CONFIG_DGRP is not setCONFIG_X86_PLATFORM_DEVICES=yCONFIG_ACER_WMI=mCONFIG_ACERHDF=mCONFIG_ASUS_LAPTOP=mCONFIG_DELL_LAPTOP=mCONFIG_DELL_WMI=mCONFIG_DELL_WMI_AIO=mCONFIG_FUJITSU_LAPTOP=m
# CONFIG_FUJITSU_LAPTOP_DEBUG is not setCONFIG_FUJITSU_TABLET=mCONFIG_AMILO_RFKILL=mCONFIG_HP_ACCEL=mCONFIG_HP_WMI=mCONFIG_MSI_LAPTOP=mCONFIG_PANASONIC_LAPTOP=mCONFIG_COMPAL_LAPTOP=mCONFIG_SONY_LAPTOP=mCONFIG_SONYPI_COMPAT=yCONFIG_IDEAPAD_LAPTOP=mCONFIG_THINKPAD_ACPI=mCONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y
# CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set
# CONFIG_THINKPAD_ACPI_DEBUG is not set
# CONFIG_THINKPAD_ACPI_UNSAFE_LEDS is not setCONFIG_THINKPAD_ACPI_VIDEO=yCONFIG_THINKPAD_ACPI_HOTKEY_POLL=yCONFIG_SENSORS_HDAPS=m
# CONFIG_INTEL_MENLOW is not setCONFIG_EEEPC_LAPTOP=mCONFIG_ASUS_WMI=mCONFIG_ASUS_NB_WMI=mCONFIG_EEEPC_WMI=mCONFIG_ACPI_WMI=mCONFIG_MSI_WMI=mCONFIG_TOPSTAR_LAPTOP=mCONFIG_ACPI_TOSHIBA=mCONFIG_TOSHIBA_BT_RFKILL=mCONFIG_ACPI_CMPC=mCONFIG_INTEL_IPS=m
# CONFIG_IBM_RTL is not set
# CONFIG_XO15_EBOOK is not setCONFIG_SAMSUNG_LAPTOP=mCONFIG_MXM_WMI=mCONFIG_INTEL_OAKTRAIL=mCONFIG_SAMSUNG_Q10=mCONFIG_APPLE_GMUX=m
#
# Hardware Spinlock drivers
#CONFIG_CLKEVT_I8253=yCONFIG_I8253_LOCK=yCONFIG_CLKBLD_I8253=yCONFIG_IOMMU_API=yCONFIG_IOMMU_SUPPORT=yCONFIG_AMD_IOMMU=yCONFIG_AMD_IOMMU_STATS=yCONFIG_AMD_IOMMU_V2=mCONFIG_DMAR_TABLE=yCONFIG_INTEL_IOMMU=y
# CONFIG_INTEL_IOMMU_DEFAULT_ON is not setCONFIG_INTEL_IOMMU_FLOPPY_WA=yCONFIG_IRQ_REMAP=y
#
# Remoteproc drivers (EXPERIMENTAL)
#
# CONFIG_STE_MODEM_RPROC is not set
#
# Rpmsg drivers (EXPERIMENTAL)
#
# CONFIG_VIRT_DRIVERS is not set
# CONFIG_PM_DEVFREQ is not set
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
# CONFIG_IIO is not set
# CONFIG_VME_BUS is not set
# CONFIG_PWM is not set
#
# Firmware Drivers
#CONFIG_EDD=m
# CONFIG_EDD_OFF is not setCONFIG_FIRMWARE_MEMMAP=yCONFIG_EFI_VARS=yCONFIG_DELL_RBU=mCONFIG_DCDBAS=mCONFIG_DMIID=yCONFIG_DMI_SYSFS=yCONFIG_ISCSI_IBFT_FIND=yCONFIG_ISCSI_IBFT=m
# CONFIG_GOOGLE_FIRMWARE is not set
#
# File systems
#CONFIG_DCACHE_WORD_ACCESS=y
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not setCONFIG_EXT4_FS=yCONFIG_EXT4_USE_FOR_EXT23=yCONFIG_EXT4_FS_XATTR=yCONFIG_EXT4_FS_POSIX_ACL=yCONFIG_EXT4_FS_SECURITY=y
# CONFIG_EXT4_DEBUG is not setCONFIG_JBD2=y
# CONFIG_JBD2_DEBUG is not setCONFIG_FS_MBCACHE=yCONFIG_REISERFS_FS=m
# CONFIG_REISERFS_CHECK is not setCONFIG_REISERFS_PROC_INFO=yCONFIG_REISERFS_FS_XATTR=yCONFIG_REISERFS_FS_POSIX_ACL=yCONFIG_REISERFS_FS_SECURITY=yCONFIG_JFS_FS=mCONFIG_JFS_POSIX_ACL=yCONFIG_JFS_SECURITY=y
# CONFIG_JFS_DEBUG is not set
# CONFIG_JFS_STATISTICS is not setCONFIG_XFS_FS=mCONFIG_XFS_QUOTA=yCONFIG_XFS_POSIX_ACL=y
# CONFIG_XFS_RT is not set
# CONFIG_XFS_DEBUG is not setCONFIG_GFS2_FS=mCONFIG_GFS2_FS_LOCKING_DLM=yCONFIG_OCFS2_FS=mCONFIG_OCFS2_FS_O2CB=mCONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
# CONFIG_OCFS2_FS_STATS is not set
# CONFIG_OCFS2_DEBUG_MASKLOG is not set
# CONFIG_OCFS2_DEBUG_FS is not setCONFIG_BTRFS_FS=mCONFIG_BTRFS_FS_POSIX_ACL=y
# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not setCONFIG_NILFS2_FS=mCONFIG_FS_POSIX_ACL=yCONFIG_EXPORTFS=yCONFIG_FILE_LOCKING=yCONFIG_FSNOTIFY=yCONFIG_DNOTIFY=yCONFIG_INOTIFY_USER=yCONFIG_FANOTIFY=yCONFIG_FANOTIFY_ACCESS_PERMISSIONS=yCONFIG_QUOTA=yCONFIG_QUOTA_NETLINK_INTERFACE=y
# CONFIG_PRINT_QUOTA_WARNING is not set
# CONFIG_QUOTA_DEBUG is not setCONFIG_QUOTA_TREE=y
# CONFIG_QFMT_V1 is not setCONFIG_QFMT_V2=yCONFIG_QUOTACTL=yCONFIG_QUOTACTL_COMPAT=yCONFIG_AUTOFS4_FS=yCONFIG_FUSE_FS=mCONFIG_CUSE=mCONFIG_GENERIC_ACL=y
#
# Caches
#CONFIG_FSCACHE=mCONFIG_FSCACHE_STATS=y
# CONFIG_FSCACHE_HISTOGRAM is not set
# CONFIG_FSCACHE_DEBUG is not setCONFIG_FSCACHE_OBJECT_LIST=yCONFIG_CACHEFILES=m
# CONFIG_CACHEFILES_DEBUG is not set
# CONFIG_CACHEFILES_HISTOGRAM is not set
#
# CD-ROM/DVD Filesystems
#CONFIG_ISO9660_FS=yCONFIG_JOLIET=yCONFIG_ZISOFS=yCONFIG_UDF_FS=mCONFIG_UDF_NLS=y
#
# DOS/FAT/NT Filesystems
#CONFIG_FAT_FS=mCONFIG_MSDOS_FS=mCONFIG_VFAT_FS=mCONFIG_FAT_DEFAULT_CODEPAGE=437CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#CONFIG_PROC_FS=yCONFIG_PROC_KCORE=yCONFIG_PROC_VMCORE=yCONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=yCONFIG_SYSFS=yCONFIG_TMPFS=yCONFIG_TMPFS_POSIX_ACL=yCONFIG_TMPFS_XATTR=yCONFIG_HUGETLBFS=yCONFIG_HUGETLB_PAGE=yCONFIG_CONFIGFS_FS=y CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not setCONFIG_AFFS_FS=mCONFIG_ECRYPT_FS=mCONFIG_HFS_FS=mCONFIG_HFSPLUS_FS=mCONFIG_BEFS_FS=m
# CONFIG_BEFS_DEBUG is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set CONFIG_UBIFS_FS=m
# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set CONFIG_UBIFS_FS_LZO=yCONFIG_UBIFS_FS_ZLIB=y
# CONFIG_LOGFS is not setCONFIG_CRAMFS=mCONFIG_SQUASHFS=mCONFIG_SQUASHFS_XATTR=y CONFIG_SQUASHFS_ZLIB=yCONFIG_SQUASHFS_LZO=yCONFIG_SQUASHFS_XZ=y
# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
# CONFIG_SQUASHFS_EMBEDDED is not set CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
# CONFIG_VXFS_FS is not setCONFIG_MINIX_FS=m
# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX6FS_FS is not set CONFIG_ROMFS_FS=m CONFIG_ROMFS_BACKED_BY_BLOCK=y
# CONFIG_ROMFS_BACKED_BY_MTD is not set
# CONFIG_ROMFS_BACKED_BY_BOTH is not set CONFIG_ROMFS_ON_BLOCK=yCONFIG_PSTORE=y
# CONFIG_PSTORE_CONSOLE is not set
# CONFIG_PSTORE_FTRACE is not set CONFIG_PSTORE_RAM=mCONFIG_SYSV_FS=mCONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
# CONFIG_UFS_DEBUG is not set
# CONFIG_EXOFS_FS is not setCONFIG_ORE=mCONFIG_NETWORK_FILESYSTEMS=yCONFIG_NFS_FS=mCONFIG_NFS_V2=mCONFIG_NFS_V3=mCONFIG_NFS_V3_ACL=yCONFIG_NFS_V4=m
# CONFIG_NFS_SWAP is not set CONFIG_NFS_V4_1=yCONFIG_PNFS_FILE_LAYOUT=mCONFIG_PNFS_BLOCK=mCONFIG_PNFS_OBJLAYOUT=m CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" CONFIG_NFS_FSCACHE=y
# CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y CONFIG_NFS_DEBUG=yCONFIG_NFSD=mCONFIG_NFSD_V2_ACL=yCONFIG_NFSD_V3=yCONFIG_NFSD_V3_ACL=yCONFIG_NFSD_V4=y
# CONFIG_NFSD_FAULT_INJECTION is not set CONFIG_LOCKD=mCONFIG_LOCKD_V4=yCONFIG_NFS_ACL_SUPPORT=mCONFIG_NFS_COMMON=yCONFIG_SUNRPC=mCONFIG_SUNRPC_GSS=m CONFIG_SUNRPC_BACKCHANNEL=y CONFIG_SUNRPC_XPRT_RDMA=m CONFIG_RPCSEC_GSS_KRB5=m CONFIG_SUNRPC_DEBUG=yCONFIG_CEPH_FS=mCONFIG_CIFS=mCONFIG_CIFS_STATS=y
# CONFIG_CIFS_STATS2 is not set CONFIG_CIFS_WEAK_PW_HASH=y CONFIG_CIFS_UPCALL=yCONFIG_CIFS_XATTR=yCONFIG_CIFS_POSIX=yCONFIG_CIFS_ACL=y
# CONFIG_CIFS_DEBUG2 is not set CONFIG_CIFS_DFS_UPCALL=y
# CONFIG_CIFS_SMB2 is not set CONFIG_CIFS_FSCACHE=yCONFIG_NCP_FS=mCONFIG_NCPFS_PACKET_SIGNING=y CONFIG_NCPFS_IOCTL_LOCKING=y CONFIG_NCPFS_STRONG=yCONFIG_NCPFS_NFS_NS=yCONFIG_NCPFS_OS2_NS=yCONFIG_NCPFS_SMALLDOS=yCONFIG_NCPFS_NLS=yCONFIG_NCPFS_EXTRAS=yCONFIG_CODA_FS=m
# CONFIG_AFS_FS is not setCONFIG_9P_FS=mCONFIG_9P_FSCACHE=yCONFIG_9P_FS_POSIX_ACL=yCONFIG_NLS=yCONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m CONFIG_NLS_CODEPAGE_775=m CONFIG_NLS_CODEPAGE_850=m CONFIG_NLS_CODEPAGE_852=m CONFIG_NLS_CODEPAGE_855=m CONFIG_NLS_CODEPAGE_857=m CONFIG_NLS_CODEPAGE_860=m CONFIG_NLS_CODEPAGE_861=m CONFIG_NLS_CODEPAGE_862=m CONFIG_NLS_CODEPAGE_863=m CONFIG_NLS_CODEPAGE_864=m CONFIG_NLS_CODEPAGE_865=m CONFIG_NLS_CODEPAGE_866=m CONFIG_NLS_CODEPAGE_869=m CONFIG_NLS_CODEPAGE_936=m CONFIG_NLS_CODEPAGE_950=m CONFIG_NLS_CODEPAGE_932=m CONFIG_NLS_CODEPAGE_949=m CONFIG_NLS_CODEPAGE_874=m CONFIG_NLS_ISO8859_8=m CONFIG_NLS_CODEPAGE_1250=m CONFIG_NLS_CODEPAGE_1251=mCONFIG_NLS_ASCII=yCONFIG_NLS_ISO8859_1=mCONFIG_NLS_ISO8859_2=mCONFIG_NLS_ISO8859_3=mCONFIG_NLS_ISO8859_4=mCONFIG_NLS_ISO8859_5=mCONFIG_NLS_ISO8859_6=mCONFIG_NLS_ISO8859_7=mCONFIG_NLS_ISO8859_9=m CONFIG_NLS_ISO8859_13=m CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=mCONFIG_NLS_KOI8_R=mCONFIG_NLS_KOI8_U=mCONFIG_NLS_MAC_ROMAN=m CONFIG_NLS_MAC_CELTIC=m CONFIG_NLS_MAC_CENTEURO=m CONFIG_NLS_MAC_CROATIAN=m CONFIG_NLS_MAC_CYRILLIC=m CONFIG_NLS_MAC_GAELIC=m CONFIG_NLS_MAC_GREEK=m CONFIG_NLS_MAC_ICELAND=m CONFIG_NLS_MAC_INUIT=m CONFIG_NLS_MAC_ROMANIAN=m CONFIG_NLS_MAC_TURKISH=mCONFIG_NLS_UTF8=mCONFIG_DLM=mCONFIG_DLM_DEBUG=y
#
# Kernel hacking
#CONFIG_TRACE_IRQFLAGS_SUPPORT=yCONFIG_PRINTK_TIME=yCONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
# CONFIG_ENABLE_WARN_DEPRECATED is not setCONFIG_ENABLE_MUST_CHECK=yCONFIG_FRAME_WARN=2048CONFIG_MAGIC_SYSRQ=yCONFIG_STRIP_ASM_SYMS=y
# CONFIG_READABLE_ASM is not setCONFIG_UNUSED_SYMBOLS=yCONFIG_DEBUG_FS=yCONFIG_HEADERS_CHECK=y
# CONFIG_DEBUG_SECTION_MISMATCH is not setCONFIG_DEBUG_KERNEL=yCONFIG_DEBUG_SHIRQ=yCONFIG_LOCKUP_DETECTOR=yCONFIG_HARDLOCKUP_DETECTOR=y
# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not setCONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not setCONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
# CONFIG_PANIC_ON_OOPS is not setCONFIG_PANIC_ON_OOPS_VALUE=0
# CONFIG_DETECT_HUNG_TASK is not setCONFIG_SCHED_DEBUG=yCONFIG_SCHEDSTATS=yCONFIG_TIMER_STATS=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not setCONFIG_HAVE_DEBUG_KMEMLEAK=y
# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not setCONFIG_SPARSE_RCU_POINTER=y
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_ATOMIC_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not setCONFIG_STACKTRACE=y
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_KOBJECT is not setCONFIG_DEBUG_BUGVERBOSE=yCONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_INFO_REDUCED is not setCONFIG_DEBUG_VM=y
# CONFIG_DEBUG_VM_RB is not set
# CONFIG_DEBUG_VIRTUAL is not set
# CONFIG_DEBUG_WRITECOUNT is not setCONFIG_DEBUG_MEMORY_INIT=yCONFIG_DEBUG_LIST=y
# CONFIG_TEST_LIST_SORT is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_DEBUG_CREDENTIALS is not setCONFIG_ARCH_WANT_FRAME_POINTERS=yCONFIG_FRAME_POINTER=yCONFIG_BOOT_PRINTK_DELAY=y
# CONFIG_RCU_TORTURE_TEST is not setCONFIG_RCU_CPU_STALL_TIMEOUT=60
# CONFIG_RCU_CPU_STALL_INFO is not set
# CONFIG_RCU_TRACE is not set
# CONFIG_KPROBES_SANITY_TEST is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
# CONFIG_DEBUG_PER_CPU_MAPS is not set
# CONFIG_LKDTM is not set
# CONFIG_NOTIFIER_ERROR_INJECTION is not set
# CONFIG_FAULT_INJECTION is not setCONFIG_LATENCYTOP=y
# CONFIG_DEBUG_PAGEALLOC is not setCONFIG_USER_STACKTRACE_SUPPORT=yCONFIG_NOP_TRACER=yCONFIG_HAVE_FUNCTION_TRACER=yCONFIG_HAVE_FUNCTION_GRAPH_TRACER=yCONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=yCONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=yCONFIG_HAVE_DYNAMIC_FTRACE=yCONFIG_HAVE_FTRACE_MCOUNT_RECORD=yCONFIG_HAVE_SYSCALL_TRACEPOINTS=yCONFIG_HAVE_FENTRY=yCONFIG_HAVE_C_RECORDMCOUNT=yCONFIG_TRACER_MAX_TRACE=yCONFIG_TRACE_CLOCK=yCONFIG_RING_BUFFER=yCONFIG_EVENT_TRACING=yCONFIG_EVENT_POWER_TRACING_DEPRECATED=yCONFIG_CONTEXT_SWITCH_TRACER=yCONFIG_RING_BUFFER_ALLOW_SWAP=yCONFIG_TRACING=yCONFIG_GENERIC_TRACER=yCONFIG_TRACING_SUPPORT=yCONFIG_FTRACE=yCONFIG_FUNCTION_TRACER=yCONFIG_FUNCTION_GRAPH_TRACER=y
# CONFIG_IRQSOFF_TRACER is not setCONFIG_SCHED_TRACER=yCONFIG_FTRACE_SYSCALLS=yCONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
# CONFIG_PROFILE_ALL_BRANCHES is not setCONFIG_STACK_TRACER=yCONFIG_BLK_DEV_IO_TRACE=yCONFIG_KPROBE_EVENT=yCONFIG_UPROBE_EVENT=yCONFIG_PROBE_EVENTS=yCONFIG_DYNAMIC_FTRACE=yCONFIG_FUNCTION_PROFILER=yCONFIG_FTRACE_MCOUNT_RECORD=y
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_MMIOTRACE is not setCONFIG_RING_BUFFER_BENCHMARK=m
# CONFIG_RBTREE_TEST is not set
# CONFIG_INTERVAL_TREE_TEST is not setCONFIG_PROVIDE_OHCI1394_DMA_INIT=y
# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not setCONFIG_BUILD_DOCSRC=yCONFIG_DYNAMIC_DEBUG=y
# CONFIG_DMA_API_DEBUG is not setCONFIG_ATOMIC64_SELFTEST=yCONFIG_ASYNC_RAID6_TEST=m
# CONFIG_SAMPLES is not setCONFIG_HAVE_ARCH_KGDB=yCONFIG_KGDB=yCONFIG_KGDB_SERIAL_CONSOLE=yCONFIG_KGDB_TESTS=y
# CONFIG_KGDB_TESTS_ON_BOOT is not setCONFIG_KGDB_LOW_LEVEL_TRAP=yCONFIG_KGDB_KDB=yCONFIG_KDB_KEYBOARD=yCONFIG_HAVE_ARCH_KMEMCHECK=yCONFIG_TEST_KSTRTOX=yCONFIG_STRICT_DEVMEM=y
# CONFIG_X86_VERBOSE_BOOTUP is not setCONFIG_EARLY_PRINTK=yCONFIG_EARLY_PRINTK_DBGP=yCONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_X86_PTDUMP is not setCONFIG_DEBUG_RODATA=yCONFIG_DEBUG_RODATA_TEST=yCONFIG_DEBUG_SET_MODULE_RONX=yCONFIG_DEBUG_NX_TEST=m
# CONFIG_DEBUG_TLBFLUSH is not set
# CONFIG_IOMMU_DEBUG is not set
# CONFIG_IOMMU_STRESS is not setCONFIG_HAVE_MMIOTRACE_SUPPORT=yCONFIG_X86_DECODER_SELFTEST=yCONFIG_IO_DELAY_TYPE_0X80=0CONFIG_IO_DELAY_TYPE_0XED=1CONFIG_IO_DELAY_TYPE_UDELAY=2CONFIG_IO_DELAY_TYPE_NONE=3CONFIG_IO_DELAY_0X80=y
# CONFIG_IO_DELAY_0XED is not set
# CONFIG_IO_DELAY_UDELAY is not set
# CONFIG_IO_DELAY_NONE is not setCONFIG_DEFAULT_IO_DELAY_TYPE=0CONFIG_DEBUG_BOOT_PARAMS=y
# CONFIG_CPA_DEBUG is not setCONFIG_OPTIMIZE_INLINING=y
# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
# CONFIG_DEBUG_NMI_SELFTEST is not set
#
# Security options
#CONFIG_KEYS=yCONFIG_TRUSTED_KEYS=mCONFIG_ENCRYPTED_KEYS=m CONFIG_KEYS_DEBUG_PROC_KEYS=y
# CONFIG_SECURITY_DMESG_RESTRICT is not set CONFIG_SECURITY=yCONFIG_SECURITYFS=yCONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y
# CONFIG_SECURITY_PATH is not set CONFIG_INTEL_TXT=y CONFIG_LSM_MMAP_MIN_ADDR=65536 CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 CONFIG_SECURITY_SELINUX_DISABLE=y CONFIG_SECURITY_SELINUX_DEVELOP=y CONFIG_SECURITY_SELINUX_AVC_STATS=y CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set # CONFIG_SECURITY_SMACK is not set
# CONFIG_SECURITY_TOMOYO is not set
# CONFIG_SECURITY_APPARMOR is not set
# CONFIG_SECURITY_YAMA is not set
# CONFIG_IMA is not set CONFIG_DEFAULT_SECURITY_SELINUX=y
# CONFIG_DEFAULT_SECURITY_DAC is not set CONFIG_DEFAULT_SECURITY="selinux" CONFIG_XOR_BLOCKS=mCONFIG_ASYNC_CORE=mCONFIG_ASYNC_MEMCPY=mCONFIG_ASYNC_XOR=mCONFIG_ASYNC_PQ=mCONFIG_ASYNC_RAID6_RECOV=m CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA=y CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA=y CONFIG_CRYPTO=y
#
# Crypto core or helper
#CONFIG_CRYPTO_FIPS=yCONFIG_CRYPTO_ALGAPI=yCONFIG_CRYPTO_ALGAPI2=yCONFIG_CRYPTO_AEAD=yCONFIG_CRYPTO_AEAD2=yCONFIG_CRYPTO_BLKCIPHER=yCONFIG_CRYPTO_BLKCIPHER2=yCONFIG_CRYPTO_HASH=yCONFIG_CRYPTO_HASH2=yCONFIG_CRYPTO_RNG=yCONFIG_CRYPTO_RNG2=yCONFIG_CRYPTO_PCOMP=mCONFIG_CRYPTO_PCOMP2=yCONFIG_CRYPTO_MANAGER=yCONFIG_CRYPTO_MANAGER2=yCONFIG_CRYPTO_USER=m
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not setCONFIG_CRYPTO_GF128MUL=yCONFIG_CRYPTO_NULL=mCONFIG_CRYPTO_PCRYPT=mCONFIG_CRYPTO_WORKQUEUE=yCONFIG_CRYPTO_CRYPTD=yCONFIG_CRYPTO_AUTHENC=mCONFIG_CRYPTO_TEST=mCONFIG_CRYPTO_ABLK_HELPER_X86=yCONFIG_CRYPTO_GLUE_HELPER_X86=m
#
# Authenticated Encryption with Associated Data
#CONFIG_CRYPTO_CCM=mCONFIG_CRYPTO_GCM=mCONFIG_CRYPTO_SEQIV=y
#
# Block modes
#CONFIG_CRYPTO_CBC=yCONFIG_CRYPTO_CTR=yCONFIG_CRYPTO_CTS=mCONFIG_CRYPTO_ECB=yCONFIG_CRYPTO_LRW=yCONFIG_CRYPTO_PCBC=mCONFIG_CRYPTO_XTS=y
#
# Hash modes
#CONFIG_CRYPTO_HMAC=yCONFIG_CRYPTO_XCBC=mCONFIG_CRYPTO_VMAC=m
#
# Digest
#CONFIG_CRYPTO_CRC32C=yCONFIG_CRYPTO_CRC32C_INTEL=mCONFIG_CRYPTO_GHASH=mCONFIG_CRYPTO_MD4=mCONFIG_CRYPTO_MD5=yCONFIG_CRYPTO_MICHAEL_MIC=mCONFIG_CRYPTO_RMD128=mCONFIG_CRYPTO_RMD160=mCONFIG_CRYPTO_RMD256=mCONFIG_CRYPTO_RMD320=mCONFIG_CRYPTO_SHA1=yCONFIG_CRYPTO_SHA1_SSSE3=mCONFIG_CRYPTO_SHA256=yCONFIG_CRYPTO_SHA512=mCONFIG_CRYPTO_TGR192=mCONFIG_CRYPTO_WP512=mCONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m
#
# Ciphers
#CONFIG_CRYPTO_AES=yCONFIG_CRYPTO_AES_X86_64=yCONFIG_CRYPTO_AES_NI_INTEL=yCONFIG_CRYPTO_ANUBIS=mCONFIG_CRYPTO_ARC4=mCONFIG_CRYPTO_BLOWFISH=mCONFIG_CRYPTO_BLOWFISH_COMMON=mCONFIG_CRYPTO_BLOWFISH_X86_64=mCONFIG_CRYPTO_CAMELLIA=mCONFIG_CRYPTO_CAMELLIA_X86_64=mCONFIG_CRYPTO_CAST5=m
# CONFIG_CRYPTO_CAST5_AVX_X86_64 is not setCONFIG_CRYPTO_CAST6=m
# CONFIG_CRYPTO_CAST6_AVX_X86_64 is not setCONFIG_CRYPTO_DES=mCONFIG_CRYPTO_FCRYPT=mCONFIG_CRYPTO_KHAZAD=mCONFIG_CRYPTO_SALSA20=mCONFIG_CRYPTO_SALSA20_X86_64=mCONFIG_CRYPTO_SEED=mCONFIG_CRYPTO_SERPENT=mCONFIG_CRYPTO_SERPENT_SSE2_X86_64=mCONFIG_CRYPTO_SERPENT_AVX_X86_64=mCONFIG_CRYPTO_TEA=mCONFIG_CRYPTO_TWOFISH=mCONFIG_CRYPTO_TWOFISH_COMMON=mCONFIG_CRYPTO_TWOFISH_X86_64=mCONFIG_CRYPTO_TWOFISH_X86_64_3WAY=mCONFIG_CRYPTO_TWOFISH_AVX_X86_64=m
#
# Compression
#CONFIG_CRYPTO_DEFLATE=mCONFIG_CRYPTO_ZLIB=mCONFIG_CRYPTO_LZO=m
#
# Random Number Generation
#CONFIG_CRYPTO_ANSI_CPRNG=mCONFIG_CRYPTO_USER_API=yCONFIG_CRYPTO_USER_API_HASH=yCONFIG_CRYPTO_USER_API_SKCIPHER=yCONFIG_CRYPTO_HW=yCONFIG_CRYPTO_DEV_PADLOCK=mCONFIG_CRYPTO_DEV_PADLOCK_AES=mCONFIG_CRYPTO_DEV_PADLOCK_SHA=mCONFIG_ASYMMETRIC_KEY_TYPE=yCONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=yCONFIG_PUBLIC_KEY_ALGO_RSA=yCONFIG_X509_CERTIFICATE_PARSER=yCONFIG_HAVE_KVM=yCONFIG_HAVE_KVM_IRQCHIP=yCONFIG_HAVE_KVM_EVENTFD=yCONFIG_KVM_APIC_ARCHITECTURE=yCONFIG_KVM_MMIO=yCONFIG_KVM_ASYNC_PF=yCONFIG_HAVE_KVM_MSI=yCONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=yCONFIG_VIRTUALIZATION=yCONFIG_KVM=mCONFIG_KVM_INTEL=mCONFIG_KVM_AMD=mCONFIG_KVM_MMU_AUDIT=yCONFIG_VHOST_NET=mCONFIG_TCM_VHOST=mCONFIG_BINARY_PRINTF=y
#
# Library routines
#CONFIG_RAID6_PQ=mCONFIG_BITREVERSE=yCONFIG_GENERIC_STRNCPY_FROM_USER=yCONFIG_GENERIC_STRNLEN_USER=yCONFIG_GENERIC_FIND_FIRST_BIT=yCONFIG_GENERIC_PCI_IOMAP=yCONFIG_GENERIC_IOMAP=yCONFIG_GENERIC_IO=yCONFIG_CRC_CCITT=mCONFIG_CRC16=yCONFIG_CRC_T10DIF=yCONFIG_CRC_ITU_T=mCONFIG_CRC32=y
# CONFIG_CRC32_SELFTEST is not setCONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC32_SLICEBY4 is not set
# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_BIT is not set
# CONFIG_CRC7 is not setCONFIG_LIBCRC32C=mCONFIG_CRC8=mCONFIG_ZLIB_INFLATE=yCONFIG_ZLIB_DEFLATE=mCONFIG_LZO_COMPRESS=yCONFIG_LZO_DECOMPRESS=yCONFIG_XZ_DEC=yCONFIG_XZ_DEC_X86=yCONFIG_XZ_DEC_POWERPC=yCONFIG_XZ_DEC_IA64=yCONFIG_XZ_DEC_ARM=yCONFIG_XZ_DEC_ARMTHUMB=yCONFIG_XZ_DEC_SPARC=yCONFIG_XZ_DEC_BCJ=y
# CONFIG_XZ_DEC_TEST is not setCONFIG_DECOMPRESS_GZIP=yCONFIG_DECOMPRESS_BZIP2=yCONFIG_DECOMPRESS_LZMA=yCONFIG_DECOMPRESS_XZ=yCONFIG_DECOMPRESS_LZO=yCONFIG_GENERIC_ALLOCATOR=yCONFIG_REED_SOLOMON=mCONFIG_REED_SOLOMON_ENC8=yCONFIG_REED_SOLOMON_DEC8=yCONFIG_TEXTSEARCH=yCONFIG_TEXTSEARCH_KMP=mCONFIG_TEXTSEARCH_BM=mCONFIG_TEXTSEARCH_FSM=mCONFIG_BTREE=yCONFIG_HAS_IOMEM=yCONFIG_HAS_IOPORT=yCONFIG_HAS_DMA=yCONFIG_CHECK_SIGNATURE=yCONFIG_CPU_RMAP=yCONFIG_DQL=yCONFIG_NLATTR=yCONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=yCONFIG_LRU_CACHE=mCONFIG_AVERAGE=yCONFIG_CLZ_TAB=yCONFIG_CORDIC=m
# CONFIG_DDR is not setCONFIG_MPILIB=yCONFIG_OID_REGISTRY=y
Welcome to Fedora 18 (Spherical Cow)!
[ OK ] Reached target Remote File Systems.
[ OK ] Listening on Syslog Socket.
[ OK ] Reached target Syslog.
Starting Load legacy module configuration...
[ OK ] Listening on Delayed Shutdown Socket.
[ OK ] Listening on /dev/initctl Compatibility Named Pipe.
[ [ 68.651905] SELinux: initialized (dev autofs, type autofs), uses genfs_contexts
OK ] Listening on LVM2 metadata daemon socket.
Starting Setup Virtual Console...
Starting Apply Kernel Variables...
[ OK ] Set up automount Arbitrary Executable File Formats File System Automount Point.
[ 69.052143] SELinux: initialized (dev hugetlbfs, type hugetlbfs), uses transition SIDs
[ OK ] Reached target Encrypted Volumes.
Starting Load Kernel Modules...
Mounting Debug File System...
Mounting [ 69.326800] kvm: VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL does not work properly. Using workaround
Huge Pages File System...
[ 69.519392] tun: Universal TUN/TAP device driver, 1.6
[ OK ] Listening on Device-mapper[ 69.519393] tun: (C) 1999-2004 Max Krasnyansky <[email protected]>
event daemon FIFOs.
Expecting device dev-disk-by\x2duuid-8429f30c\x2d11e9\x2d4747\x2d8567\x2d163851aa58cd.device...
Starting Configure read-only root support...
[ OK ] Listening on udev [ 69.932728] systemd-udevd[294]: starting version 194
Kernel Socket.
[ OK ] Listening o[ 69.956079] EXT4-fs (sda4): re-mounted. Opts: (null)
n udev Control Socket.
Starting udev Coldplug all Devices...
Starting udev Kernel Device Manager...
Starting Remount Root and Kernel File Systems...
Expecting device dev-disk-by\x2duuid-2A8E\x2d753D.device...
Expecting device dev-disk-by\x2duuid-95266d2c\x2d14af\x2d4bcb\x2d86b5\x2dd6e517680083.device...
Expecting device dev-disk-by\x2duuid-db550ad3\x2d1bca\x2d4b61\x2db378\x2dac29e1279f65.device...
[ OK ] Started udev Kernel Device Manager.
[ OK ] Started Load legacy module configuration.
[ OK ] Started Setup Virtual Console.
[ OK ] Started Apply Kernel Variables.
[[1;3[ 70.831909] microcode: CPU0 sig=0x206c2, pf=0x1, revision=0x13
2m OK ] Mounted POSIX Message Queue File S[ 70.869425] microcode: CPU1 sig=0x206c2, pf=0x1, revision=0x13
ystem.
[ OK ] Started Load Kernel[ 70.870293] microcode: CPU2 sig=0x206c2, pf=0x1, revision=0x13
Modules.
[ OK ] Mounted Debug Fi[ 70.871149] microcode: CPU3 sig=0x206c2, pf=0x1, revision=0x13
le System.
[ OK ] Mounted Huge Pa[ 70.964589] microcode: CPU4 sig=0x206c2, pf=0x1, revision=0x13
ges File System.
[ OK ] Started S[ 70.965017] microcode: CPU5 sig=0x206c2, pf=0x1, revision=0x13
oftware RAID Monitor Takeover.
[ OK [ 70.965740] microcode: CPU6 sig=0x206c2, pf=0x1, revision=0x13
[ 70.966384] microcode: CPU7 sig=0x206c2, pf=0x1, revision=0x13
[ OK ] Started Remount Root and Ke[ 70.967130] microcode: Microcode Update Driver: v2.00 <[email protected]>, Peter Oruba
rnel File Systems.
[ OK ] Reached[ 71.957411] dca service started, version 1.12.1
target Local File Systems (Pre).
Mou[ 71.957412] EDAC MC: Ver: 3.0.0
nting Temporary Directory...
[ 72.152175] i801_smbus 0000:00:1f.3: enabling device (0140 -> 0143)
[ 72.152374] i801_smbus 0000:00:1f.3: SMBus using PCI Interrupt
[ 72.165140] tpm_tis 00:09: 1.2 TPM (device-id 0xFE, rev-id 70)
[ 72.174116] SELinux: initialized (dev tmpfs, type tmpfs), uses transition SIDs
Starting Load Random Seed...
[ 72.669517] bnx2: Broadcom NetXtreme II Gigabit Ethernet Driver bnx2 v2.2.3 (June 27, 2012)
[ 72.669615] input: PC Speaker as /devices/platform/pcspkr/input/input4
[ 72.669871] EDAC MC1: Giving out device to 'i7core_edac.c' 'i7 core #1': DEV 0000:fe:03.0
[ 72.669898] EDAC PCI0: Giving out device to module 'i7core_edac' controller 'EDAC PCI controller': DEV '0000:fe:03.0' (POLLED)
[ 73.265230] EDAC MC0: Giving out device to 'i7core_edac.c' 'i7 core #0': DEV 0000:ff:03.0
[ 73.265254] EDAC PCI1: Giving out device to module 'i7core_edac' controller 'EDAC PCI controller': DEV '0000:ff:03.0' (POLLED)
[ 73.265333] bnx2 0000:0b:00.0 eth0: Broadcom NetXtreme II BCM5716 1000Base-T (C0) PCI Express found at mem 92000000, IRQ 28, node addr 5c:f3:fc:55:d4:48
[ 73.265641] EDAC i7core: Driver loaded, 2 memory controller(s) found.
[ 73.266165] bnx2 0000:0b:00.1 eth1: Broadcom NetXtreme II BCM5716 1000Base-T (C0) PCI Express found at mem 94000000, IRQ 40, node addr 5c:f3:fc:55:d4:49
[ 73.266299] ACPI Warning: 0x0000000000000430-0x000000000000043f SystemIO conflicts with Region \_SB_.GPUS 1 (20120913/utaddress-251)
[ 73.266300] ACPI: If an ACPI driver is available for this device, you should use it instead of the native driver
[ 73.266968] shpchp: Standard Hot Plug PCI Controller Driver version: 0.4
[ 73.290273] ioatdma: Intel(R) QuickData Technology Driver 4.00
[ 73.290322] ioatdma 0000:00:16.0: enabling device (0000 -> 0002)
[ 73.290451] ioatdma 0000:00:16.0: irq 68 for MSI/MSI-X
[ 73.290833] ioatdma 0000:00:16.1: enabling device (0000 -> 0002)
[ 73.290925] ioatdma 0000:00:16.1: irq 69 for MSI/MSI-X
[ 73.291151] ioatdma 0000:00:16.2: enabling device (0000 -> 0002)
[ 73.291212] ioatdma 0000:00:16.2: irq 70 for MSI/MSI-X
[ 73.291433] ioatdma 0000:00:16.3: enabling device (0000 -> 0002)
[ 73.291494] ioatdma 0000:00:16.3: irq 71 for MSI/MSI-X
[ 73.291957] ioatdma 0000:00:16.4: enabling device (0000 -> 0002)
[ 73.292057] ioatdma 0000:00:16.4: irq 72 for MSI/MSI-X
[ 73.292277] ioatdma 0000:00:16.5: enabling device (0000 -> 0002)
[ 73.292355] ioatdma 0000:00:16.5: irq 73 for MSI/MSI-X
[ 73.292597] ioatdma 0000:00:16.6: enabling device (0000 -> 0002)
[ 73.292735] ioatdma 0000:00:16.6: irq 74 for MSI/MSI-X
[ 73.292959] ioatdma 0000:00:16.7: enabling device (0000 -> 0002)
[ 73.293020] ioatdma 0000:00:16.7: irq 75 for MSI/MSI-X
[ 75.691285] iTCO_vendor_support: vendor-support=0
[ 75.813413] cdc_ether 4-2:1.0 usb0: register 'cdc_ether' at usb-0000:00:1a.1-2, CDC Ethernet Device, 5e:f3:fc:55:d4:4d
[ 75.813441] usbcore: registered new interface driver cdc_ether
[ 77.020152] iTCO_wdt: Intel TCO WatchDog Timer Driver v1.10
[ 77.020234] iTCO_wdt: unable to reset NO_REBOOT flag, device disabled by hardware/BIOS
Mounting Configuration File System...
[ 77.454931] SELinux: initialized (dev configfs, type configfs), uses genfs_contexts
[ OK ] Stopped Trigger Flushing of Journal to Persistent Storage.
Stopping Journal Service...
[ OK ] Stopped Journal Service.
Starting Journal Service...
[ OK ] Started Journal Service.
[ OK ] Mounted Temporary Directory.
[ OK ] Mounted Configuration File System.
[ OK ] Started udev Coldplug all Devices[ 77.943792] Adding 8175612k swap on /dev/sda3. Priority:-1 extents:1 across:8175612k
.
[ OK ] Started Load Random Seed.
Starting udev Wait for Complete Device Initialization...
[ OK ] Found device ServeRAID_M5015.
Activating swap /dev/disk/by-uuid/8429f30c-11e9-4747-8567-163851aa58cd...
[ OK ] Found device ServeRAID_M5015.
Starting File System Check[ 78.407610] EXT4-fs (sda2): mounted filesystem with ordered data mode. Opts: (null)
on /dev/disk/by-uuid/95266d2c-14af-4bcb-86b5-d6e517680083...
[ 78.410550] SELinux: initialized (dev sda2, type ext4), uses xattr
systemd-fsck[389]: /dev/sda2: recovering journal
systemd-fsck[389]: /dev/sda2: clean, 70/128016 files, 153973/512000 blocks
[ OK ] Started udev Wait for Complete Device Initialization.
[ OK ] Activated swap /dev/disk/by-uuid/8429f30c-11e9-4747-8567-163851aa58cd.
[ OK ] Started File System Check on /dev/disk/by-uuid/95266d2c-14af-4bcb-86b5-d6e517680083.
Mounting /boot...
[ OK ] Reached target Swap.
Starting Wait for storage scan...
[ OK ] Mounted /boot.
[ OK ] Found device ServeRAID_M5015.
Starting File System Check on /dev/disk/by-uuid/db550ad3-1bca-4b61-b378-ac29e1279f65...
[ OK ] Started Wait for storage scan.
systemd-fsck[405]: /dev/sda5: recovering journal
Starting Initialize storage subsystems (RAID, LVM, etc.)...
systemd-fsck[ 79.573761] SELinux: initialized (dev sda1, type vfat), uses genfs_contexts
[405]: /dev/sda5: clean, 230/5079040 files, 382649/20313600 blocks
[ OK ] Found device ServeRAID_M5015.
Mounting /boot/efi...
[ OK ] Started File System Che[ 79.945416] EXT4-fs (sda5): mounted filesystem with ordered data mode. Opts: (null)
ck on /dev/disk/by-uuid/db550ad3-1bca-4b61-b378-ac29e1279f65.
[ 79.945421] SELinux: initialized (dev sda5, type ext4), uses xattr
[ OK ] Started Initialize storage subsystems (RAID, LVM, etc.).
Starting Initialize storage subsystems (RAID, LVM, etc.)...
Mounting /home...
[ OK ] Mounted /boot/efi.
[ OK ] Started Initialize storage subsystems (RAID, LVM, etc.).
[ OK ] Mounted /home.
Starting Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling...
[ OK ] Started Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling.
[ [ 80.764347] type=1400 audit(1351260878.586:4): avc: denied { read } for pid=433 comm="systemd-tmpfile" name="lock" dev="sda4" ino=3145784 scontext=system_u:system_r:systemd_tmpfiles_t:s0 tcontext=system_u:object_r:var_t:s0 tclass=lnk_file
OK ] Reached target Local File Systems.
Starting Recreate Volatile Files and Directories...
Starting [ 80.764572] type=1400 audit(1351260878.586:5): avc: denied { read } for pid=433 comm="systemd-tmpfile" name="lock" dev="sda4" ino=3145784 scontext=system_u:system_r:systemd_tmpfiles_t:s0 tcontext=system_u:object_r:var_t:s0 tclass=lnk_file
Trigger Flushing of Journal to Persistent Storage...
[ 81.643401] systemd-journald[385]: Received SIGUSR1
Starting Tell Plymouth To Write Out Runtime Data...
[ OK ] Started Recreate Volatile Files and Directories.
[ OK ] Started Trigger Flushing of Journal to Persistent Storage.
[ OK ] Started Tell Plymouth To Write Out Runtime Data.
[ OK ] Reached target System Initialization.
Starting Restore Sound Card State...
[ OK ] Listening on RPCbind Server Activation Socket.
[ OK ] Listening on CUPS Printing Service Sockets.
[ OK ] Listening on Avahi mDNS/DNS-SD Stack Activation Socket.
[ OK ] Listening on PC/SC Smart Card Daemon Activation Socket.
[ OK ] Listening on D-Bus System Message Bus Socket.
[ OK ] Reached target Sockets.
[ OK ] Reached target Basic System.
Starting LSB: Starts and stops login iSCSI daem[ 82.766212] Loading iSCSI transport class v2.0-870.
on....
Starting firewalld - dynamic firewall daemon...
Starting Security Auditing Service...
Starting ABRT Automated Bug Reporting Tool...
[ OK ] Started ABRT Automated Bug Reporting Tool.
Starting irqbalance daemon...
[ 83.186928] iscsi: registered transport (tcp)
Starting Machine Check Exception Logging Daemon...
Starting Harvest vmcores for ABRT...
Starting Install ABRT coredump hook...
Starting ABRT Xorg log watcher...
[ OK ] Started ABRT Xorg log watcher.
Starting Kernel Samepage Merging...
Starting ABRT kernel log watcher...
[ 83.693943] iscsi: registered transport (iser)
[ OK ] Started ABRT kernel log watcher.
Starting Self Monitoring and Reporting Technology (SMART) Daemon...
[ 83.881448] libcxgbi:libcxgbi_init_module: tag itt 0x1fff, 13 bits, age 0xf, 4 bits.
[ 83.881449] libcxgbi:ddp_setup_host_page_size: system PAGE 4096, ddp idx 0.
[ OK ] Started Self Monitoring and Reporting Technology (SMART) Daemon.
Starting NTP client/server...
Starting Login Service...
Starting Avahi mDNS/DNS-SD Stack...
[ 84.398509] Chelsio T3 iSCSI Driver cxgb3i v2.0.0 (Jun. 2010)
[ 84.398537] iscsi: registered transport (cxgb3i)
[ 84.667763] Chelsio T4 iSCSI Driver cxgb4i v0.9.1 (Aug. 2010)
[ 84.667791] iscsi: registered transport (cxgb4i)
[ OK ] Started System Logging Service.
Starting Permit User Sessions...
Starting D-Bus System Message Bus...
[ OK ] Started D-Bus System Message Bus.
[ 85.038927] cnic: Broadcom NetXtreme II CNIC Driver cnic v2.5.14 (Sep 30, 2012)
[ 85.214112] Broadcom NetXtreme II iSCSI Driver bnx2i v2.7.2.2 (Apr 25, 2012)
[ 85.214173] iscsi: registered transport (bnx2i)
[ OK ] Started Restore Sound Card State.
[ OK ] Started Security Aud[ 85.552436] iscsi: registered transport (be2iscsi)
iting Service.
[ OK ] Started irq[ 85.552437] In beiscsi_module_init, tt=ffffffffa035b000
balance daemon.
[ OK ] Started Machine Check Exception Logging Daemon.
[ OK ] Started Harvest vmcores for ABRT.
[ OK ] Started Install ABRT coredump hook.
[ OK ] Started Kernel Samepage Merging.
[ OK ] Started Permit User Sessions.
Starting Job spooling tools...
[ OK ] Started Job spooling tools.
Starting Wait for Plymouth Boot Screen to Quit...
Starting Terminate Plymouth Boot Screen...
Starting Kernel Samepage Merging (KSM) Tuning Daemon...
Starting Command Scheduler...
[ OK ] Started Command Scheduler.
[ OK ] Started LSB: Starts and stops login iSCSI daemon..
[ OK ] Started Kernel Samepage Merging (KSM) Tuning Daemon.
[ OK ] Started Login Service.
[ OK ] Started Avahi mDNS/DNS-SD Stack.
[ 87.491448] nf_conntrack version 0.5.0 (16384 buckets, 65536 max)
[ 88.337065] bnx2 0000:0b:00.0: irq 76 for MSI/MSI-X
[ 88.433811] bnx2 0000:0b:00.0: irq 77 for MSI/MSI-X
[ 88.530554] bnx2 0000:0b:00.0: irq 78 for MSI/MSI-X
[ 88.626160] bnx2 0000:0b:00.0: irq 79 for MSI/MSI-X
[ 88.721806] bnx2 0000:0b:00.0: irq 80 for MSI/MSI-X
[ 88.816751] bnx2 0000:0b:00.0: irq 81 for MSI/MSI-X
[ 88.911473] bnx2 0000:0b:00.0: irq 82 for MSI/MSI-X
[ 89.005730] bnx2 0000:0b:00.0: irq 83 for MSI/MSI-X
[ 89.100194] bnx2 0000:0b:00.0: irq 84 for MSI/MSI-X
[ 89.241620] bnx2 0000:0b:00.0 eth0: using MSIX
[ 89.329601] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[ 89.435553] Bluetooth: Core ver 2.16
[ 89.513154] NET: Registered protocol family 31
[ 89.530802] bnx2 0000:0b:00.1: irq 85 for MSI/MSI-X
[ 89.530817] bnx2 0000:0b:00.1: irq 86 for MSI/MSI-X
[ 89.530832] bnx2 0000:0b:00.1: irq 87 for MSI/MSI-X
[ 89.530846] bnx2 0000:0b:00.1: irq 88 for MSI/MSI-X
[ 89.530862] bnx2 0000:0b:00.1: irq 89 for MSI/MSI-X
[ 89.530876] bnx2 0000:0b:00.1: irq 90 for MSI/MSI-X
[ 89.530891] bnx2 0000:0b:00.1: irq 91 for MSI/MSI-X
[ 89.530905] bnx2 0000:0b:00.1: irq 92 for MSI/MSI-X
[ 89.530919] bnx2 0000:0b:00.1: irq 93 for MSI/MSI-X
[ 89.578639] bnx2 0000:0b:00.1 eth1: using MSIX
[ 89.578693] IPv6: ADDRCONF(NETDEV_UP): eth1: link is not ready
[ 90.611119] Bluetooth: HCI device and connection manager initialized
[ 90.718006] Bluetooth: HCI socket layer initialized
[ 90.807276] Bluetooth: L2CAP socket layer initialized
[ 90.897726] Bluetooth: SCO socket layer initialized
[ 91.047382] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 91.140772] Bluetooth: BNEP filters: protocol multicast
[ 91.233105] Bluetooth: BNEP socket layer initialized
[ 92.497381] bnx2 0000:0b:00.0 eth0: NIC Copper Link is Up, 1000 Mbps full duplex
[ 92.587116]
[ 92.605283] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 92.768491] bnx2 0000:0b:00.
1 eth1: NIC Copper Link is Up, 1000 Mbps full duplex
[ 92.857692]
[ 92.875815] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
[ 94.355591] Ebtables v2.0 registered
[ 94.468819] ip6_tables: (C) 2000-2006 Netfilter Core Team
[ 94.656930] cgroup: libvirtd (860) created nested cgroup for controller "memory" which has incomplete hierarchy support. Nested cgroups may change behavior in the future.
[ 94.841229] cgroup: "memory" requires setting use_hierarchy to 1 on the root.
[ 94.841332] cgroup: libvirtd (860) created nested cgroup for controller "devi[ 94.841380] cgroup: libvirtd (860) created nested cgroup for controller "freezer" which has incomplete hierarchy support. Nested cgroups may change behavior in the future.
[ 94.841430] cgroup: libvirtd (860) created nested cgroup for controller "blkio" which has incomplete hierarchy support. Nested cgroups may change behavior in the future.
[ 158.926026] [drm] mga base 0
[ 160.492547] fuse init (API version 7.20)
[ 160.541437] SELinux: initialized (dev fuse, type fuse), uses genfs_contexts
[ 179.734405] ------------[ cut here ]------------
[ 179.804754] kernel BUG at mm/memcontrol.c:3263!
[ 179.874356] invalid opcode: 0000 [#1] SMP
[ 179.939377] Modules linked in: fuse ip6table_filter ip6_tables ebtable_nat ebtables bnep bluetooth rfkill iptable_mangle nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack be2iscsi iscsi_boot_sysfs bnx2i cnic uio cxgb4i cxgb4 cxgb3i cxgb3 mdio libcxgbi ib_iser rdma_cm ib_addr iw_cm ib_cm ib_sa ib_mad ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi vfat fat iTCO_wdt cdc_ether coretemp iTCO_vendor_support usbnet mii ioatdma lpc_ich crc32c_intel bnx2 shpchp i7core_edac pcspkr tpm_tis tpm i2c_i801 mfd_core tpm_bios edac_core dca serio_raw microcode vhost_net tun macvtap macvlan kvm_intel kvm uinput mgag200 i2c_algo_bit drm_kms_helper ttm drm megaraid_sas i2c_core
[ 180.737647] CPU 7
[ 180.759586] Pid: 1316, comm: X Not tainted 3.7.0-rc2+ #3 IBM IBM System x3400 M3 Server -[7379I08]-/69Y4356
[ 180.918591] RIP: 0010:[<ffffffff8118c39a>] [<ffffffff8118c39a>] mem_cgroup_prepare_migration+0xba/0xd0
[ 181.047572] RSP: 0000:ffff880179113d38 EFLAGS: 00013202
[ 181.127009] RAX: 0040100000084069 RBX: ffffea0005b28000 RCX: ffffea00099a805c
[ 181.228674] RDX: ffff880179113d90 RSI: ffffea00099a8000 RDI: ffffea0005b28000
[ 181.331080] RBP: ffff880179113d58 R08: 0000000000280000 R09: ffff88027fffff80
[ 181.433163] R10: 00000000000000d4 R11: 00000037e9f7bd90 R12: ffff880179113d90
[ 181.533866] R13: 00007fc5ffa00000 R14: ffff880178001fe8 R15: 000000016ca001e0
[ 181.635264] FS: 00007fc600ddb940(0000) GS:ffff88027fc60000(0000) knlGS:0000000000000000
[ 181.753726] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 181.842013] CR2: 00007fc5ffa00000 CR3: 00000001779d2000 CR4: 00000000000007e0
[ 181.945346] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 182.049416] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 182.153796] Process X (pid: 1316, threadinfo ffff880179112000, task ffff880179364620)
[ 182.266464] Stack:
[ 182.309943] ffff880177d2c980 00007fc5ffa00000 ffffea0005b28000 ffff880177d2c980
[ 182.418164] ffff880179113dc8 ffffffff81183b60 ffff880177d2c9dc 0000000178001fe0
[ 182.526366] ffff880177856a50 ffffea00099a8000 ffff880177d2cc38 0000000000000000
[ 182.633709] Call Trace:
[ 182.681450] [<ffffffff81183b60>] do_huge_pmd_numa_page+0x180/0x500
[ 182.775090] [<ffffffff811585c9>] handle_mm_fault+0x1e9/0x360
[ 182.863038] [<ffffffff81632b62>] __do_page_fault+0x172/0x4e0
[ 182.950574] [<ffffffff8101c283>] ? __switch_to_xtra+0x163/0x1a0
[ 183.041512] [<ffffffff8101281e>] ? __switch_to+0x3ce/0x4a0
[ 183.126832] [<ffffffff8162d686>] ? __schedule+0x3c6/0x7a0
[ 183.211216] [<ffffffff81632ede>] do_page_fault+0xe/0x10
[ 183.293705] [<ffffffff8162f518>] page_fault+0x28/0x30
[ 183.373909] Code: 00 48 8b 78 08 48 8b 57 10 83 e2 01 75 05 f0 83 47 08 01 f6 43 08 01 74 bb f0 80 08 04 eb b5 f3 90 48 8b 10 80 e2 01 75 f6 eb 94 <0f> 0b 0f 1f 40 00 e8 9c b4 49 00 66 66 2e 0f 1f 84 00 00 00 00
[ 183.651946] RIP [<ffffffff8118c39a>] mem_cgroup_prepare_migration+0xba/0xd0
[ 183.760378] RSP <ffff880179113d38> Quoted 10 lines · Zhouping Liu
[ 180.918591] RIP: 0010:[<ffffffff8118c39a>] [<ffffffff8118c39a>] mem_cgroup_prepare_migration+0xba/0xd0[ 182.681450] [<ffffffff81183b60>] do_huge_pmd_numa_page+0x180/0x500 [ 182.775090] [<ffffffff811585c9>] handle_mm_fault+0x1e9/0x360 [ 182.863038] [<ffffffff81632b62>] __do_page_fault+0x172/0x4e0 [ 182.950574] [<ffffffff8101c283>] ? __switch_to_xtra+0x163/0x1a0 [ 183.041512] [<ffffffff8101281e>] ? __switch_to+0x3ce/0x4a0 [ 183.126832] [<ffffffff8162d686>] ? __schedule+0x3c6/0x7a0 [ 183.211216] [<ffffffff81632ede>] do_page_fault+0xe/0x10 [ 183.293705] [<ffffffff8162f518>] page_fault+0x28/0x30
Johannes, this looks like the thp migration memcg hookery gone bad, could you have a look at this?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 12 lines · Peter Zijlstra
Quoted 10 lines · Zhouping Liu
[ 180.918591] RIP: 0010:[<ffffffff8118c39a>] [<ffffffff8118c39a>] mem_cgroup_prepare_migration+0xba/0xd0[ 182.681450] [<ffffffff81183b60>] do_huge_pmd_numa_page+0x180/0x500 [ 182.775090] [<ffffffff811585c9>] handle_mm_fault+0x1e9/0x360 [ 182.863038] [<ffffffff81632b62>] __do_page_fault+0x172/0x4e0 [ 182.950574] [<ffffffff8101c283>] ? __switch_to_xtra+0x163/0x1a0 [ 183.041512] [<ffffffff8101281e>] ? __switch_to+0x3ce/0x4a0 [ 183.126832] [<ffffffff8162d686>] ? __schedule+0x3c6/0x7a0 [ 183.211216] [<ffffffff81632ede>] do_page_fault+0xe/0x10 [ 183.293705] [<ffffffff8162f518>] page_fault+0x28/0x30
Quoted 2 lines
Johannes, this looks like the thp migration memcg hookery gone bad, could you have a look at this?
Meanwhile, Zhouping Liu, could you please not apply the last patch:
[PATCH] sched, numa, mm: Add memcg support to do_huge_pmd_numa_page()
and see whether it boots/works without that?
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 12 lines · Ingo Molnar
Quoted 10 lines · Peter Zijlstra
Quoted 9 lines · Zhouping Liu
[ 180.918591] RIP: 0010:[<ffffffff8118c39a>] [<ffffffff8118c39a>] mem_cgroup_prepare_migration+0xba/0xd0 [ 182.681450] [<ffffffff81183b60>] do_huge_pmd_numa_page+0x180/0x500 [ 182.775090] [<ffffffff811585c9>] handle_mm_fault+0x1e9/0x360 [ 182.863038] [<ffffffff81632b62>] __do_page_fault+0x172/0x4e0 [ 182.950574] [<ffffffff8101c283>] ? __switch_to_xtra+0x163/0x1a0 [ 183.041512] [<ffffffff8101281e>] ? __switch_to+0x3ce/0x4a0 [ 183.126832] [<ffffffff8162d686>] ? __schedule+0x3c6/0x7a0 [ 183.211216] [<ffffffff81632ede>] do_page_fault+0xe/0x10 [ 183.293705] [<ffffffff8162f518>] page_fault+0x28/0x30
Quoted 8 lines
Quoted 2 lines
Johannes, this looks like the thp migration memcg hookery gone bad, could you have a look at this?
Meanwhile, Zhouping Liu, could you please not apply the last patch:
[PATCH] sched, numa, mm: Add memcg support to
do_huge_pmd_numa_page()and see whether it boots/works without that?
Ok, I reverted the 31st patch, will provide the results here after I finish testing.
Thanks,
Zhouping
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 12 lines · Ingo Molnar
Quoted 10 lines · Peter Zijlstra
Quoted 9 lines · Zhouping Liu
[ 180.918591] RIP: 0010:[<ffffffff8118c39a>] [<ffffffff8118c39a>] mem_cgroup_prepare_migration+0xba/0xd0 [ 182.681450] [<ffffffff81183b60>] do_huge_pmd_numa_page+0x180/0x500 [ 182.775090] [<ffffffff811585c9>] handle_mm_fault+0x1e9/0x360 [ 182.863038] [<ffffffff81632b62>] __do_page_fault+0x172/0x4e0 [ 182.950574] [<ffffffff8101c283>] ? __switch_to_xtra+0x163/0x1a0 [ 183.041512] [<ffffffff8101281e>] ? __switch_to+0x3ce/0x4a0 [ 183.126832] [<ffffffff8162d686>] ? __schedule+0x3c6/0x7a0 [ 183.211216] [<ffffffff81632ede>] do_page_fault+0xe/0x10 [ 183.293705] [<ffffffff8162f518>] page_fault+0x28/0x30
Quoted 8 lines
Quoted 2 lines
Johannes, this looks like the thp migration memcg hookery gone bad, could you have a look at this?
Meanwhile, Zhouping Liu, could you please not apply the last patch:
[PATCH] sched, numa, mm: Add memcg support to
do_huge_pmd_numa_page()and see whether it boots/works without that?
Hi Ingo,
your supposed is right, after reverting the 31st patch(sched, numa, mm: Add memcg support to do_huge_pmd_numa_page()) the issue is gone, thank you.
Thanks,
Zhouping
Quoted 10 lines
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 20 lines · Zhouping Liu
Quoted 19 lines · Ingo Molnar
Quoted 10 lines · Peter Zijlstra
Quoted 9 lines · Zhouping Liu
[ 180.918591] RIP: 0010:[<ffffffff8118c39a>] [<ffffffff8118c39a>] mem_cgroup_prepare_migration+0xba/0xd0 [ 182.681450] [<ffffffff81183b60>] do_huge_pmd_numa_page+0x180/0x500 [ 182.775090] [<ffffffff811585c9>] handle_mm_fault+0x1e9/0x360 [ 182.863038] [<ffffffff81632b62>] __do_page_fault+0x172/0x4e0 [ 182.950574] [<ffffffff8101c283>] ? __switch_to_xtra+0x163/0x1a0 [ 183.041512] [<ffffffff8101281e>] ? __switch_to+0x3ce/0x4a0 [ 183.126832] [<ffffffff8162d686>] ? __schedule+0x3c6/0x7a0 [ 183.211216] [<ffffffff81632ede>] do_page_fault+0xe/0x10 [ 183.293705] [<ffffffff8162f518>] page_fault+0x28/0x30Quoted 2 lines
Johannes, this looks like the thp migration memcg hookery gone bad, could you have a look at this?
Meanwhile, Zhouping Liu, could you please not apply the last patch:
[PATCH] sched, numa, mm: Add memcg support to
do_huge_pmd_numa_page()
Quoted 7 lines
Quoted 1 line
and see whether it boots/works without that?
Hi Ingo,
your supposed is right, after reverting the 31st patch(sched, numa,
mm: Add memcg support todo_huge_pmd_numa_page())
the issue is gone, thank you.
The tested bits you can find in the numa/core tree:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git numa/core
It includes all changes (patches #1-#30) except patch #31 - I wanted to test and apply that last patch today, but won't do it now that you've reported this regression.
Thanks,
Ingo
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Johannes Weiner
maintainerQuoted 12 lines · Peter Zijlstra
Quoted 10 lines · Zhouping Liu
[ 180.918591] RIP: 0010:[<ffffffff8118c39a>] [<ffffffff8118c39a>] mem_cgroup_prepare_migration+0xba/0xd0[ 182.681450] [<ffffffff81183b60>] do_huge_pmd_numa_page+0x180/0x500 [ 182.775090] [<ffffffff811585c9>] handle_mm_fault+0x1e9/0x360 [ 182.863038] [<ffffffff81632b62>] __do_page_fault+0x172/0x4e0 [ 182.950574] [<ffffffff8101c283>] ? __switch_to_xtra+0x163/0x1a0 [ 183.041512] [<ffffffff8101281e>] ? __switch_to+0x3ce/0x4a0 [ 183.126832] [<ffffffff8162d686>] ? __schedule+0x3c6/0x7a0 [ 183.211216] [<ffffffff81632ede>] do_page_fault+0xe/0x10 [ 183.293705] [<ffffffff8162f518>] page_fault+0x28/0x30
Quoted 2 lines
Johannes, this looks like the thp migration memcg hookery gone bad, could you have a look at this?
Oops. Here is an incremental fix, feel free to fold it into #31.
---
mm/huge_memory.c +15 -7
@@ -801,8 +801,6 @@ void do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,if (!new_page) goto alloc_fail; -mem_cgroup_prepare_migration (page, new_page, &memcg); - lru =PageLRU (page);if (lru &&isolate_lru_page (page))/* does an implicit get_page() */
@@ -835,6 +833,14 @@ void do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,return ; } +/* +* Traditional migration needs to prepare the memcg charge +* transaction early to prevent the old page from being +* uncharged when installing migration entries. Here we can +* save the potential rollback and start the charge transfer +* only when migration is already known to end successfully. +*/ +mem_cgroup_prepare_migration (page, new_page, &memcg); entry =mk_pmd (new_page, vma->vm_page_prot); entry =maybe_pmd_mkwrite (pmd_mkdirty (entry), vma);
@@ -845,6 +851,12 @@ void do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,set_pmd_at (mm, haddr, pmd, entry);update_mmu_cache_pmd (vma, address, entry);page_remove_rmap (page); +/* +* Finish the charge transaction under the page table lock to +* prevent split_huge_page() from dividing up the charge +* before it's fully transferred to the new page. +*/ +mem_cgroup_end_migration (memcg, page, new_page, true);spin_unlock (&mm->page_table_lock);put_page (page);/* Drop the rmap reference */
@@ -856,18 +868,14 @@ void do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,unlock_page (new_page); -mem_cgroup_end_migration (memcg, page, new_page, true); -unlock_page (page);put_page (page);/* Drop the local reference */ return ; alloc_fail: -if (new_page) { -mem_cgroup_end_migration (memcg, page, new_page, false); +if (new_page)put_page (new_page); - }unlock_page (page);
mm/memcontrol.c +5 -2
@@ -3255,15 +3255,18 @@ void mem_cgroup_prepare_migration(struct page *page, struct page *newpage, struct mem_cgroup **memcgp) {struct mem_cgroup *memcg =NULL ; +unsigned int nr_pages =1 ;struct page_cgroup *pc;enum charge_type ctype; *memcgp =NULL ; -VM_BUG_ON (PageTransHuge (page));if (mem_cgroup_disabled ())return ; +if (PageTransHuge (page)) + nr_pages <<=compound_order (page); + pc =lookup_page_cgroup (page);lock_page_cgroup (pc);if (PageCgroupUsed (pc)) {
@@ -3325,7 +3328,7 @@ void mem_cgroup_prepare_migration(struct page *page, struct page *newpage,* charged to the res_counter since we plan on replacing the * old one and only one page is going to be left afterwards. */ -__mem_cgroup_commit_charge (memcg, newpage,1 , ctype, false); +__mem_cgroup_commit_charge (memcg, newpage, nr_pages, ctype, false); }/* remove redundant charge if migration failed*/
Quoted 11 lines · Johannes Weiner
Quoted 10 lines · Peter Zijlstra
Quoted 9 lines · Zhouping Liu
[ 180.918591] RIP: 0010:[<ffffffff8118c39a>] [<ffffffff8118c39a>] mem_cgroup_prepare_migration+0xba/0xd0 [ 182.681450] [<ffffffff81183b60>] do_huge_pmd_numa_page+0x180/0x500 [ 182.775090] [<ffffffff811585c9>] handle_mm_fault+0x1e9/0x360 [ 182.863038] [<ffffffff81632b62>] __do_page_fault+0x172/0x4e0 [ 182.950574] [<ffffffff8101c283>] ? __switch_to_xtra+0x163/0x1a0 [ 183.041512] [<ffffffff8101281e>] ? __switch_to+0x3ce/0x4a0 [ 183.126832] [<ffffffff8162d686>] ? __schedule+0x3c6/0x7a0 [ 183.211216] [<ffffffff81632ede>] do_page_fault+0xe/0x10 [ 183.293705] [<ffffffff8162f518>] page_fault+0x28/0x30
Quoted 3 lines
Quoted 2 lines
Johannes, this looks like the thp migration memcg hookery gone bad, could you have a look at this?
Oops. Here is an incremental fix, feel free to fold it into #31.
Hi Johannes,
Tested the below patch, and I'm sure it has fixed the above issue, thank you.
Zhouping
Quoted 90 lines
Signed-off-by Johannes Weiner <[email protected]>---
mm/huge_memory.c +15
-7@@ -801,8 +801,6 @@ void do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,if (!new_page) goto alloc_fail; -mem_cgroup_prepare_migration (page, new_page, &memcg); - lru =PageLRU (page);if (lru &&isolate_lru_page (page))/* does an implicit get_page() */ @@ -835,6 +833,14 @@ void do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,return ; } +/* +* Traditional migration needs to prepare the memcg charge +* transaction early to prevent the old page from being +* uncharged when installing migration entries. Here we can +* save the potential rollback and start the charge transfer +* only when migration is already known to end successfully. +*/ +mem_cgroup_prepare_migration (page, new_page, &memcg); entry =mk_pmd (new_page, vma->vm_page_prot); entry =maybe_pmd_mkwrite (pmd_mkdirty (entry), vma);@@ -845,6 +851,12 @@ void do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,set_pmd_at (mm, haddr, pmd, entry);update_mmu_cache_pmd (vma, address, entry);page_remove_rmap (page); +/* +* Finish the charge transaction under the page table lock to +* prevent split_huge_page() from dividing up the charge +* before it's fully transferred to the new page. +*/ +mem_cgroup_end_migration (memcg, page, new_page, true);spin_unlock (&mm->page_table_lock);put_page (page);/* Drop the rmap reference */ @@ -856,18 +868,14 @@ void do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,unlock_page (new_page); -mem_cgroup_end_migration (memcg, page, new_page, true); -unlock_page (page);put_page (page);/* Drop the local reference */ return ; alloc_fail: -if (new_page) { -mem_cgroup_end_migration (memcg, page, new_page, false); +if (new_page)put_page (new_page); - }unlock_page (page);mm/memcontrol.c +4
-1@@ -3255,15 +3255,18 @@ void mem_cgroup_prepare_migration(struct page *page, struct page *newpage, struct mem_cgroup **memcgp) {struct mem_cgroup *memcg =NULL ; +unsigned int nr_pages =1 ;struct page_cgroup *pc;enum charge_type ctype; *memcgp =NULL ; -VM_BUG_ON (PageTransHuge (page));if (mem_cgroup_disabled ())return ; +if (PageTransHuge (page)) + nr_pages <<=compound_order (page); + pc =lookup_page_cgroup (page);lock_page_cgroup (pc);if (PageCgroupUsed (pc)) {
mm/memcontrol.c void mem_cgroup_prepare_migration(struct page *page, struct page *newpage, · line 3334
Quoted 8 lines
mm/memcontrol.c +1
-1@@ -3325,7 +3328,7 @@ void mem_cgroup_prepare_migration(struct page *page, struct page *newpage,* charged to the res_counter since we plan on replacing the * old one and only one page is going to be left afterwards. */ -__mem_cgroup_commit_charge (memcg, newpage,1 , ctype, false); +__mem_cgroup_commit_charge (memcg, newpage, nr_pages, ctype, false); }/* remove redundant charge if migration failed*/
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>