From nobody@FreeBSD.org  Wed Jun 26 09:57:35 2013
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1])
	by hub.freebsd.org (Postfix) with ESMTP id A6A637C
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 26 Jun 2013 09:57:35 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from oldred.freebsd.org (oldred.freebsd.org [8.8.178.121])
	by mx1.freebsd.org (Postfix) with ESMTP id 7EA031AF7
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 26 Jun 2013 09:57:35 +0000 (UTC)
Received: from oldred.freebsd.org ([127.0.1.6])
	by oldred.freebsd.org (8.14.5/8.14.7) with ESMTP id r5Q9vZLk021688
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 26 Jun 2013 09:57:35 GMT
	(envelope-from nobody@oldred.freebsd.org)
Received: (from nobody@localhost)
	by oldred.freebsd.org (8.14.5/8.14.5/Submit) id r5Q9vZ5e021687;
	Wed, 26 Jun 2013 09:57:35 GMT
	(envelope-from nobody)
Message-Id: <201306260957.r5Q9vZ5e021687@oldred.freebsd.org>
Date: Wed, 26 Jun 2013 09:57:35 GMT
From: Shahar Klein <shahark@mellanox.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Bug assigning HCA from IB to ETH
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         179999
>Category:       kern
>Synopsis:       [ofed] [patch] Bug assigning HCA from IB to ETH
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    jhb
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jun 26 10:00:01 UTC 2013
>Closed-Date:    Wed Aug 07 18:01:08 UTC 2013
>Last-Modified:  Wed Aug 07 18:01:08 UTC 2013
>Originator:     Shahar Klein
>Release:        9.1
>Organization:
Mellanox
>Environment:
FreeBSD alf10 9.1-RELEASE FreeBSD 9.1-RELEASE #0 r243825: Tue Dec  4 09:23:10 UTC 2012     root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64
>Description:
The Mellanox HCA ConnectX3 can work in IB mode or ETH mode. It comes defauled to IB and assigning to ETH is done via sysctl:
sys.device.mlx4_core0.mlx4_port1 = desired_mode
 This operation, when trying to assign eth mode, currently fails with:
sysctl: sys.device.mlx4_core0.mlx4_port1: Invalid argument
>How-To-Repeat:
sys.device.mlx4_core0.mlx4_port1 = eth
>Fix:
diff -ur sysA/ofed/drivers/net/mlx4/main.c sysB/ofed/drivers/net/mlx4/main.c
--- sysA/ofed/drivers/net/mlx4/main.c   2013-06-26 12:50:46.000000000 +0300
+++ sysB/ofed/drivers/net/mlx4/main.c   2013-06-26 12:51:15.000000000 +0300
@@ -479,11 +479,11 @@
        int i;
        int err = 0;

-       if (!strcmp(buf, "ib\n"))
+       if (!strcmp(buf, "ib"))
                info->tmp_type = MLX4_PORT_TYPE_IB;
-       else if (!strcmp(buf, "eth\n"))
+       else if (!strcmp(buf, "eth"))
                info->tmp_type = MLX4_PORT_TYPE_ETH;
-       else if (!strcmp(buf, "auto\n"))
+       else if (!strcmp(buf, "auto"))
                info->tmp_type = MLX4_PORT_TYPE_AUTO;
        else {
                mlx4_err(mdev, "%s is not supported port type\n", buf);
diff -ur sysA/ofed/include/linux/sysfs.h sysB/ofed/include/linux/sysfs.h
--- sysA/ofed/include/linux/sysfs.h     2013-06-26 12:50:47.000000000 +0300
+++ sysB/ofed/include/linux/sysfs.h     2013-06-26 12:52:24.000000000 +0300
@@ -104,7 +104,9 @@
        error = SYSCTL_OUT(req, buf, len);
        if (error || !req->newptr || ops->store == NULL)
                goto out;
-       error = SYSCTL_IN(req, buf, PAGE_SIZE);
+        len = req->newlen - req->newidx;
+        error = SYSCTL_IN(req, buf, len);
+        ((char *)buf)[len] = '\0';
        if (error)
                goto out;
        len = ops->store(kobj, attr, buf, req->newlen);


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Wed Jun 26 23:10:19 UTC 2013 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=179999 

From: John Baldwin <jhb@freebsd.org>
To: bug-followup@freebsd.org,
 shahark@mellanox.com
Cc:  
Subject: Re: kern/179999: [ofed] [patch] Bug assigning HCA from IB to ETH
Date: Thu, 27 Jun 2013 14:10:42 -0400

 Thanks, I think the sysfs fix has a few issues though (it writes to buf[] even 
 if the copyin() fails, and it doesn't enforce a bounds check).  It does seem 
 that this should probably be using sysctl_handle_string() instead of doing it 
 by hand, but for now I've just adjusted your patch.  Can you please test this 
 version?
 
 Index: ofed/drivers/net/mlx4/main.c
 ===================================================================
 --- ofed/drivers/net/mlx4/main.c	(revision 252306)
 +++ ofed/drivers/net/mlx4/main.c	(working copy)
 @@ -479,11 +479,11 @@
  	int i;
  	int err = 0;
  
 -	if (!strcmp(buf, "ib\n"))
 +	if (!strcmp(buf, "ib"))
  		info->tmp_type = MLX4_PORT_TYPE_IB;
 -	else if (!strcmp(buf, "eth\n"))
 +	else if (!strcmp(buf, "eth"))
  		info->tmp_type = MLX4_PORT_TYPE_ETH;
 -	else if (!strcmp(buf, "auto\n"))
 +	else if (!strcmp(buf, "auto"))
  		info->tmp_type = MLX4_PORT_TYPE_AUTO;
  	else {
  		mlx4_err(mdev, "%s is not supported port type\n", buf);
 Index: ofed/include/linux/sysfs.h
 ===================================================================
 --- ofed/include/linux/sysfs.h	(revision 252306)
 +++ ofed/include/linux/sysfs.h	(working copy)
 @@ -104,10 +104,15 @@
  	error = SYSCTL_OUT(req, buf, len);
  	if (error || !req->newptr || ops->store == NULL)
  		goto out;
 -	error = SYSCTL_IN(req, buf, PAGE_SIZE);
 +	len = req->newlen - req->newidx;
 +	if (len >= PAGE_SIZE)
 +		error = EINVAL;
 +	else 
 +		error = SYSCTL_IN(req, buf, len);
  	if (error)
  		goto out;
 -	len = ops->store(kobj, attr, buf, req->newlen);
 +	((char *)buf)[len] = '\0';
 +	len = ops->store(kobj, attr, buf, len);
  	if (len < 0)
  		error = -len;
  out:
 
 -- 
 John Baldwin

From: Shahar Klein <shahark@mellanox.com>
To: John Baldwin <jhb@freebsd.org>, "bug-followup@freebsd.org"
	<bug-followup@freebsd.org>
Cc: Orit Moskovich <oritm@mellanox.com>, Oded Shanoon <odeds@mellanox.com>
Subject: RE: kern/179999: [ofed] [patch] Bug assigning HCA from IB to ETH
Date: Thu, 4 Jul 2013 12:34:09 +0000

 Thanks John
 
 I've tested this version and it works fine.
 
 
 Shahar Klein
 
 -----Original Message-----
 From: John Baldwin [mailto:jhb@freebsd.org]=20
 Sent: Friday, June 28, 2013 12:20 AM
 To: bug-followup@freebsd.org; Shahar Klein
 Subject: Re: kern/179999: [ofed] [patch] Bug assigning HCA from IB to ETH
 
 Thanks, I think the sysfs fix has a few issues though (it writes to buf[] e=
 ven if the copyin() fails, and it doesn't enforce a bounds check).  It does=
  seem that this should probably be using sysctl_handle_string() instead of =
 doing it by hand, but for now I've just adjusted your patch.  Can you pleas=
 e test this version?
 
 Index: ofed/drivers/net/mlx4/main.c
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 --- ofed/drivers/net/mlx4/main.c	(revision 252306)
 +++ ofed/drivers/net/mlx4/main.c	(working copy)
 @@ -479,11 +479,11 @@
  	int i;
  	int err =3D 0;
 =20
 -	if (!strcmp(buf, "ib\n"))
 +	if (!strcmp(buf, "ib"))
  		info->tmp_type =3D MLX4_PORT_TYPE_IB;
 -	else if (!strcmp(buf, "eth\n"))
 +	else if (!strcmp(buf, "eth"))
  		info->tmp_type =3D MLX4_PORT_TYPE_ETH;
 -	else if (!strcmp(buf, "auto\n"))
 +	else if (!strcmp(buf, "auto"))
  		info->tmp_type =3D MLX4_PORT_TYPE_AUTO;
  	else {
  		mlx4_err(mdev, "%s is not supported port type\n", buf);
 Index: ofed/include/linux/sysfs.h
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 --- ofed/include/linux/sysfs.h	(revision 252306)
 +++ ofed/include/linux/sysfs.h	(working copy)
 @@ -104,10 +104,15 @@
  	error =3D SYSCTL_OUT(req, buf, len);
  	if (error || !req->newptr || ops->store =3D=3D NULL)
  		goto out;
 -	error =3D SYSCTL_IN(req, buf, PAGE_SIZE);
 +	len =3D req->newlen - req->newidx;
 +	if (len >=3D PAGE_SIZE)
 +		error =3D EINVAL;
 +	else=20
 +		error =3D SYSCTL_IN(req, buf, len);
  	if (error)
  		goto out;
 -	len =3D ops->store(kobj, attr, buf, req->newlen);
 +	((char *)buf)[len] =3D '\0';
 +	len =3D ops->store(kobj, attr, buf, len);
  	if (len < 0)
  		error =3D -len;
  out:
 
 --
 John Baldwin
State-Changed-From-To: open->patched 
State-Changed-By: jhb 
State-Changed-When: Mon Jul 8 21:25:21 UTC 2013 
State-Changed-Why:  
Fix applied to HEAD.  Thanks! 


Responsible-Changed-From-To: freebsd-net->jhb 
Responsible-Changed-By: jhb 
Responsible-Changed-When: Mon Jul 8 21:25:21 UTC 2013 
Responsible-Changed-Why:  
Fix applied to HEAD.  Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=179999 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/179999: commit references a PR
Date: Mon,  8 Jul 2013 21:25:20 +0000 (UTC)

 Author: jhb
 Date: Mon Jul  8 21:25:12 2013
 New Revision: 253048
 URL: http://svnweb.freebsd.org/changeset/base/253048
 
 Log:
   Allow mlx4 devices to switch from Ethernet to Infiniband (and vice versa):
   - Fix sysctl wrapper for sysfs attributes to properly handle new string
     values similar to sysctl_handle_string() (only copyin the user's
     supplied length and nul-terminate the string).
   - Don't check for a trailing newline when evaluating the desired operating
     mode of a mlx4 device.
   
   PR:		kern/179999
   Submitted by:	Shahar Klein <shahark@mellanox.com>
   MFC after:	1 week
 
 Modified:
   head/sys/ofed/drivers/net/mlx4/main.c
   head/sys/ofed/include/linux/sysfs.h
 
 Modified: head/sys/ofed/drivers/net/mlx4/main.c
 ==============================================================================
 --- head/sys/ofed/drivers/net/mlx4/main.c	Mon Jul  8 21:17:20 2013	(r253047)
 +++ head/sys/ofed/drivers/net/mlx4/main.c	Mon Jul  8 21:25:12 2013	(r253048)
 @@ -479,11 +479,11 @@ static ssize_t set_port_type(struct devi
  	int i;
  	int err = 0;
  
 -	if (!strcmp(buf, "ib\n"))
 +	if (!strcmp(buf, "ib"))
  		info->tmp_type = MLX4_PORT_TYPE_IB;
 -	else if (!strcmp(buf, "eth\n"))
 +	else if (!strcmp(buf, "eth"))
  		info->tmp_type = MLX4_PORT_TYPE_ETH;
 -	else if (!strcmp(buf, "auto\n"))
 +	else if (!strcmp(buf, "auto"))
  		info->tmp_type = MLX4_PORT_TYPE_AUTO;
  	else {
  		mlx4_err(mdev, "%s is not supported port type\n", buf);
 
 Modified: head/sys/ofed/include/linux/sysfs.h
 ==============================================================================
 --- head/sys/ofed/include/linux/sysfs.h	Mon Jul  8 21:17:20 2013	(r253047)
 +++ head/sys/ofed/include/linux/sysfs.h	Mon Jul  8 21:25:12 2013	(r253048)
 @@ -104,10 +104,15 @@ sysctl_handle_attr(SYSCTL_HANDLER_ARGS)
  	error = SYSCTL_OUT(req, buf, len);
  	if (error || !req->newptr || ops->store == NULL)
  		goto out;
 -	error = SYSCTL_IN(req, buf, PAGE_SIZE);
 +	len = req->newlen - req->newidx;
 +	if (len >= PAGE_SIZE)
 +		error = EINVAL;
 +	else 
 +		error = SYSCTL_IN(req, buf, len);
  	if (error)
  		goto out;
 -	len = ops->store(kobj, attr, buf, req->newlen);
 +	((char *)buf)[len] = '\0';
 +	len = ops->store(kobj, attr, buf, len);
  	if (len < 0)
  		error = -len;
  out:
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/179999: commit references a PR
Date: Tue,  6 Aug 2013 19:24:21 +0000 (UTC)

 Author: jhb
 Date: Tue Aug  6 19:23:57 2013
 New Revision: 254006
 URL: http://svnweb.freebsd.org/changeset/base/254006
 
 Log:
   MFC 253048,253423,253449,253653,253774,253785:
   - Allow mlx4 devices to switch between Ethernet and Infiniband:
     - Fix sysfs attribute handling by using sysctl_handle_string() and
       properly handling trailing newlines in attribute values.
     - Remove check forbidding requests that would result in one port being
       set to Ethernet and the subsequent port being set to IB.
   - Avoid trashing IP fragments by correctly managing hardware checksumming.
   - Fix panics when downing or unloading the mlx4 driver.
   
   PR:		kern/179999, kern/174213, kern/180430, kern/180791
 
 Modified:
   stable/9/sys/ofed/drivers/net/mlx4/en_netdev.c
   stable/9/sys/ofed/drivers/net/mlx4/en_tx.c
   stable/9/sys/ofed/drivers/net/mlx4/main.c
   stable/9/sys/ofed/include/linux/sysfs.h
 Directory Properties:
   stable/9/sys/   (props changed)
 
 Modified: stable/9/sys/ofed/drivers/net/mlx4/en_netdev.c
 ==============================================================================
 --- stable/9/sys/ofed/drivers/net/mlx4/en_netdev.c	Tue Aug  6 19:14:02 2013	(r254005)
 +++ stable/9/sys/ofed/drivers/net/mlx4/en_netdev.c	Tue Aug  6 19:23:57 2013	(r254006)
 @@ -43,6 +43,7 @@
  #include <net/if_vlan_var.h>
  #include <sys/sockio.h>
  
 +static void mlx4_en_init_locked(struct mlx4_en_priv *priv);
  static void mlx4_en_sysctl_stat(struct mlx4_en_priv *priv);
  
  static void mlx4_en_vlan_rx_add_vid(void *arg, struct net_device *dev, u16 vid)
 @@ -495,11 +496,6 @@ static void mlx4_en_do_get_stats(struct 
  
  		queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
  	}
 -	if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
 -		panic("mlx4_en_do_get_stats: Unexpected mac removed for %d\n",
 -		    priv->port);
 -		mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
 -	}
  	mutex_unlock(&mdev->state_lock);
  }
  
 @@ -688,8 +684,8 @@ int mlx4_en_start_port(struct net_device
  	mlx4_en_set_multicast(dev);
  
  	/* Enable the queues. */
 -	atomic_clear_int(&dev->if_drv_flags, IFF_DRV_OACTIVE);
 -	atomic_set_int(&dev->if_drv_flags, IFF_DRV_RUNNING);
 +	dev->if_drv_flags &= ~IFF_DRV_OACTIVE;
 +	dev->if_drv_flags |= IFF_DRV_RUNNING;
  
  	callout_reset(&priv->watchdog_timer, MLX4_EN_WATCHDOG_TIMEOUT,
  	    mlx4_en_watchdog_timeout, priv);
 @@ -761,7 +757,7 @@ void mlx4_en_stop_port(struct net_device
  
  	callout_stop(&priv->watchdog_timer);
  
 -	atomic_clear_int(&dev->if_drv_flags, IFF_DRV_RUNNING);
 +	dev->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
  }
  
  static void mlx4_en_restart(struct work_struct *work)
 @@ -802,19 +798,30 @@ mlx4_en_init(void *arg)
  {
  	struct mlx4_en_priv *priv;
  	struct mlx4_en_dev *mdev;
 +
 +	priv = arg;
 +	mdev = priv->mdev;
 +	mutex_lock(&mdev->state_lock);
 +	mlx4_en_init_locked(priv);
 +	mutex_unlock(&mdev->state_lock);
 +}
 +
 +static void
 +mlx4_en_init_locked(struct mlx4_en_priv *priv)
 +{
 +
 +	struct mlx4_en_dev *mdev;
  	struct ifnet *dev;
  	int i;
  
 -	priv = arg;
  	dev = priv->dev;
  	mdev = priv->mdev;
 -	mutex_lock(&mdev->state_lock);
  	if (dev->if_drv_flags & IFF_DRV_RUNNING)
  		mlx4_en_stop_port(dev);
  
  	if (!mdev->device_up) {
  		en_err(priv, "Cannot open - device down/disabled\n");
 -		goto out;
 +		return;
  	}
  
  	/* Reset HW statistics and performance counters */
 @@ -835,9 +842,6 @@ mlx4_en_init(void *arg)
  	mlx4_en_set_default_moderation(priv);
  	if (mlx4_en_start_port(dev))
  		en_err(priv, "Failed starting port:%d\n", priv->port);
 -
 -out:
 -	mutex_unlock(&mdev->state_lock);
  }
  
  void mlx4_en_free_resources(struct mlx4_en_priv *priv)
 @@ -927,9 +931,14 @@ void mlx4_en_destroy_netdev(struct net_d
  	if (priv->sysctl)
  		sysctl_ctx_free(&priv->conf_ctx);
  
 +	mutex_lock(&mdev->state_lock);
 +	mlx4_en_stop_port(dev);
 +	mutex_unlock(&mdev->state_lock);
 +
  	cancel_delayed_work(&priv->stats_task);
  	/* flush any pending task for this netdev */
  	flush_workqueue(mdev->workqueue);
 +	callout_drain(&priv->watchdog_timer);
  
  	/* Detach the netdev so tasks would not attempt to access it */
  	mutex_lock(&mdev->state_lock);
 @@ -1091,31 +1100,32 @@ static int mlx4_en_ioctl(struct ifnet *d
  		error = -mlx4_en_change_mtu(dev, ifr->ifr_mtu);
  		break;
  	case SIOCSIFFLAGS:
 +		mutex_lock(&mdev->state_lock);
  		if (dev->if_flags & IFF_UP) {
 -			if ((dev->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 -				mutex_lock(&mdev->state_lock);
 +			if ((dev->if_drv_flags & IFF_DRV_RUNNING) == 0)
  				mlx4_en_start_port(dev);
 -				mutex_unlock(&mdev->state_lock);
 -			} else
 +			else
  				mlx4_en_set_multicast(dev);
  		} else {
 -			mutex_lock(&mdev->state_lock);
  			if (dev->if_drv_flags & IFF_DRV_RUNNING) {
  				mlx4_en_stop_port(dev);
  				if_link_state_change(dev, LINK_STATE_DOWN);
  			}
 -			mutex_unlock(&mdev->state_lock);
  		}
 +		mutex_unlock(&mdev->state_lock);
  		break;
  	case SIOCADDMULTI:
  	case SIOCDELMULTI:
 +		mutex_lock(&mdev->state_lock);
  		mlx4_en_set_multicast(dev);
 +		mutex_unlock(&mdev->state_lock);
  		break;
  	case SIOCSIFMEDIA:
  	case SIOCGIFMEDIA:
  		error = ifmedia_ioctl(dev, ifr, &priv->media, command);
  		break;
  	case SIOCSIFCAP:
 +		mutex_lock(&mdev->state_lock);
  		mask = ifr->ifr_reqcap ^ dev->if_capenable;
  		if (mask & IFCAP_HWCSUM)
  			dev->if_capenable ^= IFCAP_HWCSUM;
 @@ -1130,7 +1140,8 @@ static int mlx4_en_ioctl(struct ifnet *d
  		if (mask & IFCAP_WOL_MAGIC)
  			dev->if_capenable ^= IFCAP_WOL_MAGIC;
  		if (dev->if_drv_flags & IFF_DRV_RUNNING)
 -			mlx4_en_init(priv);
 +			mlx4_en_init_locked(priv);
 +		mutex_unlock(&mdev->state_lock);
  		VLAN_CAPABILITIES(dev);
  		break;
  	default:
 
 Modified: stable/9/sys/ofed/drivers/net/mlx4/en_tx.c
 ==============================================================================
 --- stable/9/sys/ofed/drivers/net/mlx4/en_tx.c	Tue Aug  6 19:14:02 2013	(r254005)
 +++ stable/9/sys/ofed/drivers/net/mlx4/en_tx.c	Tue Aug  6 19:23:57 2013	(r254006)
 @@ -780,8 +780,12 @@ retry:
  	tx_desc->ctrl.srcrb_flags = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE |
  						MLX4_WQE_CTRL_SOLICITED);
  	if (mb->m_pkthdr.csum_flags & (CSUM_IP|CSUM_TCP|CSUM_UDP)) {
 -		tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
 -							 MLX4_WQE_CTRL_TCP_UDP_CSUM);
 +		if (mb->m_pkthdr.csum_flags & CSUM_IP)
 +			tx_desc->ctrl.srcrb_flags |=
 +			    cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM);
 +		if (mb->m_pkthdr.csum_flags & (CSUM_TCP|CSUM_UDP))
 +			tx_desc->ctrl.srcrb_flags |=
 +			    cpu_to_be32(MLX4_WQE_CTRL_TCP_UDP_CSUM);
  		priv->port_stats.tx_chksum_offload++;
  	}
  
 
 Modified: stable/9/sys/ofed/drivers/net/mlx4/main.c
 ==============================================================================
 --- stable/9/sys/ofed/drivers/net/mlx4/main.c	Tue Aug  6 19:14:02 2013	(r254005)
 +++ stable/9/sys/ofed/drivers/net/mlx4/main.c	Tue Aug  6 19:23:57 2013	(r254006)
 @@ -209,9 +209,6 @@ int mlx4_check_port_params(struct mlx4_d
  					 "on this HCA, aborting.\n");
  				return -EINVAL;
  			}
 -			if (port_type[i] == MLX4_PORT_TYPE_ETH &&
 -			    port_type[i + 1] == MLX4_PORT_TYPE_IB)
 -				return -EINVAL;
  		}
  	}
  
 
 Modified: stable/9/sys/ofed/include/linux/sysfs.h
 ==============================================================================
 --- stable/9/sys/ofed/include/linux/sysfs.h	Tue Aug  6 19:14:02 2013	(r254005)
 +++ stable/9/sys/ofed/include/linux/sysfs.h	Tue Aug  6 19:23:57 2013	(r254006)
 @@ -75,39 +75,42 @@ sysctl_handle_attr(SYSCTL_HANDLER_ARGS)
  	struct kobject *kobj;
  	struct attribute *attr;
  	const struct sysfs_ops *ops;
 -	void *buf;
 +	char *buf;
  	int error;
  	ssize_t len;
  
  	kobj = arg1;
  	attr = (struct attribute *)arg2;
 -	buf = (void *)get_zeroed_page(GFP_KERNEL);
 -	len = 1;	/* Copy out a NULL byte at least. */
  	if (kobj->ktype == NULL || kobj->ktype->sysfs_ops == NULL)
  		return (ENODEV);
 -	ops = kobj->ktype->sysfs_ops;
 +	buf = (char *)get_zeroed_page(GFP_KERNEL);
  	if (buf == NULL)
  		return (ENOMEM);
 +	ops = kobj->ktype->sysfs_ops;
  	if (ops->show) {
  		len = ops->show(kobj, attr, buf);
  		/*
 -		 * It's valid not to have a 'show' so we just return 1 byte
 -		 * of NULL.
 +		 * It's valid to not have a 'show' so just return an
 +		 * empty string.
  	 	 */
  		if (len < 0) {
  			error = -len;
 -			len = 1;
  			if (error != EIO)
  				goto out;
  		}
 +
 +		/* Trim trailing newline. */
 +		len--;
 +		buf[len] = '\0';
  	}
 -	error = SYSCTL_OUT(req, buf, len);
 -	if (error || !req->newptr || ops->store == NULL)
 -		goto out;
 -	error = SYSCTL_IN(req, buf, PAGE_SIZE);
 -	if (error)
 +
 +	/* Leave one trailing byte to append a newline. */
 +	error = sysctl_handle_string(oidp, buf, PAGE_SIZE - 1, req);
 +	if (error != 0 || req->newptr == NULL || ops->store == NULL)
  		goto out;
 -	len = ops->store(kobj, attr, buf, req->newlen);
 +	len = strlcat(buf, "\n", PAGE_SIZE);
 +	KASSERT(len < PAGE_SIZE, ("new attribute truncated"));
 +	len = ops->store(kobj, attr, buf, len);
  	if (len < 0)
  		error = -len;
  out:
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/179999: commit references a PR
Date: Tue,  6 Aug 2013 20:04:58 +0000 (UTC)

 Author: jhb
 Date: Tue Aug  6 20:04:44 2013
 New Revision: 254007
 URL: http://svnweb.freebsd.org/changeset/base/254007
 
 Log:
   MFC 253048,253423,253449,253653,253774,253785:
   - Allow mlx4 devices to switch between Ethernet and Infiniband:
     - Fix sysfs attribute handling by using sysctl_handle_string() and
       properly handling trailing newlines in attribute values.
     - Remove check forbidding requests that would result in one port being
       set to Ethernet and the subsequent port being set to IB.
   - Avoid trashing IP fragments by correctly managing hardware checksumming.
   - Fix panics when downing or unloading the mlx4 driver.
   
   PR:		kern/179999, kern/174213, kern/180430, kern/180791
   Approved by:	re (kib)
 
 Modified:
   releng/9.2/sys/ofed/drivers/net/mlx4/en_netdev.c
   releng/9.2/sys/ofed/drivers/net/mlx4/en_tx.c
   releng/9.2/sys/ofed/drivers/net/mlx4/main.c
   releng/9.2/sys/ofed/include/linux/sysfs.h
 Directory Properties:
   releng/9.2/sys/   (props changed)
 
 Modified: releng/9.2/sys/ofed/drivers/net/mlx4/en_netdev.c
 ==============================================================================
 --- releng/9.2/sys/ofed/drivers/net/mlx4/en_netdev.c	Tue Aug  6 19:23:57 2013	(r254006)
 +++ releng/9.2/sys/ofed/drivers/net/mlx4/en_netdev.c	Tue Aug  6 20:04:44 2013	(r254007)
 @@ -43,6 +43,7 @@
  #include <net/if_vlan_var.h>
  #include <sys/sockio.h>
  
 +static void mlx4_en_init_locked(struct mlx4_en_priv *priv);
  static void mlx4_en_sysctl_stat(struct mlx4_en_priv *priv);
  
  static void mlx4_en_vlan_rx_add_vid(void *arg, struct net_device *dev, u16 vid)
 @@ -495,11 +496,6 @@ static void mlx4_en_do_get_stats(struct 
  
  		queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
  	}
 -	if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
 -		panic("mlx4_en_do_get_stats: Unexpected mac removed for %d\n",
 -		    priv->port);
 -		mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
 -	}
  	mutex_unlock(&mdev->state_lock);
  }
  
 @@ -688,8 +684,8 @@ int mlx4_en_start_port(struct net_device
  	mlx4_en_set_multicast(dev);
  
  	/* Enable the queues. */
 -	atomic_clear_int(&dev->if_drv_flags, IFF_DRV_OACTIVE);
 -	atomic_set_int(&dev->if_drv_flags, IFF_DRV_RUNNING);
 +	dev->if_drv_flags &= ~IFF_DRV_OACTIVE;
 +	dev->if_drv_flags |= IFF_DRV_RUNNING;
  
  	callout_reset(&priv->watchdog_timer, MLX4_EN_WATCHDOG_TIMEOUT,
  	    mlx4_en_watchdog_timeout, priv);
 @@ -761,7 +757,7 @@ void mlx4_en_stop_port(struct net_device
  
  	callout_stop(&priv->watchdog_timer);
  
 -	atomic_clear_int(&dev->if_drv_flags, IFF_DRV_RUNNING);
 +	dev->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
  }
  
  static void mlx4_en_restart(struct work_struct *work)
 @@ -802,19 +798,30 @@ mlx4_en_init(void *arg)
  {
  	struct mlx4_en_priv *priv;
  	struct mlx4_en_dev *mdev;
 +
 +	priv = arg;
 +	mdev = priv->mdev;
 +	mutex_lock(&mdev->state_lock);
 +	mlx4_en_init_locked(priv);
 +	mutex_unlock(&mdev->state_lock);
 +}
 +
 +static void
 +mlx4_en_init_locked(struct mlx4_en_priv *priv)
 +{
 +
 +	struct mlx4_en_dev *mdev;
  	struct ifnet *dev;
  	int i;
  
 -	priv = arg;
  	dev = priv->dev;
  	mdev = priv->mdev;
 -	mutex_lock(&mdev->state_lock);
  	if (dev->if_drv_flags & IFF_DRV_RUNNING)
  		mlx4_en_stop_port(dev);
  
  	if (!mdev->device_up) {
  		en_err(priv, "Cannot open - device down/disabled\n");
 -		goto out;
 +		return;
  	}
  
  	/* Reset HW statistics and performance counters */
 @@ -835,9 +842,6 @@ mlx4_en_init(void *arg)
  	mlx4_en_set_default_moderation(priv);
  	if (mlx4_en_start_port(dev))
  		en_err(priv, "Failed starting port:%d\n", priv->port);
 -
 -out:
 -	mutex_unlock(&mdev->state_lock);
  }
  
  void mlx4_en_free_resources(struct mlx4_en_priv *priv)
 @@ -927,9 +931,14 @@ void mlx4_en_destroy_netdev(struct net_d
  	if (priv->sysctl)
  		sysctl_ctx_free(&priv->conf_ctx);
  
 +	mutex_lock(&mdev->state_lock);
 +	mlx4_en_stop_port(dev);
 +	mutex_unlock(&mdev->state_lock);
 +
  	cancel_delayed_work(&priv->stats_task);
  	/* flush any pending task for this netdev */
  	flush_workqueue(mdev->workqueue);
 +	callout_drain(&priv->watchdog_timer);
  
  	/* Detach the netdev so tasks would not attempt to access it */
  	mutex_lock(&mdev->state_lock);
 @@ -1091,31 +1100,32 @@ static int mlx4_en_ioctl(struct ifnet *d
  		error = -mlx4_en_change_mtu(dev, ifr->ifr_mtu);
  		break;
  	case SIOCSIFFLAGS:
 +		mutex_lock(&mdev->state_lock);
  		if (dev->if_flags & IFF_UP) {
 -			if ((dev->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 -				mutex_lock(&mdev->state_lock);
 +			if ((dev->if_drv_flags & IFF_DRV_RUNNING) == 0)
  				mlx4_en_start_port(dev);
 -				mutex_unlock(&mdev->state_lock);
 -			} else
 +			else
  				mlx4_en_set_multicast(dev);
  		} else {
 -			mutex_lock(&mdev->state_lock);
  			if (dev->if_drv_flags & IFF_DRV_RUNNING) {
  				mlx4_en_stop_port(dev);
  				if_link_state_change(dev, LINK_STATE_DOWN);
  			}
 -			mutex_unlock(&mdev->state_lock);
  		}
 +		mutex_unlock(&mdev->state_lock);
  		break;
  	case SIOCADDMULTI:
  	case SIOCDELMULTI:
 +		mutex_lock(&mdev->state_lock);
  		mlx4_en_set_multicast(dev);
 +		mutex_unlock(&mdev->state_lock);
  		break;
  	case SIOCSIFMEDIA:
  	case SIOCGIFMEDIA:
  		error = ifmedia_ioctl(dev, ifr, &priv->media, command);
  		break;
  	case SIOCSIFCAP:
 +		mutex_lock(&mdev->state_lock);
  		mask = ifr->ifr_reqcap ^ dev->if_capenable;
  		if (mask & IFCAP_HWCSUM)
  			dev->if_capenable ^= IFCAP_HWCSUM;
 @@ -1130,7 +1140,8 @@ static int mlx4_en_ioctl(struct ifnet *d
  		if (mask & IFCAP_WOL_MAGIC)
  			dev->if_capenable ^= IFCAP_WOL_MAGIC;
  		if (dev->if_drv_flags & IFF_DRV_RUNNING)
 -			mlx4_en_init(priv);
 +			mlx4_en_init_locked(priv);
 +		mutex_unlock(&mdev->state_lock);
  		VLAN_CAPABILITIES(dev);
  		break;
  	default:
 
 Modified: releng/9.2/sys/ofed/drivers/net/mlx4/en_tx.c
 ==============================================================================
 --- releng/9.2/sys/ofed/drivers/net/mlx4/en_tx.c	Tue Aug  6 19:23:57 2013	(r254006)
 +++ releng/9.2/sys/ofed/drivers/net/mlx4/en_tx.c	Tue Aug  6 20:04:44 2013	(r254007)
 @@ -780,8 +780,12 @@ retry:
  	tx_desc->ctrl.srcrb_flags = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE |
  						MLX4_WQE_CTRL_SOLICITED);
  	if (mb->m_pkthdr.csum_flags & (CSUM_IP|CSUM_TCP|CSUM_UDP)) {
 -		tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
 -							 MLX4_WQE_CTRL_TCP_UDP_CSUM);
 +		if (mb->m_pkthdr.csum_flags & CSUM_IP)
 +			tx_desc->ctrl.srcrb_flags |=
 +			    cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM);
 +		if (mb->m_pkthdr.csum_flags & (CSUM_TCP|CSUM_UDP))
 +			tx_desc->ctrl.srcrb_flags |=
 +			    cpu_to_be32(MLX4_WQE_CTRL_TCP_UDP_CSUM);
  		priv->port_stats.tx_chksum_offload++;
  	}
  
 
 Modified: releng/9.2/sys/ofed/drivers/net/mlx4/main.c
 ==============================================================================
 --- releng/9.2/sys/ofed/drivers/net/mlx4/main.c	Tue Aug  6 19:23:57 2013	(r254006)
 +++ releng/9.2/sys/ofed/drivers/net/mlx4/main.c	Tue Aug  6 20:04:44 2013	(r254007)
 @@ -209,9 +209,6 @@ int mlx4_check_port_params(struct mlx4_d
  					 "on this HCA, aborting.\n");
  				return -EINVAL;
  			}
 -			if (port_type[i] == MLX4_PORT_TYPE_ETH &&
 -			    port_type[i + 1] == MLX4_PORT_TYPE_IB)
 -				return -EINVAL;
  		}
  	}
  
 
 Modified: releng/9.2/sys/ofed/include/linux/sysfs.h
 ==============================================================================
 --- releng/9.2/sys/ofed/include/linux/sysfs.h	Tue Aug  6 19:23:57 2013	(r254006)
 +++ releng/9.2/sys/ofed/include/linux/sysfs.h	Tue Aug  6 20:04:44 2013	(r254007)
 @@ -75,39 +75,42 @@ sysctl_handle_attr(SYSCTL_HANDLER_ARGS)
  	struct kobject *kobj;
  	struct attribute *attr;
  	const struct sysfs_ops *ops;
 -	void *buf;
 +	char *buf;
  	int error;
  	ssize_t len;
  
  	kobj = arg1;
  	attr = (struct attribute *)arg2;
 -	buf = (void *)get_zeroed_page(GFP_KERNEL);
 -	len = 1;	/* Copy out a NULL byte at least. */
  	if (kobj->ktype == NULL || kobj->ktype->sysfs_ops == NULL)
  		return (ENODEV);
 -	ops = kobj->ktype->sysfs_ops;
 +	buf = (char *)get_zeroed_page(GFP_KERNEL);
  	if (buf == NULL)
  		return (ENOMEM);
 +	ops = kobj->ktype->sysfs_ops;
  	if (ops->show) {
  		len = ops->show(kobj, attr, buf);
  		/*
 -		 * It's valid not to have a 'show' so we just return 1 byte
 -		 * of NULL.
 +		 * It's valid to not have a 'show' so just return an
 +		 * empty string.
  	 	 */
  		if (len < 0) {
  			error = -len;
 -			len = 1;
  			if (error != EIO)
  				goto out;
  		}
 +
 +		/* Trim trailing newline. */
 +		len--;
 +		buf[len] = '\0';
  	}
 -	error = SYSCTL_OUT(req, buf, len);
 -	if (error || !req->newptr || ops->store == NULL)
 -		goto out;
 -	error = SYSCTL_IN(req, buf, PAGE_SIZE);
 -	if (error)
 +
 +	/* Leave one trailing byte to append a newline. */
 +	error = sysctl_handle_string(oidp, buf, PAGE_SIZE - 1, req);
 +	if (error != 0 || req->newptr == NULL || ops->store == NULL)
  		goto out;
 -	len = ops->store(kobj, attr, buf, req->newlen);
 +	len = strlcat(buf, "\n", PAGE_SIZE);
 +	KASSERT(len < PAGE_SIZE, ("new attribute truncated"));
 +	len = ops->store(kobj, attr, buf, len);
  	if (len < 0)
  		error = -len;
  out:
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: jhb 
State-Changed-When: Wed Aug 7 18:00:26 UTC 2013 
State-Changed-Why:  
Merged to 9 and 9.2. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=179999 
>Unformatted:
