Revision f32393c943e297b8ae180c8f83d81a156c7d0412 authored by Nathan Fontenot on 30 April 2015, 01:42:06 UTC, committed by Michael Ellerman on 01 May 2015, 03:47:24 UTC
The incorrect ordering of operations during cpu dlpar add results in invalid
affinity for the cpu being added. The ibm,associativity property in the
device tree is populated with all zeroes for the added cpu which results in
invalid affinity mappings and all cpus appear to belong to node 0.

This occurs because rtas configure-connector is called prior to making the
rtas set-indicator calls. Phyp does not assign affinity information
for a cpu until the rtas set-indicator calls are made to set the isolation
and allocation state.

Correct the order of operations to make the rtas set-indicator
calls (done in dlpar_acquire_drc) before calling rtas configure-connector.

Fixes: 1a8061c46c46 ("powerpc/pseries: Add kernel based CPU DLPAR handling")

Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent 2fa30fe
Raw File
kmemleak-test.c
/*
 * mm/kmemleak-test.c
 *
 * Copyright (C) 2008 ARM Limited
 * Written by Catalin Marinas <catalin.marinas@arm.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#define pr_fmt(fmt) "kmemleak: " fmt

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/list.h>
#include <linux/percpu.h>
#include <linux/fdtable.h>

#include <linux/kmemleak.h>

struct test_node {
	long header[25];
	struct list_head list;
	long footer[25];
};

static LIST_HEAD(test_list);
static DEFINE_PER_CPU(void *, kmemleak_test_pointer);

/*
 * Some very simple testing. This function needs to be extended for
 * proper testing.
 */
static int __init kmemleak_test_init(void)
{
	struct test_node *elem;
	int i;

	printk(KERN_INFO "Kmemleak testing\n");

	/* make some orphan objects */
	pr_info("kmalloc(32) = %p\n", kmalloc(32, GFP_KERNEL));
	pr_info("kmalloc(32) = %p\n", kmalloc(32, GFP_KERNEL));
	pr_info("kmalloc(1024) = %p\n", kmalloc(1024, GFP_KERNEL));
	pr_info("kmalloc(1024) = %p\n", kmalloc(1024, GFP_KERNEL));
	pr_info("kmalloc(2048) = %p\n", kmalloc(2048, GFP_KERNEL));
	pr_info("kmalloc(2048) = %p\n", kmalloc(2048, GFP_KERNEL));
	pr_info("kmalloc(4096) = %p\n", kmalloc(4096, GFP_KERNEL));
	pr_info("kmalloc(4096) = %p\n", kmalloc(4096, GFP_KERNEL));
#ifndef CONFIG_MODULES
	pr_info("kmem_cache_alloc(files_cachep) = %p\n",
		kmem_cache_alloc(files_cachep, GFP_KERNEL));
	pr_info("kmem_cache_alloc(files_cachep) = %p\n",
		kmem_cache_alloc(files_cachep, GFP_KERNEL));
#endif
	pr_info("vmalloc(64) = %p\n", vmalloc(64));
	pr_info("vmalloc(64) = %p\n", vmalloc(64));
	pr_info("vmalloc(64) = %p\n", vmalloc(64));
	pr_info("vmalloc(64) = %p\n", vmalloc(64));
	pr_info("vmalloc(64) = %p\n", vmalloc(64));

	/*
	 * Add elements to a list. They should only appear as orphan
	 * after the module is removed.
	 */
	for (i = 0; i < 10; i++) {
		elem = kzalloc(sizeof(*elem), GFP_KERNEL);
		pr_info("kzalloc(sizeof(*elem)) = %p\n", elem);
		if (!elem)
			return -ENOMEM;
		INIT_LIST_HEAD(&elem->list);
		list_add_tail(&elem->list, &test_list);
	}

	for_each_possible_cpu(i) {
		per_cpu(kmemleak_test_pointer, i) = kmalloc(129, GFP_KERNEL);
		pr_info("kmalloc(129) = %p\n",
			per_cpu(kmemleak_test_pointer, i));
	}

	return 0;
}
module_init(kmemleak_test_init);

static void __exit kmemleak_test_exit(void)
{
	struct test_node *elem, *tmp;

	/*
	 * Remove the list elements without actually freeing the
	 * memory.
	 */
	list_for_each_entry_safe(elem, tmp, &test_list, list)
		list_del(&elem->list);
}
module_exit(kmemleak_test_exit);

MODULE_LICENSE("GPL");
back to top