env/vtophys: store unshifted physical address
Rather than storing the page frame number, just store the full physical address of each 2 MB page. This simplifies the lookup code and makes the map generic (values are inserted and retrieved without any modification) for future uses. Change-Id: Ib1081513a0682f6b8b908f3401c00d87b00f484c Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
ee5ca14e21
commit
d1638fb677
@ -31,6 +31,7 @@
|
|||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -66,13 +67,13 @@
|
|||||||
/* Max value for a 16-bit ref count. */
|
/* Max value for a 16-bit ref count. */
|
||||||
#define VTOPHYS_MAX_REF_COUNT (0xFFFF)
|
#define VTOPHYS_MAX_REF_COUNT (0xFFFF)
|
||||||
|
|
||||||
/* Physical page frame number of a single 2MB page. */
|
/* Physical address of a single 2MB page. */
|
||||||
struct map_2mb {
|
struct map_2mb {
|
||||||
uint64_t pfn_2mb;
|
uint64_t paddr_2mb;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Second-level map table indexed by bits [21..29] of the virtual address.
|
/* Second-level map table indexed by bits [21..29] of the virtual address.
|
||||||
* Each entry contains the 2MB physical page frame number or SPDK_VTOPHYS_ERROR for entries that haven't
|
* Each entry contains the 2MB physical address or SPDK_VTOPHYS_ERROR for entries that haven't
|
||||||
* been retrieved yet.
|
* been retrieved yet.
|
||||||
*/
|
*/
|
||||||
struct map_1gb {
|
struct map_1gb {
|
||||||
@ -158,14 +159,13 @@ vtophys_get_dpdk_paddr(void *vaddr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
vtophys_get_pfn_2mb(uint64_t vfn_2mb)
|
vtophys_get_paddr(uint64_t vaddr)
|
||||||
{
|
{
|
||||||
uintptr_t vaddr, paddr;
|
uintptr_t paddr;
|
||||||
struct rte_mem_config *mcfg;
|
struct rte_mem_config *mcfg;
|
||||||
struct rte_memseg *seg;
|
struct rte_memseg *seg;
|
||||||
uint32_t seg_idx;
|
uint32_t seg_idx;
|
||||||
|
|
||||||
vaddr = vfn_2mb << SHIFT_2MB;
|
|
||||||
mcfg = rte_eal_get_configuration()->mem_config;
|
mcfg = rte_eal_get_configuration()->mem_config;
|
||||||
|
|
||||||
for (seg_idx = 0; seg_idx < RTE_MAX_MEMSEG; seg_idx++) {
|
for (seg_idx = 0; seg_idx < RTE_MAX_MEMSEG; seg_idx++) {
|
||||||
@ -178,11 +178,11 @@ vtophys_get_pfn_2mb(uint64_t vfn_2mb)
|
|||||||
vaddr < ((uintptr_t)seg->addr + seg->len)) {
|
vaddr < ((uintptr_t)seg->addr + seg->len)) {
|
||||||
paddr = seg->phys_addr;
|
paddr = seg->phys_addr;
|
||||||
paddr += (vaddr - (uintptr_t)seg->addr);
|
paddr += (vaddr - (uintptr_t)seg->addr);
|
||||||
return paddr >> SHIFT_2MB;
|
return paddr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "could not find 2MB vfn 0x%jx in DPDK mem config\n", vfn_2mb);
|
fprintf(stderr, "could not find vaddr 0x%" PRIx64 " in DPDK mem config\n", vaddr);
|
||||||
return SPDK_VTOPHYS_ERROR;
|
return SPDK_VTOPHYS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ _spdk_vtophys_register_one(uint64_t vfn_2mb)
|
|||||||
map_2mb = &map_1gb->map[idx_1gb];
|
map_2mb = &map_1gb->map[idx_1gb];
|
||||||
ref_count = &map_1gb->ref_count[idx_1gb];
|
ref_count = &map_1gb->ref_count[idx_1gb];
|
||||||
|
|
||||||
if (map_2mb->pfn_2mb == SPDK_VTOPHYS_ERROR) {
|
if (map_2mb->paddr_2mb == SPDK_VTOPHYS_ERROR) {
|
||||||
vaddr = (void *)(vfn_2mb << SHIFT_2MB);
|
vaddr = (void *)(vfn_2mb << SHIFT_2MB);
|
||||||
paddr = vtophys_get_dpdk_paddr(vaddr);
|
paddr = vtophys_get_dpdk_paddr(vaddr);
|
||||||
if (paddr == RTE_BAD_PHYS_ADDR) {
|
if (paddr == RTE_BAD_PHYS_ADDR) {
|
||||||
@ -213,7 +213,7 @@ _spdk_vtophys_register_one(uint64_t vfn_2mb)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
map_2mb->pfn_2mb = paddr >> SHIFT_2MB;
|
map_2mb->paddr_2mb = paddr & ~MASK_2MB;
|
||||||
*ref_count = 0;
|
*ref_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,14 +243,14 @@ _spdk_vtophys_unregister_one(uint64_t vfn_2mb)
|
|||||||
map_2mb = &map_1gb->map[idx_1gb];
|
map_2mb = &map_1gb->map[idx_1gb];
|
||||||
ref_count = &map_1gb->ref_count[idx_1gb];
|
ref_count = &map_1gb->ref_count[idx_1gb];
|
||||||
|
|
||||||
if (map_2mb->pfn_2mb == SPDK_VTOPHYS_ERROR || *ref_count == 0) {
|
if (map_2mb->paddr_2mb == SPDK_VTOPHYS_ERROR || *ref_count == 0) {
|
||||||
fprintf(stderr, "vaddr %p not registered\n", (void *)(vfn_2mb << SHIFT_2MB));
|
fprintf(stderr, "vaddr %p not registered\n", (void *)(vfn_2mb << SHIFT_2MB));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*ref_count)--;
|
(*ref_count)--;
|
||||||
if (*ref_count == 0) {
|
if (*ref_count == 0) {
|
||||||
map_2mb->pfn_2mb = SPDK_VTOPHYS_ERROR;
|
map_2mb->paddr_2mb = SPDK_VTOPHYS_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +310,7 @@ uint64_t
|
|||||||
spdk_vtophys(void *buf)
|
spdk_vtophys(void *buf)
|
||||||
{
|
{
|
||||||
struct map_2mb *map_2mb;
|
struct map_2mb *map_2mb;
|
||||||
uint64_t vaddr, vfn_2mb, pfn_2mb;
|
uint64_t vaddr, vfn_2mb, paddr_2mb;
|
||||||
|
|
||||||
vaddr = (uint64_t)buf;
|
vaddr = (uint64_t)buf;
|
||||||
if (vaddr & ~MASK_128TB) {
|
if (vaddr & ~MASK_128TB) {
|
||||||
@ -325,14 +325,19 @@ spdk_vtophys(void *buf)
|
|||||||
return SPDK_VTOPHYS_ERROR;
|
return SPDK_VTOPHYS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
pfn_2mb = map_2mb->pfn_2mb;
|
paddr_2mb = map_2mb->paddr_2mb;
|
||||||
if (pfn_2mb == SPDK_VTOPHYS_ERROR) {
|
if (paddr_2mb == SPDK_VTOPHYS_ERROR) {
|
||||||
pfn_2mb = vtophys_get_pfn_2mb(vfn_2mb);
|
uint64_t paddr;
|
||||||
if (pfn_2mb == SPDK_VTOPHYS_ERROR) {
|
|
||||||
|
paddr = vtophys_get_paddr(vaddr);
|
||||||
|
if (paddr == SPDK_VTOPHYS_ERROR) {
|
||||||
return SPDK_VTOPHYS_ERROR;
|
return SPDK_VTOPHYS_ERROR;
|
||||||
}
|
}
|
||||||
map_2mb->pfn_2mb = pfn_2mb;
|
|
||||||
|
/* For now, assume all valid addressess are part of 2MB or larger pages. */
|
||||||
|
paddr_2mb = paddr & ~MASK_2MB;
|
||||||
|
map_2mb->paddr_2mb = paddr_2mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (pfn_2mb << SHIFT_2MB) | ((uint64_t)buf & MASK_2MB);
|
return paddr_2mb | ((uint64_t)buf & MASK_2MB);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user