ia64/linux-2.6.18-xen.hg

view drivers/pci/syscall.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 * pci_syscall.c
3 *
4 * For architectures where we want to allow direct access
5 * to the PCI config stuff - it would probably be preferable
6 * on PCs too, but there people just do it by hand with the
7 * magic northbridge registers..
8 */
10 #include <linux/sched.h>
11 #include <linux/errno.h>
12 #include <linux/pci.h>
13 #include <linux/smp_lock.h>
14 #include <linux/syscalls.h>
15 #include <asm/uaccess.h>
16 #include "pci.h"
18 asmlinkage long
19 sys_pciconfig_read(unsigned long bus, unsigned long dfn,
20 unsigned long off, unsigned long len,
21 void __user *buf)
22 {
23 struct pci_dev *dev;
24 u8 byte;
25 u16 word;
26 u32 dword;
27 long err, cfg_ret;
29 err = -EPERM;
30 if (!capable(CAP_SYS_ADMIN))
31 goto error;
33 err = -ENODEV;
34 dev = pci_find_slot(bus, dfn);
35 if (!dev)
36 goto error;
38 lock_kernel();
39 switch (len) {
40 case 1:
41 cfg_ret = pci_user_read_config_byte(dev, off, &byte);
42 break;
43 case 2:
44 cfg_ret = pci_user_read_config_word(dev, off, &word);
45 break;
46 case 4:
47 cfg_ret = pci_user_read_config_dword(dev, off, &dword);
48 break;
49 default:
50 err = -EINVAL;
51 unlock_kernel();
52 goto error;
53 };
54 unlock_kernel();
56 err = -EIO;
57 if (cfg_ret != PCIBIOS_SUCCESSFUL)
58 goto error;
60 switch (len) {
61 case 1:
62 err = put_user(byte, (unsigned char __user *)buf);
63 break;
64 case 2:
65 err = put_user(word, (unsigned short __user *)buf);
66 break;
67 case 4:
68 err = put_user(dword, (unsigned int __user *)buf);
69 break;
70 };
71 return err;
73 error:
74 /* ??? XFree86 doesn't even check the return value. They
75 just look for 0xffffffff in the output, since that's what
76 they get instead of a machine check on x86. */
77 switch (len) {
78 case 1:
79 put_user(-1, (unsigned char __user *)buf);
80 break;
81 case 2:
82 put_user(-1, (unsigned short __user *)buf);
83 break;
84 case 4:
85 put_user(-1, (unsigned int __user *)buf);
86 break;
87 };
88 return err;
89 }
91 asmlinkage long
92 sys_pciconfig_write(unsigned long bus, unsigned long dfn,
93 unsigned long off, unsigned long len,
94 void __user *buf)
95 {
96 struct pci_dev *dev;
97 u8 byte;
98 u16 word;
99 u32 dword;
100 int err = 0;
102 if (!capable(CAP_SYS_ADMIN))
103 return -EPERM;
105 dev = pci_find_slot(bus, dfn);
106 if (!dev)
107 return -ENODEV;
109 lock_kernel();
110 switch(len) {
111 case 1:
112 err = get_user(byte, (u8 __user *)buf);
113 if (err)
114 break;
115 err = pci_user_write_config_byte(dev, off, byte);
116 if (err != PCIBIOS_SUCCESSFUL)
117 err = -EIO;
118 break;
120 case 2:
121 err = get_user(word, (u16 __user *)buf);
122 if (err)
123 break;
124 err = pci_user_write_config_word(dev, off, word);
125 if (err != PCIBIOS_SUCCESSFUL)
126 err = -EIO;
127 break;
129 case 4:
130 err = get_user(dword, (u32 __user *)buf);
131 if (err)
132 break;
133 err = pci_user_write_config_dword(dev, off, dword);
134 if (err != PCIBIOS_SUCCESSFUL)
135 err = -EIO;
136 break;
138 default:
139 err = -EINVAL;
140 break;
141 };
142 unlock_kernel();
144 return err;
145 }