ia64/linux-2.6.18-xen.hg

view drivers/md/raid6sse1.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jun 05 14:01:20 2009 +0100 (2009-06-05)
parents 831230e53067
children
line source
1 /* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright 2002 H. Peter Anvin - All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 * Bostom MA 02111-1307, USA; either version 2 of the License, or
9 * (at your option) any later version; incorporated herein by reference.
10 *
11 * ----------------------------------------------------------------------- */
13 /*
14 * raid6sse1.c
15 *
16 * SSE-1/MMXEXT implementation of RAID-6 syndrome functions
17 *
18 * This is really an MMX implementation, but it requires SSE-1 or
19 * AMD MMXEXT for prefetch support and a few other features. The
20 * support for nontemporal memory accesses is enough to make this
21 * worthwhile as a separate implementation.
22 */
24 #if defined(__i386__)
26 #include "raid6.h"
27 #include "raid6x86.h"
29 /* Defined in raid6mmx.c */
30 extern const struct raid6_mmx_constants {
31 u64 x1d;
32 } raid6_mmx_constants;
34 static int raid6_have_sse1_or_mmxext(void)
35 {
36 #ifdef __KERNEL__
37 /* Not really boot_cpu but "all_cpus" */
38 return boot_cpu_has(X86_FEATURE_MMX) &&
39 (boot_cpu_has(X86_FEATURE_XMM) ||
40 boot_cpu_has(X86_FEATURE_MMXEXT));
41 #else
42 /* User space test code - this incorrectly breaks on some Athlons */
43 u32 features = cpuid_features();
44 return ( (features & (5<<23)) == (5<<23) );
45 #endif
46 }
48 /*
49 * Plain SSE1 implementation
50 */
51 static void raid6_sse11_gen_syndrome(int disks, size_t bytes, void **ptrs)
52 {
53 u8 **dptr = (u8 **)ptrs;
54 u8 *p, *q;
55 int d, z, z0;
56 raid6_mmx_save_t sa;
58 z0 = disks - 3; /* Highest data disk */
59 p = dptr[z0+1]; /* XOR parity */
60 q = dptr[z0+2]; /* RS syndrome */
62 /* This is really MMX code, not SSE */
63 raid6_before_mmx(&sa);
65 asm volatile("movq %0,%%mm0" : : "m" (raid6_mmx_constants.x1d));
66 asm volatile("pxor %mm5,%mm5"); /* Zero temp */
68 for ( d = 0 ; d < bytes ; d += 8 ) {
69 asm volatile("prefetchnta %0" : : "m" (dptr[z0][d]));
70 asm volatile("movq %0,%%mm2" : : "m" (dptr[z0][d])); /* P[0] */
71 asm volatile("prefetchnta %0" : : "m" (dptr[z0-1][d]));
72 asm volatile("movq %mm2,%mm4"); /* Q[0] */
73 asm volatile("movq %0,%%mm6" : : "m" (dptr[z0-1][d]));
74 for ( z = z0-2 ; z >= 0 ; z-- ) {
75 asm volatile("prefetchnta %0" : : "m" (dptr[z][d]));
76 asm volatile("pcmpgtb %mm4,%mm5");
77 asm volatile("paddb %mm4,%mm4");
78 asm volatile("pand %mm0,%mm5");
79 asm volatile("pxor %mm5,%mm4");
80 asm volatile("pxor %mm5,%mm5");
81 asm volatile("pxor %mm6,%mm2");
82 asm volatile("pxor %mm6,%mm4");
83 asm volatile("movq %0,%%mm6" : : "m" (dptr[z][d]));
84 }
85 asm volatile("pcmpgtb %mm4,%mm5");
86 asm volatile("paddb %mm4,%mm4");
87 asm volatile("pand %mm0,%mm5");
88 asm volatile("pxor %mm5,%mm4");
89 asm volatile("pxor %mm5,%mm5");
90 asm volatile("pxor %mm6,%mm2");
91 asm volatile("pxor %mm6,%mm4");
93 asm volatile("movntq %%mm2,%0" : "=m" (p[d]));
94 asm volatile("movntq %%mm4,%0" : "=m" (q[d]));
95 }
97 raid6_after_mmx(&sa);
98 asm volatile("sfence" : : : "memory");
99 }
101 const struct raid6_calls raid6_sse1x1 = {
102 raid6_sse11_gen_syndrome,
103 raid6_have_sse1_or_mmxext,
104 "sse1x1",
105 1 /* Has cache hints */
106 };
108 /*
109 * Unrolled-by-2 SSE1 implementation
110 */
111 static void raid6_sse12_gen_syndrome(int disks, size_t bytes, void **ptrs)
112 {
113 u8 **dptr = (u8 **)ptrs;
114 u8 *p, *q;
115 int d, z, z0;
116 raid6_mmx_save_t sa;
118 z0 = disks - 3; /* Highest data disk */
119 p = dptr[z0+1]; /* XOR parity */
120 q = dptr[z0+2]; /* RS syndrome */
122 raid6_before_mmx(&sa);
124 asm volatile("movq %0,%%mm0" : : "m" (raid6_mmx_constants.x1d));
125 asm volatile("pxor %mm5,%mm5"); /* Zero temp */
126 asm volatile("pxor %mm7,%mm7"); /* Zero temp */
128 /* We uniformly assume a single prefetch covers at least 16 bytes */
129 for ( d = 0 ; d < bytes ; d += 16 ) {
130 asm volatile("prefetchnta %0" : : "m" (dptr[z0][d]));
131 asm volatile("movq %0,%%mm2" : : "m" (dptr[z0][d])); /* P[0] */
132 asm volatile("movq %0,%%mm3" : : "m" (dptr[z0][d+8])); /* P[1] */
133 asm volatile("movq %mm2,%mm4"); /* Q[0] */
134 asm volatile("movq %mm3,%mm6"); /* Q[1] */
135 for ( z = z0-1 ; z >= 0 ; z-- ) {
136 asm volatile("prefetchnta %0" : : "m" (dptr[z][d]));
137 asm volatile("pcmpgtb %mm4,%mm5");
138 asm volatile("pcmpgtb %mm6,%mm7");
139 asm volatile("paddb %mm4,%mm4");
140 asm volatile("paddb %mm6,%mm6");
141 asm volatile("pand %mm0,%mm5");
142 asm volatile("pand %mm0,%mm7");
143 asm volatile("pxor %mm5,%mm4");
144 asm volatile("pxor %mm7,%mm6");
145 asm volatile("movq %0,%%mm5" : : "m" (dptr[z][d]));
146 asm volatile("movq %0,%%mm7" : : "m" (dptr[z][d+8]));
147 asm volatile("pxor %mm5,%mm2");
148 asm volatile("pxor %mm7,%mm3");
149 asm volatile("pxor %mm5,%mm4");
150 asm volatile("pxor %mm7,%mm6");
151 asm volatile("pxor %mm5,%mm5");
152 asm volatile("pxor %mm7,%mm7");
153 }
154 asm volatile("movntq %%mm2,%0" : "=m" (p[d]));
155 asm volatile("movntq %%mm3,%0" : "=m" (p[d+8]));
156 asm volatile("movntq %%mm4,%0" : "=m" (q[d]));
157 asm volatile("movntq %%mm6,%0" : "=m" (q[d+8]));
158 }
160 raid6_after_mmx(&sa);
161 asm volatile("sfence" : :: "memory");
162 }
164 const struct raid6_calls raid6_sse1x2 = {
165 raid6_sse12_gen_syndrome,
166 raid6_have_sse1_or_mmxext,
167 "sse1x2",
168 1 /* Has cache hints */
169 };
171 #endif