aboutsummaryrefslogtreecommitdiffstats
path: root/mm/hugetlb.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r--mm/hugetlb.c274
1 files changed, 248 insertions, 26 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 1125d818ea06..544f7bcb615e 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -24,6 +24,7 @@
24#include <asm/io.h> 24#include <asm/io.h>
25 25
26#include <linux/hugetlb.h> 26#include <linux/hugetlb.h>
27#include <linux/node.h>
27#include "internal.h" 28#include "internal.h"
28 29
29const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; 30const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
@@ -1320,39 +1321,71 @@ out:
1320static struct kobject *hugepages_kobj; 1321static struct kobject *hugepages_kobj;
1321static struct kobject *hstate_kobjs[HUGE_MAX_HSTATE]; 1322static struct kobject *hstate_kobjs[HUGE_MAX_HSTATE];
1322 1323
1323static struct hstate *kobj_to_hstate(struct kobject *kobj) 1324static struct hstate *kobj_to_node_hstate(struct kobject *kobj, int *nidp);
1325
1326static struct hstate *kobj_to_hstate(struct kobject *kobj, int *nidp)
1324{ 1327{
1325 int i; 1328 int i;
1329
1326 for (i = 0; i < HUGE_MAX_HSTATE; i++) 1330 for (i = 0; i < HUGE_MAX_HSTATE; i++)
1327 if (hstate_kobjs[i] == kobj) 1331 if (hstate_kobjs[i] == kobj) {
1332 if (nidp)
1333 *nidp = NUMA_NO_NODE;
1328 return &hstates[i]; 1334 return &hstates[i];
1329 BUG(); 1335 }
1330 return NULL; 1336
1337 return kobj_to_node_hstate(kobj, nidp);
1331} 1338}
1332 1339
1333static ssize_t nr_hugepages_show_common(struct kobject *kobj, 1340static ssize_t nr_hugepages_show_common(struct kobject *kobj,
1334 struct kobj_attribute *attr, char *buf) 1341 struct kobj_attribute *attr, char *buf)
1335{ 1342{
1336 struct hstate *h = kobj_to_hstate(kobj); 1343 struct hstate *h;
1337 return sprintf(buf, "%lu\n", h->nr_huge_pages); 1344 unsigned long nr_huge_pages;
1345 int nid;
1346
1347 h = kobj_to_hstate(kobj, &nid);
1348 if (nid == NUMA_NO_NODE)
1349 nr_huge_pages = h->nr_huge_pages;
1350 else
1351 nr_huge_pages = h->nr_huge_pages_node[nid];
1352
1353 return sprintf(buf, "%lu\n", nr_huge_pages);
1338} 1354}
1339static ssize_t nr_hugepages_store_common(bool obey_mempolicy, 1355static ssize_t nr_hugepages_store_common(bool obey_mempolicy,
1340 struct kobject *kobj, struct kobj_attribute *attr, 1356 struct kobject *kobj, struct kobj_attribute *attr,
1341 const char *buf, size_t len) 1357 const char *buf, size_t len)
1342{ 1358{
1343 int err; 1359 int err;
1360 int nid;
1344 unsigned long count; 1361 unsigned long count;
1345 struct hstate *h = kobj_to_hstate(kobj); 1362 struct hstate *h;
1346 NODEMASK_ALLOC(nodemask_t, nodes_allowed); 1363 NODEMASK_ALLOC(nodemask_t, nodes_allowed);
1347 1364
1348 err = strict_strtoul(buf, 10, &count); 1365 err = strict_strtoul(buf, 10, &count);
1349 if (err) 1366 if (err)
1350 return 0; 1367 return 0;
1351 1368
1352 if (!(obey_mempolicy && init_nodemask_of_mempolicy(nodes_allowed))) { 1369 h = kobj_to_hstate(kobj, &nid);
1353 NODEMASK_FREE(nodes_allowed); 1370 if (nid == NUMA_NO_NODE) {
1354 nodes_allowed = &node_online_map; 1371 /*
1355 } 1372 * global hstate attribute
1373 */
1374 if (!(obey_mempolicy &&
1375 init_nodemask_of_mempolicy(nodes_allowed))) {
1376 NODEMASK_FREE(nodes_allowed);
1377 nodes_allowed = &node_states[N_HIGH_MEMORY];
1378 }
1379 } else if (nodes_allowed) {
1380 /*
1381 * per node hstate attribute: adjust count to global,
1382 * but restrict alloc/free to the specified node.
1383 */
1384 count += h->nr_huge_pages - h->nr_huge_pages_node[nid];
1385 init_nodemask_of_node(nodes_allowed, nid);
1386 } else
1387 nodes_allowed = &node_states[N_HIGH_MEMORY];
1388
1356 h->max_huge_pages = set_max_huge_pages(h, count, nodes_allowed); 1389 h->max_huge_pages = set_max_huge_pages(h, count, nodes_allowed);
1357 1390
1358 if (nodes_allowed != &node_online_map) 1391 if (nodes_allowed != &node_online_map)
@@ -1398,7 +1431,7 @@ HSTATE_ATTR(nr_hugepages_mempolicy);
1398static ssize_t nr_overcommit_hugepages_show(struct kobject *kobj, 1431static ssize_t nr_overcommit_hugepages_show(struct kobject *kobj,
1399 struct kobj_attribute *attr, char *buf) 1432 struct kobj_attribute *attr, char *buf)
1400{ 1433{
1401 struct hstate *h = kobj_to_hstate(kobj); 1434 struct hstate *h = kobj_to_hstate(kobj, NULL);
1402 return sprintf(buf, "%lu\n", h->nr_overcommit_huge_pages); 1435 return sprintf(buf, "%lu\n", h->nr_overcommit_huge_pages);
1403} 1436}
1404static ssize_t nr_overcommit_hugepages_store(struct kobject *kobj, 1437static ssize_t nr_overcommit_hugepages_store(struct kobject *kobj,
@@ -1406,7 +1439,7 @@ static ssize_t nr_overcommit_hugepages_store(struct kobject *kobj,
1406{ 1439{
1407 int err; 1440 int err;
1408 unsigned long input; 1441 unsigned long input;
1409 struct hstate *h = kobj_to_hstate(kobj); 1442 struct hstate *h = kobj_to_hstate(kobj, NULL);
1410 1443
1411 err = strict_strtoul(buf, 10, &input); 1444 err = strict_strtoul(buf, 10, &input);
1412 if (err) 1445 if (err)
@@ -1423,15 +1456,24 @@ HSTATE_ATTR(nr_overcommit_hugepages);
1423static ssize_t free_hugepages_show(struct kobject *kobj, 1456static ssize_t free_hugepages_show(struct kobject *kobj,
1424 struct kobj_attribute *attr, char *buf) 1457 struct kobj_attribute *attr, char *buf)
1425{ 1458{
1426 struct hstate *h = kobj_to_hstate(kobj); 1459 struct hstate *h;
1427 return sprintf(buf, "%lu\n", h->free_huge_pages); 1460 unsigned long free_huge_pages;
1461 int nid;
1462
1463 h = kobj_to_hstate(kobj, &nid);
1464 if (nid == NUMA_NO_NODE)
1465 free_huge_pages = h->free_huge_pages;
1466 else
1467 free_huge_pages = h->free_huge_pages_node[nid];
1468
1469 return sprintf(buf, "%lu\n", free_huge_pages);
1428} 1470}
1429HSTATE_ATTR_RO(free_hugepages); 1471HSTATE_ATTR_RO(free_hugepages);
1430 1472
1431static ssize_t resv_hugepages_show(struct kobject *kobj, 1473static ssize_t resv_hugepages_show(struct kobject *kobj,
1432 struct kobj_attribute *attr, char *buf) 1474 struct kobj_attribute *attr, char *buf)
1433{ 1475{
1434 struct hstate *h = kobj_to_hstate(kobj); 1476 struct hstate *h = kobj_to_hstate(kobj, NULL);
1435 return sprintf(buf, "%lu\n", h->resv_huge_pages); 1477 return sprintf(buf, "%lu\n", h->resv_huge_pages);
1436} 1478}
1437HSTATE_ATTR_RO(resv_hugepages); 1479HSTATE_ATTR_RO(resv_hugepages);
@@ -1439,8 +1481,17 @@ HSTATE_ATTR_RO(resv_hugepages);
1439static ssize_t surplus_hugepages_show(struct kobject *kobj, 1481static ssize_t surplus_hugepages_show(struct kobject *kobj,
1440 struct kobj_attribute *attr, char *buf) 1482 struct kobj_attribute *attr, char *buf)
1441{ 1483{
1442 struct hstate *h = kobj_to_hstate(kobj); 1484 struct hstate *h;
1443 return sprintf(buf, "%lu\n", h->surplus_huge_pages); 1485 unsigned long surplus_huge_pages;
1486 int nid;
1487
1488 h = kobj_to_hstate(kobj, &nid);
1489 if (nid == NUMA_NO_NODE)
1490 surplus_huge_pages = h->surplus_huge_pages;
1491 else
1492 surplus_huge_pages = h->surplus_huge_pages_node[nid];
1493
1494 return sprintf(buf, "%lu\n", surplus_huge_pages);
1444} 1495}
1445HSTATE_ATTR_RO(surplus_hugepages); 1496HSTATE_ATTR_RO(surplus_hugepages);
1446 1497
@@ -1460,19 +1511,21 @@ static struct attribute_group hstate_attr_group = {
1460 .attrs = hstate_attrs, 1511 .attrs = hstate_attrs,
1461}; 1512};
1462 1513
1463static int __init hugetlb_sysfs_add_hstate(struct hstate *h) 1514static int __init hugetlb_sysfs_add_hstate(struct hstate *h,
1515 struct kobject *parent,
1516 struct kobject **hstate_kobjs,
1517 struct attribute_group *hstate_attr_group)
1464{ 1518{
1465 int retval; 1519 int retval;
1520 int hi = h - hstates;
1466 1521
1467 hstate_kobjs[h - hstates] = kobject_create_and_add(h->name, 1522 hstate_kobjs[hi] = kobject_create_and_add(h->name, parent);
1468 hugepages_kobj); 1523 if (!hstate_kobjs[hi])
1469 if (!hstate_kobjs[h - hstates])
1470 return -ENOMEM; 1524 return -ENOMEM;
1471 1525
1472 retval = sysfs_create_group(hstate_kobjs[h - hstates], 1526 retval = sysfs_create_group(hstate_kobjs[hi], hstate_attr_group);
1473 &hstate_attr_group);
1474 if (retval) 1527 if (retval)
1475 kobject_put(hstate_kobjs[h - hstates]); 1528 kobject_put(hstate_kobjs[hi]);
1476 1529
1477 return retval; 1530 return retval;
1478} 1531}
@@ -1487,17 +1540,184 @@ static void __init hugetlb_sysfs_init(void)
1487 return; 1540 return;
1488 1541
1489 for_each_hstate(h) { 1542 for_each_hstate(h) {
1490 err = hugetlb_sysfs_add_hstate(h); 1543 err = hugetlb_sysfs_add_hstate(h, hugepages_kobj,
1544 hstate_kobjs, &hstate_attr_group);
1491 if (err) 1545 if (err)
1492 printk(KERN_ERR "Hugetlb: Unable to add hstate %s", 1546 printk(KERN_ERR "Hugetlb: Unable to add hstate %s",
1493 h->name); 1547 h->name);
1494 } 1548 }
1495} 1549}
1496 1550
1551#ifdef CONFIG_NUMA
1552
1553/*
1554 * node_hstate/s - associate per node hstate attributes, via their kobjects,
1555 * with node sysdevs in node_devices[] using a parallel array. The array
1556 * index of a node sysdev or _hstate == node id.
1557 * This is here to avoid any static dependency of the node sysdev driver, in
1558 * the base kernel, on the hugetlb module.
1559 */
1560struct node_hstate {
1561 struct kobject *hugepages_kobj;
1562 struct kobject *hstate_kobjs[HUGE_MAX_HSTATE];
1563};
1564struct node_hstate node_hstates[MAX_NUMNODES];
1565
1566/*
1567 * A subset of global hstate attributes for node sysdevs
1568 */
1569static struct attribute *per_node_hstate_attrs[] = {
1570 &nr_hugepages_attr.attr,
1571 &free_hugepages_attr.attr,
1572 &surplus_hugepages_attr.attr,
1573 NULL,
1574};
1575
1576static struct attribute_group per_node_hstate_attr_group = {
1577 .attrs = per_node_hstate_attrs,
1578};
1579
1580/*
1581 * kobj_to_node_hstate - lookup global hstate for node sysdev hstate attr kobj.
1582 * Returns node id via non-NULL nidp.
1583 */
1584static struct hstate *kobj_to_node_hstate(struct kobject *kobj, int *nidp)
1585{
1586 int nid;
1587
1588 for (nid = 0; nid < nr_node_ids; nid++) {
1589 struct node_hstate *nhs = &node_hstates[nid];
1590 int i;
1591 for (i = 0; i < HUGE_MAX_HSTATE; i++)
1592 if (nhs->hstate_kobjs[i] == kobj) {
1593 if (nidp)
1594 *nidp = nid;
1595 return &hstates[i];
1596 }
1597 }
1598
1599 BUG();
1600 return NULL;
1601}
1602
1603/*
1604 * Unregister hstate attributes from a single node sysdev.
1605 * No-op if no hstate attributes attached.
1606 */
1607void hugetlb_unregister_node(struct node *node)
1608{
1609 struct hstate *h;
1610 struct node_hstate *nhs = &node_hstates[node->sysdev.id];
1611
1612 if (!nhs->hugepages_kobj)
1613 return;
1614
1615 for_each_hstate(h)
1616 if (nhs->hstate_kobjs[h - hstates]) {
1617 kobject_put(nhs->hstate_kobjs[h - hstates]);
1618 nhs->hstate_kobjs[h - hstates] = NULL;
1619 }
1620
1621 kobject_put(nhs->hugepages_kobj);
1622 nhs->hugepages_kobj = NULL;
1623}
1624
1625/*
1626 * hugetlb module exit: unregister hstate attributes from node sysdevs
1627 * that have them.
1628 */
1629static void hugetlb_unregister_all_nodes(void)
1630{
1631 int nid;
1632
1633 /*
1634 * disable node sysdev registrations.
1635 */
1636 register_hugetlbfs_with_node(NULL, NULL);
1637
1638 /*
1639 * remove hstate attributes from any nodes that have them.
1640 */
1641 for (nid = 0; nid < nr_node_ids; nid++)
1642 hugetlb_unregister_node(&node_devices[nid]);
1643}
1644
1645/*
1646 * Register hstate attributes for a single node sysdev.
1647 * No-op if attributes already registered.
1648 */
1649void hugetlb_register_node(struct node *node)
1650{
1651 struct hstate *h;
1652 struct node_hstate *nhs = &node_hstates[node->sysdev.id];
1653 int err;
1654
1655 if (nhs->hugepages_kobj)
1656 return; /* already allocated */
1657
1658 nhs->hugepages_kobj = kobject_create_and_add("hugepages",
1659 &node->sysdev.kobj);
1660 if (!nhs->hugepages_kobj)
1661 return;
1662
1663 for_each_hstate(h) {
1664 err = hugetlb_sysfs_add_hstate(h, nhs->hugepages_kobj,
1665 nhs->hstate_kobjs,
1666 &per_node_hstate_attr_group);
1667 if (err) {
1668 printk(KERN_ERR "Hugetlb: Unable to add hstate %s"
1669 " for node %d\n",
1670 h->name, node->sysdev.id);
1671 hugetlb_unregister_node(node);
1672 break;
1673 }
1674 }
1675}
1676
1677/*
1678 * hugetlb init time: register hstate attributes for all registered
1679 * node sysdevs. All on-line nodes should have registered their
1680 * associated sysdev by the time the hugetlb module initializes.
1681 */
1682static void hugetlb_register_all_nodes(void)
1683{
1684 int nid;
1685
1686 for (nid = 0; nid < nr_node_ids; nid++) {
1687 struct node *node = &node_devices[nid];
1688 if (node->sysdev.id == nid)
1689 hugetlb_register_node(node);
1690 }
1691
1692 /*
1693 * Let the node sysdev driver know we're here so it can
1694 * [un]register hstate attributes on node hotplug.
1695 */
1696 register_hugetlbfs_with_node(hugetlb_register_node,
1697 hugetlb_unregister_node);
1698}
1699#else /* !CONFIG_NUMA */
1700
1701static struct hstate *kobj_to_node_hstate(struct kobject *kobj, int *nidp)
1702{
1703 BUG();
1704 if (nidp)
1705 *nidp = -1;
1706 return NULL;
1707}
1708
1709static void hugetlb_unregister_all_nodes(void) { }
1710
1711static void hugetlb_register_all_nodes(void) { }
1712
1713#endif
1714
1497static void __exit hugetlb_exit(void) 1715static void __exit hugetlb_exit(void)
1498{ 1716{
1499 struct hstate *h; 1717 struct hstate *h;
1500 1718
1719 hugetlb_unregister_all_nodes();
1720
1501 for_each_hstate(h) { 1721 for_each_hstate(h) {
1502 kobject_put(hstate_kobjs[h - hstates]); 1722 kobject_put(hstate_kobjs[h - hstates]);
1503 } 1723 }
@@ -1532,6 +1752,8 @@ static int __init hugetlb_init(void)
1532 1752
1533 hugetlb_sysfs_init(); 1753 hugetlb_sysfs_init();
1534 1754
1755 hugetlb_register_all_nodes();
1756
1535 return 0; 1757 return 0;
1536} 1758}
1537module_init(hugetlb_init); 1759module_init(hugetlb_init);