summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilson Sung <wilsonsung@google.com>2020-02-17 14:40:25 +0800
committerWilson Sung <wilsonsung@google.com>2020-02-17 14:50:07 +0800
commit497908947a2496da943625aec8b193ad89c692af (patch)
tree7979f5bad7674fea0925861255eaa894d579455b
parentdf7ee6ef20b0e01af170dc11a81fc85902b2f689 (diff)
parent384f80012cfcad8b1c79c715aecae5806bf31703 (diff)
downloaddata-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.mk9
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_ipa.c18
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_mdio.c19
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_platform.c17
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_rgmii_io_macro.c23
-rw-r--r--drivers/emac-dwc-eqos/emac_perf_settings.sh22
-rw-r--r--drivers/rmnet/perf/rmnet_perf_config.c7
-rw-r--r--drivers/rmnet/shs/rmnet_shs.h4
-rw-r--r--drivers/rmnet/shs/rmnet_shs_config.c6
-rwxr-xr-xdrivers/rmnet/shs/rmnet_shs_main.c19
-rw-r--r--drivers/rmnet/shs/rmnet_shs_wq.c13
-rw-r--r--drivers/rmnet/shs/rmnet_shs_wq.h6
-rw-r--r--drivers/rmnet/shs/rmnet_shs_wq_mem.c103
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();
}