ia64/linux-2.6.18-xen.hg

view drivers/serial/jsm/jsm_driver.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 * Copyright 2003 Digi International (www.digi.com)
3 *
4 * Copyright (C) 2004 IBM Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
13 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 * Temple Place - Suite 330, Boston,
19 * MA 02111-1307, USA.
20 *
21 * Contact Information:
22 * Scott H Kilau <Scott_Kilau@digi.com>
23 * Wendy Xiong <wendyx@us.ibm.com>
24 *
25 *
26 ***********************************************************************/
27 #include <linux/moduleparam.h>
28 #include <linux/pci.h>
30 #include "jsm.h"
32 MODULE_AUTHOR("Digi International, http://www.digi.com");
33 MODULE_DESCRIPTION("Driver for the Digi International "
34 "Neo PCI based product line");
35 MODULE_LICENSE("GPL");
36 MODULE_SUPPORTED_DEVICE("jsm");
38 #define JSM_DRIVER_NAME "jsm"
39 #define NR_PORTS 32
40 #define JSM_MINOR_START 0
42 struct uart_driver jsm_uart_driver = {
43 .owner = THIS_MODULE,
44 .driver_name = JSM_DRIVER_NAME,
45 .dev_name = "ttyn",
46 .major = 0,
47 .minor = JSM_MINOR_START,
48 .nr = NR_PORTS,
49 };
51 int jsm_debug;
52 module_param(jsm_debug, int, 0);
53 MODULE_PARM_DESC(jsm_debug, "Driver debugging level");
55 static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
56 {
57 int rc = 0;
58 struct jsm_board *brd;
59 static int adapter_count = 0;
60 int retval;
62 rc = pci_enable_device(pdev);
63 if (rc) {
64 dev_err(&pdev->dev, "Device enable FAILED\n");
65 goto out;
66 }
68 rc = pci_request_regions(pdev, "jsm");
69 if (rc) {
70 dev_err(&pdev->dev, "pci_request_region FAILED\n");
71 goto out_disable_device;
72 }
74 brd = kmalloc(sizeof(struct jsm_board), GFP_KERNEL);
75 if (!brd) {
76 dev_err(&pdev->dev,
77 "memory allocation for board structure failed\n");
78 rc = -ENOMEM;
79 goto out_release_regions;
80 }
81 memset(brd, 0, sizeof(struct jsm_board));
83 /* store the info for the board we've found */
84 brd->boardnum = adapter_count++;
85 brd->pci_dev = pdev;
86 brd->maxports = 2;
88 spin_lock_init(&brd->bd_lock);
89 spin_lock_init(&brd->bd_intr_lock);
91 /* store which revision we have */
92 pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev);
94 brd->irq = pdev->irq;
96 jsm_printk(INIT, INFO, &brd->pci_dev,
97 "jsm_found_board - NEO adapter\n");
99 /* get the PCI Base Address Registers */
100 brd->membase = pci_resource_start(pdev, 0);
101 brd->membase_end = pci_resource_end(pdev, 0);
103 if (brd->membase & 1)
104 brd->membase &= ~3;
105 else
106 brd->membase &= ~15;
108 /* Assign the board_ops struct */
109 brd->bd_ops = &jsm_neo_ops;
111 brd->bd_uart_offset = 0x200;
112 brd->bd_dividend = 921600;
114 brd->re_map_membase = ioremap(brd->membase, 0x1000);
115 if (!brd->re_map_membase) {
116 dev_err(&pdev->dev,
117 "card has no PCI Memory resources, "
118 "failing board.\n");
119 rc = -ENOMEM;
120 goto out_kfree_brd;
121 }
123 rc = request_irq(brd->irq, brd->bd_ops->intr,
124 IRQF_DISABLED|IRQF_SHARED, "JSM", brd);
125 if (rc) {
126 printk(KERN_WARNING "Failed to hook IRQ %d\n",brd->irq);
127 goto out_iounmap;
128 }
130 rc = jsm_tty_init(brd);
131 if (rc < 0) {
132 dev_err(&pdev->dev, "Can't init tty devices (%d)\n", rc);
133 retval = -ENXIO;
134 goto out_free_irq;
135 }
137 rc = jsm_uart_port_init(brd);
138 if (rc < 0) {
139 /* XXX: leaking all resources from jsm_tty_init here! */
140 dev_err(&pdev->dev, "Can't init uart port (%d)\n", rc);
141 retval = -ENXIO;
142 goto out_free_irq;
143 }
145 /* Log the information about the board */
146 dev_info(&pdev->dev, "board %d: Digi Neo (rev %d), irq %d\n",
147 adapter_count, brd->rev, brd->irq);
149 /*
150 * allocate flip buffer for board.
151 *
152 * Okay to malloc with GFP_KERNEL, we are not at interrupt
153 * context, and there are no locks held.
154 */
155 brd->flipbuf = kmalloc(MYFLIPLEN, GFP_KERNEL);
156 if (!brd->flipbuf) {
157 /* XXX: leaking all resources from jsm_tty_init and
158 jsm_uart_port_init here! */
159 dev_err(&pdev->dev, "memory allocation for flipbuf failed\n");
160 retval = -ENOMEM;
161 goto out_free_irq;
162 }
163 memset(brd->flipbuf, 0, MYFLIPLEN);
165 pci_set_drvdata(pdev, brd);
167 return 0;
168 out_free_irq:
169 free_irq(brd->irq, brd);
170 out_iounmap:
171 iounmap(brd->re_map_membase);
172 out_kfree_brd:
173 kfree(brd);
174 out_release_regions:
175 pci_release_regions(pdev);
176 out_disable_device:
177 pci_disable_device(pdev);
178 out:
179 return rc;
180 }
182 static void jsm_remove_one(struct pci_dev *pdev)
183 {
184 struct jsm_board *brd = pci_get_drvdata(pdev);
185 int i = 0;
187 jsm_remove_uart_port(brd);
189 free_irq(brd->irq, brd);
190 iounmap(brd->re_map_membase);
192 /* Free all allocated channels structs */
193 for (i = 0; i < brd->maxports; i++) {
194 if (brd->channels[i]) {
195 kfree(brd->channels[i]->ch_rqueue);
196 kfree(brd->channels[i]->ch_equeue);
197 kfree(brd->channels[i]->ch_wqueue);
198 kfree(brd->channels[i]);
199 }
200 }
202 pci_release_regions(pdev);
203 pci_disable_device(pdev);
204 kfree(brd->flipbuf);
205 kfree(brd);
206 }
208 static struct pci_device_id jsm_pci_tbl[] = {
209 { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2DB9), 0, 0, 0 },
210 { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2DB9PRI), 0, 0, 1 },
211 { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45), 0, 0, 2 },
212 { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45PRI), 0, 0, 3 },
213 { 0, }
214 };
215 MODULE_DEVICE_TABLE(pci, jsm_pci_tbl);
217 static struct pci_driver jsm_driver = {
218 .name = "jsm",
219 .id_table = jsm_pci_tbl,
220 .probe = jsm_probe_one,
221 .remove = __devexit_p(jsm_remove_one),
222 };
224 static int __init jsm_init_module(void)
225 {
226 int rc;
228 rc = uart_register_driver(&jsm_uart_driver);
229 if (!rc) {
230 rc = pci_register_driver(&jsm_driver);
231 if (rc)
232 uart_unregister_driver(&jsm_uart_driver);
233 }
234 return rc;
235 }
237 static void __exit jsm_exit_module(void)
238 {
239 pci_unregister_driver(&jsm_driver);
240 uart_unregister_driver(&jsm_uart_driver);
241 }
243 module_init(jsm_init_module);
244 module_exit(jsm_exit_module);