From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.tuxdriver.com (charlotte.tuxdriver.com [70.61.120.58]) by dpdk.org (Postfix) with ESMTP id 044EBC408 for ; Mon, 11 May 2015 14:55:09 +0200 (CEST) Received: from hmsreliant.think-freely.org ([2001:470:8:a08:7aac:c0ff:fec2:933b] helo=localhost) by smtp.tuxdriver.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.63) (envelope-from ) id 1YrnEb-0006c3-0V; Mon, 11 May 2015 08:55:07 -0400 Date: Mon, 11 May 2015 08:54:54 -0400 From: Neil Horman To: Stephen Hemminger Message-ID: <20150511125454.GA8310@hmsreliant.think-freely.org> References: <1431041135-6289-1-git-send-email-stephen@networkplumber.org> <1431041135-6289-2-git-send-email-stephen@networkplumber.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1431041135-6289-2-git-send-email-stephen@networkplumber.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-Spam-Score: -2.9 (--) X-Spam-Status: No Cc: dev@dpdk.org, Stephen Hemminger Subject: Re: [dpdk-dev] [PATCH 1/4] pci: allow access to PCI config space X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 May 2015 12:55:09 -0000 On Thu, May 07, 2015 at 04:25:32PM -0700, Stephen Hemminger wrote: > From: Stephen Hemminger > > Some drivers need ability to access PCI config (for example for power > management). This adds an abstraction to do this; only implemented > on Linux, but should be possible on BSD. > > Signed-off-by: Stephen Hemminger > --- > lib/librte_eal/common/include/rte_pci.h | 28 +++++++++++++++ > lib/librte_eal/linuxapp/eal/eal_pci.c | 48 +++++++++++++++++++++++++ > lib/librte_eal/linuxapp/eal/eal_pci_init.h | 11 ++++++ > lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 14 ++++++++ > lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 16 +++++++++ > lib/librte_eal/linuxapp/eal/rte_eal_version.map | 2 ++ > 6 files changed, 119 insertions(+) > > diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h > index 223d3cd..cea982a 100644 > --- a/lib/librte_eal/common/include/rte_pci.h > +++ b/lib/librte_eal/common/include/rte_pci.h > @@ -393,6 +393,34 @@ void rte_eal_pci_register(struct rte_pci_driver *driver); > */ > void rte_eal_pci_unregister(struct rte_pci_driver *driver); > > +/** > + * Read PCI config space. > + * > + * @param device > + * A pointer to a rte_pci_device structure describing the device > + * to use > + * @param buf > + * A data buffer where the bytes should be read into > + * @param size > + * The length of the data buffer. > + */ > +int rte_eal_pci_read_config(const struct rte_pci_device *device, > + void *buf, size_t len, off_t offset); > + > +/** > + * Write PCI config space. > + * > + * @param device > + * A pointer to a rte_pci_device structure describing the device > + * to use > + * @param buf > + * A data buffer containing the bytes should be written > + * @param size > + * The length of the data buffer. > + */ > +int rte_eal_pci_write_config(const struct rte_pci_device *device, > + const void *buf, size_t len, off_t offset); > + I still think this needs a BSD implementation before we pull the whole thing in. Only partially implementing infrastructure like this is bad practice, and will lead to complicated build procedures (i.e. developers will require institutional knoweldge to know that bnx2x can't build on BSD because someone still needs to implement these functions on bsd. Even having them just return -ENOTSUPP would be preferable, so that you got a proper run time error, rather than a build break, though I don't think thats even necessecary, as pci passthrough is possible in project like bhyve (implying user space pci access) Neil > #ifdef __cplusplus > } > #endif > diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c > index d2adc66..6d79a08 100644 > --- a/lib/librte_eal/linuxapp/eal/eal_pci.c > +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c > @@ -756,6 +756,54 @@ rte_eal_pci_close_one_driver(struct rte_pci_driver *dr __rte_unused, > } > #endif /* RTE_LIBRTE_EAL_HOTPLUG */ > > +/* Read PCI config space. */ > +int rte_eal_pci_read_config(const struct rte_pci_device *device, > + void *buf, size_t len, off_t offset) > +{ > + const struct rte_intr_handle *intr_handle = &device->intr_handle; > + > + switch (intr_handle->type) { > + case RTE_INTR_HANDLE_UIO: > + return pci_uio_read_config(intr_handle, buf, len, offset); > + > +#ifdef VFIO_PRESENT > + case RTE_INTR_HANDLE_VFIO_MSIX: > + case RTE_INTR_HANDLE_VFIO_MSI: > + case RTE_INTR_HANDLE_VFIO_LEGACY: > + return pci_vfio_read_config(intr_handle, buf, len, offset); > +#endif > + default: > + RTE_LOG(ERR, EAL, > + "Unknown handle type of fd %d\n", > + intr_handle->fd); > + return -1; > + } > +} > + > +/* Write PCI config space. */ > +int rte_eal_pci_write_config(const struct rte_pci_device *device, > + const void *buf, size_t len, off_t offset) > +{ > + const struct rte_intr_handle *intr_handle = &device->intr_handle; > + > + switch (intr_handle->type) { > + case RTE_INTR_HANDLE_UIO: > + return pci_uio_write_config(intr_handle, buf, len, offset); > + > +#ifdef VFIO_PRESENT > + case RTE_INTR_HANDLE_VFIO_MSIX: > + case RTE_INTR_HANDLE_VFIO_MSI: > + case RTE_INTR_HANDLE_VFIO_LEGACY: > + return pci_vfio_write_config(intr_handle, buf, len, offset); > +#endif > + default: > + RTE_LOG(ERR, EAL, > + "Unknown handle type of fd %d\n", > + intr_handle->fd); > + return -1; > + } > +} > + > /* Init the PCI EAL subsystem */ > int > rte_eal_pci_init(void) > diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h > index aa7b755..c28e5b0 100644 > --- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h > +++ b/lib/librte_eal/linuxapp/eal/eal_pci_init.h > @@ -68,6 +68,11 @@ void *pci_find_max_end_va(void); > void *pci_map_resource(void *requested_addr, int fd, off_t offset, > size_t size, int additional_flags); > > +int pci_uio_read_config(const struct rte_intr_handle *intr_handle, > + void *buf, size_t len, off_t offs); > +int pci_uio_write_config(const struct rte_intr_handle *intr_handle, > + const void *buf, size_t len, off_t offs); > + > /* map IGB_UIO resource prototype */ > int pci_uio_map_resource(struct rte_pci_device *dev); > > @@ -86,6 +91,12 @@ int pci_vfio_enable(void); > int pci_vfio_is_enabled(void); > int pci_vfio_mp_sync_setup(void); > > +/* access config space */ > +int pci_vfio_read_config(const struct rte_intr_handle *intr_handle, > + void *buf, size_t len, off_t offs); > +int pci_vfio_write_config(const struct rte_intr_handle *intr_handle, > + const void *buf, size_t len, off_t offs); > + > /* map VFIO resource prototype */ > int pci_vfio_map_resource(struct rte_pci_device *dev); > int pci_vfio_get_group_fd(int iommu_group_fd); > diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c > index 2d1c69b..bbc59ed 100644 > --- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c > +++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c > @@ -58,6 +58,20 @@ EAL_REGISTER_TAILQ(rte_uio_tailq) > > #define OFF_MAX ((uint64_t)(off_t)-1) > > +int > +pci_uio_read_config(const struct rte_intr_handle *intr_handle, > + void *buf, size_t len, off_t offset) > +{ > + return pread(intr_handle->uio_cfg_fd, buf, len, offset); > +} > + > +int > +pci_uio_write_config(const struct rte_intr_handle *intr_handle, > + const void *buf, size_t len, off_t offset) > +{ > + return pwrite(intr_handle->uio_cfg_fd, buf, len, offset); > +} > + > static int > pci_uio_set_bus_master(int dev_fd) > { > diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c > index aea1fb1..092a369 100644 > --- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c > +++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c > @@ -77,6 +77,22 @@ EAL_REGISTER_TAILQ(rte_vfio_tailq) > /* per-process VFIO config */ > static struct vfio_config vfio_cfg; > > +int > +pci_vfio_read_config(const struct rte_intr_handle *intr_handle, > + void *buf, size_t len, off_t offs) > +{ > + return pread64(intr_handle->vfio_dev_fd, buf, len, > + VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs); > +} > + > +int > +pci_vfio_write_config(const struct rte_intr_handle *intr_handle, > + const void *buf, size_t len, off_t offs) > +{ > + return pwrite64(intr_handle->vfio_dev_fd, buf, len, > + VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs); > +} > + > /* get PCI BAR number where MSI-X interrupts are */ > static int > pci_vfio_get_msix_bar(int fd, int *msix_bar, uint32_t *msix_table_offset, > diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map > index 7e850a9..494aae0 100644 > --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map > +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map > @@ -42,9 +42,11 @@ DPDK_2.0 { > rte_eal_pci_dump; > rte_eal_pci_probe; > rte_eal_pci_probe_one; > + rte_eal_pci_read_config; > rte_eal_pci_register; > rte_eal_pci_scan; > rte_eal_pci_unregister; > + rte_eal_pci_write_config; > rte_eal_process_type; > rte_eal_remote_launch; > rte_eal_tailq_lookup; > -- > 2.1.4 > >