Skip to content

Commit

Permalink
npu2: Add XTS_BDF_MAP wildcard refcount
Browse files Browse the repository at this point in the history
Currently PID wildcard is programmed into the NPU once and never cleared
up. This works for the bare metal as MSR does not change while the host
OS is running.

However with the device virtualization, we need to keep track of wildcard
entries use and clear them up before switching a GPU from a host to
a guest or vice versa.

This adds refcount to a NPU2, one counter per wildcard entry. The index
is a short lparid (4 bits long) which is allocated in opal_npu_map_lpar()
and should be smaller than NPU2_XTS_BDF_MAP_SIZE (defined as 16).

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Acked-by: Reza Arbab <arbab@linux.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
  • Loading branch information
aik authored and stewartsmith committed Feb 26, 2019
1 parent b821f8c commit ba1d95a
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 16 deletions.
46 changes: 30 additions & 16 deletions hw/npu2.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#include <ccan/str/str.h>
#include <ccan/array_size/array_size.h>
#include <affinity.h>
#include <npu2-regs.h>
#include <npu2.h>
#include <lock.h>
#include <xscom.h>
Expand Down Expand Up @@ -2144,19 +2143,25 @@ static int64_t opal_npu_init_context(uint64_t phb_id, int pasid __unused,
GETFIELD(NPU2_XTS_PID_MAP_MSR, xts_bdf_pid)) {
NPU2ERR(p, "%s: Unexpected MSR value\n", __func__);
id = OPAL_PARAMETER;
goto out;
} else if (!p->ctx_ref[id]) {
NPU2ERR(p, "%s: Unexpected mapping\n", __func__);
id = OPAL_INTERNAL_ERROR;
goto out;
}

goto out;
}

/* Write the entry */
NPU2DBG(p, "XTS_PID_MAP[%03d] = 0x%08llx\n", id, xts_bdf_pid);
npu2_write(p, NPU2_XTS_PID_MAP + id*0x20, xts_bdf_pid);
if (!p->ctx_ref[id]) {
NPU2DBG(p, "XTS_PID_MAP[%03d] = 0x%08llx\n", id, xts_bdf_pid);
npu2_write(p, NPU2_XTS_PID_MAP + id*0x20, xts_bdf_pid);

if (!GETFIELD(NPU2_XTS_BDF_MAP_VALID, xts_bdf)) {
xts_bdf = SETFIELD(NPU2_XTS_BDF_MAP_VALID, xts_bdf, 1);
npu2_write(p, NPU2_XTS_BDF_MAP + id*8, xts_bdf);
if (!GETFIELD(NPU2_XTS_BDF_MAP_VALID, xts_bdf)) {
xts_bdf = SETFIELD(NPU2_XTS_BDF_MAP_VALID, xts_bdf, 1);
npu2_write(p, NPU2_XTS_BDF_MAP + id*8, xts_bdf);
}
}
++p->ctx_ref[id];

out:
unlock(&p->lock);
Expand All @@ -2170,7 +2175,7 @@ static int opal_npu_destroy_context(uint64_t phb_id, uint64_t pid __unused,
struct phb *phb = pci_get_phb(phb_id);
struct npu2 *p;
uint64_t xts_bdf;
int rc = 0;
int rc = OPAL_PARAMETER, id;

if (!phb || phb->phb_type != phb_type_npu_v2)
return OPAL_PARAMETER;
Expand All @@ -2183,14 +2188,23 @@ static int opal_npu_destroy_context(uint64_t phb_id, uint64_t pid __unused,
if (npu_table_search(p, NPU2_XTS_BDF_MAP, 8, NPU2_XTS_BDF_MAP_SIZE,
&xts_bdf, NPU2_XTS_BDF_MAP_BDF) < 0) {
NPU2ERR(p, "LPARID not associated with any GPU\n");
rc = OPAL_PARAMETER;
} else {
/*
* The bdf/pid table contains wildcard entries and MSR bits
* which we need to clear between switching a device from
* a host to a guest or vice versa.
*/
id = GETFIELD(NPU2_XTS_BDF_MAP_LPARSHORT, xts_bdf);
if (p->ctx_ref[id]) {
--p->ctx_ref[id];
if (!p->ctx_ref[id]) {
NPU2DBG(p, "XTS_PID_MAP[%03d] = 0 (destroy)\n",
id);
npu2_write(p, NPU2_XTS_PID_MAP + id*0x20, 0);
}
rc = OPAL_SUCCESS;
}
}

/*
* The bdf/pid table only contains wildcard entries, so we don't
* need to remove anything here.
*/

unlock(&p->lock);
return rc;
}
Expand Down
2 changes: 2 additions & 0 deletions include/npu2.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <pci.h>
#include <phys-map.h>
#include <npu2-regs.h>

/* Debugging options */
#define NPU2DBG(p, fmt, a...) prlog(PR_DEBUG, "NPU%d: " fmt, \
Expand Down Expand Up @@ -158,6 +159,7 @@ struct npu2 {
uint32_t total_devices;
struct npu2_dev *devices;
enum phys_map_type gpu_map_type;
int ctx_ref[NPU2_XTS_BDF_MAP_SIZE];

/* IODA cache */
uint64_t tve_cache[16];
Expand Down

0 comments on commit ba1d95a

Please sign in to comment.