[dpdk-dev] [PATCHv4 1/5] pmdinfogen: Add buildtools and pmdinfogen utility

Neil Horman nhorman at tuxdriver.com
Wed May 25 19:22:27 CEST 2016


On Wed, May 25, 2016 at 03:21:19PM +0200, Thomas Monjalon wrote:
> 2016-05-24 15:41, Neil Horman:
> > pmdinfogen is a tool used to parse object files and build json strings for use in
> > later determining hardware support in a dso or application binary.  pmdinfo
> > looks for the non-exported symbol names this_pmd_name<n> and this_pmd_tbl<n>
> > (where n is a integer counter).  It records the name of each of these tuples,
> > using the later to find the symbolic name of the pci_table for physical devices
> > that the object supports.  With this information, it outputs a C file with a
> > single line of the form:
> > 
> > static char *<pmd_name>_driver_info[] __attribute__((used)) = " \
> > 	PMD_DRIVER_INFO=<json string>";
> > 
> > Where <pmd_name> is the arbitrary name of the pmd, and <json_string> is the json
> > encoded string that hold relevant pmd information, including the pmd name, type
> > and optional array of pci device/vendor ids that the driver supports.
> > 
> > This c file is suitable for compiling to object code, then relocatably linking
> > into the parent file from which the C was generated.  This creates an entry in
> > the string table of the object that can inform a later tool about hardware
> > support.
> 
> This description is helpful and should be in the doc:
> 	doc/guides/prog_guide/dev_kit_build_system.rst
Yeah, ok I can add that. 

> 
> > --- a/GNUmakefile
> > +++ b/GNUmakefile
> > -ROOTDIRS-y := lib drivers app
> > +ROOTDIRS-y := buildtools lib drivers app
> 
> Why a new directory?
> It is not a script nor an end-user tool, I guess.
Dependencies.  This tool has to be built prior to the rest of the dpdk, but app
already relies on dpdk libraries to be built, so you get circular dependencies.
I could have put it in scripts I guess, but its not a script.  Its own directory
seemed to make the most sense, given those two points

> 
> I feel strange to build an app for the build system.
Why?  I agree its not overly common, but theres lots of precident for it.
The linux and bsd kernels obviously do this for modules, and there are lots of
tools that convert generic descriptions in xml into platform native source code
prior to compilation.

> For information, do you know some Python lib to do this kind of tool?
> 
No, if there was I would have used it, but this sort of thing is project
specific, theres no 'generic' symbol stringification solution available.

> > +++ b/buildtools/pmdinfogen/Makefile
> > +#CFLAGS += $(WERROR_FLAGS) -g
> > +CFLAGS += -g
> 
> Please choose one line or the other or none of them.
> 
Oh, thats a debug error, I can fix that.

> > +include $(RTE_SDK)/mk/rte.buildtools.mk
> 
> Why a new Makefile? Can you use rte.hostapp.mk?
> 
I don't know, maybe.  Nothing else currently uses rte.hostapp.mk, so I missed
its existance.  I make the argument that, that being the case, we should stick
with the Makefile I just tested with, and remove the rte.hostapp.mk file


> > +++ b/buildtools/pmdinfogen/pmdinfogen.c
> [...]
> > +	/*
> > + 	 * If this returns NULL, then this is a PMD_VDEV, because
> > + 	 * it has no pci table reference
> > + 	 */
> 
> We can imagine physical PMD not using PCI.
> I think this comment should be removed.
We can, but currently its a true statement.  we have two types of PMDs, a PDEV
and a VDEV, the former is a pci device, and the latter is a virtual device, so
you can imply the PDEV type from the presence of pci entries, and VDEV from the
alternative.  If we were to do something, I would recommend adding a macro to
explicitly ennumerate each pmds type.  I would prefer to wait until that was a
need however, as it can be done invisibly to the user.

> 
> > +	if (!tmpsym) {
> > +		drv->pci_tbl = NULL;
> > +		return 0;
> > +	}
> [...]
> > +
> > +
> > +	return 0;
> > +	
> > +}
> 
> That's a lot of blank lines ;)
> 
My eyes were getting tired :)

> [...]
> > +		fprintf(ofd,"\\\"type\\\" : \\\"%s\\\", ", drv->pci_tbl ? "PMD_PDEV" : "PMD_VDEV");
> 
> Please forget the naming PDEV/VDEV.
> 
I don't know what you mean here, you would rather they be named PCI and Virtual,
or something else?


> [...]
> > +	if (info.drivers) {
> > +		output_pmd_info_string(&info, argv[2]);
> > +		rc = 0;
> > +	} else {
> > +		fprintf(stderr, "Hmm, Appears to be a driver but no drivers registered\n");
> 
> Why it appears to be a driver?
> What means "no drivers registered" exactly?
> 
It means that the tool has identified this file as a driver based on some
criteria (in this case the source code contained a use of the
PMD_REGISTER_DRIVER macro, but for whatever reason, when this tool scanned it,
it never located the pmd_driver_name<n> symbol.  It should never happen, and
serves as a indicator to the developer that they need to investigate either the
construction of the driver or the use of this tool.



> > +++ b/buildtools/pmdinfogen/pmdinfogen.h
> [...]
> > +#define Elf_Ehdr    Elf64_Ehdr
> > +#define Elf_Shdr    Elf64_Shdr
> > +#define Elf_Sym     Elf64_Sym
> > +#define Elf_Addr    Elf64_Addr
> > +#define Elf_Sword   Elf64_Sxword
> > +#define Elf_Section Elf64_Half
> > +#define ELF_ST_BIND ELF64_ST_BIND
> > +#define ELF_ST_TYPE ELF64_ST_TYPE
> > +
> > +#define Elf_Rel     Elf64_Rel
> > +#define Elf_Rela    Elf64_Rela
> > +#define ELF_R_SYM   ELF64_R_SYM
> > +#define ELF_R_TYPE  ELF64_R_TYPE
> 
> Why these defines are needed?
> 
Because I borrowed the code from modpost.c, which allows for both ELF32 and
ELF64 compilation.  I wanted to keep it in place should DPDK ever target
different sized architectures.

> > +#define TO_NATIVE(x) (x)
> 
> Nice :) Why?
> 
Because there is more than intel in the world :).  For alternate endian
machines, this can easily be redefined to accomodate that.


> > +struct rte_pci_id {
> > +	uint16_t vendor_id;           /**< Vendor ID or PCI_ANY_ID. */
> > +	uint16_t device_id;           /**< Device ID or PCI_ANY_ID. */
> > +	uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */
> > +	uint16_t subsystem_device_id; /**< Subsystem device ID or PCI_ANY_ID. */
> > +};
> [...]
> > +struct pmd_driver {
> > +	Elf_Sym *name_sym;
> > +	const char *name;
> > +	struct rte_pci_id *pci_tbl;
> > +	struct pmd_driver *next;
> > +
> > +	const char* opt_vals[PMD_OPT_MAX];
> > +};
> 
> Are you duplicating some structures from EAL?
> It will be out of sync easily.
> 
Only the rte_pci_id, which hasn't changed since the initial public release of
the DPDK.  We can clean this up later if you like, but I'm really not too
worried about it.

> > +struct elf_info {
> > +	unsigned long size;
> > +	Elf_Ehdr     *hdr;
> > +	Elf_Shdr     *sechdrs;
> > +	Elf_Sym      *symtab_start;
> > +	Elf_Sym      *symtab_stop;
> > +	Elf_Section  export_sec;
> > +	Elf_Section  export_unused_sec;
> > +	Elf_Section  export_gpl_sec;
> > +	Elf_Section  export_unused_gpl_sec;
> > +	Elf_Section  export_gpl_future_sec;
> > +	char         *strtab;
> > +	char	     *modinfo;
> > +	unsigned int modinfo_len;
> 
> Why these fields?
> 
Because thats how you parse an ELF file and look up the information you need to
extract the data this tool then exports.  I don't mean to sound short, but your
question doesn't really make any sense.  The members of this structure are
needed to extract the info from object files to build the export strings that
pmdinfo.py needs later.


> > +++ b/mk/rte.buildtools.mk
> 
> This file must be removed I think.
> We are going to be sick after digesting so much makefiles ;)
> 
See above, given that I just tested this, and rte.hostapp.mk isn't used, I'd
recommend deleting the latter, rather than deleting this one and moving to the
old one.

> Last comment,
> The MAINTAINERS file must be updated for this tool.
> 
Yeah, I can do that.

> Thanks for taking care of tooling.
> 
Yup



More information about the dev mailing list