ia64/linux-2.6.18-xen.hg

view drivers/block/cciss.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 CCISS_H
2 #define CCISS_H
4 #include <linux/genhd.h>
6 #include "cciss_cmd.h"
9 #define NWD 16
10 #define NWD_SHIFT 4
11 #define MAX_PART (1 << NWD_SHIFT)
13 #define IO_OK 0
14 #define IO_ERROR 1
16 struct ctlr_info;
17 typedef struct ctlr_info ctlr_info_t;
19 struct access_method {
20 void (*submit_command)(ctlr_info_t *h, CommandList_struct *c);
21 void (*set_intr_mask)(ctlr_info_t *h, unsigned long val);
22 unsigned long (*fifo_full)(ctlr_info_t *h);
23 unsigned long (*intr_pending)(ctlr_info_t *h);
24 unsigned long (*command_completed)(ctlr_info_t *h);
25 };
26 typedef struct _drive_info_struct
27 {
28 __u32 LunID;
29 int usage_count;
30 struct request_queue *queue;
31 sector_t nr_blocks;
32 int block_size;
33 int heads;
34 int sectors;
35 int cylinders;
36 int raid_level; /* set to -1 to indicate that
37 * the drive is not in use/configured
38 */
39 int busy_configuring; /*This is set when the drive is being removed
40 *to prevent it from being opened or it's queue
41 *from being started.
42 */
43 } drive_info_struct;
45 #ifdef CONFIG_CISS_SCSI_TAPE
47 struct sendcmd_reject_list {
48 int ncompletions;
49 unsigned long *complete; /* array of NR_CMDS tags */
50 };
52 #endif
53 struct ctlr_info
54 {
55 int ctlr;
56 char devname[8];
57 char *product_name;
58 char firm_ver[4]; // Firmware version
59 struct pci_dev *pdev;
60 __u32 board_id;
61 void __iomem *vaddr;
62 unsigned long paddr;
63 CfgTable_struct __iomem *cfgtable;
64 int interrupts_enabled;
65 int major;
66 int max_commands;
67 int commands_outstanding;
68 int max_outstanding; /* Debug */
69 int num_luns;
70 int highest_lun;
71 int usage_count; /* number of opens all all minor devices */
72 # define DOORBELL_INT 0
73 # define PERF_MODE_INT 1
74 # define SIMPLE_MODE_INT 2
75 # define MEMQ_MODE_INT 3
76 unsigned int intr[4];
77 unsigned int msix_vector;
78 unsigned int msi_vector;
80 // information about each logical volume
81 drive_info_struct drv[CISS_MAX_LUN];
83 struct access_method access;
85 /* queue and queue Info */
86 CommandList_struct *reqQ;
87 CommandList_struct *cmpQ;
88 unsigned int Qdepth;
89 unsigned int maxQsinceinit;
90 unsigned int maxSG;
91 spinlock_t lock;
93 //* pointers to command and error info pool */
94 CommandList_struct *cmd_pool;
95 dma_addr_t cmd_pool_dhandle;
96 ErrorInfo_struct *errinfo_pool;
97 dma_addr_t errinfo_pool_dhandle;
98 unsigned long *cmd_pool_bits;
99 int nr_allocs;
100 int nr_frees;
101 int busy_configuring;
102 int busy_initializing;
104 /* This element holds the zero based queue number of the last
105 * queue to be started. It is used for fairness.
106 */
107 int next_to_run;
109 // Disk structures we need to pass back
110 struct gendisk *gendisk[NWD];
111 #ifdef CONFIG_CISS_SCSI_TAPE
112 void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
113 /* list of block side commands the scsi error handling sucked up */
114 /* and saved for later processing */
115 struct sendcmd_reject_list scsi_rejects;
116 #endif
117 unsigned char alive;
118 };
120 /* Defining the diffent access_menthods */
121 /*
122 * Memory mapped FIFO interface (SMART 53xx cards)
123 */
124 #define SA5_DOORBELL 0x20
125 #define SA5_REQUEST_PORT_OFFSET 0x40
126 #define SA5_REPLY_INTR_MASK_OFFSET 0x34
127 #define SA5_REPLY_PORT_OFFSET 0x44
128 #define SA5_INTR_STATUS 0x30
129 #define SA5_SCRATCHPAD_OFFSET 0xB0
131 #define SA5_CTCFG_OFFSET 0xB4
132 #define SA5_CTMEM_OFFSET 0xB8
134 #define SA5_INTR_OFF 0x08
135 #define SA5B_INTR_OFF 0x04
136 #define SA5_INTR_PENDING 0x08
137 #define SA5B_INTR_PENDING 0x04
138 #define FIFO_EMPTY 0xffffffff
139 #define CCISS_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */
141 #define CISS_ERROR_BIT 0x02
143 #define CCISS_INTR_ON 1
144 #define CCISS_INTR_OFF 0
145 /*
146 Send the command to the hardware
147 */
148 static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c)
149 {
150 #ifdef CCISS_DEBUG
151 printk("Sending %x - down to controller\n", c->busaddr );
152 #endif /* CCISS_DEBUG */
153 writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
154 h->commands_outstanding++;
155 if ( h->commands_outstanding > h->max_outstanding)
156 h->max_outstanding = h->commands_outstanding;
157 }
159 /*
160 * This card is the opposite of the other cards.
161 * 0 turns interrupts on...
162 * 0x08 turns them off...
163 */
164 static void SA5_intr_mask(ctlr_info_t *h, unsigned long val)
165 {
166 if (val)
167 { /* Turn interrupts on */
168 h->interrupts_enabled = 1;
169 writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
170 } else /* Turn them off */
171 {
172 h->interrupts_enabled = 0;
173 writel( SA5_INTR_OFF,
174 h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
175 }
176 }
177 /*
178 * This card is the opposite of the other cards.
179 * 0 turns interrupts on...
180 * 0x04 turns them off...
181 */
182 static void SA5B_intr_mask(ctlr_info_t *h, unsigned long val)
183 {
184 if (val)
185 { /* Turn interrupts on */
186 h->interrupts_enabled = 1;
187 writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
188 } else /* Turn them off */
189 {
190 h->interrupts_enabled = 0;
191 writel( SA5B_INTR_OFF,
192 h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
193 }
194 }
195 /*
196 * Returns true if fifo is full.
197 *
198 */
199 static unsigned long SA5_fifo_full(ctlr_info_t *h)
200 {
201 if( h->commands_outstanding >= h->max_commands)
202 return(1);
203 else
204 return(0);
206 }
207 /*
208 * returns value read from hardware.
209 * returns FIFO_EMPTY if there is nothing to read
210 */
211 static unsigned long SA5_completed(ctlr_info_t *h)
212 {
213 unsigned long register_value
214 = readl(h->vaddr + SA5_REPLY_PORT_OFFSET);
215 if(register_value != FIFO_EMPTY)
216 {
217 h->commands_outstanding--;
218 #ifdef CCISS_DEBUG
219 printk("cciss: Read %lx back from board\n", register_value);
220 #endif /* CCISS_DEBUG */
221 }
222 #ifdef CCISS_DEBUG
223 else
224 {
225 printk("cciss: FIFO Empty read\n");
226 }
227 #endif
228 return ( register_value);
230 }
231 /*
232 * Returns true if an interrupt is pending..
233 */
234 static unsigned long SA5_intr_pending(ctlr_info_t *h)
235 {
236 unsigned long register_value =
237 readl(h->vaddr + SA5_INTR_STATUS);
238 #ifdef CCISS_DEBUG
239 printk("cciss: intr_pending %lx\n", register_value);
240 #endif /* CCISS_DEBUG */
241 if( register_value & SA5_INTR_PENDING)
242 return 1;
243 return 0 ;
244 }
246 /*
247 * Returns true if an interrupt is pending..
248 */
249 static unsigned long SA5B_intr_pending(ctlr_info_t *h)
250 {
251 unsigned long register_value =
252 readl(h->vaddr + SA5_INTR_STATUS);
253 #ifdef CCISS_DEBUG
254 printk("cciss: intr_pending %lx\n", register_value);
255 #endif /* CCISS_DEBUG */
256 if( register_value & SA5B_INTR_PENDING)
257 return 1;
258 return 0 ;
259 }
262 static struct access_method SA5_access = {
263 SA5_submit_command,
264 SA5_intr_mask,
265 SA5_fifo_full,
266 SA5_intr_pending,
267 SA5_completed,
268 };
270 static struct access_method SA5B_access = {
271 SA5_submit_command,
272 SA5B_intr_mask,
273 SA5_fifo_full,
274 SA5B_intr_pending,
275 SA5_completed,
276 };
278 struct board_type {
279 __u32 board_id;
280 char *product_name;
281 struct access_method *access;
282 };
284 #define CCISS_LOCK(i) (&hba[i]->lock)
286 #endif /* CCISS_H */