|
@@ -254,7 +254,7 @@ static bool pages_correctly_reserved(unsigned long start_pfn,
|
|
|
* OK to have direct references to sparsemem variables in here.
|
|
|
*/
|
|
|
static int
|
|
|
-memory_block_action(unsigned long phys_index, unsigned long action)
|
|
|
+memory_block_action(unsigned long phys_index, unsigned long action, int online_type)
|
|
|
{
|
|
|
unsigned long start_pfn;
|
|
|
unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
|
|
@@ -269,7 +269,7 @@ memory_block_action(unsigned long phys_index, unsigned long action)
|
|
|
if (!pages_correctly_reserved(start_pfn, nr_pages))
|
|
|
return -EBUSY;
|
|
|
|
|
|
- ret = online_pages(start_pfn, nr_pages);
|
|
|
+ ret = online_pages(start_pfn, nr_pages, online_type);
|
|
|
break;
|
|
|
case MEM_OFFLINE:
|
|
|
ret = offline_pages(start_pfn, nr_pages);
|
|
@@ -284,7 +284,8 @@ memory_block_action(unsigned long phys_index, unsigned long action)
|
|
|
}
|
|
|
|
|
|
static int __memory_block_change_state(struct memory_block *mem,
|
|
|
- unsigned long to_state, unsigned long from_state_req)
|
|
|
+ unsigned long to_state, unsigned long from_state_req,
|
|
|
+ int online_type)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
|
|
@@ -296,7 +297,7 @@ static int __memory_block_change_state(struct memory_block *mem,
|
|
|
if (to_state == MEM_OFFLINE)
|
|
|
mem->state = MEM_GOING_OFFLINE;
|
|
|
|
|
|
- ret = memory_block_action(mem->start_section_nr, to_state);
|
|
|
+ ret = memory_block_action(mem->start_section_nr, to_state, online_type);
|
|
|
|
|
|
if (ret) {
|
|
|
mem->state = from_state_req;
|
|
@@ -319,12 +320,14 @@ out:
|
|
|
}
|
|
|
|
|
|
static int memory_block_change_state(struct memory_block *mem,
|
|
|
- unsigned long to_state, unsigned long from_state_req)
|
|
|
+ unsigned long to_state, unsigned long from_state_req,
|
|
|
+ int online_type)
|
|
|
{
|
|
|
int ret;
|
|
|
|
|
|
mutex_lock(&mem->state_mutex);
|
|
|
- ret = __memory_block_change_state(mem, to_state, from_state_req);
|
|
|
+ ret = __memory_block_change_state(mem, to_state, from_state_req,
|
|
|
+ online_type);
|
|
|
mutex_unlock(&mem->state_mutex);
|
|
|
|
|
|
return ret;
|
|
@@ -338,10 +341,18 @@ store_mem_state(struct device *dev,
|
|
|
|
|
|
mem = container_of(dev, struct memory_block, dev);
|
|
|
|
|
|
- if (!strncmp(buf, "online", min((int)count, 6)))
|
|
|
- ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE);
|
|
|
- else if(!strncmp(buf, "offline", min((int)count, 7)))
|
|
|
- ret = memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
|
|
|
+ if (!strncmp(buf, "online_kernel", min_t(int, count, 13)))
|
|
|
+ ret = memory_block_change_state(mem, MEM_ONLINE,
|
|
|
+ MEM_OFFLINE, ONLINE_KERNEL);
|
|
|
+ else if (!strncmp(buf, "online_movable", min_t(int, count, 14)))
|
|
|
+ ret = memory_block_change_state(mem, MEM_ONLINE,
|
|
|
+ MEM_OFFLINE, ONLINE_MOVABLE);
|
|
|
+ else if (!strncmp(buf, "online", min_t(int, count, 6)))
|
|
|
+ ret = memory_block_change_state(mem, MEM_ONLINE,
|
|
|
+ MEM_OFFLINE, ONLINE_KEEP);
|
|
|
+ else if(!strncmp(buf, "offline", min_t(int, count, 7)))
|
|
|
+ ret = memory_block_change_state(mem, MEM_OFFLINE,
|
|
|
+ MEM_ONLINE, -1);
|
|
|
|
|
|
if (ret)
|
|
|
return ret;
|
|
@@ -676,7 +687,7 @@ int offline_memory_block(struct memory_block *mem)
|
|
|
|
|
|
mutex_lock(&mem->state_mutex);
|
|
|
if (mem->state != MEM_OFFLINE)
|
|
|
- ret = __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
|
|
|
+ ret = __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1);
|
|
|
mutex_unlock(&mem->state_mutex);
|
|
|
|
|
|
return ret;
|