ia64/linux-2.6.18-xen.hg

view drivers/net/oaknet.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 *
3 * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
4 *
5 * Module name: oaknet.c
6 *
7 * Description:
8 * Driver for the National Semiconductor DP83902AV Ethernet controller
9 * on-board the IBM PowerPC "Oak" evaluation board. Adapted from the
10 * various other 8390 drivers written by Donald Becker and Paul Gortmaker.
11 *
12 * Additional inspiration from the "tcd8390.c" driver from TiVo, Inc.
13 * and "enetLib.c" from IBM.
14 *
15 */
17 #include <linux/module.h>
18 #include <linux/errno.h>
19 #include <linux/delay.h>
20 #include <linux/netdevice.h>
21 #include <linux/etherdevice.h>
22 #include <linux/init.h>
23 #include <linux/jiffies.h>
25 #include <asm/board.h>
26 #include <asm/io.h>
28 #include "8390.h"
31 /* Preprocessor Defines */
33 #if !defined(TRUE) || TRUE != 1
34 #define TRUE 1
35 #endif
37 #if !defined(FALSE) || FALSE != 0
38 #define FALSE 0
39 #endif
41 #define OAKNET_START_PG 0x20 /* First page of TX buffer */
42 #define OAKNET_STOP_PG 0x40 /* Last pagge +1 of RX ring */
44 #define OAKNET_WAIT (2 * HZ / 100) /* 20 ms */
46 /* Experimenting with some fixes for a broken driver... */
48 #define OAKNET_DISINT
49 #define OAKNET_HEADCHECK
50 #define OAKNET_RWFIX
53 /* Global Variables */
55 static const char *name = "National DP83902AV";
57 static struct net_device *oaknet_devs;
60 /* Function Prototypes */
62 static int oaknet_open(struct net_device *dev);
63 static int oaknet_close(struct net_device *dev);
65 static void oaknet_reset_8390(struct net_device *dev);
66 static void oaknet_get_8390_hdr(struct net_device *dev,
67 struct e8390_pkt_hdr *hdr, int ring_page);
68 static void oaknet_block_input(struct net_device *dev, int count,
69 struct sk_buff *skb, int ring_offset);
70 static void oaknet_block_output(struct net_device *dev, int count,
71 const unsigned char *buf, int start_page);
73 static void oaknet_dma_error(struct net_device *dev, const char *name);
76 /*
77 * int oaknet_init()
78 *
79 * Description:
80 * This routine performs all the necessary platform-specific initiali-
81 * zation and set-up for the IBM "Oak" evaluation board's National
82 * Semiconductor DP83902AV "ST-NIC" Ethernet controller.
83 *
84 * Input(s):
85 * N/A
86 *
87 * Output(s):
88 * N/A
89 *
90 * Returns:
91 * 0 if OK, otherwise system error number on error.
92 *
93 */
94 static int __init oaknet_init(void)
95 {
96 register int i;
97 int reg0, regd;
98 int ret = -ENOMEM;
99 struct net_device *dev;
100 #if 0
101 unsigned long ioaddr = OAKNET_IO_BASE;
102 #else
103 unsigned long ioaddr = ioremap(OAKNET_IO_BASE, OAKNET_IO_SIZE);
104 #endif
105 bd_t *bip = (bd_t *)__res;
107 if (!ioaddr)
108 return -ENOMEM;
110 dev = alloc_ei_netdev();
111 if (!dev)
112 goto out_unmap;
114 ret = -EBUSY;
115 if (!request_region(OAKNET_IO_BASE, OAKNET_IO_SIZE, name))
116 goto out_dev;
118 /* Quick register check to see if the device is really there. */
120 ret = -ENODEV;
121 if ((reg0 = ei_ibp(ioaddr)) == 0xFF)
122 goto out_region;
124 /*
125 * That worked. Now a more thorough check, using the multicast
126 * address registers, that the device is definitely out there
127 * and semi-functional.
128 */
130 ei_obp(E8390_NODMA + E8390_PAGE1 + E8390_STOP, ioaddr + E8390_CMD);
131 regd = ei_ibp(ioaddr + 0x0D);
132 ei_obp(0xFF, ioaddr + 0x0D);
133 ei_obp(E8390_NODMA + E8390_PAGE0, ioaddr + E8390_CMD);
134 ei_ibp(ioaddr + EN0_COUNTER0);
136 /* It's no good. Fix things back up and leave. */
138 ret = -ENODEV;
139 if (ei_ibp(ioaddr + EN0_COUNTER0) != 0) {
140 ei_obp(reg0, ioaddr);
141 ei_obp(regd, ioaddr + 0x0D);
142 goto out_region;
143 }
145 SET_MODULE_OWNER(dev);
147 /*
148 * This controller is on an embedded board, so the base address
149 * and interrupt assignments are pre-assigned and unchageable.
150 */
152 dev->base_addr = ioaddr;
153 dev->irq = OAKNET_INT;
155 /*
156 * Disable all chip interrupts for now and ACK all pending
157 * interrupts.
158 */
160 ei_obp(0x0, ioaddr + EN0_IMR);
161 ei_obp(0xFF, ioaddr + EN0_ISR);
163 /* Attempt to get the interrupt line */
165 ret = -EAGAIN;
166 if (request_irq(dev->irq, ei_interrupt, 0, name, dev)) {
167 printk("%s: unable to request interrupt %d.\n",
168 name, dev->irq);
169 goto out_region;
170 }
172 /* Tell the world about what and where we've found. */
174 printk("%s: %s at", dev->name, name);
175 for (i = 0; i < ETHER_ADDR_LEN; ++i) {
176 dev->dev_addr[i] = bip->bi_enetaddr[i];
177 printk("%c%.2x", (i ? ':' : ' '), dev->dev_addr[i]);
178 }
179 printk(", found at %#lx, using IRQ %d.\n", dev->base_addr, dev->irq);
181 /* Set up some required driver fields and then we're done. */
183 ei_status.name = name;
184 ei_status.word16 = FALSE;
185 ei_status.tx_start_page = OAKNET_START_PG;
186 ei_status.rx_start_page = OAKNET_START_PG + TX_PAGES;
187 ei_status.stop_page = OAKNET_STOP_PG;
189 ei_status.reset_8390 = &oaknet_reset_8390;
190 ei_status.block_input = &oaknet_block_input;
191 ei_status.block_output = &oaknet_block_output;
192 ei_status.get_8390_hdr = &oaknet_get_8390_hdr;
194 dev->open = oaknet_open;
195 dev->stop = oaknet_close;
196 #ifdef CONFIG_NET_POLL_CONTROLLER
197 dev->poll_controller = ei_poll;
198 #endif
200 NS8390_init(dev, FALSE);
201 ret = register_netdev(dev);
202 if (ret)
203 goto out_irq;
205 oaknet_devs = dev;
206 return 0;
208 out_irq;
209 free_irq(dev->irq, dev);
210 out_region:
211 release_region(OAKNET_IO_BASE, OAKNET_IO_SIZE);
212 out_dev:
213 free_netdev(dev);
214 out_unmap:
215 iounmap(ioaddr);
216 return ret;
217 }
219 /*
220 * static int oaknet_open()
221 *
222 * Description:
223 * This routine is a modest wrapper around ei_open, the 8390-generic,
224 * driver open routine. This just increments the module usage count
225 * and passes along the status from ei_open.
226 *
227 * Input(s):
228 * *dev - Pointer to the device structure for this driver.
229 *
230 * Output(s):
231 * *dev - Pointer to the device structure for this driver, potentially
232 * modified by ei_open.
233 *
234 * Returns:
235 * 0 if OK, otherwise < 0 on error.
236 *
237 */
238 static int
239 oaknet_open(struct net_device *dev)
240 {
241 int status = ei_open(dev);
242 return (status);
243 }
245 /*
246 * static int oaknet_close()
247 *
248 * Description:
249 * This routine is a modest wrapper around ei_close, the 8390-generic,
250 * driver close routine. This just decrements the module usage count
251 * and passes along the status from ei_close.
252 *
253 * Input(s):
254 * *dev - Pointer to the device structure for this driver.
255 *
256 * Output(s):
257 * *dev - Pointer to the device structure for this driver, potentially
258 * modified by ei_close.
259 *
260 * Returns:
261 * 0 if OK, otherwise < 0 on error.
262 *
263 */
264 static int
265 oaknet_close(struct net_device *dev)
266 {
267 int status = ei_close(dev);
268 return (status);
269 }
271 /*
272 * static void oaknet_reset_8390()
273 *
274 * Description:
275 * This routine resets the DP83902 chip.
276 *
277 * Input(s):
278 * *dev - Pointer to the device structure for this driver.
279 *
280 * Output(s):
281 * N/A
282 *
283 * Returns:
284 * N/A
285 *
286 */
287 static void
288 oaknet_reset_8390(struct net_device *dev)
289 {
290 int base = E8390_BASE;
292 /*
293 * We have no provision of reseting the controller as is done
294 * in other drivers, such as "ne.c". However, the following
295 * seems to work well enough in the TiVo driver.
296 */
298 printk("Resetting %s...\n", dev->name);
299 ei_obp(E8390_STOP | E8390_NODMA | E8390_PAGE0, base + E8390_CMD);
300 ei_status.txing = 0;
301 ei_status.dmaing = 0;
302 }
304 /*
305 * static void oaknet_get_8390_hdr()
306 *
307 * Description:
308 * This routine grabs the 8390-specific header. It's similar to the
309 * block input routine, but we don't need to be concerned with ring wrap
310 * as the header will be at the start of a page, so we optimize accordingly.
311 *
312 * Input(s):
313 * *dev - Pointer to the device structure for this driver.
314 * *hdr - Pointer to storage for the 8390-specific packet header.
315 * ring_page - ?
316 *
317 * Output(s):
318 * *hdr - Pointer to the 8390-specific packet header for the just-
319 * received frame.
320 *
321 * Returns:
322 * N/A
323 *
324 */
325 static void
326 oaknet_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
327 int ring_page)
328 {
329 int base = dev->base_addr;
331 /*
332 * This should NOT happen. If it does, it is the LAST thing you'll
333 * see.
334 */
336 if (ei_status.dmaing) {
337 oaknet_dma_error(dev, "oaknet_get_8390_hdr");
338 return;
339 }
341 ei_status.dmaing |= 0x01;
342 outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, base + OAKNET_CMD);
343 outb_p(sizeof(struct e8390_pkt_hdr), base + EN0_RCNTLO);
344 outb_p(0, base + EN0_RCNTHI);
345 outb_p(0, base + EN0_RSARLO); /* On page boundary */
346 outb_p(ring_page, base + EN0_RSARHI);
347 outb_p(E8390_RREAD + E8390_START, base + OAKNET_CMD);
349 if (ei_status.word16)
350 insw(base + OAKNET_DATA, hdr,
351 sizeof(struct e8390_pkt_hdr) >> 1);
352 else
353 insb(base + OAKNET_DATA, hdr,
354 sizeof(struct e8390_pkt_hdr));
356 /* Byte-swap the packet byte count */
358 hdr->count = le16_to_cpu(hdr->count);
360 outb_p(ENISR_RDC, base + EN0_ISR); /* ACK Remote DMA interrupt */
361 ei_status.dmaing &= ~0x01;
362 }
364 /*
365 * XXX - Document me.
366 */
367 static void
368 oaknet_block_input(struct net_device *dev, int count, struct sk_buff *skb,
369 int ring_offset)
370 {
371 int base = OAKNET_BASE;
372 char *buf = skb->data;
374 /*
375 * This should NOT happen. If it does, it is the LAST thing you'll
376 * see.
377 */
379 if (ei_status.dmaing) {
380 oaknet_dma_error(dev, "oaknet_block_input");
381 return;
382 }
384 #ifdef OAKNET_DISINT
385 save_flags(flags);
386 cli();
387 #endif
389 ei_status.dmaing |= 0x01;
390 ei_obp(E8390_NODMA + E8390_PAGE0 + E8390_START, base + E8390_CMD);
391 ei_obp(count & 0xff, base + EN0_RCNTLO);
392 ei_obp(count >> 8, base + EN0_RCNTHI);
393 ei_obp(ring_offset & 0xff, base + EN0_RSARLO);
394 ei_obp(ring_offset >> 8, base + EN0_RSARHI);
395 ei_obp(E8390_RREAD + E8390_START, base + E8390_CMD);
396 if (ei_status.word16) {
397 ei_isw(base + E8390_DATA, buf, count >> 1);
398 if (count & 0x01) {
399 buf[count - 1] = ei_ib(base + E8390_DATA);
400 #ifdef OAKNET_HEADCHECK
401 bytes++;
402 #endif
403 }
404 } else {
405 ei_isb(base + E8390_DATA, buf, count);
406 }
407 #ifdef OAKNET_HEADCHECK
408 /*
409 * This was for the ALPHA version only, but enough people have
410 * been encountering problems so it is still here. If you see
411 * this message you either 1) have a slightly incompatible clone
412 * or 2) have noise/speed problems with your bus.
413 */
415 /* DMA termination address check... */
416 {
417 int addr, tries = 20;
418 do {
419 /* DON'T check for 'ei_ibp(EN0_ISR) & ENISR_RDC' here
420 -- it's broken for Rx on some cards! */
421 int high = ei_ibp(base + EN0_RSARHI);
422 int low = ei_ibp(base + EN0_RSARLO);
423 addr = (high << 8) + low;
424 if (((ring_offset + bytes) & 0xff) == low)
425 break;
426 } while (--tries > 0);
427 if (tries <= 0)
428 printk("%s: RX transfer address mismatch,"
429 "%#4.4x (expected) vs. %#4.4x (actual).\n",
430 dev->name, ring_offset + bytes, addr);
431 }
432 #endif
433 ei_obp(ENISR_RDC, base + EN0_ISR); /* ACK Remote DMA interrupt */
434 ei_status.dmaing &= ~0x01;
436 #ifdef OAKNET_DISINT
437 restore_flags(flags);
438 #endif
439 }
441 /*
442 * static void oaknet_block_output()
443 *
444 * Description:
445 * This routine...
446 *
447 * Input(s):
448 * *dev - Pointer to the device structure for this driver.
449 * count - Number of bytes to be transferred.
450 * *buf -
451 * start_page -
452 *
453 * Output(s):
454 * N/A
455 *
456 * Returns:
457 * N/A
458 *
459 */
460 static void
461 oaknet_block_output(struct net_device *dev, int count,
462 const unsigned char *buf, int start_page)
463 {
464 int base = E8390_BASE;
465 #if 0
466 int bug;
467 #endif
468 unsigned long start;
469 #ifdef OAKNET_DISINT
470 unsigned long flags;
471 #endif
472 #ifdef OAKNET_HEADCHECK
473 int retries = 0;
474 #endif
476 /* Round the count up for word writes. */
478 if (ei_status.word16 && (count & 0x1))
479 count++;
481 /*
482 * This should NOT happen. If it does, it is the LAST thing you'll
483 * see.
484 */
486 if (ei_status.dmaing) {
487 oaknet_dma_error(dev, "oaknet_block_output");
488 return;
489 }
491 #ifdef OAKNET_DISINT
492 save_flags(flags);
493 cli();
494 #endif
496 ei_status.dmaing |= 0x01;
498 /* Make sure we are in page 0. */
500 ei_obp(E8390_PAGE0 + E8390_START + E8390_NODMA, base + E8390_CMD);
502 #ifdef OAKNET_HEADCHECK
503 retry:
504 #endif
506 #if 0
507 /*
508 * The 83902 documentation states that the processor needs to
509 * do a "dummy read" before doing the remote write to work
510 * around a chip bug they don't feel like fixing.
511 */
513 bug = 0;
514 while (1) {
515 unsigned int rdhi;
516 unsigned int rdlo;
518 /* Now the normal output. */
519 ei_obp(ENISR_RDC, base + EN0_ISR);
520 ei_obp(count & 0xff, base + EN0_RCNTLO);
521 ei_obp(count >> 8, base + EN0_RCNTHI);
522 ei_obp(0x00, base + EN0_RSARLO);
523 ei_obp(start_page, base + EN0_RSARHI);
525 if (bug++)
526 break;
528 /* Perform the dummy read */
529 rdhi = ei_ibp(base + EN0_CRDAHI);
530 rdlo = ei_ibp(base + EN0_CRDALO);
531 ei_obp(E8390_RREAD + E8390_START, base + E8390_CMD);
533 while (1) {
534 unsigned int nrdhi;
535 unsigned int nrdlo;
536 nrdhi = ei_ibp(base + EN0_CRDAHI);
537 nrdlo = ei_ibp(base + EN0_CRDALO);
538 if ((rdhi != nrdhi) || (rdlo != nrdlo))
539 break;
540 }
541 }
542 #else
543 #ifdef OAKNET_RWFIX
544 /*
545 * Handle the read-before-write bug the same way as the
546 * Crynwr packet driver -- the Nat'l Semi. method doesn't work.
547 * Actually this doesn't always work either, but if you have
548 * problems with your 83902 this is better than nothing!
549 */
551 ei_obp(0x42, base + EN0_RCNTLO);
552 ei_obp(0x00, base + EN0_RCNTHI);
553 ei_obp(0x42, base + EN0_RSARLO);
554 ei_obp(0x00, base + EN0_RSARHI);
555 ei_obp(E8390_RREAD + E8390_START, base + E8390_CMD);
556 /* Make certain that the dummy read has occurred. */
557 udelay(6);
558 #endif
560 ei_obp(ENISR_RDC, base + EN0_ISR);
562 /* Now the normal output. */
563 ei_obp(count & 0xff, base + EN0_RCNTLO);
564 ei_obp(count >> 8, base + EN0_RCNTHI);
565 ei_obp(0x00, base + EN0_RSARLO);
566 ei_obp(start_page, base + EN0_RSARHI);
567 #endif /* 0/1 */
569 ei_obp(E8390_RWRITE + E8390_START, base + E8390_CMD);
570 if (ei_status.word16) {
571 ei_osw(E8390_BASE + E8390_DATA, buf, count >> 1);
572 } else {
573 ei_osb(E8390_BASE + E8390_DATA, buf, count);
574 }
576 #ifdef OAKNET_DISINT
577 restore_flags(flags);
578 #endif
580 start = jiffies;
582 #ifdef OAKNET_HEADCHECK
583 /*
584 * This was for the ALPHA version only, but enough people have
585 * been encountering problems so it is still here.
586 */
588 {
589 /* DMA termination address check... */
590 int addr, tries = 20;
591 do {
592 int high = ei_ibp(base + EN0_RSARHI);
593 int low = ei_ibp(base + EN0_RSARLO);
594 addr = (high << 8) + low;
595 if ((start_page << 8) + count == addr)
596 break;
597 } while (--tries > 0);
599 if (tries <= 0) {
600 printk("%s: Tx packet transfer address mismatch,"
601 "%#4.4x (expected) vs. %#4.4x (actual).\n",
602 dev->name, (start_page << 8) + count, addr);
603 if (retries++ == 0)
604 goto retry;
605 }
606 }
607 #endif
609 while ((ei_ibp(base + EN0_ISR) & ENISR_RDC) == 0) {
610 if (time_after(jiffies, start + OAKNET_WAIT)) {
611 printk("%s: timeout waiting for Tx RDC.\n", dev->name);
612 oaknet_reset_8390(dev);
613 NS8390_init(dev, TRUE);
614 break;
615 }
616 }
618 ei_obp(ENISR_RDC, base + EN0_ISR); /* Ack intr. */
619 ei_status.dmaing &= ~0x01;
620 }
622 /*
623 * static void oaknet_dma_error()
624 *
625 * Description:
626 * This routine prints out a last-ditch informative message to the console
627 * indicating that a DMA error occurred. If you see this, it's the last
628 * thing you'll see.
629 *
630 * Input(s):
631 * *dev - Pointer to the device structure for this driver.
632 * *name - Informative text (e.g. function name) indicating where the
633 * DMA error occurred.
634 *
635 * Output(s):
636 * N/A
637 *
638 * Returns:
639 * N/A
640 *
641 */
642 static void
643 oaknet_dma_error(struct net_device *dev, const char *name)
644 {
645 printk(KERN_EMERG "%s: DMAing conflict in %s."
646 "[DMAstat:%d][irqlock:%d][intr:%ld]\n",
647 dev->name, name, ei_status.dmaing, ei_status.irqlock,
648 dev->interrupt);
649 }
651 /*
652 * Oak Ethernet module unload interface.
653 */
654 static void __exit oaknet_cleanup_module (void)
655 {
656 /* Convert to loop once driver supports multiple devices. */
657 unregister_netdev(oaknet_dev);
658 free_irq(oaknet_devs->irq, oaknet_devs);
659 release_region(oaknet_devs->base_addr, OAKNET_IO_SIZE);
660 iounmap(ioaddr);
661 free_netdev(oaknet_devs);
662 }
664 module_init(oaknet_init);
665 module_exit(oaknet_cleanup_module);
666 MODULE_LICENSE("GPL");