ia64/linux-2.6.18-xen.hg

view drivers/pci/access.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 #include <linux/pci.h>
2 #include <linux/module.h>
3 #include <linux/ioport.h>
5 #include "pci.h"
7 /*
8 * This interrupt-safe spinlock protects all accesses to PCI
9 * configuration space.
10 */
12 static DEFINE_SPINLOCK(pci_lock);
14 /*
15 * Wrappers for all PCI configuration access functions. They just check
16 * alignment, do locking and call the low-level functions pointed to
17 * by pci_dev->ops.
18 */
20 #define PCI_byte_BAD 0
21 #define PCI_word_BAD (pos & 1)
22 #define PCI_dword_BAD (pos & 3)
24 #define PCI_OP_READ(size,type,len) \
25 int pci_bus_read_config_##size \
26 (struct pci_bus *bus, unsigned int devfn, int pos, type *value) \
27 { \
28 int res; \
29 unsigned long flags; \
30 u32 data = 0; \
31 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
32 spin_lock_irqsave(&pci_lock, flags); \
33 res = bus->ops->read(bus, devfn, pos, len, &data); \
34 *value = (type)data; \
35 spin_unlock_irqrestore(&pci_lock, flags); \
36 return res; \
37 }
39 #define PCI_OP_WRITE(size,type,len) \
40 int pci_bus_write_config_##size \
41 (struct pci_bus *bus, unsigned int devfn, int pos, type value) \
42 { \
43 int res; \
44 unsigned long flags; \
45 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
46 spin_lock_irqsave(&pci_lock, flags); \
47 res = bus->ops->write(bus, devfn, pos, len, value); \
48 spin_unlock_irqrestore(&pci_lock, flags); \
49 return res; \
50 }
52 PCI_OP_READ(byte, u8, 1)
53 PCI_OP_READ(word, u16, 2)
54 PCI_OP_READ(dword, u32, 4)
55 PCI_OP_WRITE(byte, u8, 1)
56 PCI_OP_WRITE(word, u16, 2)
57 PCI_OP_WRITE(dword, u32, 4)
59 EXPORT_SYMBOL(pci_bus_read_config_byte);
60 EXPORT_SYMBOL(pci_bus_read_config_word);
61 EXPORT_SYMBOL(pci_bus_read_config_dword);
62 EXPORT_SYMBOL(pci_bus_write_config_byte);
63 EXPORT_SYMBOL(pci_bus_write_config_word);
64 EXPORT_SYMBOL(pci_bus_write_config_dword);
66 static u32 pci_user_cached_config(struct pci_dev *dev, int pos)
67 {
68 u32 data;
70 data = dev->saved_config_space[pos/sizeof(dev->saved_config_space[0])];
71 data >>= (pos % sizeof(dev->saved_config_space[0])) * 8;
72 return data;
73 }
75 #define PCI_USER_READ_CONFIG(size,type) \
76 int pci_user_read_config_##size \
77 (struct pci_dev *dev, int pos, type *val) \
78 { \
79 unsigned long flags; \
80 int ret = 0; \
81 u32 data = -1; \
82 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
83 spin_lock_irqsave(&pci_lock, flags); \
84 if (likely(!dev->block_ucfg_access)) \
85 ret = dev->bus->ops->read(dev->bus, dev->devfn, \
86 pos, sizeof(type), &data); \
87 else if (pos < sizeof(dev->saved_config_space)) \
88 data = pci_user_cached_config(dev, pos); \
89 spin_unlock_irqrestore(&pci_lock, flags); \
90 *val = (type)data; \
91 return ret; \
92 }
94 #define PCI_USER_WRITE_CONFIG(size,type) \
95 int pci_user_write_config_##size \
96 (struct pci_dev *dev, int pos, type val) \
97 { \
98 unsigned long flags; \
99 int ret = -EIO; \
100 if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
101 spin_lock_irqsave(&pci_lock, flags); \
102 if (likely(!dev->block_ucfg_access)) \
103 ret = dev->bus->ops->write(dev->bus, dev->devfn, \
104 pos, sizeof(type), val); \
105 spin_unlock_irqrestore(&pci_lock, flags); \
106 return ret; \
107 }
109 PCI_USER_READ_CONFIG(byte, u8)
110 PCI_USER_READ_CONFIG(word, u16)
111 PCI_USER_READ_CONFIG(dword, u32)
112 PCI_USER_WRITE_CONFIG(byte, u8)
113 PCI_USER_WRITE_CONFIG(word, u16)
114 PCI_USER_WRITE_CONFIG(dword, u32)
116 /**
117 * pci_block_user_cfg_access - Block userspace PCI config reads/writes
118 * @dev: pci device struct
119 *
120 * This function blocks any userspace PCI config accesses from occurring.
121 * When blocked, any writes will be bit bucketed and reads will return the
122 * data saved using pci_save_state for the first 64 bytes of config
123 * space and return 0xff for all other config reads.
124 **/
125 void pci_block_user_cfg_access(struct pci_dev *dev)
126 {
127 unsigned long flags;
129 pci_save_state(dev);
131 /* spinlock to synchronize with anyone reading config space now */
132 spin_lock_irqsave(&pci_lock, flags);
133 dev->block_ucfg_access = 1;
134 spin_unlock_irqrestore(&pci_lock, flags);
135 }
136 EXPORT_SYMBOL_GPL(pci_block_user_cfg_access);
138 /**
139 * pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes
140 * @dev: pci device struct
141 *
142 * This function allows userspace PCI config accesses to resume.
143 **/
144 void pci_unblock_user_cfg_access(struct pci_dev *dev)
145 {
146 unsigned long flags;
148 /* spinlock to synchronize with anyone reading saved config space */
149 spin_lock_irqsave(&pci_lock, flags);
150 dev->block_ucfg_access = 0;
151 spin_unlock_irqrestore(&pci_lock, flags);
152 }
153 EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access);