bugfix for multi process of hns3 PMD
cover bugfix for multi process of hns3 PMD
This patch set contains bugfix and code optimization for multi process of hns3 PMD.
Huisong Li (4):
net/hns3: decrease the count when secondary process exits net/hns3: fix MP action register and unregister net/hns3: fix lack of unregistering MP action for secondary net/hns3: refactor multi-process initialization
drivers/net/hns3/hns3_ethdev.c | 34 +++++------- drivers/net/hns3/hns3_ethdev_vf.c | 35 +++++-------- drivers/net/hns3/hns3_mp.c | 86 ++++++++++++++++++++++--------- drivers/net/hns3/hns3_mp.h | 11 ++-- 4 files changed, 98 insertions(+), 68 deletions(-)
Signature · 1 line
2.33.0
PATCH 1/4 net/hns3: decrease the count when secondary process exits
From: Huisong Li <[email protected]>
The "secondary_cnt" will be increased when a secondary process initialized. But the value of this variable is not decreased when the secondary process exits, which causes the primary process senses that the secondary process still exists. As a result, the primary process fails to send messages to the secondary process after the secondary process exits.
--- drivers/net/hns3/hns3_ethdev.c | 10 +++++++--- drivers/net/hns3/hns3_ethdev_vf.c | 10 +++++++--- drivers/net/hns3/hns3_mp.c | 4 +++- 3 files changed, 17 insertions(+), 7 deletions(-)
drivers/net/hns3/hns3_ethdev.c +7 -3
@@ -5849,8 +5849,10 @@ hns3_dev_close(struct rte_eth_dev *eth_dev)struct hns3_hw *hw = &hns->hw;int ret =0 ; -if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) +if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) { +__atomic_fetch_sub (&hw->secondary_cnt,1 , __ATOMIC_RELAXED);return 0 ; + }if (hw->adapter_state ==HNS3_NIC_STARTED ) ret =hns3_dev_stop (eth_dev);
@@ -7376,7 +7378,7 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) "process, ret = %d", ret); goto err_mp_init_secondary; } - hw->secondary_cnt++; +__atomic_fetch_add (&hw->secondary_cnt,1 , __ATOMIC_RELAXED);hns3_tx_push_init (eth_dev);return 0 ; }
@@ -7479,8 +7481,10 @@ hns3_dev_uninit(struct rte_eth_dev *eth_dev)PMD_INIT_FUNC_TRACE (); -if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) +if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) { +__atomic_fetch_sub (&hw->secondary_cnt,1 , __ATOMIC_RELAXED);return 0 ; + }if (hw->adapter_state <HNS3_NIC_CLOSING )hns3_dev_close (eth_dev);
drivers/net/hns3/hns3_ethdev_vf.c +7 -3
@@ -1892,8 +1892,10 @@ hns3vf_dev_close(struct rte_eth_dev *eth_dev)struct hns3_hw *hw = &hns->hw;int ret =0 ; -if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) +if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) { +__atomic_fetch_sub (&hw->secondary_cnt,1 , __ATOMIC_RELAXED);return 0 ; + }if (hw->adapter_state ==HNS3_NIC_STARTED ) ret =hns3vf_dev_stop (eth_dev);
@@ -2684,7 +2686,7 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) "process, ret = %d", ret); goto err_mp_init_secondary; } - hw->secondary_cnt++; +__atomic_fetch_add (&hw->secondary_cnt,1 , __ATOMIC_RELAXED);hns3_tx_push_init (eth_dev);return 0 ; }
@@ -2786,8 +2788,10 @@ hns3vf_dev_uninit(struct rte_eth_dev *eth_dev)PMD_INIT_FUNC_TRACE (); -if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) +if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) { +__atomic_fetch_sub (&hw->secondary_cnt,1 , __ATOMIC_RELAXED);return 0 ; + }if (hw->adapter_state <HNS3_NIC_CLOSING )hns3vf_dev_close (eth_dev);
drivers/net/hns3/hns3_mp.c +3 -1
@@ -150,8 +150,10 @@ mp_req_on_rxtx(struct rte_eth_dev *dev, enum hns3_mp_req_type type)int ret;int i; -if (rte_eal_process_type () ==RTE_PROC_SECONDARY || !hw->secondary_cnt) +if (rte_eal_process_type () ==RTE_PROC_SECONDARY || +__atomic_load_n (&hw->secondary_cnt, __ATOMIC_RELAXED) ==0 )return ; +if (!mp_req_type_is_valid (type)) {hns3_err (hw,"port %u unknown request (req_type %d)" , dev->data->port_id, type);
Signature · 1 line
2.33.0
PATCH 2/4 net/hns3: fix MP action register and unregister
In reply to Min Hu (Connor)From: Huisong Li <[email protected]>
The multi-process has the following problems:
1) After a port in primary process is closed, the mp action of the process is unregistered. which will cause that other device in the primary process cannot respond to requests from secondary processes.
2) Because variable "hns3_inited" is set to true without returning an initial value, the mp action cannot be registered again after it is unregistered.
3) The mp action of primary and secondary process need to be registered only once regardless of port numbers in the process. That's what variable "hns3_inited" does. But the variable is difficult to understand.
This patch adds a hns3_process_local_data structure to resolve above problems.
--- drivers/net/hns3/hns3_ethdev.c | 2 ++ drivers/net/hns3/hns3_ethdev_vf.c | 2 ++ drivers/net/hns3/hns3_mp.c | 37 ++++++++++++++++++------------- drivers/net/hns3/hns3_mp.h | 7 ++++++ 4 files changed, 33 insertions(+), 15 deletions(-)
drivers/net/hns3/hns3_ethdev.c +2 -0
@@ -7379,6 +7379,7 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) goto err_mp_init_secondary; }__atomic_fetch_add (&hw->secondary_cnt,1 , __ATOMIC_RELAXED); + process_data.eth_dev_cnt++;hns3_tx_push_init (eth_dev);return 0 ; }
@@ -7390,6 +7391,7 @@ hns3_dev_init(struct rte_eth_dev *eth_dev) ret); goto err_mp_init_primary; } + process_data.eth_dev_cnt++; hw->adapter_state =HNS3_NIC_UNINITIALIZED ; hns->is_vf = false;
drivers/net/hns3/hns3_ethdev_vf.c +2 -0
@@ -2687,6 +2687,7 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) goto err_mp_init_secondary; }__atomic_fetch_add (&hw->secondary_cnt,1 , __ATOMIC_RELAXED); + process_data.eth_dev_cnt++;hns3_tx_push_init (eth_dev);return 0 ; }
@@ -2698,6 +2699,7 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev) ret); goto err_mp_init_primary; } + process_data.eth_dev_cnt++; hw->adapter_state =HNS3_NIC_UNINITIALIZED ; hns->is_vf = true;
drivers/net/hns3/hns3_mp.c +22 -15
@@ -12,7 +12,8 @@#include "hns3_rxtx.h" #include "hns3_mp.h" -static bool hns3_inited; +/* local data for primary or secondary process. */ +struct hns3_process_local_data process_data;/* * Initialize IPC message.
@@ -230,14 +231,15 @@ int hns3_mp_init_primary(void) {int ret; -if (!hns3_inited) { -/* primary is allowed to not support IPC */ - ret =rte_mp_action_register (HNS3_MP_NAME , mp_primary_handle); -if (ret && rte_errno !=ENOTSUP ) -return ret; +if (process_data.init_done) +return 0 ; - hns3_inited = true; - } +/* primary is allowed to not support IPC */ + ret =rte_mp_action_register (HNS3_MP_NAME , mp_primary_handle); +if (ret && rte_errno !=ENOTSUP ) +return ret; + + process_data.init_done = true;return 0 ; }
@@ -247,8 +249,12 @@ int hns3_mp_init_primary(void)*/ void hns3_mp_uninit_primary (void ) { -if (hns3_inited) + process_data.eth_dev_cnt--; + +if (process_data.eth_dev_cnt ==0 ) {rte_mp_action_unregister (HNS3_MP_NAME ); + process_data.init_done = false; + } }/*
@@ -258,13 +264,14 @@ int hns3_mp_init_secondary(void) {int ret; -if (!hns3_inited) { - ret =rte_mp_action_register (HNS3_MP_NAME , mp_secondary_handle); -if (ret) -return ret; +if (process_data.init_done) +return 0 ; - hns3_inited = true; - } + ret =rte_mp_action_register (HNS3_MP_NAME , mp_secondary_handle); +if (ret) +return ret; + + process_data.init_done = true;return 0 ; }
drivers/net/hns3/hns3_mp.h +7 -0
@@ -5,6 +5,13 @@#ifndef _HNS3_MP_H_#define _HNS3_MP_H_ +/* Local data for primary or secondary process. */ +struct hns3_process_local_data { +bool init_done;/* Process action register completed flag. */ +int eth_dev_cnt;/* Ethdev count under the current process. */ +}; +extern struct hns3_process_local_data process_data; +void hns3_mp_req_start_rxtx (struct rte_eth_dev *dev);void hns3_mp_req_stop_rxtx (struct rte_eth_dev *dev);void hns3_mp_req_start_tx (struct rte_eth_dev *dev);
Signature · 1 line
2.33.0
Re: [dpdk-dev] [PATCH 2/4] net/hns3: fix MP action register and unregister
Quoted 22 lines · Min Hu (Connor)
From: Huisong Li <[email protected]>
The multi-process has the following problems:
1) After a port in primary process is closed, the mp action of the process is unregistered. which will cause that other device in the primary process cannot respond to requests from secondary processes.
2) Because variable "hns3_inited" is set to true without returning an initial value, the mp action cannot be registered again after it is unregistered.
3) The mp action of primary and secondary process need to be registered only once regardless of port numbers in the process. That's what variable "hns3_inited" does. But the variable is difficult to understand.This patch adds a
hns3_process_local_datastructure to resolve above problems.Fixes 9570b1fdbdad ("net/hns3: check multi-process action register result")Fixes 23d4b61fee5d ("net/hns3: support multiple process")Signed-off-by Huisong Li <[email protected]>Signed-off-by Min Hu (Connor) <[email protected]>
<...>
drivers/net/hns3/hns3_mp.c line 17
Quoted 8 lines
drivers/net/hns3/hns3_mp.c +2
-1@@ -12,7 +12,8 @@#include "hns3_rxtx.h" #include "hns3_mp.h" -static bool hns3_inited; +/* local data for primary or secondary process. */ +struct hns3_process_local_data process_data;
I was here to complain about non-static global variable that doesn't have driver namespace ('hns3_'), but I can see later patches are converting this variable to a static global, so I guess it is OK to have it temporarily.
PATCH 3/4 net/hns3: fix lack of unregistering MP action for secondary
In reply to Min Hu (Connor)From: Huisong Li <[email protected]>
This patch fixes lack of unregistering MP action for secondary process when PMD is closed.
--- drivers/net/hns3/hns3_ethdev.c | 6 ++++-- drivers/net/hns3/hns3_ethdev_vf.c | 6 ++++-- drivers/net/hns3/hns3_mp.c | 5 +---- drivers/net/hns3/hns3_mp.h | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-)
drivers/net/hns3/hns3_ethdev.c +4 -2
@@ -5851,6 +5851,7 @@ hns3_dev_close(struct rte_eth_dev *eth_dev)if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) {__atomic_fetch_sub (&hw->secondary_cnt,1 , __ATOMIC_RELAXED); +hns3_mp_uninit ();return 0 ; }
@@ -5867,7 +5868,7 @@ hns3_dev_close(struct rte_eth_dev *eth_dev)hns3_uninit_pf (eth_dev);hns3_free_all_queues (eth_dev);rte_free (hw->reset.wait_data); -hns3_mp_uninit_primary (); +hns3_mp_uninit ();hns3_warn (hw,"Close port %u finished" , hw->data->port_id);return ret;
@@ -7462,7 +7463,7 @@ hns3_dev_init(struct rte_eth_dev *eth_dev)rte_free (hw->reset.wait_data); err_init_reset: -hns3_mp_uninit_primary (); +hns3_mp_uninit (); err_mp_init_primary: err_mp_init_secondary:
@@ -7485,6 +7486,7 @@ hns3_dev_uninit(struct rte_eth_dev *eth_dev)if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) {__atomic_fetch_sub (&hw->secondary_cnt,1 , __ATOMIC_RELAXED); +hns3_mp_uninit ();return 0 ; }
drivers/net/hns3/hns3_ethdev_vf.c +4 -2
@@ -1894,6 +1894,7 @@ hns3vf_dev_close(struct rte_eth_dev *eth_dev)if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) {__atomic_fetch_sub (&hw->secondary_cnt,1 , __ATOMIC_RELAXED); +hns3_mp_uninit ();return 0 ; }
@@ -1909,7 +1910,7 @@ hns3vf_dev_close(struct rte_eth_dev *eth_dev)hns3vf_uninit_vf (eth_dev);hns3_free_all_queues (eth_dev);rte_free (hw->reset.wait_data); -hns3_mp_uninit_primary (); +hns3_mp_uninit ();hns3_warn (hw,"Close port %u finished" , hw->data->port_id);return ret;
@@ -2768,7 +2769,7 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev)rte_free (hw->reset.wait_data); err_init_reset: -hns3_mp_uninit_primary (); +hns3_mp_uninit (); err_mp_init_primary: err_mp_init_secondary:
@@ -2792,6 +2793,7 @@ hns3vf_dev_uninit(struct rte_eth_dev *eth_dev)if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) {__atomic_fetch_sub (&hw->secondary_cnt,1 , __ATOMIC_RELAXED); +hns3_mp_uninit ();return 0 ; }
drivers/net/hns3/hns3_mp.c +1 -4
@@ -244,10 +244,7 @@ int hns3_mp_init_primary(void)return 0 ; } -/* -* Un-initialize by primary process. -*/ -void hns3_mp_uninit_primary (void ) +void hns3_mp_uninit (void ) { process_data.eth_dev_cnt--;
drivers/net/hns3/hns3_mp.h +1 -1
@@ -18,7 +18,7 @@ void hns3_mp_req_start_tx(struct rte_eth_dev *dev);void hns3_mp_req_stop_tx (struct rte_eth_dev *dev);int hns3_mp_init_primary (void ); -void hns3_mp_uninit_primary (void ); +void hns3_mp_uninit (void );int hns3_mp_init_secondary (void );#endif /* _HNS3_MP_H_ */
Signature · 1 line
2.33.0
PATCH 4/4 net/hns3: refactor multi-process initialization
In reply to Min Hu (Connor)From: Huisong Li <[email protected]>
Currently, the logic of the PF and VF initialization codes for multiple process is the same. A common function can be extracted to initialize and unload multiple process.
--- drivers/net/hns3/hns3_ethdev.c | 34 +++++------------ drivers/net/hns3/hns3_ethdev_vf.c | 33 +++++----------- drivers/net/hns3/hns3_mp.c | 62 ++++++++++++++++++++++++------- drivers/net/hns3/hns3_mp.h | 6 +-- 4 files changed, 68 insertions(+), 67 deletions(-)
drivers/net/hns3/hns3_ethdev.c +9 -25
@@ -5850,8 +5850,7 @@ hns3_dev_close(struct rte_eth_dev *eth_dev)int ret =0 ;if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) { -__atomic_fetch_sub (&hw->secondary_cnt,1 , __ATOMIC_RELAXED); -hns3_mp_uninit (); +hns3_mp_uninit (eth_dev);return 0 ; }
@@ -5868,7 +5867,7 @@ hns3_dev_close(struct rte_eth_dev *eth_dev)hns3_uninit_pf (eth_dev);hns3_free_all_queues (eth_dev);rte_free (hw->reset.wait_data); -hns3_mp_uninit (); +hns3_mp_uninit (eth_dev);hns3_warn (hw,"Close port %u finished" , hw->data->port_id);return ret;
@@ -7372,28 +7371,15 @@ hns3_dev_init(struct rte_eth_dev *eth_dev)hns3_set_rxtx_function (eth_dev); eth_dev->dev_ops = &hns3_eth_dev_ops; eth_dev->rx_queue_count = hns3_rx_queue_count; + ret =hns3_mp_init (eth_dev); +if (ret) + goto err_mp_init; +if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) { - ret =hns3_mp_init_secondary (); -if (ret) { -PMD_INIT_LOG (ERR ,"Failed to init for secondary " -"process, ret = %d" , ret); - goto err_mp_init_secondary; - } -__atomic_fetch_add (&hw->secondary_cnt,1 , __ATOMIC_RELAXED); - process_data.eth_dev_cnt++;hns3_tx_push_init (eth_dev);return 0 ; } - ret =hns3_mp_init_primary (); -if (ret) { -PMD_INIT_LOG (ERR , -"Failed to init for primary process, ret = %d" , - ret); - goto err_mp_init_primary; - } - process_data.eth_dev_cnt++; - hw->adapter_state =HNS3_NIC_UNINITIALIZED ; hns->is_vf = false; hw->data = eth_dev->data;
@@ -7463,10 +7449,9 @@ hns3_dev_init(struct rte_eth_dev *eth_dev)rte_free (hw->reset.wait_data); err_init_reset: -hns3_mp_uninit (); +hns3_mp_uninit (eth_dev); -err_mp_init_primary: -err_mp_init_secondary: +err_mp_init: eth_dev->dev_ops =NULL ; eth_dev->rx_pkt_burst =NULL ; eth_dev->rx_descriptor_status =NULL ;
@@ -7485,8 +7470,7 @@ hns3_dev_uninit(struct rte_eth_dev *eth_dev)PMD_INIT_FUNC_TRACE ();if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) { -__atomic_fetch_sub (&hw->secondary_cnt,1 , __ATOMIC_RELAXED); -hns3_mp_uninit (); +hns3_mp_uninit (eth_dev);return 0 ; }
drivers/net/hns3/hns3_ethdev_vf.c +9 -24
@@ -1893,8 +1893,7 @@ hns3vf_dev_close(struct rte_eth_dev *eth_dev)int ret =0 ;if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) { -__atomic_fetch_sub (&hw->secondary_cnt,1 , __ATOMIC_RELAXED); -hns3_mp_uninit (); +hns3_mp_uninit (eth_dev);return 0 ; }
@@ -1910,7 +1909,7 @@ hns3vf_dev_close(struct rte_eth_dev *eth_dev)hns3vf_uninit_vf (eth_dev);hns3_free_all_queues (eth_dev);rte_free (hw->reset.wait_data); -hns3_mp_uninit (); +hns3_mp_uninit (eth_dev);hns3_warn (hw,"Close port %u finished" , hw->data->port_id);return ret;
@@ -2680,28 +2679,15 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev)hns3_set_rxtx_function (eth_dev); eth_dev->dev_ops = &hns3vf_eth_dev_ops; eth_dev->rx_queue_count = hns3_rx_queue_count; + ret =hns3_mp_init (eth_dev); +if (ret) + goto err_mp_init; +if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) { - ret =hns3_mp_init_secondary (); -if (ret) { -PMD_INIT_LOG (ERR ,"Failed to init for secondary " -"process, ret = %d" , ret); - goto err_mp_init_secondary; - } -__atomic_fetch_add (&hw->secondary_cnt,1 , __ATOMIC_RELAXED); - process_data.eth_dev_cnt++;hns3_tx_push_init (eth_dev);return 0 ; } - ret =hns3_mp_init_primary (); -if (ret) { -PMD_INIT_LOG (ERR , -"Failed to init for primary process, ret = %d" , - ret); - goto err_mp_init_primary; - } - process_data.eth_dev_cnt++; - hw->adapter_state =HNS3_NIC_UNINITIALIZED ; hns->is_vf = true; hw->data = eth_dev->data;
@@ -2769,10 +2755,9 @@ hns3vf_dev_init(struct rte_eth_dev *eth_dev)rte_free (hw->reset.wait_data); err_init_reset: -hns3_mp_uninit (); +hns3_mp_uninit (eth_dev); -err_mp_init_primary: -err_mp_init_secondary: +err_mp_init: eth_dev->dev_ops =NULL ; eth_dev->rx_pkt_burst =NULL ; eth_dev->rx_descriptor_status =NULL ;
@@ -2793,7 +2778,7 @@ hns3vf_dev_uninit(struct rte_eth_dev *eth_dev)if (rte_eal_process_type () !=RTE_PROC_PRIMARY ) {__atomic_fetch_sub (&hw->secondary_cnt,1 , __ATOMIC_RELAXED); -hns3_mp_uninit (); +hns3_mp_uninit (eth_dev);return 0 ; }
drivers/net/hns3/hns3_mp.c +48 -14
92 lines not on this page · raw message
drivers/net/hns3/hns3_mp.h +2 -4
@@ -10,15 +10,13 @@ struct hns3_process_local_data {bool init_done;/* Process action register completed flag. */ int eth_dev_cnt; /* Ethdev count under the current process. */ }; -extern struct hns3_process_local_data process_data;void hns3_mp_req_start_rxtx (struct rte_eth_dev *dev);void hns3_mp_req_stop_rxtx (struct rte_eth_dev *dev);void hns3_mp_req_start_tx (struct rte_eth_dev *dev);void hns3_mp_req_stop_tx (struct rte_eth_dev *dev); -int hns3_mp_init_primary (void ); -void hns3_mp_uninit (void ); -int hns3_mp_init_secondary (void ); +int hns3_mp_init (struct rte_eth_dev *dev); +void hns3_mp_uninit (struct rte_eth_dev *dev);#endif /* _HNS3_MP_H_ */
Signature · 1 line
2.33.0
Quoted 9 lines · Min Hu (Connor)
This patch set contains bugfix and code optimization for multi process of hns3 PMD.
Huisong Li (4):
net/hns3: decrease the count when secondary process exits net/hns3: fix MP action register and unregister net/hns3: fix lack of unregistering MP action for secondary net/hns3: refactor multi-process initialization
Series applied to dpdk-next-net/main, thanks.