memory hotplug

Nov 12, 2011 02:30

Либо я тупой, либо что-то тут не так. (пост - поток сознания, пишу в процессе поиска).

Пытаюсь завести memory hotplug. (всё ещё надеюсь)

echo 1024000 >/sys/devices/system/xen_memory/xen_memory0/target_kb

[1923974.462100] System RAM resource 8000000 - fffffff cannot be added
[1923974.462119] xen_balloon: reserve_additional_memory: add_memory() failed: -17

Не поленился, нашёл функцию. Нашёл коды ошибок:

-17:
include/asm-generic/errno-base.h:#define EEXIST 17 /* File exists */
include/asm-generic/errno.h:#define EUCLEAN 117 /* Structure needs cleaning */

В самой функции add_memory():


lock_memory_hotplug();
res = register_memory_resource(start, size);
ret = -EEXIST;
if (!res)
goto out;
...
out:
unlock_memory_hotplug();
return ret;

ползём в static struct resource *register_memory_resource(u64 start, u64 size)

{
struct resource *res;
res = kzalloc(sizeof(struct resource), GFP_KERNEL);
BUG_ON(!res);

res->name = "System RAM";
res->start = start;
res->end = start + size - 1;
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
if (request_resource(&iomem_resource, res) < 0) {
printk("System RAM resource %llx - %llx cannot be added\n",
(unsigned long long)res->start, (unsigned long long)res->end);
kfree(res);
res = NULL;
}
return res;
}

request_resource(&iomem_resource, res) < 0

int request_resource(struct resource *root, struct resource *new)
{
struct resource *conflict;

conflict = request_resource_conflict(root, new);
return conflict ? -EBUSY : 0;
}

Таким образом, оно пытается добавить ресурс в "дерево" (список?) iomem_resource, но функция request_resource_conflict говорит о том, что оно конфликтует.

Функция request_resource_conflict...

/**
* request_resource_conflict - request and reserve an I/O or memory resource
* @root: root resource descriptor
* @new: resource descriptor desired by caller
*
* Returns 0 for success, conflict resource on error.
*/
struct resource *request_resource_conflict(struct resource *root, struct resource *new)
{
struct resource *conflict;

write_lock(&resource_lock);
conflict = __request_resource(root, new);
write_unlock(&resource_lock);
return conflict;
}

прямым путём в __request_resource(root, new);

смотрим (фрагмент):

/* Return the conflict entry if you can't request it */
static struct resource * __request_resource(struct resource *root, struct resource *new)
{
resource_size_t start = new->start;
resource_size_t end = new->end;
struct resource *tmp, **p;

if (end < start)
return root;
if (start < root->start)
return root;
if (end > root->end)
return root;
p = &root->child;
for (;;) {
tmp = *p;
if (!tmp || tmp->start > end) {
new->sibling = tmp;
*p = new;
new->parent = root;
return NULL;
}
p = &tmp->sibling;
if (tmp->end < start)
continue;
return tmp;
}
}

Насколько мне хватает мозгов - мы возвращаем конфликт если у нас в списке есть перекрытия.

Ок, таким образом, мы передаём неправильные значения. Вероятнее всего, в районе add_memory.

Возвращаемся назад.

hotplug_start_paddr = PFN_PHYS(SECTION_ALIGN_UP(max_pfn));
balloon_hotplug = round_up(balloon_hotplug, PAGES_PER_SECTION);
nid = memory_add_physaddr_to_nid(hotplug_start_paddr);

rc = add_memory(nid, hotplug_start_paddr, balloon_hotplug << PAGE_SHIFT);

Гипотеза - проблема в hotplug_start_paddr. Мы запрашиваем слишком ... слишком низко? Кстати, у нас несколько десятков мегабайт сожрано непонятно кем (различается dom_mem и TotalMem внутри домена).

Смертельный эксперимент - давайте попробуем увеличить PFN_PHYS на два (э... грубо, больно, так делать нельзя...)... (ушёл пересобирать ядро).

Увы, не работает. то есть ведёт себя ровно так же.

только регионы другие:

[1930279.232900] System RAM resource 10000000 - 1fffffff cannot be added
[1930279.232912] xen_balloon: reserve_additional_memory: add_memory() failed: -17

Что-то я капитально не понимаю.

Уточняю, кажется, я тут всё капитально не понимаю.

memory hotplug, xen, linux

Previous post Next post
Up