Либо я тупой, либо что-то тут не так. (пост - поток сознания, пишу в процессе поиска).
Пытаюсь завести 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
Что-то я капитально не понимаю.
Уточняю, кажется, я тут всё капитально не понимаю.