Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 176251
b: refs/heads/master
c: 39da08c
h: refs/heads/master
i:
  176249: 9bd23cd
  176247: b59554b
v: v3
  • Loading branch information
Lee Schermerhorn authored and Linus Torvalds committed Dec 15, 2009
1 parent e90335f commit 06237d0
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4faf8d950ec438c49ae4526b897c30f8a2cad741
refs/heads/master: 39da08cb074cf19cb249832a2a955dfb28837e65
57 changes: 47 additions & 10 deletions trunk/drivers/base/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,14 @@ static SYSDEV_ATTR(distance, S_IRUGO, node_read_distance, NULL);
static node_registration_func_t __hugetlb_register_node;
static node_registration_func_t __hugetlb_unregister_node;

static inline void hugetlb_register_node(struct node *node)
static inline bool hugetlb_register_node(struct node *node)
{
if (__hugetlb_register_node &&
node_state(node->sysdev.id, N_HIGH_MEMORY))
node_state(node->sysdev.id, N_HIGH_MEMORY)) {
__hugetlb_register_node(node);
return true;
}
return false;
}

static inline void hugetlb_unregister_node(struct node *node)
Expand Down Expand Up @@ -387,10 +390,31 @@ static int link_mem_sections(int nid)
return err;
}

#ifdef CONFIG_HUGETLBFS
/*
* Handle per node hstate attribute [un]registration on transistions
* to/from memoryless state.
*/
static void node_hugetlb_work(struct work_struct *work)
{
struct node *node = container_of(work, struct node, node_work);

/*
* We only get here when a node transitions to/from memoryless state.
* We can detect which transition occurred by examining whether the
* node has memory now. hugetlb_register_node() already check this
* so we try to register the attributes. If that fails, then the
* node has transitioned to memoryless, try to unregister the
* attributes.
*/
if (!hugetlb_register_node(node))
hugetlb_unregister_node(node);
}

static void init_node_hugetlb_work(int nid)
{
INIT_WORK(&node_devices[nid].node_work, node_hugetlb_work);
}

static int node_memory_callback(struct notifier_block *self,
unsigned long action, void *arg)
Expand All @@ -399,14 +423,16 @@ static int node_memory_callback(struct notifier_block *self,
int nid = mnb->status_change_nid;

switch (action) {
case MEM_ONLINE: /* memory successfully brought online */
case MEM_ONLINE:
case MEM_OFFLINE:
/*
* offload per node hstate [un]registration to a work thread
* when transitioning to/from memoryless state.
*/
if (nid != NUMA_NO_NODE)
hugetlb_register_node(&node_devices[nid]);
break;
case MEM_OFFLINE: /* or offline */
if (nid != NUMA_NO_NODE)
hugetlb_unregister_node(&node_devices[nid]);
schedule_work(&node_devices[nid].node_work);
break;

case MEM_GOING_ONLINE:
case MEM_GOING_OFFLINE:
case MEM_CANCEL_ONLINE:
Expand All @@ -417,15 +443,23 @@ static int node_memory_callback(struct notifier_block *self,

return NOTIFY_OK;
}
#else
#endif /* CONFIG_HUGETLBFS */
#else /* !CONFIG_MEMORY_HOTPLUG_SPARSE */

static int link_mem_sections(int nid) { return 0; }
#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */

#if !defined(CONFIG_MEMORY_HOTPLUG_SPARSE) || \
!defined(CONFIG_HUGETLBFS)
static inline int node_memory_callback(struct notifier_block *self,
unsigned long action, void *arg)
{
return NOTIFY_OK;
}
#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */

static void init_node_hugetlb_work(int nid) { }

#endif

int register_one_node(int nid)
{
Expand All @@ -449,6 +483,9 @@ int register_one_node(int nid)

/* link memory sections under this node */
error = link_mem_sections(nid);

/* initialize work queue for memory hot plug */
init_node_hugetlb_work(nid);
}

return error;
Expand Down
5 changes: 5 additions & 0 deletions trunk/include/linux/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@

#include <linux/sysdev.h>
#include <linux/cpumask.h>
#include <linux/workqueue.h>

struct node {
struct sys_device sysdev;

#if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_HUGETLBFS)
struct work_struct node_work;
#endif
};

struct memory_block;
Expand Down

0 comments on commit 06237d0

Please sign in to comment.