From f8aa86dd1622804d81020a7dbb1116f276b340f3 Mon Sep 17 00:00:00 2001 From: Andrew Perepechko Date: Fri, 14 Feb 2020 05:20:09 +0300 Subject: [PATCH] LU-13294 libcfs: incorrect rotor behaviour Signed int cpt rotor is set to -1 on initialization. cfs_cpt_spread_node() improperly handles this value via "if (!rotor--)" check. The condition is never true with negative rotor values, so for_each_node_mask() only exits with node = MAX_NUMNODES. kmalloc_node() attempts to determine the zonelist based on the passed node id and maps MAX_NUMNODES to some random pointer. Crash. BUG: unable to handle kernel paging request at 0000000100002007 IP: [] __alloc_pages_nodemask+0x97/0x420 Change-Id: I4df74e394bdfc2a918d66aa12e6852ff0f6738ab Signed-off-by: Andrew Perepechko Cray-bug-id: LUS-8492 Reviewed-on: https://review.whamcloud.com/37709 Reviewed-by: Alexander Boyko Reviewed-by: James Simmons Reviewed-by: Alexander Zarochentsev Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- libcfs/include/libcfs/libcfs_cpu.h | 4 ++-- libcfs/libcfs/libcfs_cpu.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libcfs/include/libcfs/libcfs_cpu.h b/libcfs/include/libcfs/libcfs_cpu.h index 34db1f6..404b07a 100644 --- a/libcfs/include/libcfs/libcfs_cpu.h +++ b/libcfs/include/libcfs/libcfs_cpu.h @@ -91,7 +91,7 @@ struct cfs_cpu_partition { /* NUMA distance between CPTs */ unsigned int *cpt_distance; /* spread rotor for NUMA allocator */ - int cpt_spread_rotor; + unsigned int cpt_spread_rotor; /* NUMA node if cpt_nodemask is empty */ int cpt_node; }; @@ -101,7 +101,7 @@ struct cfs_cpu_partition { struct cfs_cpt_table { #ifdef CONFIG_SMP /* spread rotor for NUMA allocator */ - int ctb_spread_rotor; + unsigned int ctb_spread_rotor; /* maximum NUMA distance between all nodes in table */ unsigned int ctb_distance; /* partitions tables */ diff --git a/libcfs/libcfs/libcfs_cpu.c b/libcfs/libcfs/libcfs_cpu.c index 808169a..68046a7 100644 --- a/libcfs/libcfs/libcfs_cpu.c +++ b/libcfs/libcfs/libcfs_cpu.c @@ -627,7 +627,7 @@ int cfs_cpt_spread_node(struct cfs_cpt_table *cptab, int cpt) { nodemask_t *mask; int weight; - int rotor; + unsigned int rotor; int node = 0; /* convert CPU partition ID to HW node id */ -- 1.8.3.1