view Documentation/cli-sti-removal.txt @ 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
line source
2 #### cli()/sti() removal guide, started by Ingo Molnar <mingo@redhat.com>
5 as of 2.5.28, five popular macros have been removed on SMP, and
6 are being phased out on UP:
8 cli(), sti(), save_flags(flags), save_flags_cli(flags), restore_flags(flags)
10 until now it was possible to protect driver code against interrupt
11 handlers via a cli(), but from now on other, more lightweight methods
12 have to be used for synchronization, such as spinlocks or semaphores.
14 for example, driver code that used to do something like:
16 struct driver_data;
18 irq_handler (...)
19 {
20 ....
21 driver_data.finish = 1;
22 driver_data.new_work = 0;
23 ....
24 }
26 ...
28 ioctl_func (...)
29 {
30 ...
31 cli();
32 ...
33 driver_data.finish = 0;
34 driver_data.new_work = 2;
35 ...
36 sti();
37 ...
38 }
40 was SMP-correct because the cli() function ensured that no
41 interrupt handler (amongst them the above irq_handler()) function
42 would execute while the cli()-ed section is executing.
44 but from now on a more direct method of locking has to be used:
46 spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;
47 struct driver_data;
49 irq_handler (...)
50 {
51 unsigned long flags;
52 ....
53 spin_lock_irqsave(&driver_lock, flags);
54 ....
55 driver_data.finish = 1;
56 driver_data.new_work = 0;
57 ....
58 spin_unlock_irqrestore(&driver_lock, flags);
59 ....
60 }
62 ...
64 ioctl_func (...)
65 {
66 ...
67 spin_lock_irq(&driver_lock);
68 ...
69 driver_data.finish = 0;
70 driver_data.new_work = 2;
71 ...
72 spin_unlock_irq(&driver_lock);
73 ...
74 }
76 the above code has a number of advantages:
78 - the locking relation is easier to understand - actual lock usage
79 pinpoints the critical sections. cli() usage is too opaque.
80 Easier to understand means it's easier to debug.
82 - it's faster, because spinlocks are faster to acquire than the
83 potentially heavily-used IRQ lock. Furthermore, your driver does
84 not have to wait eg. for a big heavy SCSI interrupt to finish,
85 because the driver_lock spinlock is only used by your driver.
86 cli() on the other hand was used by many drivers, and extended
87 the critical section to the whole IRQ handler function - creating
88 serious lock contention.
91 to make the transition easier, we've still kept the cli(), sti(),
92 save_flags(), save_flags_cli() and restore_flags() macros defined
93 on UP systems - but their usage will be phased out until 2.6 is
94 released.
96 drivers that want to disable local interrupts (interrupts on the
97 current CPU), can use the following five macros:
99 local_irq_disable(), local_irq_enable(), local_save_flags(flags),
100 local_irq_save(flags), local_irq_restore(flags)
102 but beware, their meaning and semantics are much simpler, far from
103 that of the old cli(), sti(), save_flags(flags) and restore_flags(flags)
104 SMP meaning:
106 local_irq_disable() => turn local IRQs off
108 local_irq_enable() => turn local IRQs on
110 local_save_flags(flags) => save the current IRQ state into flags. The
111 state can be on or off. (on some
112 architectures there's even more bits in it.)
114 local_irq_save(flags) => save the current IRQ state into flags and
115 disable interrupts.
117 local_irq_restore(flags) => restore the IRQ state from flags.
119 (local_irq_save can save both irqs on and irqs off state, and
120 local_irq_restore can restore into both irqs on and irqs off state.)
122 another related change is that synchronize_irq() now takes a parameter:
123 synchronize_irq(irq). This change too has the purpose of making SMP
124 synchronization more lightweight - this way you can wait for your own
125 interrupt handler to finish, no need to wait for other IRQ sources.
128 why were these changes done? The main reason was the architectural burden
129 of maintaining the cli()/sti() interface - it became a real problem. The
130 new interrupt system is much more streamlined, easier to understand, debug,
131 and it's also a bit faster - the same happened to it that will happen to
132 cli()/sti() using drivers once they convert to spinlocks :-)