Thread (60 messages) 60 messages, 9 authors, 2020-04-03

RE: [PATCH v4 07/25] ocxl: Add functions to map/unmap LPC memory

From: Alastair D'Silva <hidden>
Date: 2020-04-03 03:50:55
Also in: linux-mm, lkml, nvdimm

-----Original Message-----
From: Dan Williams <redacted>
Sent: Wednesday, 1 April 2020 7:49 PM
To: Alastair D'Silva <redacted>
Cc: Aneesh Kumar K . V <redacted>; Oliver O'Halloran
[off-list ref]; Benjamin Herrenschmidt
[off-list ref]; Paul Mackerras [off-list ref]; Michael
Ellerman [off-list ref]; Frederic Barrat [off-list ref];
Andrew Donnellan [off-list ref]; Arnd Bergmann
[off-list ref]; Greg Kroah-Hartman [off-list ref];
Vishal Verma [off-list ref]; Dave Jiang
[off-list ref]; Ira Weiny [off-list ref]; Andrew Morton
[off-list ref]; Mauro Carvalho Chehab
[off-list ref]; David S. Miller [off-list ref];
Rob Herring [off-list ref]; Anton Blanchard [off-list ref];
Krzysztof Kozlowski [off-list ref]; Mahesh Salgaonkar
[off-list ref]; Madhavan Srinivasan
[off-list ref]; Cédric Le Goater [off-list ref]; Anju T
Sudhakar [off-list ref]; Hari Bathini
[off-list ref]; Thomas Gleixner [off-list ref]; Greg
Kurz [off-list ref]; Nicholas Piggin [off-list ref]; Masahiro
Yamada [off-list ref]; Alexey Kardashevskiy
[off-list ref]; Linux Kernel Mailing List [off-list ref];
linuxppc-dev [off-list ref]; linux-nvdimm <linux-
nvdimm@lists.01.org>; Linux MM [off-list ref]
Subject: Re: [PATCH v4 07/25] ocxl: Add functions to map/unmap LPC
memory

On Sun, Mar 29, 2020 at 10:23 PM Alastair D'Silva [off-list ref]
wrote:
quoted
Add functions to map/unmap LPC memory
"map memory" is an overloaded term. I'm guessing this patch has nothing to
do with mapping memory in the MMU. Is it updating hardware resource
decoders to start claiming address space that was allocated previously?
It's similar to MMIO - these calls end up setting up a BAR which places the LPC
memory into a physical memory range addressable by the kernel.
quoted
Signed-off-by: Alastair D'Silva <redacted>
Acked-by: Frederic Barrat <redacted>
---
 drivers/misc/ocxl/core.c          | 51 +++++++++++++++++++++++++++++++
 drivers/misc/ocxl/ocxl_internal.h |  3 ++
 include/misc/ocxl.h               | 21 +++++++++++++
 3 files changed, 75 insertions(+)
diff --git a/drivers/misc/ocxl/core.c b/drivers/misc/ocxl/core.c index
2531c6cf19a0..75ff14e3882a 100644
--- a/drivers/misc/ocxl/core.c
+++ b/drivers/misc/ocxl/core.c
@@ -210,6 +210,56 @@ static void unmap_mmio_areas(struct ocxl_afu
*afu)
quoted
        release_fn_bar(afu->fn, afu->config.global_mmio_bar);  }

+int ocxl_afu_map_lpc_mem(struct ocxl_afu *afu) {
+       struct pci_dev *dev = to_pci_dev(afu->fn->dev.parent);
+
+       if ((afu->config.lpc_mem_size + afu-
config.special_purpose_mem_size) == 0)
+               return 0;
+
+       afu->lpc_base_addr = ocxl_link_lpc_map(afu->fn->link, dev);
+       if (afu->lpc_base_addr == 0)
+               return -EINVAL;
+
+       if (afu->config.lpc_mem_size > 0) {
+               afu->lpc_res.start = afu->lpc_base_addr + afu-
config.lpc_mem_offset;
+               afu->lpc_res.end = afu->lpc_res.start + afu->config.lpc_mem_size
- 1;
quoted
+       }
+
+       if (afu->config.special_purpose_mem_size > 0) {
+               afu->special_purpose_res.start = afu->lpc_base_addr +
+                                                afu->config.special_purpose_mem_offset;
+               afu->special_purpose_res.end = afu->special_purpose_res.start +
+                                              afu->config.special_purpose_mem_size - 1;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ocxl_afu_map_lpc_mem);
+
+struct resource *ocxl_afu_lpc_mem(struct ocxl_afu *afu) {
+       return &afu->lpc_res;
+}
+EXPORT_SYMBOL_GPL(ocxl_afu_lpc_mem);
+
+static void unmap_lpc_mem(struct ocxl_afu *afu) {
+       struct pci_dev *dev = to_pci_dev(afu->fn->dev.parent);
+
+       if (afu->lpc_res.start || afu->special_purpose_res.start) {
+               void *link = afu->fn->link;
+
+               // only release the link when the the last consumer calls release
+               ocxl_link_lpc_release(link, dev);
+
+               afu->lpc_res.start = 0;
+               afu->lpc_res.end = 0;
+               afu->special_purpose_res.start = 0;
+               afu->special_purpose_res.end = 0;
+       }
+}
+
 static int configure_afu(struct ocxl_afu *afu, u8 afu_idx, struct
pci_dev *dev)  {
        int rc;
@@ -251,6 +301,7 @@ static int configure_afu(struct ocxl_afu *afu, u8
afu_idx, struct pci_dev *dev)

 static void deconfigure_afu(struct ocxl_afu *afu)  {
+       unmap_lpc_mem(afu);
        unmap_mmio_areas(afu);
        reclaim_afu_pasid(afu);
        reclaim_afu_actag(afu);
diff --git a/drivers/misc/ocxl/ocxl_internal.h
b/drivers/misc/ocxl/ocxl_internal.h
index 2d7575225bd7..7b975a89db7b 100644
--- a/drivers/misc/ocxl/ocxl_internal.h
+++ b/drivers/misc/ocxl/ocxl_internal.h
@@ -52,6 +52,9 @@ struct ocxl_afu {
        void __iomem *global_mmio_ptr;
        u64 pp_mmio_start;
        void *private;
+       u64 lpc_base_addr; /* Covers both LPC & special purpose memory */
+       struct resource lpc_res;
+       struct resource special_purpose_res;
 };

 enum ocxl_context_status {
diff --git a/include/misc/ocxl.h b/include/misc/ocxl.h index
357ef1aadbc0..d8b0b4d46bfb 100644
--- a/include/misc/ocxl.h
+++ b/include/misc/ocxl.h
@@ -203,6 +203,27 @@ int ocxl_irq_set_handler(struct ocxl_context
*ctx, int irq_id,

 // AFU Metadata

+/**
+ * ocxl_afu_map_lpc_mem() - Map the LPC system & special purpose
+memory for an AFU
+ * Do not call this during device discovery, as there may me multiple
s/me/be/

quoted
+ * devices on a link, and the memory is mapped for the whole link,
+not
+ * just one device. It should only be called after all devices have
+ * registered their memory on the link.
+ *
+ * @afu: The AFU that has the LPC memory to map
+ *
+ * Returns 0 on success, negative on failure  */ int
+ocxl_afu_map_lpc_mem(struct ocxl_afu *afu);
+
+/**
+ * ocxl_afu_lpc_mem() - Get the physical address range of LPC memory
+for an AFU
+ * @afu: The AFU associated with the LPC memory
+ *
+ * Returns a pointer to the resource struct for the physical address
+range  */ struct resource *ocxl_afu_lpc_mem(struct ocxl_afu *afu);
+
 /**
  * ocxl_afu_config() - Get a pointer to the config for an AFU
  * @afu: a pointer to the AFU to get the config for
--
2.24.1


-- 
Alastair D'Silva           mob: 0423 762 819
skype: alastair_dsilva     msn: alastair@d-silva.org
blog: http://alastair.d-silva.org    Twitter: @EvilDeece
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help