ia64/linux-2.6.18-xen.hg

view drivers/md/raid6mmx.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 * raid6mmx.c
15 *
16 * MMX implementation of RAID-6 syndrome functions
17 */
19 #if defined(__i386__)
21 #include "raid6.h"
22 #include "raid6x86.h"
24 /* Shared with raid6sse1.c */
25 const struct raid6_mmx_constants {
26 u64 x1d;
27 } raid6_mmx_constants = {
28 0x1d1d1d1d1d1d1d1dULL,
29 };
31 static int raid6_have_mmx(void)
32 {
33 #ifdef __KERNEL__
34 /* Not really "boot_cpu" but "all_cpus" */
35 return boot_cpu_has(X86_FEATURE_MMX);
36 #else
37 /* User space test code */
38 u32 features = cpuid_features();
39 return ( (features & (1<<23)) == (1<<23) );
40 #endif
41 }
43 /*
44 * Plain MMX implementation
45 */
46 static void raid6_mmx1_gen_syndrome(int disks, size_t bytes, void **ptrs)
47 {
48 u8 **dptr = (u8 **)ptrs;
49 u8 *p, *q;
50 int d, z, z0;
51 raid6_mmx_save_t sa;
53 z0 = disks - 3; /* Highest data disk */
54 p = dptr[z0+1]; /* XOR parity */
55 q = dptr[z0+2]; /* RS syndrome */
57 raid6_before_mmx(&sa);
59 asm volatile("movq %0,%%mm0" : : "m" (raid6_mmx_constants.x1d));
60 asm volatile("pxor %mm5,%mm5"); /* Zero temp */
62 for ( d = 0 ; d < bytes ; d += 8 ) {
63 asm volatile("movq %0,%%mm2" : : "m" (dptr[z0][d])); /* P[0] */
64 asm volatile("movq %mm2,%mm4"); /* Q[0] */
65 for ( z = z0-1 ; z >= 0 ; z-- ) {
66 asm volatile("movq %0,%%mm6" : : "m" (dptr[z][d]));
67 asm volatile("pcmpgtb %mm4,%mm5");
68 asm volatile("paddb %mm4,%mm4");
69 asm volatile("pand %mm0,%mm5");
70 asm volatile("pxor %mm5,%mm4");
71 asm volatile("pxor %mm5,%mm5");
72 asm volatile("pxor %mm6,%mm2");
73 asm volatile("pxor %mm6,%mm4");
74 }
75 asm volatile("movq %%mm2,%0" : "=m" (p[d]));
76 asm volatile("pxor %mm2,%mm2");
77 asm volatile("movq %%mm4,%0" : "=m" (q[d]));
78 asm volatile("pxor %mm4,%mm4");
79 }
81 raid6_after_mmx(&sa);
82 }
84 const struct raid6_calls raid6_mmxx1 = {
85 raid6_mmx1_gen_syndrome,
86 raid6_have_mmx,
87 "mmxx1",
88 0
89 };
91 /*
92 * Unrolled-by-2 MMX implementation
93 */
94 static void raid6_mmx2_gen_syndrome(int disks, size_t bytes, void **ptrs)
95 {
96 u8 **dptr = (u8 **)ptrs;
97 u8 *p, *q;
98 int d, z, z0;
99 raid6_mmx_save_t sa;
101 z0 = disks - 3; /* Highest data disk */
102 p = dptr[z0+1]; /* XOR parity */
103 q = dptr[z0+2]; /* RS syndrome */
105 raid6_before_mmx(&sa);
107 asm volatile("movq %0,%%mm0" : : "m" (raid6_mmx_constants.x1d));
108 asm volatile("pxor %mm5,%mm5"); /* Zero temp */
109 asm volatile("pxor %mm7,%mm7"); /* Zero temp */
111 for ( d = 0 ; d < bytes ; d += 16 ) {
112 asm volatile("movq %0,%%mm2" : : "m" (dptr[z0][d])); /* P[0] */
113 asm volatile("movq %0,%%mm3" : : "m" (dptr[z0][d+8]));
114 asm volatile("movq %mm2,%mm4"); /* Q[0] */
115 asm volatile("movq %mm3,%mm6"); /* Q[1] */
116 for ( z = z0-1 ; z >= 0 ; z-- ) {
117 asm volatile("pcmpgtb %mm4,%mm5");
118 asm volatile("pcmpgtb %mm6,%mm7");
119 asm volatile("paddb %mm4,%mm4");
120 asm volatile("paddb %mm6,%mm6");
121 asm volatile("pand %mm0,%mm5");
122 asm volatile("pand %mm0,%mm7");
123 asm volatile("pxor %mm5,%mm4");
124 asm volatile("pxor %mm7,%mm6");
125 asm volatile("movq %0,%%mm5" : : "m" (dptr[z][d]));
126 asm volatile("movq %0,%%mm7" : : "m" (dptr[z][d+8]));
127 asm volatile("pxor %mm5,%mm2");
128 asm volatile("pxor %mm7,%mm3");
129 asm volatile("pxor %mm5,%mm4");
130 asm volatile("pxor %mm7,%mm6");
131 asm volatile("pxor %mm5,%mm5");
132 asm volatile("pxor %mm7,%mm7");
133 }
134 asm volatile("movq %%mm2,%0" : "=m" (p[d]));
135 asm volatile("movq %%mm3,%0" : "=m" (p[d+8]));
136 asm volatile("movq %%mm4,%0" : "=m" (q[d]));
137 asm volatile("movq %%mm6,%0" : "=m" (q[d+8]));
138 }
140 raid6_after_mmx(&sa);
141 }
143 const struct raid6_calls raid6_mmxx2 = {
144 raid6_mmx2_gen_syndrome,
145 raid6_have_mmx,
146 "mmxx2",
147 0
148 };
150 #endif