Re: [PATCH v4 03/13] SIW network and RDMA core interface

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

 



On Wed, Jan 30, 2019 at 06:21:26PM +0100, bmt@xxxxxxxxxxxxxx wrote:

> +static int siw_modify_port(struct ib_device *base_dev, u8 port, int mask,
> +			   struct ib_port_modify *props)
> +{
> +	return -EOPNOTSUPP;
> +}

Drivers should not unconditionally return EOPNOTSUPP, just don't set
the ops pointer. For all of these cases.

> +static struct net_device *siw_get_netdev(struct ib_device *base_dev, u8 port)
> +{
> +	struct siw_device *sdev = siw_dev_base2siw(base_dev);
> +
> +	if (!sdev->netdev)
> +		return NULL;
> +
> +	dev_hold(sdev->netdev);
> +
> +	return sdev->netdev;
> +}

Since this is based on my series it should not provid get_netdev, but
use the new set_netdev flow.
> +static void siw_unregistered(struct ib_device *base_dev)
> +{
> +	struct siw_device *sdev = siw_dev_base2siw(base_dev);
> +
> +	siw_device_cleanup(sdev);
> +	siw_device_destroy(sdev);
> +}
> +
> +static struct siw_device *siw_device_create(struct net_device *netdev)
> +{
> +	struct siw_device *sdev;
> +	struct ib_device *base_dev;
> +	struct device *parent = netdev->dev.parent;
> +
> +	sdev = (struct siw_device *)ib_alloc_device(sizeof(*sdev));
> +	if (!sdev)
> +		goto out;
> +
> +	base_dev = &sdev->base_dev;
> +
> +	base_dev->driver_unregister = siw_unregistered;

This is some weird branch this is based on .. This is in ops in the
latest revision  of my series

> +	base_dev->phys_port_cnt = 1;
> +
> +	base_dev->dev.parent = parent;
> +	base_dev->dev.dma_ops = &dma_virt_ops;
> +
> +	base_dev->num_comp_vectors = num_possible_cpus();
> +	base_dev->ops.query_device = siw_query_device;
> +	base_dev->ops.query_port = siw_query_port;
> +	base_dev->ops.get_port_immutable = siw_get_port_immutable;
> +	base_dev->ops.get_netdev = siw_get_netdev;
> +	base_dev->ops.query_qp = siw_query_qp;
> +	base_dev->ops.modify_port = siw_modify_port;
> +	base_dev->ops.query_pkey = siw_query_pkey;
> +	base_dev->ops.query_gid = siw_query_gid;
> +	base_dev->ops.alloc_ucontext = siw_alloc_ucontext;
> +	base_dev->ops.dealloc_ucontext = siw_dealloc_ucontext;
> +	base_dev->ops.mmap = siw_mmap;
> +	base_dev->ops.alloc_pd = siw_alloc_pd;
> +	base_dev->ops.dealloc_pd = siw_dealloc_pd;
> +	base_dev->ops.create_ah = siw_create_ah;
> +	base_dev->ops.destroy_ah = siw_destroy_ah;
> +	base_dev->ops.create_qp = siw_create_qp;
> +	base_dev->ops.modify_qp = siw_verbs_modify_qp;
> +	base_dev->ops.destroy_qp = siw_destroy_qp;
> +	base_dev->ops.create_cq = siw_create_cq;
> +	base_dev->ops.destroy_cq = siw_destroy_cq;
> +	base_dev->ops.resize_cq = NULL;
> +	base_dev->ops.poll_cq = siw_poll_cq;
> +	base_dev->ops.get_dma_mr = siw_get_dma_mr;
> +	base_dev->ops.reg_user_mr = siw_reg_user_mr;
> +	base_dev->ops.dereg_mr = siw_dereg_mr;
> +	base_dev->ops.alloc_mr = siw_alloc_mr;
> +	base_dev->ops.map_mr_sg = siw_map_mr_sg;
> +	base_dev->ops.dealloc_mw = NULL;
> +
> +	base_dev->ops.create_srq = siw_create_srq;
> +	base_dev->ops.modify_srq = siw_modify_srq;
> +	base_dev->ops.query_srq = siw_query_srq;
> +	base_dev->ops.destroy_srq = siw_destroy_srq;
> +	base_dev->ops.post_srq_recv = siw_post_srq_recv;
> +
> +	base_dev->ops.attach_mcast = NULL;
> +	base_dev->ops.detach_mcast = NULL;
> +	base_dev->ops.process_mad = siw_no_mad;
> +
> +	base_dev->ops.req_notify_cq = siw_req_notify_cq;
> +	base_dev->ops.post_send = siw_post_send;
> +	base_dev->ops.post_recv = siw_post_receive;
> +
> +	base_dev->ops.drain_sq = siw_verbs_sq_flush;
> +	base_dev->ops.drain_rq = siw_verbs_rq_flush;

Nope. Use ops properly like all other drivers.

> +static void siw_netdev_unregistered(struct work_struct *work)
> +{
> +	struct siw_device *sdev = container_of(work, struct siw_device,
> +					       netdev_unregister);
> +
> +	struct siw_qp_attrs qp_attrs;
> +	struct list_head *pos, *tmp;
> +
> +	memset(&qp_attrs, 0, sizeof(qp_attrs));
> +	qp_attrs.state = SIW_QP_STATE_ERROR;
> +
> +	/*
> +	 * Mark all current QP's of this device dead
> +	 */
> +	list_for_each_safe(pos, tmp, &sdev->qp_list) {
> +		struct siw_qp *qp = list_entry(pos, struct siw_qp, devq);
> +
> +		down_write(&qp->state_lock);
> +		(void) siw_qp_modify(qp, &qp_attrs, SIW_QP_ATTR_STATE);
> +		up_write(&qp->state_lock);
> +	}

Don't put code around ib_unregister. If you need to do things use a
callback at the right moment in the unregister flow. You might need to
add a callback (see my latest series)

> +	ib_unregister_device_and_put(&sdev->base_dev);

A 'put' probably should not be held into a WQ, this is a good way to
deadlock.

This shared pattern with rxe also needs to move into the core code, I
think.

> +}
> +
> +static int siw_netdev_event(struct notifier_block *nb, unsigned long event,
> +			    void *arg)
> +{
> +	struct net_device	*netdev = netdev_notifier_info_to_dev(arg);
> +	struct siw_device	*sdev;
> +
> +	dev_dbg(&netdev->dev, "siw: event %lu\n", event);
> +
> +	if (dev_net(netdev) != &init_net)
> +		return NOTIFY_OK;
> +
> +	sdev = siw_dev_from_netdev(netdev);

It seems like obfuscation to wrapper ib_device_get_by_netdev() like
this..

> +	pr_info("SoftiWARP attached\n");

Lets not print stuff like this during module load

You should also largely run the whole thing through clang-format

Jason



[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