All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tom Rix <trix@redhat.com>
To: Lizhi Hou <lizhi.hou@xilinx.com>, linux-kernel@vger.kernel.org
Cc: linux-fpga@vger.kernel.org, maxz@xilinx.com,
	sonal.santan@xilinx.com, yliu@xilinx.com,
	michal.simek@xilinx.com, stefanos@xilinx.com,
	devicetree@vger.kernel.org, mdf@kernel.org, robh@kernel.org,
	Max Zhen <max.zhen@xilinx.com>
Subject: Re: [PATCH V5 XRT Alveo 05/20] fpga: xrt: group driver
Date: Mon, 3 May 2021 06:10:05 -0700	[thread overview]
Message-ID: <0af9a4ad-5216-05a3-2db5-60f879296baa@redhat.com> (raw)
In-Reply-To: <20210427205431.23896-6-lizhi.hou@xilinx.com>


On 4/27/21 1:54 PM, Lizhi Hou wrote:
> group driver that manages life cycle of a bunch of leaf driver instances
> and bridges them with root.
>
> Signed-off-by: Sonal Santan <sonal.santan@xilinx.com>
> Signed-off-by: Max Zhen <max.zhen@xilinx.com>
> Signed-off-by: Lizhi Hou <lizhi.hou@xilinx.com>
> ---
>   drivers/fpga/xrt/include/group.h |  25 +++
>   drivers/fpga/xrt/lib/group.c     | 278 +++++++++++++++++++++++++++++++
>   2 files changed, 303 insertions(+)
>   create mode 100644 drivers/fpga/xrt/include/group.h
>   create mode 100644 drivers/fpga/xrt/lib/group.c
>
> diff --git a/drivers/fpga/xrt/include/group.h b/drivers/fpga/xrt/include/group.h
> new file mode 100644
> index 000000000000..09e9d03f53fe
> --- /dev/null
> +++ b/drivers/fpga/xrt/include/group.h
> @@ -0,0 +1,25 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2020-2021 Xilinx, Inc.
> + *
> + * Authors:
> + *	Cheng Zhen <maxz@xilinx.com>
> + */
> +
> +#ifndef _XRT_GROUP_H_
> +#define _XRT_GROUP_H_
> +
> +#include "xleaf.h"
> +
> +/*
> + * Group driver leaf calls.
> + */
> +enum xrt_group_leaf_cmd {
> +	XRT_GROUP_GET_LEAF = XRT_XLEAF_CUSTOM_BASE, /* See comments in xleaf.h */
> +	XRT_GROUP_PUT_LEAF,
> +	XRT_GROUP_INIT_CHILDREN,
> +	XRT_GROUP_FINI_CHILDREN,
> +	XRT_GROUP_TRIGGER_EVENT,
> +};
> +
> +#endif	/* _XRT_GROUP_H_ */
> diff --git a/drivers/fpga/xrt/lib/group.c b/drivers/fpga/xrt/lib/group.c
> new file mode 100644
> index 000000000000..b45f05449e0b
> --- /dev/null
> +++ b/drivers/fpga/xrt/lib/group.c
> @@ -0,0 +1,278 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Xilinx Alveo FPGA Group Driver
> + *
> + * Copyright (C) 2020-2021 Xilinx, Inc.
> + *
> + * Authors:
> + *	Cheng Zhen <maxz@xilinx.com>
> + */
> +
> +#include <linux/mod_devicetable.h>
> +#include "xleaf.h"
> +#include "subdev_pool.h"
> +#include "group.h"
> +#include "metadata.h"
> +#include "lib-drv.h"
> +
> +#define XRT_GRP "xrt_group"
> +
> +struct xrt_group {
> +	struct xrt_device *xdev;
> +	struct xrt_subdev_pool leaves;
> +	bool leaves_created;
> +	struct mutex lock; /* lock for group */
> +};
> +
> +static int xrt_grp_root_cb(struct device *dev, void *parg,
> +			   enum xrt_root_cmd cmd, void *arg)
> +{
> +	int rc;
> +	struct xrt_device *xdev =
> +		container_of(dev, struct xrt_device, dev);
> +	struct xrt_group *xg = (struct xrt_group *)parg;
> +
> +	switch (cmd) {
> +	case XRT_ROOT_GET_LEAF_HOLDERS: {
> +		struct xrt_root_get_holders *holders =
> +			(struct xrt_root_get_holders *)arg;
> +		rc = xrt_subdev_pool_get_holders(&xg->leaves,
> +						 holders->xpigh_xdev,
> +						 holders->xpigh_holder_buf,
> +						 holders->xpigh_holder_buf_len);
> +		break;
> +	}
> +	default:
> +		/* Forward parent call to root. */
> +		rc = xrt_subdev_root_request(xdev, cmd, arg);
> +		break;
> +	}
> +
> +	return rc;
> +}
> +
> +/*
> + * Cut subdev's dtb from group's dtb based on passed-in endpoint descriptor.
> + * Return the subdev's dtb through dtbp, if found.
> + */
> +static int xrt_grp_cut_subdev_dtb(struct xrt_group *xg, struct xrt_dev_endpoints *eps,
> +				  char *grp_dtb, char **dtbp)
> +{
> +	int ret, i, ep_count = 0;
> +	char *dtb = NULL;
> +
> +	ret = xrt_md_create(DEV(xg->xdev), &dtb);
> +	if (ret)
> +		return ret;
> +
> +	for (i = 0; eps->xse_names[i].ep_name || eps->xse_names[i].compat; i++) {
> +		const char *ep_name = eps->xse_names[i].ep_name;
> +		const char *compat = eps->xse_names[i].compat;
> +
> +		if (!ep_name)
> +			xrt_md_get_compatible_endpoint(DEV(xg->xdev), grp_dtb, compat, &ep_name);
> +		if (!ep_name)
> +			continue;
> +
> +		ret = xrt_md_copy_endpoint(DEV(xg->xdev), dtb, grp_dtb, ep_name, compat, NULL);
> +		if (ret)
> +			continue;
> +		xrt_md_del_endpoint(DEV(xg->xdev), grp_dtb, ep_name, compat);
> +		ep_count++;
> +	}
> +	/* Found enough endpoints, return the subdev's dtb. */
> +	if (ep_count >= eps->xse_min_ep) {
> +		*dtbp = dtb;
> +		return 0;
> +	}
> +
> +	/* Cleanup - Restore all endpoints that has been deleted, if any. */
> +	if (ep_count > 0) {
> +		xrt_md_copy_endpoint(DEV(xg->xdev), grp_dtb, dtb,
> +				     XRT_MD_NODE_ENDPOINTS, NULL, NULL);
> +	}
> +	vfree(dtb);
> +	*dtbp = NULL;
> +	return 0;
> +}
> +
> +static int xrt_grp_create_leaves(struct xrt_group *xg)
> +{
> +	struct xrt_subdev_platdata *pdata = DEV_PDATA(xg->xdev);
> +	struct xrt_dev_endpoints *eps = NULL;
> +	int ret = 0, failed = 0;
> +	enum xrt_subdev_id did;
> +	char *grp_dtb = NULL;
> +	unsigned long mlen;
> +
> +	if (!pdata)
> +		return -EINVAL;
> +
> +	mlen = xrt_md_size(DEV(xg->xdev), pdata->xsp_dtb);
> +	if (mlen == XRT_MD_INVALID_LENGTH) {
> +		xrt_err(xg->xdev, "invalid dtb, len %ld", mlen);
> +		return -EINVAL;
> +	}
> +
> +	mutex_lock(&xg->lock);
> +
> +	if (xg->leaves_created) {
> +		/*
> +		 * This is expected since caller does not keep track of the state of the group
> +		 * and may, in some cases, still try to create leaves after it has already been
> +		 * created. This special error code will let the caller know what is going on.
> +		 */

ok

Reviewed-by: Tom Rix <trix@redhat.com>

> +		mutex_unlock(&xg->lock);
> +		return -EEXIST;
> +	}
> +
> +	grp_dtb = vmalloc(mlen);
> +	if (!grp_dtb) {
> +		mutex_unlock(&xg->lock);
> +		return -ENOMEM;
> +	}
> +
> +	/* Create all leaves based on dtb. */
> +	xrt_info(xg->xdev, "bringing up leaves...");
> +	memcpy(grp_dtb, pdata->xsp_dtb, mlen);
> +	for (did = 0; did < XRT_SUBDEV_NUM; did++) {
> +		eps = xrt_drv_get_endpoints(did);
> +		while (eps && eps->xse_names) {
> +			char *dtb = NULL;
> +
> +			ret = xrt_grp_cut_subdev_dtb(xg, eps, grp_dtb, &dtb);
> +			if (ret) {
> +				failed++;
> +				xrt_err(xg->xdev, "failed to cut subdev dtb for drv %s: %d",
> +					xrt_drv_name(did), ret);
> +			}
> +			if (!dtb) {
> +				/*
> +				 * No more dtb to cut or bad things happened for this instance,
> +				 * switch to the next one.
> +				 */
> +				eps++;
> +				continue;
> +			}
> +
> +			/* Found a dtb for this instance, let's add it. */
> +			ret = xrt_subdev_pool_add(&xg->leaves, did, xrt_grp_root_cb, xg, dtb);
> +			if (ret < 0) {
> +				/*
> +				 * It is not a fatal error here. Some functionality is not usable
> +				 * due to this missing device, but the error can be handled
> +				 * when the functionality is used.
ok
> +				 */
> +				failed++;
> +				xrt_err(xg->xdev, "failed to add %s: %d", xrt_drv_name(did), ret);
> +			}
> +			vfree(dtb);
> +			/* Continue searching for the same instance from grp_dtb. */
> +		}
> +	}
> +
> +	xg->leaves_created = true;
> +	vfree(grp_dtb);
> +	mutex_unlock(&xg->lock);
> +	return failed == 0 ? 0 : -ECHILD;
> +}
> +
> +static void xrt_grp_remove_leaves(struct xrt_group *xg)
> +{
> +	mutex_lock(&xg->lock);
> +
> +	if (!xg->leaves_created) {
> +		mutex_unlock(&xg->lock);
> +		return;
> +	}
> +
> +	xrt_info(xg->xdev, "tearing down leaves...");
> +	xrt_subdev_pool_fini(&xg->leaves);
> +	xg->leaves_created = false;
> +
> +	mutex_unlock(&xg->lock);
> +}
> +
> +static int xrt_grp_probe(struct xrt_device *xdev)
> +{
> +	struct xrt_group *xg;
> +
> +	xrt_info(xdev, "probing...");
> +
> +	xg = devm_kzalloc(&xdev->dev, sizeof(*xg), GFP_KERNEL);
> +	if (!xg)
> +		return -ENOMEM;
> +
> +	xg->xdev = xdev;
> +	mutex_init(&xg->lock);
> +	xrt_subdev_pool_init(DEV(xdev), &xg->leaves);
> +	xrt_set_drvdata(xdev, xg);
> +
> +	return 0;
> +}
> +
> +static void xrt_grp_remove(struct xrt_device *xdev)
> +{
> +	struct xrt_group *xg = xrt_get_drvdata(xdev);
> +
> +	xrt_info(xdev, "leaving...");
> +	xrt_grp_remove_leaves(xg);
> +}
> +
> +static int xrt_grp_leaf_call(struct xrt_device *xdev, u32 cmd, void *arg)
> +{
> +	int rc = 0;
> +	struct xrt_group *xg = xrt_get_drvdata(xdev);
> +
> +	switch (cmd) {
> +	case XRT_XLEAF_EVENT:
> +		/* Simply forward to every child. */
> +		xrt_subdev_pool_handle_event(&xg->leaves,
> +					     (struct xrt_event *)arg);
> +		break;
> +	case XRT_GROUP_GET_LEAF: {
> +		struct xrt_root_get_leaf *get_leaf =
> +			(struct xrt_root_get_leaf *)arg;
> +
> +		rc = xrt_subdev_pool_get(&xg->leaves, get_leaf->xpigl_match_cb,
> +					 get_leaf->xpigl_match_arg,
> +					 DEV(get_leaf->xpigl_caller_xdev),
> +					 &get_leaf->xpigl_tgt_xdev);
> +		break;
> +	}
> +	case XRT_GROUP_PUT_LEAF: {
> +		struct xrt_root_put_leaf *put_leaf =
> +			(struct xrt_root_put_leaf *)arg;
> +
> +		rc = xrt_subdev_pool_put(&xg->leaves, put_leaf->xpipl_tgt_xdev,
> +					 DEV(put_leaf->xpipl_caller_xdev));
> +		break;
> +	}
> +	case XRT_GROUP_INIT_CHILDREN:
> +		rc = xrt_grp_create_leaves(xg);
> +		break;
> +	case XRT_GROUP_FINI_CHILDREN:
> +		xrt_grp_remove_leaves(xg);
> +		break;
> +	case XRT_GROUP_TRIGGER_EVENT:
> +		xrt_subdev_pool_trigger_event(&xg->leaves, (enum xrt_events)(uintptr_t)arg);
> +		break;
> +	default:
> +		xrt_err(xdev, "unknown IOCTL cmd %d", cmd);
> +		rc = -EINVAL;
> +		break;
> +	}
> +	return rc;
> +}
> +
> +static struct xrt_driver xrt_group_driver = {
> +	.driver	= {
> +		.name    = XRT_GRP,
> +	},
> +	.subdev_id = XRT_SUBDEV_GRP,
> +	.probe = xrt_grp_probe,
> +	.remove = xrt_grp_remove,
> +	.leaf_call = xrt_grp_leaf_call,
> +};
> +
> +XRT_LEAF_INIT_FINI_FUNC(group);


  reply	other threads:[~2021-05-03 13:10 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-27 20:54 [PATCH V5 XRT Alveo 00/20] XRT Alveo driver overview Lizhi Hou
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 01/20] Documentation: fpga: Add a document describing XRT Alveo drivers Lizhi Hou
2021-04-28 19:40   ` Tom Rix
2021-05-03 23:00   ` Moritz Fischer
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 02/20] fpga: xrt: driver metadata helper functions Lizhi Hou
2021-05-01 20:19   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 03/20] fpga: xrt: xclbin file " Lizhi Hou
2021-05-03 13:00   ` Tom Rix
2021-05-03 23:19   ` Moritz Fischer
2021-05-05 17:21     ` Lizhi Hou
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 04/20] fpga: xrt: xrt-lib driver manager Lizhi Hou
2021-05-03 13:06   ` Tom Rix
2021-05-03 21:51     ` Lizhi Hou
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 05/20] fpga: xrt: group driver Lizhi Hou
2021-05-03 13:10   ` Tom Rix [this message]
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 06/20] fpga: xrt: char dev node helper functions Lizhi Hou
2021-05-03 13:27   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 07/20] fpga: xrt: root driver infrastructure Lizhi Hou
2021-05-03 13:37   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 08/20] fpga: xrt: " Lizhi Hou
2021-05-03 13:46   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 09/20] fpga: xrt: management physical function driver (root) Lizhi Hou
2021-05-03 13:49   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 10/20] fpga: xrt: main driver for management function device Lizhi Hou
2021-05-04 13:50   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 11/20] fpga: xrt: fpga-mgr and region implementation for xclbin download Lizhi Hou
2021-05-04 13:56   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 12/20] fpga: xrt: VSEC driver Lizhi Hou
2021-05-04 14:00   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 13/20] fpga: xrt: User Clock Subsystem driver Lizhi Hou
2021-05-04 14:03   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 14/20] fpga: xrt: ICAP driver Lizhi Hou
2021-05-04 14:05   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 15/20] fpga: xrt: devctl xrt driver Lizhi Hou
2021-05-04 14:07   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 16/20] fpga: xrt: clock driver Lizhi Hou
2021-05-04 14:08   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 17/20] fpga: xrt: clock frequency counter driver Lizhi Hou
2021-05-04 14:10   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 18/20] fpga: xrt: DDR calibration driver Lizhi Hou
2021-05-04 14:11   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 19/20] fpga: xrt: partition isolation driver Lizhi Hou
2021-05-04 14:13   ` Tom Rix
2021-04-27 20:54 ` [PATCH V5 XRT Alveo 20/20] fpga: xrt: Kconfig and Makefile updates for XRT drivers Lizhi Hou
2021-04-27 23:53   ` kernel test robot
2021-04-27 23:53     ` kernel test robot
2021-04-28  3:12   ` kernel test robot
2021-04-28  3:12     ` kernel test robot
2021-04-28  3:12   ` [RFC PATCH] fpga: xrt: xmgnt_bridge_ops can be static kernel test robot
2021-04-28  3:12     ` kernel test robot
2021-05-04 14:18   ` [PATCH V5 XRT Alveo 20/20] fpga: xrt: Kconfig and Makefile updates for XRT drivers Tom Rix
2021-04-28 17:36 ` [PATCH V5 XRT Alveo 00/20] XRT Alveo driver overview Tom Rix

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0af9a4ad-5216-05a3-2db5-60f879296baa@redhat.com \
    --to=trix@redhat.com \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-fpga@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizhi.hou@xilinx.com \
    --cc=max.zhen@xilinx.com \
    --cc=maxz@xilinx.com \
    --cc=mdf@kernel.org \
    --cc=michal.simek@xilinx.com \
    --cc=robh@kernel.org \
    --cc=sonal.santan@xilinx.com \
    --cc=stefanos@xilinx.com \
    --cc=yliu@xilinx.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.