diff options
| author | Manikanta Maddireddy <mmaddireddy@nvidia.com> | 2019-07-19 06:35:36 -0400 |
|---|---|---|
| committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2019-12-03 03:08:48 -0500 |
| commit | 36c404b67253c2deecc97ac113c2105efeadf5b0 (patch) | |
| tree | d615b52b56287ff28b515628f896f203511a9350 | |
| parent | 05559ec95ad9491f989dd15911f946bc9776bb55 (diff) | |
PCI: Process control messages in the same context
Process control messages in the same kthread context instead of scheduling
a separate work for the same to improve performance.
Bug 200495545
Change-Id: Iac004bd313754e61d789dff233cf487b1f4710d2
Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2183364
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Tested-by: Vidya Sagar <vidyas@nvidia.com>
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
| -rw-r--r-- | drivers/net/ethernet/nvidia/pcie/tegra_vnet.c | 34 | ||||
| -rw-r--r-- | drivers/pci/endpoint/functions/pci-epf-tegra-vnet.c | 33 |
2 files changed, 20 insertions, 47 deletions
diff --git a/drivers/net/ethernet/nvidia/pcie/tegra_vnet.c b/drivers/net/ethernet/nvidia/pcie/tegra_vnet.c index 7b929c2fe..8bfa3460b 100644 --- a/drivers/net/ethernet/nvidia/pcie/tegra_vnet.c +++ b/drivers/net/ethernet/nvidia/pcie/tegra_vnet.c | |||
| @@ -197,8 +197,6 @@ struct tvnet_priv { | |||
| 197 | struct bar_md *bar_md; | 197 | struct bar_md *bar_md; |
| 198 | struct ep_ring_buf ep_mem; | 198 | struct ep_ring_buf ep_mem; |
| 199 | struct host_ring_buf host_mem; | 199 | struct host_ring_buf host_mem; |
| 200 | struct work_struct ctrl_msg_work; | ||
| 201 | struct work_struct alloc_buf_work; | ||
| 202 | struct list_head ep2h_empty_list; | 200 | struct list_head ep2h_empty_list; |
| 203 | /* To protect ep2h empty list */ | 201 | /* To protect ep2h empty list */ |
| 204 | spinlock_t ep2h_empty_lock; | 202 | spinlock_t ep2h_empty_lock; |
| @@ -466,7 +464,9 @@ static void tvnet_stop_tx_queue(struct tvnet_priv *tvnet) | |||
| 466 | 464 | ||
| 467 | static void tvnet_stop_rx_work(struct tvnet_priv *tvnet) | 465 | static void tvnet_stop_rx_work(struct tvnet_priv *tvnet) |
| 468 | { | 466 | { |
| 469 | cancel_work_sync(&tvnet->alloc_buf_work); | 467 | /* wait for interrupt handle to return to ensure rx is stopped */ |
| 468 | synchronize_irq(pci_irq_vector(tvnet->pdev, 0)); | ||
| 469 | synchronize_irq(pci_irq_vector(tvnet->pdev, 1)); | ||
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | static void tvnet_clear_data_msg_counters(struct tvnet_priv *tvnet) | 472 | static void tvnet_clear_data_msg_counters(struct tvnet_priv *tvnet) |
| @@ -808,10 +808,8 @@ static void tvnet_setup_bar0_md(struct tvnet_priv *tvnet) | |||
| 808 | tvnet->ep2h_full.wr = &ep_mem->ep_cnt->ep2h_full_wr_cnt; | 808 | tvnet->ep2h_full.wr = &ep_mem->ep_cnt->ep2h_full_wr_cnt; |
| 809 | } | 809 | } |
| 810 | 810 | ||
| 811 | static void process_ctrl_msg(struct work_struct *work) | 811 | static void process_ctrl_msg(struct tvnet_priv *tvnet) |
| 812 | { | 812 | { |
| 813 | struct tvnet_priv *tvnet = | ||
| 814 | container_of(work, struct tvnet_priv, ctrl_msg_work); | ||
| 815 | struct ctrl_msg msg; | 813 | struct ctrl_msg msg; |
| 816 | 814 | ||
| 817 | while (tvnet_ivc_rd_available(&tvnet->ep2h_ctrl)) { | 815 | while (tvnet_ivc_rd_available(&tvnet->ep2h_ctrl)) { |
| @@ -881,26 +879,11 @@ static int process_ep2h_msg(struct tvnet_priv *tvnet) | |||
| 881 | return count; | 879 | return count; |
| 882 | } | 880 | } |
| 883 | 881 | ||
| 884 | static void alloc_ep2h_rx_buf(struct work_struct *work) | ||
| 885 | { | ||
| 886 | struct tvnet_priv *tvnet = | ||
| 887 | container_of(work, struct tvnet_priv, alloc_buf_work); | ||
| 888 | |||
| 889 | if (tvnet->os_link_state == OS_LINK_STATE_UP) | ||
| 890 | tvnet_alloc_empty_buffers(tvnet); | ||
| 891 | } | ||
| 892 | |||
| 893 | static irqreturn_t tvnet_irq_ctrl(int irq, void *data) | 882 | static irqreturn_t tvnet_irq_ctrl(int irq, void *data) |
| 894 | { | 883 | { |
| 895 | struct net_device *ndev = data; | 884 | struct net_device *ndev = data; |
| 896 | struct tvnet_priv *tvnet = netdev_priv(ndev); | 885 | struct tvnet_priv *tvnet = netdev_priv(ndev); |
| 897 | 886 | ||
| 898 | if (tvnet_ivc_rd_available(&tvnet->ep2h_ctrl)) | ||
| 899 | schedule_work(&tvnet->ctrl_msg_work); | ||
| 900 | |||
| 901 | if (!tvnet_ivc_full(&tvnet->ep2h_empty)) | ||
| 902 | schedule_work(&tvnet->alloc_buf_work); | ||
| 903 | |||
| 904 | if (netif_queue_stopped(ndev)) { | 887 | if (netif_queue_stopped(ndev)) { |
| 905 | if ((tvnet->os_link_state == OS_LINK_STATE_UP) && | 888 | if ((tvnet->os_link_state == OS_LINK_STATE_UP) && |
| 906 | tvnet_ivc_rd_available(&tvnet->h2ep_empty) && | 889 | tvnet_ivc_rd_available(&tvnet->h2ep_empty) && |
| @@ -910,6 +893,13 @@ static irqreturn_t tvnet_irq_ctrl(int irq, void *data) | |||
| 910 | } | 893 | } |
| 911 | } | 894 | } |
| 912 | 895 | ||
| 896 | if (tvnet_ivc_rd_available(&tvnet->ep2h_ctrl)) | ||
| 897 | process_ctrl_msg(tvnet); | ||
| 898 | |||
| 899 | if (!tvnet_ivc_full(&tvnet->ep2h_empty) && | ||
| 900 | (tvnet->os_link_state == OS_LINK_STATE_UP)) | ||
| 901 | tvnet_alloc_empty_buffers(tvnet); | ||
| 902 | |||
| 913 | return IRQ_HANDLED; | 903 | return IRQ_HANDLED; |
| 914 | } | 904 | } |
| 915 | 905 | ||
| @@ -1053,8 +1043,6 @@ static int tvnet_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
| 1053 | tvnet_write_dma_msix_settings(tvnet); | 1043 | tvnet_write_dma_msix_settings(tvnet); |
| 1054 | #endif | 1044 | #endif |
| 1055 | 1045 | ||
| 1056 | INIT_WORK(&tvnet->ctrl_msg_work, process_ctrl_msg); | ||
| 1057 | INIT_WORK(&tvnet->alloc_buf_work, alloc_ep2h_rx_buf); | ||
| 1058 | INIT_LIST_HEAD(&tvnet->ep2h_empty_list); | 1046 | INIT_LIST_HEAD(&tvnet->ep2h_empty_list); |
| 1059 | spin_lock_init(&tvnet->ep2h_empty_lock); | 1047 | spin_lock_init(&tvnet->ep2h_empty_lock); |
| 1060 | 1048 | ||
diff --git a/drivers/pci/endpoint/functions/pci-epf-tegra-vnet.c b/drivers/pci/endpoint/functions/pci-epf-tegra-vnet.c index d3cca653a..026402166 100644 --- a/drivers/pci/endpoint/functions/pci-epf-tegra-vnet.c +++ b/drivers/pci/endpoint/functions/pci-epf-tegra-vnet.c | |||
| @@ -253,8 +253,6 @@ struct pci_epf_tvnet { | |||
| 253 | /* To synchronize network link state machine*/ | 253 | /* To synchronize network link state machine*/ |
| 254 | struct mutex link_state_lock; | 254 | struct mutex link_state_lock; |
| 255 | wait_queue_head_t link_state_wq; | 255 | wait_queue_head_t link_state_wq; |
| 256 | struct work_struct ctrl_msg_work; | ||
| 257 | struct work_struct alloc_buf_work; | ||
| 258 | struct list_head h2ep_empty_list; | 256 | struct list_head h2ep_empty_list; |
| 259 | #if ENABLE_DMA | 257 | #if ENABLE_DMA |
| 260 | struct dma_desc_cnt desc_cnt; | 258 | struct dma_desc_cnt desc_cnt; |
| @@ -569,7 +567,7 @@ static void tvnet_stop_tx_queue(struct pci_epf_tvnet *tvnet) | |||
| 569 | 567 | ||
| 570 | static void tvnet_stop_rx_work(struct pci_epf_tvnet *tvnet) | 568 | static void tvnet_stop_rx_work(struct pci_epf_tvnet *tvnet) |
| 571 | { | 569 | { |
| 572 | cancel_work_sync(&tvnet->alloc_buf_work); | 570 | /* TODO wait for syncpoint interrupt handlers */ |
| 573 | } | 571 | } |
| 574 | 572 | ||
| 575 | static void tvnet_clear_data_msg_counters(struct pci_epf_tvnet *tvnet) | 573 | static void tvnet_clear_data_msg_counters(struct pci_epf_tvnet *tvnet) |
| @@ -884,10 +882,8 @@ static const struct net_device_ops tvnet_netdev_ops = { | |||
| 884 | .ndo_start_xmit = tvnet_start_xmit, | 882 | .ndo_start_xmit = tvnet_start_xmit, |
| 885 | }; | 883 | }; |
| 886 | 884 | ||
| 887 | static void process_ctrl_msg(struct work_struct *work) | 885 | static void process_ctrl_msg(struct pci_epf_tvnet *tvnet) |
| 888 | { | 886 | { |
| 889 | struct pci_epf_tvnet *tvnet = | ||
| 890 | container_of(work, struct pci_epf_tvnet, ctrl_msg_work); | ||
| 891 | struct ctrl_msg msg; | 887 | struct ctrl_msg msg; |
| 892 | 888 | ||
| 893 | while (tvnet_ivc_rd_available(&tvnet->h2ep_ctrl)) { | 889 | while (tvnet_ivc_rd_available(&tvnet->h2ep_ctrl)) { |
| @@ -978,15 +974,6 @@ static int process_h2ep_msg(struct pci_epf_tvnet *tvnet) | |||
| 978 | return count; | 974 | return count; |
| 979 | } | 975 | } |
| 980 | 976 | ||
| 981 | static void alloc_h2ep_rx_buf(struct work_struct *work) | ||
| 982 | { | ||
| 983 | struct pci_epf_tvnet *tvnet = | ||
| 984 | container_of(work, struct pci_epf_tvnet, alloc_buf_work); | ||
| 985 | |||
| 986 | if (tvnet->os_link_state == OS_LINK_STATE_UP) | ||
| 987 | tvnet_alloc_empty_buffers(tvnet); | ||
| 988 | } | ||
| 989 | |||
| 990 | #if ENABLE_DMA | 977 | #if ENABLE_DMA |
| 991 | static void tvnet_setup_ep_dma(struct pci_epf_tvnet *tvnet) | 978 | static void tvnet_setup_ep_dma(struct pci_epf_tvnet *tvnet) |
| 992 | { | 979 | { |
| @@ -1067,12 +1054,6 @@ static void ctrl_irqsp_callback(void *private_data) | |||
| 1067 | struct pci_epf_tvnet *tvnet = dev_get_drvdata(data_irqsp->dev); | 1054 | struct pci_epf_tvnet *tvnet = dev_get_drvdata(data_irqsp->dev); |
| 1068 | struct net_device *ndev = tvnet->ndev; | 1055 | struct net_device *ndev = tvnet->ndev; |
| 1069 | 1056 | ||
| 1070 | if (tvnet_ivc_rd_available(&tvnet->h2ep_ctrl)) | ||
| 1071 | schedule_work(&tvnet->ctrl_msg_work); | ||
| 1072 | |||
| 1073 | if (!tvnet_ivc_full(&tvnet->h2ep_empty)) | ||
| 1074 | schedule_work(&tvnet->alloc_buf_work); | ||
| 1075 | |||
| 1076 | if (netif_queue_stopped(ndev)) { | 1057 | if (netif_queue_stopped(ndev)) { |
| 1077 | if ((tvnet->os_link_state == OS_LINK_STATE_UP) && | 1058 | if ((tvnet->os_link_state == OS_LINK_STATE_UP) && |
| 1078 | tvnet_ivc_rd_available(&tvnet->ep2h_empty) && | 1059 | tvnet_ivc_rd_available(&tvnet->ep2h_empty) && |
| @@ -1081,6 +1062,13 @@ static void ctrl_irqsp_callback(void *private_data) | |||
| 1081 | } | 1062 | } |
| 1082 | } | 1063 | } |
| 1083 | 1064 | ||
| 1065 | if (tvnet_ivc_rd_available(&tvnet->h2ep_ctrl)) | ||
| 1066 | process_ctrl_msg(tvnet); | ||
| 1067 | |||
| 1068 | if (!tvnet_ivc_full(&tvnet->h2ep_empty) && | ||
| 1069 | (tvnet->os_link_state == OS_LINK_STATE_UP)) | ||
| 1070 | tvnet_alloc_empty_buffers(tvnet); | ||
| 1071 | |||
| 1084 | schedule_work(&data_irqsp->reprime_work); | 1072 | schedule_work(&data_irqsp->reprime_work); |
| 1085 | } | 1073 | } |
| 1086 | 1074 | ||
| @@ -1605,8 +1593,6 @@ static int pci_epf_tvnet_bind(struct pci_epf *epf) | |||
| 1605 | mutex_init(&tvnet->link_state_lock); | 1593 | mutex_init(&tvnet->link_state_lock); |
| 1606 | init_waitqueue_head(&tvnet->link_state_wq); | 1594 | init_waitqueue_head(&tvnet->link_state_wq); |
| 1607 | 1595 | ||
| 1608 | INIT_WORK(&tvnet->ctrl_msg_work, process_ctrl_msg); | ||
| 1609 | INIT_WORK(&tvnet->alloc_buf_work, alloc_h2ep_rx_buf); | ||
| 1610 | INIT_LIST_HEAD(&tvnet->h2ep_empty_list); | 1596 | INIT_LIST_HEAD(&tvnet->h2ep_empty_list); |
| 1611 | spin_lock_init(&tvnet->h2ep_empty_lock); | 1597 | spin_lock_init(&tvnet->h2ep_empty_lock); |
| 1612 | 1598 | ||
| @@ -1683,7 +1669,6 @@ static void pci_epf_tvnet_unbind(struct pci_epf *epf) | |||
| 1683 | 1669 | ||
| 1684 | cancel_work_sync(&tvnet->ctrl_irqsp->reprime_work); | 1670 | cancel_work_sync(&tvnet->ctrl_irqsp->reprime_work); |
| 1685 | cancel_work_sync(&tvnet->data_irqsp->reprime_work); | 1671 | cancel_work_sync(&tvnet->data_irqsp->reprime_work); |
| 1686 | cancel_work_sync(&tvnet->alloc_buf_work); | ||
| 1687 | pci_epc_stop(epc); | 1672 | pci_epc_stop(epc); |
| 1688 | pci_epc_clear_bar(epc, BAR_0); | 1673 | pci_epc_clear_bar(epc, BAR_0); |
| 1689 | dma_free_coherent(cdev, | 1674 | dma_free_coherent(cdev, |
