Skip to content

Commit 45e9f9a

Browse files
swahlhpehansendc
authored andcommitted
x86/platform/uv: Helper functions for allocating and freeing conversion tables
Add alloc_conv_table() and FREE_1_TO_1_TABLE() to reduce duplicated code among the conversion tables we use. Signed-off-by: Steve Wahl <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Link: https://lore.kernel.org/all/20230519190752.3297140-6-steve.wahl%40hpe.com
1 parent 35bd896 commit 45e9f9a

File tree

1 file changed

+53
-44
lines changed

1 file changed

+53
-44
lines changed

arch/x86/kernel/apic/x2apic_uv_x.c

Lines changed: 53 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,16 +1491,50 @@ static __init void boot_init_possible_blades(struct uv_hub_info_s *hub_info)
14911491
pr_info("UV: number nodes/possible blades %d\n", uv_pb);
14921492
}
14931493

1494+
static int __init alloc_conv_table(int num_elem, unsigned short **table)
1495+
{
1496+
int i;
1497+
size_t bytes;
1498+
1499+
bytes = num_elem * sizeof(*table[0]);
1500+
*table = kmalloc(bytes, GFP_KERNEL);
1501+
if (WARN_ON_ONCE(!*table))
1502+
return -ENOMEM;
1503+
for (i = 0; i < num_elem; i++)
1504+
((unsigned short *)*table)[i] = SOCK_EMPTY;
1505+
return 0;
1506+
}
1507+
1508+
/* Remove conversion table if it's 1:1 */
1509+
#define FREE_1_TO_1_TABLE(tbl, min, max, max2) free_1_to_1_table(&tbl, #tbl, min, max, max2)
1510+
1511+
static void __init free_1_to_1_table(unsigned short **tp, char *tname, int min, int max, int max2)
1512+
{
1513+
int i;
1514+
unsigned short *table = *tp;
1515+
1516+
if (table == NULL)
1517+
return;
1518+
if (max != max2)
1519+
return;
1520+
for (i = 0; i < max; i++) {
1521+
if (i != table[i])
1522+
return;
1523+
}
1524+
kfree(table);
1525+
*tp = NULL;
1526+
pr_info("UV: %s is 1:1, conversion table removed\n", tname);
1527+
}
1528+
14941529
static void __init build_socket_tables(void)
14951530
{
14961531
struct uv_gam_range_entry *gre = uv_gre_table;
1497-
int num, nump;
1532+
int nums, numn, nump;
14981533
int cpu, i, lnid;
14991534
int minsock = _min_socket;
15001535
int maxsock = _max_socket;
15011536
int minpnode = _min_pnode;
15021537
int maxpnode = _max_pnode;
1503-
size_t bytes;
15041538

15051539
if (!gre) {
15061540
if (is_uv2_hub() || is_uv3_hub()) {
@@ -1511,22 +1545,20 @@ static void __init build_socket_tables(void)
15111545
BUG();
15121546
}
15131547

1514-
/* Build socket id -> node id, pnode */
1515-
num = maxsock - minsock + 1;
1516-
bytes = num * sizeof(_socket_to_node[0]);
1517-
_socket_to_node = kmalloc(bytes, GFP_KERNEL);
1518-
_socket_to_pnode = kmalloc(bytes, GFP_KERNEL);
1519-
1548+
numn = num_possible_nodes();
15201549
nump = maxpnode - minpnode + 1;
1521-
bytes = nump * sizeof(_pnode_to_socket[0]);
1522-
_pnode_to_socket = kmalloc(bytes, GFP_KERNEL);
1523-
BUG_ON(!_socket_to_node || !_socket_to_pnode || !_pnode_to_socket);
1524-
1525-
for (i = 0; i < num; i++)
1526-
_socket_to_node[i] = _socket_to_pnode[i] = SOCK_EMPTY;
1527-
1528-
for (i = 0; i < nump; i++)
1529-
_pnode_to_socket[i] = SOCK_EMPTY;
1550+
nums = maxsock - minsock + 1;
1551+
1552+
/* Allocate and clear tables */
1553+
if ((alloc_conv_table(nump, &_pnode_to_socket) < 0)
1554+
|| (alloc_conv_table(nums, &_socket_to_pnode) < 0)
1555+
|| (alloc_conv_table(numn, &_node_to_pnode) < 0)
1556+
|| (alloc_conv_table(nums, &_socket_to_node) < 0)) {
1557+
kfree(_pnode_to_socket);
1558+
kfree(_socket_to_pnode);
1559+
kfree(_node_to_pnode);
1560+
return;
1561+
}
15301562

15311563
/* Fill in pnode/node/addr conversion list values: */
15321564
pr_info("UV: GAM Building socket/pnode conversion tables\n");
@@ -1565,10 +1597,6 @@ static void __init build_socket_tables(void)
15651597
}
15661598

15671599
/* Set up physical blade to pnode translation from GAM Range Table: */
1568-
bytes = num_possible_nodes() * sizeof(_node_to_pnode[0]);
1569-
_node_to_pnode = kmalloc(bytes, GFP_KERNEL);
1570-
BUG_ON(!_node_to_pnode);
1571-
15721600
for (lnid = 0; lnid < num_possible_nodes(); lnid++) {
15731601
unsigned short sockid;
15741602

@@ -1585,31 +1613,12 @@ static void __init build_socket_tables(void)
15851613
}
15861614

15871615
/*
1588-
* If socket id == pnode or socket id == node for all nodes,
1616+
* If e.g. socket id == pnode for all pnodes,
15891617
* system runs faster by removing corresponding conversion table.
15901618
*/
1591-
pr_info("UV: Checking socket->node/pnode for identity maps\n");
1592-
if (minsock == 0) {
1593-
for (i = 0; i < num; i++)
1594-
if (_socket_to_node[i] == SOCK_EMPTY || i != _socket_to_node[i])
1595-
break;
1596-
if (i >= num) {
1597-
kfree(_socket_to_node);
1598-
_socket_to_node = NULL;
1599-
pr_info("UV: 1:1 socket_to_node table removed\n");
1600-
}
1601-
}
1602-
if (minsock == minpnode) {
1603-
for (i = 0; i < num; i++)
1604-
if (_socket_to_pnode[i] != SOCK_EMPTY &&
1605-
_socket_to_pnode[i] != i + minpnode)
1606-
break;
1607-
if (i >= num) {
1608-
kfree(_socket_to_pnode);
1609-
_socket_to_pnode = NULL;
1610-
pr_info("UV: 1:1 socket_to_pnode table removed\n");
1611-
}
1612-
}
1619+
FREE_1_TO_1_TABLE(_socket_to_node, _min_socket, nums, numn);
1620+
FREE_1_TO_1_TABLE(_socket_to_pnode, _min_pnode, nums, nump);
1621+
FREE_1_TO_1_TABLE(_pnode_to_socket, _min_pnode, nums, nump);
16131622
}
16141623

16151624
/* Check which reboot to use */

0 commit comments

Comments
 (0)