diff options
author | Wilson Sung <wilsonsung@google.com> | 2020-02-17 14:40:25 +0800 |
---|---|---|
committer | Wilson Sung <wilsonsung@google.com> | 2020-02-17 14:50:07 +0800 |
commit | 497908947a2496da943625aec8b193ad89c692af (patch) | |
tree | 7979f5bad7674fea0925861255eaa894d579455b | |
parent | df7ee6ef20b0e01af170dc11a81fc85902b2f689 (diff) | |
parent | 384f80012cfcad8b1c79c715aecae5806bf31703 (diff) | |
download | data-kernel-497908947a2496da943625aec8b193ad89c692af.tar.gz |
Merge branch 'LA.UM.9.1.R1.10.00.00.604.021' via branch 'qcom-msm-4.14' into android-msm-floral-4.14android-r-preview-4_r0.7android-msm-coral-4.14-r-preview-4
Bug: 149660093
Change-Id: Ibc0260e3160dd1a4b421b2559312bc16a5c0c7d8
Signed-off-by: Wilson Sung <wilsonsung@google.com>
-rw-r--r-- | drivers/emac-dwc-eqos/Android.mk | 9 | ||||
-rw-r--r-- | drivers/emac-dwc-eqos/DWC_ETH_QOS_ipa.c | 18 | ||||
-rw-r--r-- | drivers/emac-dwc-eqos/DWC_ETH_QOS_mdio.c | 19 | ||||
-rw-r--r-- | drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c | 17 | ||||
-rw-r--r-- | drivers/emac-dwc-eqos/DWC_ETH_QOS_rgmii_io_macro.c | 23 | ||||
-rw-r--r-- | drivers/emac-dwc-eqos/emac_perf_settings.sh | 22 | ||||
-rw-r--r-- | drivers/rmnet/perf/rmnet_perf_config.c | 7 | ||||
-rw-r--r-- | drivers/rmnet/shs/rmnet_shs.h | 4 | ||||
-rw-r--r-- | drivers/rmnet/shs/rmnet_shs_config.c | 6 | ||||
-rwxr-xr-x | drivers/rmnet/shs/rmnet_shs_main.c | 19 | ||||
-rw-r--r-- | drivers/rmnet/shs/rmnet_shs_wq.c | 13 | ||||
-rw-r--r-- | drivers/rmnet/shs/rmnet_shs_wq.h | 6 | ||||
-rw-r--r-- | drivers/rmnet/shs/rmnet_shs_wq_mem.c | 103 |
13 files changed, 210 insertions, 56 deletions
diff --git a/drivers/emac-dwc-eqos/Android.mk b/drivers/emac-dwc-eqos/Android.mk index a50d64f..cff761a 100644 --- a/drivers/emac-dwc-eqos/Android.mk +++ b/drivers/emac-dwc-eqos/Android.mk @@ -22,6 +22,15 @@ KBUILD_OPTIONS += DCONFIG_DEBUGFS_OBJ=1 LOCAL_MODULE := emac_dwc_eqos.ko LOCAL_MODULE_TAGS := optional include $(DLKM_DIR)/AndroidKernelModule.mk + +include $(CLEAR_VARS) +LOCAL_MODULE := emac_perf_settings.sh +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/emac +LOCAL_SRC_FILES := emac_perf_settings.sh +include $(BUILD_PREBUILT) + endif endif diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_ipa.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_ipa.c index c09a6f5..f871ce3 100644 --- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_ipa.c +++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_ipa.c @@ -684,15 +684,19 @@ static void ntn_ipa_notify_cb(void *priv, enum ipa_dp_evt_type evt, /* Submit packet to network stack */ /* If its a ping packet submit it via rx_ni else use rx */ - if (ip_hdr->protocol == IPPROTO_ICMP) { - stat = netif_rx_ni(skb); - } else if ((pdata->dev->stats.rx_packets % - IPA_ETH_RX_SOFTIRQ_THRESH) == 0){ - stat = netif_rx_ni(skb); + /* If NAPI is enabled call receive_skb */ + if(ipa_get_lan_rx_napi()){ + stat = netif_receive_skb(skb); } else { - stat = netif_rx(skb); + if (ip_hdr->protocol == IPPROTO_ICMP) { + stat = netif_rx_ni(skb); + } else if ((pdata->dev->stats.rx_packets % + IPA_ETH_RX_SOFTIRQ_THRESH) == 0){ + stat = netif_rx_ni(skb); + } else { + stat = netif_rx(skb); + } } - if(stat == NET_RX_DROP) { pdata->dev->stats.rx_dropped++; } else { diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_mdio.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_mdio.c index 57c9383..faac49e 100644 --- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_mdio.c +++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_mdio.c @@ -543,7 +543,8 @@ static void set_phy_rx_tx_delay(struct DWC_ETH_QOS_prv_data *pdata, EMACDBG("Read 0x%x from offset 0x8\n",phydata); phydata = 0; - if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2) { + if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2 + || pdata->emac_hw_version_type == EMAC_HW_v2_1_1) { u16 tx_clk = 0xE; /* Provide TX_CLK delay of -0.06nsec */ DWC_ETH_QOS_mdio_mmd_register_read_direct(pdata, pdata->phyaddr, @@ -562,7 +563,8 @@ static void set_phy_rx_tx_delay(struct DWC_ETH_QOS_prv_data *pdata, DWC_ETH_QOS_mdio_mmd_register_read_direct(pdata, pdata->phyaddr, DWC_ETH_QOS_MICREL_PHY_DEBUG_MMD_DEV_ADDR,0x5,&phydata); phydata &= ~(0xFF); - if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2) + if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2 || + pdata->emac_hw_version_type == EMAC_HW_v2_1_1) phydata |= ((0x2 << 12) | (0x2 << 8) | (0x2 << 4) | 0x2); else /* Default settings for EMAC_HW_v2_1_0 */ @@ -579,7 +581,8 @@ static void set_phy_rx_tx_delay(struct DWC_ETH_QOS_prv_data *pdata, DWC_ETH_QOS_mdio_mmd_register_read_direct(pdata, pdata->phyaddr, DWC_ETH_QOS_MICREL_PHY_DEBUG_MMD_DEV_ADDR,0x4,&phydata); phydata &= ~(0xF << 4); - if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2) + if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2 || + pdata->emac_hw_version_type == EMAC_HW_v2_1_1) phydata |= (0x2 << 4); else /* Default settings for EMAC_HW_v2_1_0 */ @@ -654,9 +657,10 @@ static void configure_phy_rx_tx_delay(struct DWC_ETH_QOS_prv_data *pdata) set_phy_rx_tx_delay(pdata, ENABLE_RX_DELAY, ENABLE_TX_DELAY); } else { /* Settings for RGMII ID mode. - Not applicable for EMAC core version 2.1.0 and 2.1.2 */ + Not applicable for EMAC core version 2.1.0, 2.1.2 and 2.1.1 */ if (pdata->emac_hw_version_type != EMAC_HW_v2_1_0 && - pdata->emac_hw_version_type != EMAC_HW_v2_1_2) + pdata->emac_hw_version_type != EMAC_HW_v2_1_2 && + pdata->emac_hw_version_type != EMAC_HW_v2_1_1) set_phy_rx_tx_delay(pdata, DISABLE_RX_DELAY, DISABLE_TX_DELAY); } break; @@ -675,9 +679,10 @@ static void configure_phy_rx_tx_delay(struct DWC_ETH_QOS_prv_data *pdata) set_phy_rx_tx_delay(pdata, DISABLE_RX_DELAY, ENABLE_TX_DELAY); } else { /* Settings for RGMII ID mode */ - /* Not applicable for EMAC core version 2.1.0 and 2.1.2 */ + /* Not applicable for EMAC core version 2.1.0, 2.1.2 and 2.1.1 */ if (pdata->emac_hw_version_type != EMAC_HW_v2_1_0 && - pdata->emac_hw_version_type != EMAC_HW_v2_1_2) + pdata->emac_hw_version_type != EMAC_HW_v2_1_2 && + pdata->emac_hw_version_type != EMAC_HW_v2_1_1) set_phy_rx_tx_delay(pdata, DISABLE_RX_DELAY, DISABLE_TX_DELAY); } } diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c index 4d57d7a..50d1e55 100644 --- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c +++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c @@ -1037,8 +1037,9 @@ int DWC_ETH_QOS_enable_ptp_clk(struct device *dev) int ret; const char* ptp_clock_name; - if (dwc_eth_qos_res_data.emac_hw_version_type == EMAC_HW_v2_1_0 || - dwc_eth_qos_res_data.emac_hw_version_type == EMAC_HW_v2_1_2) + if (dwc_eth_qos_res_data.emac_hw_version_type == EMAC_HW_v2_1_0 + || dwc_eth_qos_res_data.emac_hw_version_type == EMAC_HW_v2_1_2 + || dwc_eth_qos_res_data.emac_hw_version_type == EMAC_HW_v2_1_1) ptp_clock_name = "emac_ptp_clk"; else ptp_clock_name = "eth_ptp_clk"; @@ -1186,8 +1187,9 @@ static int DWC_ETH_QOS_get_clks(struct device *dev) dwc_eth_qos_res_data.rgmii_clk = NULL; dwc_eth_qos_res_data.ptp_clk = NULL; - if (dwc_eth_qos_res_data.emac_hw_version_type == EMAC_HW_v2_1_0 || - (dwc_eth_qos_res_data.emac_hw_version_type == EMAC_HW_v2_1_2)) { + if (dwc_eth_qos_res_data.emac_hw_version_type == EMAC_HW_v2_1_0 + || dwc_eth_qos_res_data.emac_hw_version_type == EMAC_HW_v2_1_2 + || dwc_eth_qos_res_data.emac_hw_version_type == EMAC_HW_v2_1_1) { /* EMAC core version 2.1.0 clocks */ axi_clock_name = "emac_axi_clk"; ahb_clock_name = "emac_slv_ahb_clk"; @@ -2262,6 +2264,13 @@ int DWC_ETH_QOS_remove(struct platform_device *pdev) static void DWC_ETH_QOS_shutdown(struct platform_device *pdev) { pr_info("qcom-emac-dwc-eqos: DWC_ETH_QOS_shutdown\n"); +#ifdef DWC_ETH_QOS_BUILTIN + if (gDWC_ETH_QOS_prv_data->dev->flags & IFF_UP) { + gDWC_ETH_QOS_prv_data->dev->netdev_ops->ndo_stop(gDWC_ETH_QOS_prv_data->dev); + gDWC_ETH_QOS_prv_data->dev->flags &= ~IFF_UP; + } + DWC_ETH_QOS_remove(pdev); +#endif } #ifdef CONFIG_PM diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_rgmii_io_macro.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_rgmii_io_macro.c index ad6736f..ebd302c 100644 --- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_rgmii_io_macro.c +++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_rgmii_io_macro.c @@ -364,7 +364,8 @@ int DWC_ETH_QOS_rgmii_io_macro_init(struct DWC_ETH_QOS_prv_data *pdata) uint rgmii_data_divide_clk; ULONG data; - if (pdata->emac_hw_version_type == EMAC_HW_v2_3_0 || (pdata->emac_hw_version_type == EMAC_HW_v2_3_1)) { + if (pdata->emac_hw_version_type == EMAC_HW_v2_3_0 || (pdata->emac_hw_version_type == EMAC_HW_v2_3_1) + || (pdata->emac_hw_version_type == EMAC_HW_v2_1_1)) { if(pdata->io_macro_phy_intf == RGMII_MODE) loopback_mode_en = 0x1; rgmii_data_divide_clk = 0x0; @@ -403,7 +404,8 @@ int DWC_ETH_QOS_rgmii_io_macro_init(struct DWC_ETH_QOS_prv_data *pdata) RGMII_LOOPBACK_EN_UDFWR(loopback_mode_en); if (pdata->emac_hw_version_type == EMAC_HW_v2_1_0 || pdata->emac_hw_version_type == EMAC_HW_v2_1_2 || - (pdata->emac_hw_version_type == EMAC_HW_v2_3_1)) + (pdata->emac_hw_version_type == EMAC_HW_v2_3_1) || + pdata->emac_hw_version_type == EMAC_HW_v2_1_1) RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x1); } else { /* Enable DDR mode*/ @@ -429,6 +431,8 @@ int DWC_ETH_QOS_rgmii_io_macro_init(struct DWC_ETH_QOS_prv_data *pdata) SDCC_HC_PRG_RCLK_DLY_UDFWR(52); else if (pdata->emac_hw_version_type == EMAC_HW_v2_3_1) SDCC_HC_PRG_RCLK_DLY_UDFWR(104); + else if (pdata->emac_hw_version_type == EMAC_HW_v2_1_1) + SDCC_HC_PRG_RCLK_DLY_UDFWR(130); else { /* Program PRG_RCLK_DLY to 57 for a required delay of 1.8 ns */ SDCC_HC_PRG_RCLK_DLY_UDFWR(57); } @@ -459,9 +463,11 @@ int DWC_ETH_QOS_rgmii_io_macro_init(struct DWC_ETH_QOS_prv_data *pdata) RGMII_LOOPBACK_EN_UDFWR(loopback_mode_en); if (pdata->emac_hw_version_type == EMAC_HW_v2_1_0 || pdata->emac_hw_version_type == EMAC_HW_v2_1_2 || - (pdata->emac_hw_version_type == EMAC_HW_v2_3_1)) + (pdata->emac_hw_version_type == EMAC_HW_v2_3_1) || + pdata->emac_hw_version_type == EMAC_HW_v2_1_1) RGMII_CONFIG_2_RX_PROG_SWAP_UDFWR(0x1); - if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2) + if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2 || + pdata->emac_hw_version_type == EMAC_HW_v2_1_1) RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x1); } else{ RGMII_DDR_MODE_UDFWR(0x1); @@ -506,9 +512,11 @@ int DWC_ETH_QOS_rgmii_io_macro_init(struct DWC_ETH_QOS_prv_data *pdata) RGMII_LOOPBACK_EN_UDFWR(loopback_mode_en); if (pdata->emac_hw_version_type == EMAC_HW_v2_1_0 || pdata->emac_hw_version_type == EMAC_HW_v2_1_2 || - (pdata->emac_hw_version_type == EMAC_HW_v2_3_1)) + (pdata->emac_hw_version_type == EMAC_HW_v2_3_1) || + pdata->emac_hw_version_type == EMAC_HW_v2_1_1) RGMII_CONFIG_2_RX_PROG_SWAP_UDFWR(0x1); - if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2) + if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2 || + pdata->emac_hw_version_type == EMAC_HW_v2_1_1) RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x1); } else{ RGMII_DDR_MODE_UDFWR(0x1); @@ -570,7 +578,8 @@ int DWC_ETH_QOS_rgmii_io_macro_init(struct DWC_ETH_QOS_prv_data *pdata) RGMII_CONFIG_2_DATA_DIVIDE_CLK_SEL_UDFWR(0x1); RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x0); RGMII_CONFIG_2_RERVED_CONFIG_16_EN_UDFWR(0x1); - if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2) + if (pdata->emac_hw_version_type == EMAC_HW_v2_1_2 || + pdata->emac_hw_version_type == EMAC_HW_v2_1_1) RGMII_CONFIG_2_TX_CLK_PHASE_SHIFT_EN_UDFWR(0x1); if (pdata->emac_hw_version_type == EMAC_HW_v2_3_1) RGMII_LOOPBACK_EN_UDFWR(0x1); diff --git a/drivers/emac-dwc-eqos/emac_perf_settings.sh b/drivers/emac-dwc-eqos/emac_perf_settings.sh new file mode 100644 index 0000000..508e69d --- /dev/null +++ b/drivers/emac-dwc-eqos/emac_perf_settings.sh @@ -0,0 +1,22 @@ +#!/vendor/bin/sh +#Copyright (c) 2019, The Linux Foundation. All rights reserved. +# +#This program is free software; you can redistribute it and/or modify +#it under the terms of the GNU General Public License version 2 and +#only version 2 as published by the Free Software Foundation. +# +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. +# +# +echo 12582912 > /proc/sys/net/core/wmem_max; +echo 12582912 > /proc/sys/net/core/rmem_max; +echo 10240 87380 12582912 > /proc/sys/net/ipv4/tcp_rmem; +echo 10240 87380 12582912 > /proc/sys/net/ipv4/tcp_wmem; +echo 12582912 > /proc/sys/net/ipv4/udp_rmem_min; +echo 12582912 > /proc/sys/net/ipv4/udp_wmem_min; +echo 1 > /proc/sys/net/ipv4/tcp_window_scaling; +echo 18 > /sys/class/net/eth0/queues/rx-0/rps_cpus; + diff --git a/drivers/rmnet/perf/rmnet_perf_config.c b/drivers/rmnet/perf/rmnet_perf_config.c index 8a5f50e..be245d3 100644 --- a/drivers/rmnet/perf/rmnet_perf_config.c +++ b/drivers/rmnet/perf/rmnet_perf_config.c @@ -397,7 +397,9 @@ static int rmnet_perf_config_notify_cb(struct notifier_block *nb, switch (event) { case NETDEV_UNREGISTER: - if (rmnet_is_real_dev_registered(dev) && + pr_info("%s(): rmnet_perf netdevice unregister, name = %s\n", + __func__, dev->name); + if (perf && rmnet_is_real_dev_registered(dev) && rmnet_perf_config_hook_registered() && (!strncmp(dev->name, "rmnet_ipa0", 10) || !strncmp(dev->name, "rmnet_mhi0", 10))) { @@ -413,6 +415,7 @@ static int rmnet_perf_config_notify_cb(struct notifier_block *nb, RCU_INIT_POINTER(rmnet_perf_deag_entry, NULL); RCU_INIT_POINTER(rmnet_perf_desc_entry, NULL); RCU_INIT_POINTER(rmnet_perf_chain_end, NULL); + perf = NULL; } break; case NETDEV_REGISTER: @@ -421,7 +424,7 @@ static int rmnet_perf_config_notify_cb(struct notifier_block *nb, /* Check prevents us from allocating resources for every * interface */ - if (!rmnet_perf_config_hook_registered() && + if (!perf && !rmnet_perf_config_hook_registered() && strncmp(dev->name, "rmnet_data", 10) == 0) { struct rmnet_priv *priv = netdev_priv(dev); diff --git a/drivers/rmnet/shs/rmnet_shs.h b/drivers/rmnet/shs/rmnet_shs.h index f6ce09e..b7bf773 100644 --- a/drivers/rmnet/shs/rmnet_shs.h +++ b/drivers/rmnet/shs/rmnet_shs.h @@ -299,7 +299,7 @@ extern int (*rmnet_shs_skb_entry)(struct sk_buff *skb, int rmnet_shs_is_lpwr_cpu(u16 cpu); void rmnet_shs_cancel_table(void); void rmnet_shs_rx_wq_init(void); -void rmnet_shs_rx_wq_exit(void); +unsigned int rmnet_shs_rx_wq_exit(void); int rmnet_shs_get_mask_len(u8 mask); int rmnet_shs_chk_and_flush_node(struct rmnet_shs_skbn_s *node, @@ -314,7 +314,7 @@ void rmnet_shs_assign(struct sk_buff *skb, struct rmnet_port *port); void rmnet_shs_flush_table(u8 is_force_flush, u8 ctxt); void rmnet_shs_cpu_node_remove(struct rmnet_shs_skbn_s *node); void rmnet_shs_init(struct net_device *dev, struct net_device *vnd); -void rmnet_shs_exit(void); +void rmnet_shs_exit(unsigned int cpu_switch); void rmnet_shs_ps_on_hdlr(void *port); void rmnet_shs_ps_off_hdlr(void *port); void rmnet_shs_update_cpu_proc_q_all_cpus(void); diff --git a/drivers/rmnet/shs/rmnet_shs_config.c b/drivers/rmnet/shs/rmnet_shs_config.c index e6b4002..6a628dc 100644 --- a/drivers/rmnet/shs/rmnet_shs_config.c +++ b/drivers/rmnet/shs/rmnet_shs_config.c @@ -99,14 +99,16 @@ static int rmnet_shs_dev_notify_cb(struct notifier_block *nb, * phy_dev is going down. */ if (!rmnet_vnd_total && rmnet_shs_cfg.rmnet_shs_init_complete) { + unsigned int cpu_switch; + pr_info("rmnet_shs deinit %s going down ", dev->name); RCU_INIT_POINTER(rmnet_shs_skb_entry, NULL); qmi_rmnet_ps_ind_deregister(rmnet_shs_cfg.port, &rmnet_shs_cfg.rmnet_idl_ind_cb); rmnet_shs_cancel_table(); - rmnet_shs_rx_wq_exit(); + cpu_switch = rmnet_shs_rx_wq_exit(); rmnet_shs_wq_exit(); - rmnet_shs_exit(); + rmnet_shs_exit(cpu_switch); trace_rmnet_shs_high(RMNET_SHS_MODULE, RMNET_SHS_MODULE_INIT_WQ, 0xDEF, 0xDEF, 0xDEF, diff --git a/drivers/rmnet/shs/rmnet_shs_main.c b/drivers/rmnet/shs/rmnet_shs_main.c index ae66460..2accd29 100755 --- a/drivers/rmnet/shs/rmnet_shs_main.c +++ b/drivers/rmnet/shs/rmnet_shs_main.c @@ -1359,14 +1359,25 @@ void rmnet_shs_rx_wq_init(void) INIT_WORK(&shs_rx_work.work, rmnet_flush_buffered); } -void rmnet_shs_rx_wq_exit(void) +unsigned int rmnet_shs_rx_wq_exit(void) { + unsigned int cpu_switch = rmnet_shs_inst_rate_switch; int i; - for (i = 0; i < MAX_CPUS; i++) + /* Disable any further core_flush timer starts untill cleanup + * is complete. + */ + rmnet_shs_inst_rate_switch = 0; + + for (i = 0; i < MAX_CPUS; i++) { + hrtimer_cancel(&GET_CTIMER(i)); + cancel_work_sync(&rmnet_shs_cfg.core_flush[i].work); + } cancel_work_sync(&shs_rx_work.work); + + return cpu_switch; } void rmnet_shs_ps_on_hdlr(void *port) @@ -1724,7 +1735,7 @@ void rmnet_shs_assign(struct sk_buff *skb, struct rmnet_port *port) /* Cancels the flushing timer if it has been armed * Deregisters DL marker indications */ -void rmnet_shs_exit(void) +void rmnet_shs_exit(unsigned int cpu_switch) { rmnet_shs_freq_exit(); rmnet_shs_cfg.dl_mrk_ind_cb.dl_hdr_handler = NULL; @@ -1738,5 +1749,5 @@ void rmnet_shs_exit(void) memset(&rmnet_shs_cfg, 0, sizeof(rmnet_shs_cfg)); rmnet_shs_cfg.port = NULL; rmnet_shs_cfg.rmnet_shs_init_complete = 0; - + rmnet_shs_inst_rate_switch = cpu_switch; } diff --git a/drivers/rmnet/shs/rmnet_shs_wq.c b/drivers/rmnet/shs/rmnet_shs_wq.c index 298058c..4c69b57 100644 --- a/drivers/rmnet/shs/rmnet_shs_wq.c +++ b/drivers/rmnet/shs/rmnet_shs_wq.c @@ -455,6 +455,9 @@ static u64 rmnet_shs_wq_get_flow_avg_pps(struct rmnet_shs_wq_hstat_s *hnode) /* More weight to current value */ new_weight = rmnet_shs_wq_tuning; old_weight = 100 - rmnet_shs_wq_tuning; + } else { + old_weight = rmnet_shs_wq_tuning; + new_weight = 100 - rmnet_shs_wq_tuning; } /* computing weighted average per flow, if the flow has just started, @@ -2191,3 +2194,13 @@ u64 rmnet_shs_wq_get_max_allowed_pps(u16 cpu) return rmnet_shs_cpu_rx_max_pps_thresh[cpu]; } + +void rmnet_shs_wq_ep_lock_bh(void) +{ + spin_lock_bh(&rmnet_shs_ep_lock); +} + +void rmnet_shs_wq_ep_unlock_bh(void) +{ + spin_unlock_bh(&rmnet_shs_ep_lock); +} diff --git a/drivers/rmnet/shs/rmnet_shs_wq.h b/drivers/rmnet/shs/rmnet_shs_wq.h index ed37dc8..0d86200 100644 --- a/drivers/rmnet/shs/rmnet_shs_wq.h +++ b/drivers/rmnet/shs/rmnet_shs_wq.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -285,4 +285,8 @@ int rmnet_shs_wq_try_to_move_flow(u16 cur_cpu, u16 dest_cpu, u32 hash_to_move, int rmnet_shs_wq_set_flow_segmentation(u32 hash_to_set, u8 seg_enable); +void rmnet_shs_wq_ep_lock_bh(void); + +void rmnet_shs_wq_ep_unlock_bh(void); + #endif /*_RMNET_SHS_WQ_H_*/ diff --git a/drivers/rmnet/shs/rmnet_shs_wq_mem.c b/drivers/rmnet/shs/rmnet_shs_wq_mem.c index e80d424..1675517 100644 --- a/drivers/rmnet/shs/rmnet_shs_wq_mem.c +++ b/drivers/rmnet/shs/rmnet_shs_wq_mem.c @@ -49,13 +49,14 @@ static int rmnet_shs_vm_fault(struct vm_fault *vmf) struct page *page = NULL; struct rmnet_shs_mmap_info *info; - + rmnet_shs_wq_ep_lock_bh(); info = (struct rmnet_shs_mmap_info *) vmf->vma->vm_private_data; if (info->data) { page = virt_to_page(info->data); get_page(page); vmf->page = page; } + rmnet_shs_wq_ep_unlock_bh(); return 0; } @@ -80,13 +81,19 @@ static int rmnet_shs_open_caps(struct inode *inode, struct file *filp) struct rmnet_shs_mmap_info *info; rm_err("%s", "SHS_MEM: rmnet_shs_open - entry\n"); + + rmnet_shs_wq_ep_lock_bh(); if (!cap_shared) { - info = kzalloc(sizeof(struct rmnet_shs_mmap_info), GFP_KERNEL); - if (!info) { - rm_err("%s", "SHS_MEM: rmnet_shs_open - FAILED\n"); - return -ENOMEM; + info = kzalloc(sizeof(struct rmnet_shs_mmap_info), GFP_ATOMIC); + if (!info) + goto fail; + + info->data = (char *)get_zeroed_page(GFP_ATOMIC); + if (!info->data) { + kfree(info); + goto fail; } - info->data = (char *)get_zeroed_page(GFP_KERNEL); + cap_shared = info; rm_err("SHS_MEM: virt_to_phys = 0x%llx cap_shared = 0x%llx\n", (unsigned long long)virt_to_phys((void *)info), @@ -94,10 +101,16 @@ static int rmnet_shs_open_caps(struct inode *inode, struct file *filp) } filp->private_data = cap_shared; + rmnet_shs_wq_ep_unlock_bh(); rm_err("%s", "SHS_MEM: rmnet_shs_open - OK\n"); return 0; + +fail: + rmnet_shs_wq_ep_unlock_bh(); + rm_err("%s", "SHS_MEM: rmnet_shs_open - FAILED\n"); + return -ENOMEM; } static int rmnet_shs_open_g_flows(struct inode *inode, struct file *filp) @@ -105,20 +118,33 @@ static int rmnet_shs_open_g_flows(struct inode *inode, struct file *filp) struct rmnet_shs_mmap_info *info; rm_err("%s", "SHS_MEM: rmnet_shs_open g_flows - entry\n"); + + rmnet_shs_wq_ep_lock_bh(); if (!gflow_shared) { - info = kzalloc(sizeof(struct rmnet_shs_mmap_info), GFP_KERNEL); - if (!info) { - rm_err("%s", "SHS_MEM: rmnet_shs_open - FAILED\n"); - return -ENOMEM; + info = kzalloc(sizeof(struct rmnet_shs_mmap_info), GFP_ATOMIC); + if (!info) + goto fail; + + info->data = (char *)get_zeroed_page(GFP_ATOMIC); + if (!info->data) { + kfree(info); + goto fail; } - info->data = (char *)get_zeroed_page(GFP_KERNEL); + gflow_shared = info; rm_err("SHS_MEM: virt_to_phys = 0x%llx gflow_shared = 0x%llx\n", (unsigned long long)virt_to_phys((void *)info), (unsigned long long)virt_to_phys((void *)gflow_shared)); } filp->private_data = gflow_shared; + rmnet_shs_wq_ep_unlock_bh(); + return 0; + +fail: + rmnet_shs_wq_ep_unlock_bh(); + rm_err("%s", "SHS_MEM: rmnet_shs_open - FAILED\n"); + return -ENOMEM; } static int rmnet_shs_open_ss_flows(struct inode *inode, struct file *filp) @@ -126,34 +152,50 @@ static int rmnet_shs_open_ss_flows(struct inode *inode, struct file *filp) struct rmnet_shs_mmap_info *info; rm_err("%s", "SHS_MEM: rmnet_shs_open ss_flows - entry\n"); + + rmnet_shs_wq_ep_lock_bh(); if (!ssflow_shared) { - info = kzalloc(sizeof(struct rmnet_shs_mmap_info), GFP_KERNEL); - if (!info) { - rm_err("%s", "SHS_MEM: rmnet_shs_open - FAILED\n"); - return -ENOMEM; + info = kzalloc(sizeof(struct rmnet_shs_mmap_info), GFP_ATOMIC); + if (!info) + goto fail; + + info->data = (char *)get_zeroed_page(GFP_ATOMIC); + if (!info->data) { + kfree(info); + goto fail; } - info->data = (char *)get_zeroed_page(GFP_KERNEL); + ssflow_shared = info; rm_err("SHS_MEM: virt_to_phys = 0x%llx ssflow_shared = 0x%llx\n", (unsigned long long)virt_to_phys((void *)info), (unsigned long long)virt_to_phys((void *)ssflow_shared)); } filp->private_data = ssflow_shared; + rmnet_shs_wq_ep_unlock_bh(); + return 0; + +fail: + rmnet_shs_wq_ep_unlock_bh(); + rm_err("%s", "SHS_MEM: rmnet_shs_open - FAILED\n"); + return -ENOMEM; } static ssize_t rmnet_shs_read(struct file *filp, char __user *buf, size_t len, loff_t *off) { struct rmnet_shs_mmap_info *info; - int ret; + int ret = 0; rm_err("%s", "SHS_MEM: rmnet_shs_read - entry\n"); + + rmnet_shs_wq_ep_lock_bh(); info = filp->private_data; ret = min_t(size_t, len, RMNET_SHS_BUFFER_SIZE); if (copy_to_user(buf, info->data, ret)) ret = -EFAULT; + rmnet_shs_wq_ep_unlock_bh(); - return 0; + return ret; } static ssize_t rmnet_shs_write(struct file *filp, const char __user *buf, size_t len, loff_t *off) @@ -162,12 +204,17 @@ static ssize_t rmnet_shs_write(struct file *filp, const char __user *buf, size_t int ret; rm_err("%s", "SHS_MEM: rmnet_shs_write - entry\n"); + + rmnet_shs_wq_ep_lock_bh(); info = filp->private_data; ret = min_t(size_t, len, RMNET_SHS_BUFFER_SIZE); if (copy_from_user(info->data, buf, ret)) - return -EFAULT; + ret = -EFAULT; else - return len; + ret = len; + rmnet_shs_wq_ep_unlock_bh(); + + return ret; } static int rmnet_shs_release_caps(struct inode *inode, struct file *filp) @@ -175,6 +222,8 @@ static int rmnet_shs_release_caps(struct inode *inode, struct file *filp) struct rmnet_shs_mmap_info *info; rm_err("%s", "SHS_MEM: rmnet_shs_release - entry\n"); + + rmnet_shs_wq_ep_lock_bh(); if (cap_shared) { info = filp->private_data; cap_shared = NULL; @@ -182,6 +231,8 @@ static int rmnet_shs_release_caps(struct inode *inode, struct file *filp) kfree(info); filp->private_data = NULL; } + rmnet_shs_wq_ep_unlock_bh(); + return 0; } @@ -190,6 +241,8 @@ static int rmnet_shs_release_g_flows(struct inode *inode, struct file *filp) struct rmnet_shs_mmap_info *info; rm_err("%s", "SHS_MEM: rmnet_shs_release - entry\n"); + + rmnet_shs_wq_ep_lock_bh(); if (gflow_shared) { info = filp->private_data; gflow_shared = NULL; @@ -197,6 +250,8 @@ static int rmnet_shs_release_g_flows(struct inode *inode, struct file *filp) kfree(info); filp->private_data = NULL; } + rmnet_shs_wq_ep_unlock_bh(); + return 0; } @@ -205,6 +260,8 @@ static int rmnet_shs_release_ss_flows(struct inode *inode, struct file *filp) struct rmnet_shs_mmap_info *info; rm_err("%s", "SHS_MEM: rmnet_shs_release - entry\n"); + + rmnet_shs_wq_ep_lock_bh(); if (ssflow_shared) { info = filp->private_data; ssflow_shared = NULL; @@ -212,6 +269,8 @@ static int rmnet_shs_release_ss_flows(struct inode *inode, struct file *filp) kfree(info); filp->private_data = NULL; } + rmnet_shs_wq_ep_unlock_bh(); + return 0; } @@ -607,9 +666,11 @@ void rmnet_shs_wq_mem_init(void) proc_create(RMNET_SHS_PROC_G_FLOWS, 0644, shs_proc_dir, &rmnet_shs_g_flows_fops); proc_create(RMNET_SHS_PROC_SS_FLOWS, 0644, shs_proc_dir, &rmnet_shs_ss_flows_fops); + rmnet_shs_wq_ep_lock_bh(); cap_shared = NULL; gflow_shared = NULL; ssflow_shared = NULL; + rmnet_shs_wq_ep_unlock_bh(); } /* Remove shs files and folders from proc fs */ @@ -620,7 +681,9 @@ void rmnet_shs_wq_mem_deinit(void) remove_proc_entry(RMNET_SHS_PROC_SS_FLOWS, shs_proc_dir); remove_proc_entry(RMNET_SHS_PROC_DIR, NULL); + rmnet_shs_wq_ep_lock_bh(); cap_shared = NULL; gflow_shared = NULL; ssflow_shared = NULL; + rmnet_shs_wq_ep_unlock_bh(); } |