Re: [RFC 04/20] RDMA/irdma: Add driver framework definitions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2019-09-26 at 20:30 +0300, Leon Romanovsky wrote:
> On Thu, Sep 26, 2019 at 09:45:03AM -0700, Jeff Kirsher wrote:
> > From: Mustafa Ismail <mustafa.ismail@xxxxxxxxx>
> > 
> > Register irdma as a platform driver capable of supporting platform
> > devices from multi-generation RDMA capable Intel HW. Establish the
> > interface with all supported netdev peer devices and initialize HW.
> > 
> > Signed-off-by: Mustafa Ismail <mustafa.ismail@xxxxxxxxx>
> > Signed-off-by: Shiraz Saleem <shiraz.saleem@xxxxxxxxx>
> > Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@xxxxxxxxx>
> > ---
> >  drivers/infiniband/hw/irdma/i40iw_if.c | 270 +++++++++++
> >  drivers/infiniband/hw/irdma/irdma_if.c | 436 +++++++++++++++++
> >  drivers/infiniband/hw/irdma/main.c     | 531 ++++++++++++++++++++
> >  drivers/infiniband/hw/irdma/main.h     | 639
> > +++++++++++++++++++++++++
> >  4 files changed, 1876 insertions(+)
> >  create mode 100644 drivers/infiniband/hw/irdma/i40iw_if.c
> >  create mode 100644 drivers/infiniband/hw/irdma/irdma_if.c
> >  create mode 100644 drivers/infiniband/hw/irdma/main.c
> >  create mode 100644 drivers/infiniband/hw/irdma/main.h
> > 
> > diff --git a/drivers/infiniband/hw/irdma/i40iw_if.c
> > b/drivers/infiniband/hw/irdma/i40iw_if.c
> > new file mode 100644
> > index 000000000000..3cddb091acfb
> > --- /dev/null
> > +++ b/drivers/infiniband/hw/irdma/i40iw_if.c
> > @@ -0,0 +1,270 @@
> > +// SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
> > +/* Copyright (c) 2019, Intel Corporation. */
> > +
> > +#include <linux/module.h>
> > +#include <linux/moduleparam.h>
> > +#include <linux/netdevice.h>
> > +#include <linux/etherdevice.h>
> > +#include <net/addrconf.h>
> > +#include "main.h"
> > +#include "i40iw_hw.h"
> > +#include <linux/net/intel/i40e_client.h>
> > +
> > +/**
> > + * i40iw_request_reset - Request a reset
> > + * @rf: RDMA PCI function
> > + *
> > + */
> > +void i40iw_request_reset(struct irdma_pci_f *rf)
> > +{
> > +	struct i40e_info *ldev = (struct i40e_info *)rf->ldev.if_ldev;
> > +
> > +	ldev->ops->request_reset(ldev, rf->ldev.if_client, 1);
> > +}
> > +
> > +/**
> > + * i40iw_open - client interface operation open for iwarp/uda
> > device
> > + * @ldev: LAN device information
> > + * @client: iwarp client information, provided during registration
> > + *
> > + * Called by the LAN driver during the processing of client
> > register
> > + * Create device resources, set up queues, pble and hmc objects
> > and
> > + * register the device with the ib verbs interface
> > + * Return 0 if successful, otherwise return error
> > + */
> > +static int i40iw_open(struct i40e_info *ldev, struct i40e_client
> > *client)
> > +{
> > +	struct irdma_l2params l2params = {};
> > +	struct irdma_device *iwdev = NULL;
> > +	struct irdma_handler *hdl = NULL;
> > +	struct irdma_priv_ldev *pldev;
> > +	u16 last_qset = IRDMA_NO_QSET;
> > +	struct irdma_sc_dev *dev;
> > +	struct irdma_pci_f *rf;
> > +	int err_code = -EIO;
> > +	u16 qset;
> > +	int i;
> > +
> > +	hdl = irdma_find_handler(ldev->pcidev);
> > +	if (hdl)
> > +		return 0;
> > +
> > +	hdl = kzalloc((sizeof(*hdl) + sizeof(*iwdev)), GFP_KERNEL);
> > +	if (!hdl)
> > +		return -ENOMEM;
> > +
> > +	iwdev = (struct irdma_device *)((u8 *)hdl + sizeof(*hdl));
> > +
> > +	iwdev->param_wq = alloc_ordered_workqueue("l2params",
> > WQ_MEM_RECLAIM);
> > +	if (!iwdev->param_wq)
> > +		goto error;
> > +
> > +	rf = &hdl->rf;
> > +	rf->hdl = hdl;
> > +	dev = &rf->sc_dev;
> > +	dev->back_dev = rf;
> > +	rf->rdma_ver = IRDMA_GEN_1;
> > +	hdl->platform_dev = ldev->platform_dev;
> > +	irdma_init_rf_config_params(rf);
> > +	rf->init_hw = i40iw_init_hw;
> > +	rf->hw.hw_addr = ldev->hw_addr;
> > +	rf->pdev = ldev->pcidev;
> > +	rf->netdev = ldev->netdev;
> > +	dev->pci_rev = rf->pdev->revision;
> > +	iwdev->rf = rf;
> > +	iwdev->hdl = hdl;
> > +	iwdev->ldev = &rf->ldev;
> > +	iwdev->init_state = INITIAL_STATE;
> > +	iwdev->rcv_wnd = IRDMA_CM_DEFAULT_RCV_WND_SCALED;
> > +	iwdev->rcv_wscale = IRDMA_CM_DEFAULT_RCV_WND_SCALE;
> > +	iwdev->netdev = ldev->netdev;
> > +	iwdev->create_ilq = true;
> > +	iwdev->vsi_num = 0;
> > +
> > +	pldev = &rf->ldev;
> > +	hdl->ldev = pldev;
> > +	pldev->if_client = client;
> > +	pldev->if_ldev = ldev;
> > +	pldev->fn_num = ldev->fid;
> > +	pldev->ftype = ldev->ftype;
> > +	pldev->pf_vsi_num = 0;
> > +	pldev->msix_count = ldev->msix_count;
> > +	pldev->msix_entries = ldev->msix_entries;
> > +
> > +	if (irdma_ctrl_init_hw(rf))
> > +		goto error;
> > +
> > +	l2params.mtu =
> > +		(ldev->params.mtu) ? ldev->params.mtu :
> > IRDMA_DEFAULT_MTU;
> > +	for (i = 0; i < I40E_CLIENT_MAX_USER_PRIORITY; i++) {
> > +		qset = ldev->params.qos.prio_qos[i].qs_handle;
> > +		l2params.up2tc[i] = ldev->params.qos.prio_qos[i].tc;
> > +		l2params.qs_handle_list[i] = qset;
> > +		if (last_qset == IRDMA_NO_QSET)
> > +			last_qset = qset;
> > +		else if ((qset != last_qset) && (qset !=
> > IRDMA_NO_QSET))
> > +			iwdev->dcb = true;
> > +	}
> > +
> > +	if (irdma_rt_init_hw(rf, iwdev, &l2params)) {
> > +		irdma_deinit_ctrl_hw(rf);
> > +		goto error;
> > +	}
> > +
> > +	irdma_add_handler(hdl);
> > +	return 0;
> > +error:
> > +	kfree(hdl);
> > +	return err_code;
> > +}
> > +
> > +/**
> > + * i40iw_l2params_worker - worker for l2 params change
> > + * @work: work pointer for l2 params
> > + */
> > +static void i40iw_l2params_worker(struct work_struct *work)
> > +{
> > +	struct l2params_work *dwork =
> > +		container_of(work, struct l2params_work, work);
> > +	struct irdma_device *iwdev = dwork->iwdev;
> > +
> > +	irdma_change_l2params(&iwdev->vsi, &dwork->l2params);
> > +	atomic_dec(&iwdev->params_busy);
> > +	kfree(work);
> > +}
> > +
> > +/**
> > + * i40iw_l2param_change - handle qs handles for QoS and MSS change
> > + * @ldev: LAN device information
> > + * @client: client for parameter change
> > + * @params: new parameters from L2
> > + */
> > +static void i40iw_l2param_change(struct i40e_info *ldev,
> > +				 struct i40e_client *client,
> > +				 struct i40e_params *params)
> > +{
> > +	struct irdma_l2params *l2params;
> > +	struct l2params_work *work;
> > +	struct irdma_device *iwdev;
> > +	struct irdma_handler *hdl;
> > +	int i;
> > +
> > +	hdl = irdma_find_handler(ldev->pcidev);
> > +	if (!hdl)
> > +		return;
> > +
> > +	iwdev = (struct irdma_device *)((u8 *)hdl + sizeof(*hdl));
> > +
> > +	if (atomic_read(&iwdev->params_busy))
> > +		return;
> > +	work = kzalloc(sizeof(*work), GFP_KERNEL);
> > +	if (!work)
> > +		return;
> > +
> > +	atomic_inc(&iwdev->params_busy);
> 
> Changing parameters through workqueue and perform locking with
> atomic_t, exciting.
> Please do proper locking scheme and better to avoid workqueue at all.
> 
> <...>
> 
> > +/* client interface functions */
> > +static const struct i40e_client_ops i40e_ops = {
> > +	.open = i40iw_open,
> > +	.close = i40iw_close,
> > +	.l2_param_change = i40iw_l2param_change
> > +};
> > +
> > +static struct i40e_client i40iw_client = {
> > +	.name = "irdma",
> > +	.ops = &i40e_ops,
> > +	.version.major = I40E_CLIENT_VERSION_MAJOR,
> > +	.version.minor = I40E_CLIENT_VERSION_MINOR,
> > +	.version.build = I40E_CLIENT_VERSION_BUILD,
> > +	.type = I40E_CLIENT_IWARP,
> > +};
> > +
> > +int i40iw_probe(struct platform_device *pdev)
> > +{
> > +	struct i40e_peer_dev_platform_data *pdata =
> > +		dev_get_platdata(&pdev->dev);
> > +	struct i40e_info *ldev;
> > +
> > +	if (!pdata)
> > +		return -EINVAL;
> > +
> > +	ldev = pdata->ldev;
> > +
> > +	if (ldev->version.major != I40E_CLIENT_VERSION_MAJOR ||
> > +	    ldev->version.minor != I40E_CLIENT_VERSION_MINOR) {
> > +		pr_err("version mismatch:\n");
> > +		pr_err("expected major ver %d, caller specified major
> > ver %d\n",
> > +		       I40E_CLIENT_VERSION_MAJOR, ldev->version.major);
> > +		pr_err("expected minor ver %d, caller specified minor
> > ver %d\n",
> > +		       I40E_CLIENT_VERSION_MINOR, ldev->version.minor);
> > +		return -EINVAL;
> > +	}
> 
> This is can't be in upstream code, we don't support out-of-tree
> modules,
> everything else will have proper versions.

Who is the "we" in this context?  I am sure that all the Linux
distributions would strongly disagree with this stance.  Whether or not
you support out-of-tree drivers, they do exist and this code would
ensure that if a "out-of-tree" driver is loaded, the driver will do a
sanity check to ensure the RDMA driver will work.

Attachment: signature.asc
Description: This is a digitally signed message part


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux