Skip to content

Commit f2af6d3

Browse files
davidhildenbrandmstsirkin
authored andcommitted
virtio-mem: Allow to specify an ACPI PXM as nid
We want to allow to specify (similar as for a DIMM), to which node a virtio-mem device (and, therefore, its memory) belongs. Add a new virtio-mem feature flag and export pxm_to_node, so it can be used in kernel module context. Acked-by: Michal Hocko <[email protected]> # for the export Acked-by: "Rafael J. Wysocki" <[email protected]> # for the export Acked-by: Pankaj Gupta <[email protected]> Tested-by: Pankaj Gupta <[email protected]> Cc: "Michael S. Tsirkin" <[email protected]> Cc: Jason Wang <[email protected]> Cc: Oscar Salvador <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Igor Mammedov <[email protected]> Cc: Dave Young <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Dan Williams <[email protected]> Cc: Pavel Tatashin <[email protected]> Cc: Stefan Hajnoczi <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: Len Brown <[email protected]> Cc: [email protected] Signed-off-by: David Hildenbrand <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent dfb0b2e commit f2af6d3

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

drivers/acpi/numa/srat.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ int pxm_to_node(int pxm)
3535
return NUMA_NO_NODE;
3636
return pxm_to_node_map[pxm];
3737
}
38+
EXPORT_SYMBOL(pxm_to_node);
3839

3940
int node_to_pxm(int node)
4041
{

drivers/virtio/virtio_mem.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <linux/bitmap.h>
2222
#include <linux/lockdep.h>
2323

24+
#include <acpi/acpi_numa.h>
25+
2426
enum virtio_mem_mb_state {
2527
/* Unplugged, not added to Linux. Can be reused later. */
2628
VIRTIO_MEM_MB_STATE_UNUSED = 0,
@@ -72,6 +74,8 @@ struct virtio_mem {
7274

7375
/* The device block size (for communicating with the device). */
7476
uint32_t device_block_size;
77+
/* The translated node id. NUMA_NO_NODE in case not specified. */
78+
int nid;
7579
/* Physical start address of the memory region. */
7680
uint64_t addr;
7781
/* Maximum region size in bytes. */
@@ -389,7 +393,10 @@ static int virtio_mem_sb_bitmap_prepare_next_mb(struct virtio_mem *vm)
389393
static int virtio_mem_mb_add(struct virtio_mem *vm, unsigned long mb_id)
390394
{
391395
const uint64_t addr = virtio_mem_mb_id_to_phys(mb_id);
392-
int nid = memory_add_physaddr_to_nid(addr);
396+
int nid = vm->nid;
397+
398+
if (nid == NUMA_NO_NODE)
399+
nid = memory_add_physaddr_to_nid(addr);
393400

394401
dev_dbg(&vm->vdev->dev, "adding memory block: %lu\n", mb_id);
395402
return add_memory(nid, addr, memory_block_size_bytes());
@@ -407,7 +414,10 @@ static int virtio_mem_mb_add(struct virtio_mem *vm, unsigned long mb_id)
407414
static int virtio_mem_mb_remove(struct virtio_mem *vm, unsigned long mb_id)
408415
{
409416
const uint64_t addr = virtio_mem_mb_id_to_phys(mb_id);
410-
int nid = memory_add_physaddr_to_nid(addr);
417+
int nid = vm->nid;
418+
419+
if (nid == NUMA_NO_NODE)
420+
nid = memory_add_physaddr_to_nid(addr);
411421

412422
dev_dbg(&vm->vdev->dev, "removing memory block: %lu\n", mb_id);
413423
return remove_memory(nid, addr, memory_block_size_bytes());
@@ -426,6 +436,17 @@ static void virtio_mem_retry(struct virtio_mem *vm)
426436
spin_unlock_irqrestore(&vm->removal_lock, flags);
427437
}
428438

439+
static int virtio_mem_translate_node_id(struct virtio_mem *vm, uint16_t node_id)
440+
{
441+
int node = NUMA_NO_NODE;
442+
443+
#if defined(CONFIG_ACPI_NUMA)
444+
if (virtio_has_feature(vm->vdev, VIRTIO_MEM_F_ACPI_PXM))
445+
node = pxm_to_node(node_id);
446+
#endif
447+
return node;
448+
}
449+
429450
/*
430451
* Test if a virtio-mem device overlaps with the given range. Can be called
431452
* from (notifier) callbacks lockless.
@@ -1267,6 +1288,7 @@ static bool virtio_mem_any_memory_present(unsigned long start,
12671288
static int virtio_mem_init(struct virtio_mem *vm)
12681289
{
12691290
const uint64_t phys_limit = 1UL << MAX_PHYSMEM_BITS;
1291+
uint16_t node_id;
12701292

12711293
if (!vm->vdev->config->get) {
12721294
dev_err(&vm->vdev->dev, "config access disabled\n");
@@ -1287,6 +1309,9 @@ static int virtio_mem_init(struct virtio_mem *vm)
12871309
&vm->plugged_size);
12881310
virtio_cread(vm->vdev, struct virtio_mem_config, block_size,
12891311
&vm->device_block_size);
1312+
virtio_cread(vm->vdev, struct virtio_mem_config, node_id,
1313+
&node_id);
1314+
vm->nid = virtio_mem_translate_node_id(vm, node_id);
12901315
virtio_cread(vm->vdev, struct virtio_mem_config, addr, &vm->addr);
12911316
virtio_cread(vm->vdev, struct virtio_mem_config, region_size,
12921317
&vm->region_size);
@@ -1365,6 +1390,8 @@ static int virtio_mem_init(struct virtio_mem *vm)
13651390
memory_block_size_bytes());
13661391
dev_info(&vm->vdev->dev, "subblock size: 0x%x",
13671392
vm->subblock_size);
1393+
if (vm->nid != NUMA_NO_NODE)
1394+
dev_info(&vm->vdev->dev, "nid: %d", vm->nid);
13681395

13691396
return 0;
13701397
}
@@ -1508,12 +1535,20 @@ static int virtio_mem_restore(struct virtio_device *vdev)
15081535
}
15091536
#endif
15101537

1538+
static unsigned int virtio_mem_features[] = {
1539+
#if defined(CONFIG_NUMA) && defined(CONFIG_ACPI_NUMA)
1540+
VIRTIO_MEM_F_ACPI_PXM,
1541+
#endif
1542+
};
1543+
15111544
static struct virtio_device_id virtio_mem_id_table[] = {
15121545
{ VIRTIO_ID_MEM, VIRTIO_DEV_ANY_ID },
15131546
{ 0 },
15141547
};
15151548

15161549
static struct virtio_driver virtio_mem_driver = {
1550+
.feature_table = virtio_mem_features,
1551+
.feature_table_size = ARRAY_SIZE(virtio_mem_features),
15171552
.driver.name = KBUILD_MODNAME,
15181553
.driver.owner = THIS_MODULE,
15191554
.id_table = virtio_mem_id_table,

include/uapi/linux/virtio_mem.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@
8383
* device is busy.
8484
*/
8585

86+
/* --- virtio-mem: feature bits --- */
87+
88+
/* node_id is an ACPI PXM and is valid */
89+
#define VIRTIO_MEM_F_ACPI_PXM 0
90+
91+
8692
/* --- virtio-mem: guest -> host requests --- */
8793

8894
/* request to plug memory blocks */
@@ -177,7 +183,9 @@ struct virtio_mem_resp {
177183
struct virtio_mem_config {
178184
/* Block size and alignment. Cannot change. */
179185
__u32 block_size;
180-
__u32 padding;
186+
/* Valid with VIRTIO_MEM_F_ACPI_PXM. Cannot change. */
187+
__u16 node_id;
188+
__u16 padding;
181189
/* Start address of the memory region. Cannot change. */
182190
__u64 addr;
183191
/* Region size (maximum). Cannot change. */

0 commit comments

Comments
 (0)