diff mbox series

[RFC,v2,for-next,6/7] RDMA/core: support send port event

Message ID 20200204082408.18728-7-liweihang@huawei.com (mailing list archive)
State Changes Requested
Headers show
Series ib core support to send ib port link event | expand

Commit Message

Weihang Li Feb. 4, 2020, 8:24 a.m. UTC
From: Lang Cheng <chenglang@huawei.com>

For the process of handling the link event of the net device, the driver
of each provider is similar, so it can be integrated into the ib_core for
unified processing.

Signed-off-by: Lang Cheng <chenglang@huawei.com>
---
 drivers/infiniband/core/device.c        |  1 +
 drivers/infiniband/core/roce_gid_mgmt.c | 45 +++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

Comments

Jason Gunthorpe Feb. 19, 2020, 9:07 p.m. UTC | #1
On Tue, Feb 04, 2020 at 04:24:07PM +0800, Weihang Li wrote:
> From: Lang Cheng <chenglang@huawei.com>
> 
> For the process of handling the link event of the net device, the driver
> of each provider is similar, so it can be integrated into the ib_core for
> unified processing.
> 
> Signed-off-by: Lang Cheng <chenglang@huawei.com>
>  drivers/infiniband/core/device.c        |  1 +
>  drivers/infiniband/core/roce_gid_mgmt.c | 45 +++++++++++++++++++++++++++++++++
>  2 files changed, 46 insertions(+)
> 
> diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
> index 84dd74f..0427a4d 100644
> +++ b/drivers/infiniband/core/device.c
> @@ -2225,6 +2225,7 @@ struct net_device *ib_device_get_netdev(struct ib_device *ib_dev,
>  
>  	return res;
>  }
> +EXPORT_SYMBOL(ib_device_get_netdev);
>  
>  /**
>   * ib_device_get_by_netdev - Find an IB device associated with a netdev
> diff --git a/drivers/infiniband/core/roce_gid_mgmt.c b/drivers/infiniband/core/roce_gid_mgmt.c
> index 2860def..4170ba3 100644
> +++ b/drivers/infiniband/core/roce_gid_mgmt.c
> @@ -751,6 +751,12 @@ static int netdevice_event(struct notifier_block *this, unsigned long event,
>  	struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
>  	struct netdev_event_work_cmd cmds[ROCE_NETDEV_CALLBACK_SZ] = { {NULL} };
>  
> +	enum ib_port_state last_state;
> +	enum ib_port_state curr_state;
> +	struct ib_device *device;
> +	struct ib_event ibev;
> +	unsigned int port;
> +
>  	if (ndev->type != ARPHRD_ETHER)
>  		return NOTIFY_DONE;
>  
> @@ -762,6 +768,45 @@ static int netdevice_event(struct notifier_block *this, unsigned long event,
>  		cmds[2] = add_cmd;
>  		break;
>  
> +	case NETDEV_CHANGE:
> +	case NETDEV_DOWN:
> +		device = ib_device_get_by_netdev(ndev, RDMA_DRIVER_UNKNOWN);
> +		if (!device)
> +			break;
> +
> +		rdma_for_each_port (device, port) {
> +			if (ib_device_get_netdev(device, port) != ndev)
> +				continue;

This feels strange, maybe we need to fix ib_device_get_by_netdev to
return the port too?

> +
> +			if (ib_get_cached_port_inactive_status(device, port))
> +				break;
> +
> +			ib_get_cached_port_state(device, port, &last_state);
> +			curr_state =
> +				netif_running(ndev) && netif_carrier_ok(ndev) ?
> +					IB_PORT_ACTIVE :
> +					IB_PORT_DOWN;
> +
> +			if (last_state == curr_state)
> +				break;
> +
> +			if (curr_state == IB_PORT_DOWN)
> +				ibev.event = IB_EVENT_PORT_ERR;
> +			else if (curr_state == IB_PORT_ACTIVE)
> +				ibev.event = IB_EVENT_PORT_ACTIVE;
> +			else
> +				break;

Other states are ignored?

> +
> +			ibev.device = device;
> +			ibev.element.port_num = port;
> +			ib_dispatch_event(&ibev);
> +			ibdev_dbg(ibev.device, "core send %s\n",
> +				  ib_event_msg(ibev.event));
> +		}
> +
> +		ib_device_put(device);
> +		break;

Ah the series is backwards. 

You need to organize your series so that every patch works
properly. This has to be before any drivers are removed, and you'll
need some temporary capability to disable it for drivers that have not
been migrated yet.

Jason
Lang Cheng Feb. 20, 2020, 8:48 a.m. UTC | #2
On 2020/2/20 5:07, Jason Gunthorpe wrote:
> On Tue, Feb 04, 2020 at 04:24:07PM +0800, Weihang Li wrote:
>> From: Lang Cheng <chenglang@huawei.com>
>>
>> For the process of handling the link event of the net device, the driver
>> of each provider is similar, so it can be integrated into the ib_core for
>> unified processing.
>>
>> Signed-off-by: Lang Cheng <chenglang@huawei.com>
>>   drivers/infiniband/core/device.c        |  1 +
>>   drivers/infiniband/core/roce_gid_mgmt.c | 45 +++++++++++++++++++++++++++++++++
>>   2 files changed, 46 insertions(+)
>>
>> diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
>> index 84dd74f..0427a4d 100644
>> +++ b/drivers/infiniband/core/device.c
>> @@ -2225,6 +2225,7 @@ struct net_device *ib_device_get_netdev(struct ib_device *ib_dev,
>>   
>>   	return res;
>>   }
>> +EXPORT_SYMBOL(ib_device_get_netdev);
>>   
>>   /**
>>    * ib_device_get_by_netdev - Find an IB device associated with a netdev
>> diff --git a/drivers/infiniband/core/roce_gid_mgmt.c b/drivers/infiniband/core/roce_gid_mgmt.c
>> index 2860def..4170ba3 100644
>> +++ b/drivers/infiniband/core/roce_gid_mgmt.c
>> @@ -751,6 +751,12 @@ static int netdevice_event(struct notifier_block *this, unsigned long event,
>>   	struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
>>   	struct netdev_event_work_cmd cmds[ROCE_NETDEV_CALLBACK_SZ] = { {NULL} };
>>   
>> +	enum ib_port_state last_state;
>> +	enum ib_port_state curr_state;
>> +	struct ib_device *device;
>> +	struct ib_event ibev;
>> +	unsigned int port;
>> +
>>   	if (ndev->type != ARPHRD_ETHER)
>>   		return NOTIFY_DONE;
>>   
>> @@ -762,6 +768,45 @@ static int netdevice_event(struct notifier_block *this, unsigned long event,
>>   		cmds[2] = add_cmd;
>>   		break;
>>   
>> +	case NETDEV_CHANGE:
>> +	case NETDEV_DOWN:
>> +		device = ib_device_get_by_netdev(ndev, RDMA_DRIVER_UNKNOWN);
>> +		if (!device)
>> +			break;
>> +
>> +		rdma_for_each_port (device, port) {
>> +			if (ib_device_get_netdev(device, port) != ndev)
>> +				continue;
> 
> This feels strange, maybe we need to fix ib_device_get_by_netdev to
> return the port too?

Seems ib_device_get_by_netdev is used infrequently, so the port 
information may only benefit siw and here.

> 
>> +
>> +			if (ib_get_cached_port_inactive_status(device, port))
>> +				break;
>> +
>> +			ib_get_cached_port_state(device, port, &last_state);
>> +			curr_state =
>> +				netif_running(ndev) && netif_carrier_ok(ndev) ?
>> +					IB_PORT_ACTIVE :
>> +					IB_PORT_DOWN;
>> +
>> +			if (last_state == curr_state)
>> +				break;
>> +
>> +			if (curr_state == IB_PORT_DOWN)
>> +				ibev.event = IB_EVENT_PORT_ERR;
>> +			else if (curr_state == IB_PORT_ACTIVE)
>> +				ibev.event = IB_EVENT_PORT_ACTIVE;
>> +			else
>> +				break;
> 
> Other states are ignored?

I think the "curr_state" has only two port states,
maybe the "last_state" has the 3rd state(0) to represent INIT.

> 
>> +
>> +			ibev.device = device;
>> +			ibev.element.port_num = port;
>> +			ib_dispatch_event(&ibev);
>> +			ibdev_dbg(ibev.device, "core send %s\n",
>> +				  ib_event_msg(ibev.event));
>> +		}
>> +
>> +		ib_device_put(device);
>> +		break;
> 
> Ah the series is backwards.
> 
> You need to organize your series so that every patch works
> properly. This has to be before any drivers are removed, and you'll
> need some temporary capability to disable it for drivers that have not
> been migrated yet.

Yes.I will add "some temporary capability" in next to make every patch 
works properly.

Thanks.

> 
> Jason
> 
> .
>
diff mbox series

Patch

diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 84dd74f..0427a4d 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -2225,6 +2225,7 @@  struct net_device *ib_device_get_netdev(struct ib_device *ib_dev,
 
 	return res;
 }
+EXPORT_SYMBOL(ib_device_get_netdev);
 
 /**
  * ib_device_get_by_netdev - Find an IB device associated with a netdev
diff --git a/drivers/infiniband/core/roce_gid_mgmt.c b/drivers/infiniband/core/roce_gid_mgmt.c
index 2860def..4170ba3 100644
--- a/drivers/infiniband/core/roce_gid_mgmt.c
+++ b/drivers/infiniband/core/roce_gid_mgmt.c
@@ -751,6 +751,12 @@  static int netdevice_event(struct notifier_block *this, unsigned long event,
 	struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
 	struct netdev_event_work_cmd cmds[ROCE_NETDEV_CALLBACK_SZ] = { {NULL} };
 
+	enum ib_port_state last_state;
+	enum ib_port_state curr_state;
+	struct ib_device *device;
+	struct ib_event ibev;
+	unsigned int port;
+
 	if (ndev->type != ARPHRD_ETHER)
 		return NOTIFY_DONE;
 
@@ -762,6 +768,45 @@  static int netdevice_event(struct notifier_block *this, unsigned long event,
 		cmds[2] = add_cmd;
 		break;
 
+	case NETDEV_CHANGE:
+	case NETDEV_DOWN:
+		device = ib_device_get_by_netdev(ndev, RDMA_DRIVER_UNKNOWN);
+		if (!device)
+			break;
+
+		rdma_for_each_port (device, port) {
+			if (ib_device_get_netdev(device, port) != ndev)
+				continue;
+
+			if (ib_get_cached_port_inactive_status(device, port))
+				break;
+
+			ib_get_cached_port_state(device, port, &last_state);
+			curr_state =
+				netif_running(ndev) && netif_carrier_ok(ndev) ?
+					IB_PORT_ACTIVE :
+					IB_PORT_DOWN;
+
+			if (last_state == curr_state)
+				break;
+
+			if (curr_state == IB_PORT_DOWN)
+				ibev.event = IB_EVENT_PORT_ERR;
+			else if (curr_state == IB_PORT_ACTIVE)
+				ibev.event = IB_EVENT_PORT_ACTIVE;
+			else
+				break;
+
+			ibev.device = device;
+			ibev.element.port_num = port;
+			ib_dispatch_event(&ibev);
+			ibdev_dbg(ibev.device, "core send %s\n",
+				  ib_event_msg(ibev.event));
+		}
+
+		ib_device_put(device);
+		break;
+
 	case NETDEV_UNREGISTER:
 		if (ndev->reg_state < NETREG_UNREGISTERED)
 			cmds[0] = del_cmd;