[ofa-general][PATCH 8/12 v1] mlx4: Dynamic port configuration

Roland Dreier rdreier at cisco.com
Wed Jun 4 21:20:35 PDT 2008


 > +static int mlx4_change_port_types(struct mlx4_dev *dev,
 > +				  enum mlx4_port_type *port_types)
 > +{
 > +	int i;
 > +	int err = 0;
 > +	int change = 0;
 > +	int port;
 > +
 > +	for (i = 0; i <  MLX4_MAX_PORTS; i++) {
 > +		if (port_types[i] != dev->caps.port_type[i + 1]) {
 > +			change = 1;
 > +			dev->caps.port_type[i + 1] = port_types[i];
 > +		}
 > +	}
 > +	if (change) {
 > +		mlx4_unregister_device(dev);
 > +		for (port = 1; port <= dev->caps.num_ports; port++) {
 > +			mlx4_CLOSE_PORT(dev, port);
 > +			err = mlx4_SET_PORT(dev, port);
 > +			if (err) {
 > +				mlx4_err(dev, "Failed to set port %d, "
 > +					      "aborting\n", port);
 > +				return err;
 > +			}
 > +		}
 > +		err = mlx4_register_device(dev);
 > +	}
 > +	return err;
 > +}

If I read the code correctly, there is no locking around this, so
multiple processes could race and cause all sorts of problems.  And also
you do the assignment

 > +			dev->caps.port_type[i + 1] = port_types[i];

before unregistering the device -- so there is a window where
caps.port_type has the wrong data -- not sure if this is a real issue.

 > +static ssize_t show_port_type(struct device *dev,
 > +			      struct device_attribute *attr,
 > +			      char *buf)
 > +{
 > +	struct pci_dev *pdev = to_pci_dev(dev);
 > +	struct mlx4_dev *mdev = pci_get_drvdata(pdev);
 > +	int i;
 > +
 > +	sprintf(buf, "Current port types:\n");
 > +	for (i = 1; i <= MLX4_MAX_PORTS; i++) {
 > +		sprintf(buf, "%sPort%d: %s\n", buf, i,
 > +			(mdev->caps.port_type[i] == MLX4_PORT_TYPE_IB)?
 > +			"ib": "eth");
 > +	}
 > +	return strlen(buf);
 > +}

This violates the one-value-per-file rule for sysfs if I am reading the
code correctly.

 - R.



More information about the general mailing list