ia64/linux-2.6.18-xen.hg

view drivers/rapidio/rio-sysfs.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 /*
2 * RapidIO sysfs attributes and support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
13 #include <linux/kernel.h>
14 #include <linux/rio.h>
15 #include <linux/rio_drv.h>
16 #include <linux/stat.h>
17 #include <linux/sched.h> /* for capable() */
19 #include "rio.h"
21 /* Sysfs support */
22 #define rio_config_attr(field, format_string) \
23 static ssize_t \
24 field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
25 { \
26 struct rio_dev *rdev = to_rio_dev(dev); \
27 \
28 return sprintf(buf, format_string, rdev->field); \
29 } \
31 rio_config_attr(did, "0x%04x\n");
32 rio_config_attr(vid, "0x%04x\n");
33 rio_config_attr(device_rev, "0x%08x\n");
34 rio_config_attr(asm_did, "0x%04x\n");
35 rio_config_attr(asm_vid, "0x%04x\n");
36 rio_config_attr(asm_rev, "0x%04x\n");
38 static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf)
39 {
40 struct rio_dev *rdev = to_rio_dev(dev);
41 char *str = buf;
42 int i;
44 if (!rdev->rswitch)
45 goto out;
47 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
48 if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
49 continue;
50 str +=
51 sprintf(str, "%04x %02x\n", i,
52 rdev->rswitch->route_table[i]);
53 }
55 out:
56 return (str - buf);
57 }
59 struct device_attribute rio_dev_attrs[] = {
60 __ATTR_RO(did),
61 __ATTR_RO(vid),
62 __ATTR_RO(device_rev),
63 __ATTR_RO(asm_did),
64 __ATTR_RO(asm_vid),
65 __ATTR_RO(asm_rev),
66 __ATTR_RO(routes),
67 __ATTR_NULL,
68 };
70 static ssize_t
71 rio_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
72 {
73 struct rio_dev *dev =
74 to_rio_dev(container_of(kobj, struct device, kobj));
75 unsigned int size = 0x100;
76 loff_t init_off = off;
77 u8 *data = (u8 *) buf;
79 /* Several chips lock up trying to read undefined config space */
80 if (capable(CAP_SYS_ADMIN))
81 size = 0x200000;
83 if (off > size)
84 return 0;
85 if (off + count > size) {
86 size -= off;
87 count = size;
88 } else {
89 size = count;
90 }
92 if ((off & 1) && size) {
93 u8 val;
94 rio_read_config_8(dev, off, &val);
95 data[off - init_off] = val;
96 off++;
97 size--;
98 }
100 if ((off & 3) && size > 2) {
101 u16 val;
102 rio_read_config_16(dev, off, &val);
103 data[off - init_off] = (val >> 8) & 0xff;
104 data[off - init_off + 1] = val & 0xff;
105 off += 2;
106 size -= 2;
107 }
109 while (size > 3) {
110 u32 val;
111 rio_read_config_32(dev, off, &val);
112 data[off - init_off] = (val >> 24) & 0xff;
113 data[off - init_off + 1] = (val >> 16) & 0xff;
114 data[off - init_off + 2] = (val >> 8) & 0xff;
115 data[off - init_off + 3] = val & 0xff;
116 off += 4;
117 size -= 4;
118 }
120 if (size >= 2) {
121 u16 val;
122 rio_read_config_16(dev, off, &val);
123 data[off - init_off] = (val >> 8) & 0xff;
124 data[off - init_off + 1] = val & 0xff;
125 off += 2;
126 size -= 2;
127 }
129 if (size > 0) {
130 u8 val;
131 rio_read_config_8(dev, off, &val);
132 data[off - init_off] = val;
133 off++;
134 --size;
135 }
137 return count;
138 }
140 static ssize_t
141 rio_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
142 {
143 struct rio_dev *dev =
144 to_rio_dev(container_of(kobj, struct device, kobj));
145 unsigned int size = count;
146 loff_t init_off = off;
147 u8 *data = (u8 *) buf;
149 if (off > 0x200000)
150 return 0;
151 if (off + count > 0x200000) {
152 size = 0x200000 - off;
153 count = size;
154 }
156 if ((off & 1) && size) {
157 rio_write_config_8(dev, off, data[off - init_off]);
158 off++;
159 size--;
160 }
162 if ((off & 3) && (size > 2)) {
163 u16 val = data[off - init_off + 1];
164 val |= (u16) data[off - init_off] << 8;
165 rio_write_config_16(dev, off, val);
166 off += 2;
167 size -= 2;
168 }
170 while (size > 3) {
171 u32 val = data[off - init_off + 3];
172 val |= (u32) data[off - init_off + 2] << 8;
173 val |= (u32) data[off - init_off + 1] << 16;
174 val |= (u32) data[off - init_off] << 24;
175 rio_write_config_32(dev, off, val);
176 off += 4;
177 size -= 4;
178 }
180 if (size >= 2) {
181 u16 val = data[off - init_off + 1];
182 val |= (u16) data[off - init_off] << 8;
183 rio_write_config_16(dev, off, val);
184 off += 2;
185 size -= 2;
186 }
188 if (size) {
189 rio_write_config_8(dev, off, data[off - init_off]);
190 off++;
191 --size;
192 }
194 return count;
195 }
197 static struct bin_attribute rio_config_attr = {
198 .attr = {
199 .name = "config",
200 .mode = S_IRUGO | S_IWUSR,
201 .owner = THIS_MODULE,
202 },
203 .size = 0x200000,
204 .read = rio_read_config,
205 .write = rio_write_config,
206 };
208 /**
209 * rio_create_sysfs_dev_files - create RIO specific sysfs files
210 * @rdev: device whose entries should be created
211 *
212 * Create files when @rdev is added to sysfs.
213 */
214 int rio_create_sysfs_dev_files(struct rio_dev *rdev)
215 {
216 sysfs_create_bin_file(&rdev->dev.kobj, &rio_config_attr);
218 return 0;
219 }
221 /**
222 * rio_remove_sysfs_dev_files - cleanup RIO specific sysfs files
223 * @rdev: device whose entries we should free
224 *
225 * Cleanup when @rdev is removed from sysfs.
226 */
227 void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
228 {
229 sysfs_remove_bin_file(&rdev->dev.kobj, &rio_config_attr);
230 }