ia64/linux-2.6.18-xen.hg

view drivers/pci/rom.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 * drivers/pci/rom.c
3 *
4 * (C) Copyright 2004 Jon Smirl <jonsmirl@yahoo.com>
5 * (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
6 *
7 * PCI ROM access routines
8 */
9 #include <linux/kernel.h>
10 #include <linux/pci.h>
11 #include <linux/slab.h>
13 #include "pci.h"
15 /**
16 * pci_enable_rom - enable ROM decoding for a PCI device
17 * @pdev: PCI device to enable
18 *
19 * Enable ROM decoding on @dev. This involves simply turning on the last
20 * bit of the PCI ROM BAR. Note that some cards may share address decoders
21 * between the ROM and other resources, so enabling it may disable access
22 * to MMIO registers or other card memory.
23 */
24 static int pci_enable_rom(struct pci_dev *pdev)
25 {
26 struct resource *res = pdev->resource + PCI_ROM_RESOURCE;
27 struct pci_bus_region region;
28 u32 rom_addr;
30 if (!res->flags)
31 return -1;
33 pcibios_resource_to_bus(pdev, &region, res);
34 pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
35 rom_addr &= ~PCI_ROM_ADDRESS_MASK;
36 rom_addr |= region.start | PCI_ROM_ADDRESS_ENABLE;
37 pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
38 return 0;
39 }
41 /**
42 * pci_disable_rom - disable ROM decoding for a PCI device
43 * @pdev: PCI device to disable
44 *
45 * Disable ROM decoding on a PCI device by turning off the last bit in the
46 * ROM BAR.
47 */
48 static void pci_disable_rom(struct pci_dev *pdev)
49 {
50 u32 rom_addr;
51 pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
52 rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
53 pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr);
54 }
56 /**
57 * pci_map_rom - map a PCI ROM to kernel space
58 * @pdev: pointer to pci device struct
59 * @size: pointer to receive size of pci window over ROM
60 * @return: kernel virtual pointer to image of ROM
61 *
62 * Map a PCI ROM into kernel space. If ROM is boot video ROM,
63 * the shadow BIOS copy will be returned instead of the
64 * actual ROM.
65 */
66 void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
67 {
68 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
69 loff_t start;
70 void __iomem *rom;
71 void __iomem *image;
72 int last_image;
74 /* IORESOURCE_ROM_SHADOW only set on x86 */
75 if (res->flags & IORESOURCE_ROM_SHADOW) {
76 /* primary video rom always starts here */
77 start = (loff_t)0xC0000;
78 *size = 0x20000; /* cover C000:0 through E000:0 */
79 } else {
80 if (res->flags & IORESOURCE_ROM_COPY) {
81 *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
82 return (void __iomem *)(unsigned long)
83 pci_resource_start(pdev, PCI_ROM_RESOURCE);
84 } else {
85 /* assign the ROM an address if it doesn't have one */
86 if (res->parent == NULL &&
87 pci_assign_resource(pdev,PCI_ROM_RESOURCE))
88 return NULL;
89 start = pci_resource_start(pdev, PCI_ROM_RESOURCE);
90 *size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
91 if (*size == 0)
92 return NULL;
94 /* Enable ROM space decodes */
95 if (pci_enable_rom(pdev))
96 return NULL;
97 }
98 }
100 rom = ioremap(start, *size);
101 if (!rom) {
102 /* restore enable if ioremap fails */
103 if (!(res->flags & (IORESOURCE_ROM_ENABLE |
104 IORESOURCE_ROM_SHADOW |
105 IORESOURCE_ROM_COPY)))
106 pci_disable_rom(pdev);
107 return NULL;
108 }
110 /*
111 * Try to find the true size of the ROM since sometimes the PCI window
112 * size is much larger than the actual size of the ROM.
113 * True size is important if the ROM is going to be copied.
114 */
115 image = rom;
116 do {
117 void __iomem *pds;
118 /* Standard PCI ROMs start out with these bytes 55 AA */
119 if (readb(image) != 0x55)
120 break;
121 if (readb(image + 1) != 0xAA)
122 break;
123 /* get the PCI data structure and check its signature */
124 pds = image + readw(image + 24);
125 if (readb(pds) != 'P')
126 break;
127 if (readb(pds + 1) != 'C')
128 break;
129 if (readb(pds + 2) != 'I')
130 break;
131 if (readb(pds + 3) != 'R')
132 break;
133 last_image = readb(pds + 21) & 0x80;
134 /* this length is reliable */
135 image += readw(pds + 16) * 512;
136 } while (!last_image);
138 /* never return a size larger than the PCI resource window */
139 /* there are known ROMs that get the size wrong */
140 *size = min((size_t)(image - rom), *size);
142 return rom;
143 }
145 /**
146 * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
147 * @pdev: pointer to pci device struct
148 * @size: pointer to receive size of pci window over ROM
149 * @return: kernel virtual pointer to image of ROM
150 *
151 * Map a PCI ROM into kernel space. If ROM is boot video ROM,
152 * the shadow BIOS copy will be returned instead of the
153 * actual ROM.
154 */
155 void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
156 {
157 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
158 void __iomem *rom;
160 rom = pci_map_rom(pdev, size);
161 if (!rom)
162 return NULL;
164 if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW))
165 return rom;
167 res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
168 if (!res->start)
169 return rom;
171 res->end = res->start + *size;
172 memcpy_fromio((void*)(unsigned long)res->start, rom, *size);
173 pci_unmap_rom(pdev, rom);
174 res->flags |= IORESOURCE_ROM_COPY;
176 return (void __iomem *)(unsigned long)res->start;
177 }
179 /**
180 * pci_unmap_rom - unmap the ROM from kernel space
181 * @pdev: pointer to pci device struct
182 * @rom: virtual address of the previous mapping
183 *
184 * Remove a mapping of a previously mapped ROM
185 */
186 void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
187 {
188 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
190 if (res->flags & IORESOURCE_ROM_COPY)
191 return;
193 iounmap(rom);
195 /* Disable again before continuing, leave enabled if pci=rom */
196 if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW)))
197 pci_disable_rom(pdev);
198 }
200 /**
201 * pci_remove_rom - disable the ROM and remove its sysfs attribute
202 * @pdev: pointer to pci device struct
203 *
204 * Remove the rom file in sysfs and disable ROM decoding.
205 */
206 void pci_remove_rom(struct pci_dev *pdev)
207 {
208 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
210 if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
211 sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
212 if (!(res->flags & (IORESOURCE_ROM_ENABLE |
213 IORESOURCE_ROM_SHADOW |
214 IORESOURCE_ROM_COPY)))
215 pci_disable_rom(pdev);
216 }
218 /**
219 * pci_cleanup_rom - internal routine for freeing the ROM copy created
220 * by pci_map_rom_copy called from remove.c
221 * @pdev: pointer to pci device struct
222 *
223 * Free the copied ROM if we allocated one.
224 */
225 void pci_cleanup_rom(struct pci_dev *pdev)
226 {
227 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
228 if (res->flags & IORESOURCE_ROM_COPY) {
229 kfree((void*)(unsigned long)res->start);
230 res->flags &= ~IORESOURCE_ROM_COPY;
231 res->start = 0;
232 res->end = 0;
233 }
234 }
236 EXPORT_SYMBOL(pci_map_rom);
237 EXPORT_SYMBOL(pci_map_rom_copy);
238 EXPORT_SYMBOL(pci_unmap_rom);
239 EXPORT_SYMBOL(pci_remove_rom);