ia64/linux-2.6.18-xen.hg

view drivers/mtd/chips/fwh_lock.h @ 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 #ifndef FWH_LOCK_H
2 #define FWH_LOCK_H
5 enum fwh_lock_state {
6 FWH_UNLOCKED = 0,
7 FWH_DENY_WRITE = 1,
8 FWH_IMMUTABLE = 2,
9 FWH_DENY_READ = 4,
10 };
12 struct fwh_xxlock_thunk {
13 enum fwh_lock_state val;
14 flstate_t state;
15 };
18 #define FWH_XXLOCK_ONEBLOCK_LOCK ((struct fwh_xxlock_thunk){ FWH_DENY_WRITE, FL_LOCKING})
19 #define FWH_XXLOCK_ONEBLOCK_UNLOCK ((struct fwh_xxlock_thunk){ FWH_UNLOCKED, FL_UNLOCKING})
21 /*
22 * This locking/unlock is specific to firmware hub parts. Only one
23 * is known that supports the Intel command set. Firmware
24 * hub parts cannot be interleaved as they are on the LPC bus
25 * so this code has not been tested with interleaved chips,
26 * and will likely fail in that context.
27 */
28 static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
29 unsigned long adr, int len, void *thunk)
30 {
31 struct cfi_private *cfi = map->fldrv_priv;
32 struct fwh_xxlock_thunk *xxlt = (struct fwh_xxlock_thunk *)thunk;
33 int ret;
35 /* Refuse the operation if the we cannot look behind the chip */
36 if (chip->start < 0x400000) {
37 DEBUG( MTD_DEBUG_LEVEL3,
38 "MTD %s(): chip->start: %lx wanted >= 0x400000\n",
39 __func__, chip->start );
40 return -EIO;
41 }
42 /*
43 * lock block registers:
44 * - on 64k boundariesand
45 * - bit 1 set high
46 * - block lock registers are 4MiB lower - overflow subtract (danger)
47 *
48 * The address manipulation is first done on the logical address
49 * which is 0 at the start of the chip, and then the offset of
50 * the individual chip is addted to it. Any other order a weird
51 * map offset could cause problems.
52 */
53 adr = (adr & ~0xffffUL) | 0x2;
54 adr += chip->start - 0x400000;
56 /*
57 * This is easy because these are writes to registers and not writes
58 * to flash memory - that means that we don't have to check status
59 * and timeout.
60 */
61 spin_lock(chip->mutex);
62 ret = get_chip(map, chip, adr, FL_LOCKING);
63 if (ret) {
64 spin_unlock(chip->mutex);
65 return ret;
66 }
68 chip->state = xxlt->state;
69 map_write(map, CMD(xxlt->val), adr);
71 /* Done and happy. */
72 chip->state = FL_READY;
73 put_chip(map, chip, adr);
74 spin_unlock(chip->mutex);
75 return 0;
76 }
79 static int fwh_lock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
80 {
81 int ret;
83 ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len,
84 (void *)&FWH_XXLOCK_ONEBLOCK_LOCK);
86 return ret;
87 }
90 static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
91 {
92 int ret;
94 ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len,
95 (void *)&FWH_XXLOCK_ONEBLOCK_UNLOCK);
97 return ret;
98 }
100 static void fixup_use_fwh_lock(struct mtd_info *mtd, void *param)
101 {
102 printk(KERN_NOTICE "using fwh lock/unlock method\n");
103 /* Setup for the chips with the fwh lock method */
104 mtd->lock = fwh_lock_varsize;
105 mtd->unlock = fwh_unlock_varsize;
106 }
107 #endif /* FWH_LOCK_H */