diff options
-rw-r--r-- | drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c | 5 | ||||
-rw-r--r-- | drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c | 30 | ||||
-rw-r--r-- | drivers/rmnet/shs/rmnet_shs.h | 5 | ||||
-rwxr-xr-x | drivers/rmnet/shs/rmnet_shs_main.c | 53 |
4 files changed, 69 insertions, 24 deletions
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c index b262b23..2f1f1be 100644 --- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c +++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c @@ -3730,11 +3730,6 @@ static void pre_transmit(struct DWC_ETH_QOS_prv_data *pdata, TX_CONTEXT_DESC_TDES3_OWN_MLF_WR( TX_CONTEXT_DESC->TDES3, 0x1); - /* DMA uses the MSS value programed in DMA_CR if driver - * doesn't provided the CONTEXT descriptor - */ - DMA_CR_MSS_UDFWR(QINX, tx_pkt_features->mss); - tx_desc_data->default_mss = tx_pkt_features->mss; original_start_index = tx_desc_data->cur_tx; diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c index fda72a8..c467561 100644 --- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c +++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019,2021 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 @@ -6802,8 +6802,18 @@ static void DWC_ETH_QOS_program_dcb_algorithm( DBGPR("-->DWC_ETH_QOS_program_dcb_algorithm\n"); if (copy_from_user(&l_dcb_struct, u_dcb_struct, - sizeof(struct DWC_ETH_QOS_dcb_algorithm))) - dev_alert(&pdata->pdev->dev, "Failed to fetch DCB Struct info from user\n"); + sizeof(struct DWC_ETH_QOS_dcb_algorithm))) { + dev_alert(&pdata->pdev->dev, + "Failed to fetch DCB Struct info from user\n"); + return; + } + + if (l_dcb_struct.qinx >= DWC_ETH_QOS_TX_QUEUE_CNT) { + dev_alert(&pdata->pdev->dev, + "Invaild queue number[%u] in DCB Struct from user\n", + l_dcb_struct.qinx); + return; + } hw_if->set_tx_queue_operating_mode(l_dcb_struct.qinx, (UINT)l_dcb_struct.op_mode); @@ -6839,8 +6849,10 @@ static void DWC_ETH_QOS_program_avb_algorithm( DBGPR("-->DWC_ETH_QOS_program_avb_algorithm\n"); if (copy_from_user(&l_avb_struct, u_avb_struct, - sizeof(struct DWC_ETH_QOS_avb_algorithm))) + sizeof(struct DWC_ETH_QOS_avb_algorithm))) { dev_alert(&pdata->pdev->dev, "Failed to fetch AVB Struct info from user\n"); + return; + } if (pdata->speed == SPEED_1000) avb_params = &l_avb_struct.speed1000params; @@ -6849,10 +6861,16 @@ static void DWC_ETH_QOS_program_avb_algorithm( /*Application uses 1 for CLASS A traffic and 2 for CLASS B traffic Configure right channel accordingly*/ - if (l_avb_struct.qinx == 1) + if (l_avb_struct.qinx == 1) { l_avb_struct.qinx = CLASS_A_TRAFFIC_TX_CHANNEL; - else if (l_avb_struct.qinx == 2) + } else if (l_avb_struct.qinx == 2) { l_avb_struct.qinx = CLASS_B_TRAFFIC_TX_CHANNEL; + } else { + dev_alert(&pdata->pdev->dev, + "Invalid queue number[%u] in AVB struct from user\n", + l_avb_struct.qinx); + return; + } hw_if->set_tx_queue_operating_mode(l_avb_struct.qinx, (UINT)l_avb_struct.op_mode); diff --git a/drivers/rmnet/shs/rmnet_shs.h b/drivers/rmnet/shs/rmnet_shs.h index 99ca7e4..5c28537 100644 --- a/drivers/rmnet/shs/rmnet_shs.h +++ b/drivers/rmnet/shs/rmnet_shs.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2021 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 @@ -106,6 +106,7 @@ struct rmnet_shs_cfg_s { u8 dl_ind_state; u8 map_mask; u8 map_len; + u8 ff_flag; }; @@ -178,6 +179,8 @@ enum rmnet_shs_flush_reason_e { RMNET_SHS_FLUSH_WQ_FB_FLUSH, RMNET_SHS_FLUSH_WQ_CORE_FLUSH, RMNET_SHS_FLUSH_PSH_PKT_FLUSH, + RMNET_SHS_FLUSH_WQ_FB_FF_FLUSH, + RMNET_SHS_FLUSH_Z_QUEUE_FLUSH, RMNET_SHS_FLUSH_MAX_REASON }; diff --git a/drivers/rmnet/shs/rmnet_shs_main.c b/drivers/rmnet/shs/rmnet_shs_main.c index c65298b..c46cc67 100755 --- a/drivers/rmnet/shs/rmnet_shs_main.c +++ b/drivers/rmnet/shs/rmnet_shs_main.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. +/* Copyright (c) 2018-2021 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 @@ -83,6 +83,20 @@ unsigned int rmnet_shs_byte_store_limit __read_mostly = 271800 * 80; module_param(rmnet_shs_byte_store_limit, uint, 0644); MODULE_PARM_DESC(rmnet_shs_byte_store_limit, "Maximum byte module will park"); + +unsigned int rmnet_shs_in_count = 0; +module_param(rmnet_shs_in_count, uint, 0644); +MODULE_PARM_DESC(rmnet_shs_in_count, "SKb in count"); + +unsigned int rmnet_shs_out_count = 0; +module_param(rmnet_shs_out_count, uint, 0644); +MODULE_PARM_DESC(rmnet_shs_out_count, "SKb out count"); + +unsigned int rmnet_shs_wq_fb_limit = 10; +module_param(rmnet_shs_wq_fb_limit, uint, 0644); +MODULE_PARM_DESC(rmnet_shs_wq_fb_limit, "Final fb timer"); + + unsigned int rmnet_shs_pkts_store_limit __read_mostly = 2100 * 8; module_param(rmnet_shs_pkts_store_limit, uint, 0644); MODULE_PARM_DESC(rmnet_shs_pkts_store_limit, "Maximum pkts module will park"); @@ -370,6 +384,8 @@ static void rmnet_shs_deliver_skb(struct sk_buff *skb) struct rmnet_priv *priv; struct napi_struct *napi; + rmnet_shs_out_count++; + SHS_TRACE_LOW(RMNET_SHS_DELIVER_SKB, RMNET_SHS_DELIVER_SKB_START, 0xDEF, 0xDEF, 0xDEF, 0xDEF, skb, NULL); @@ -392,6 +408,7 @@ static void rmnet_shs_deliver_skb_wq(struct sk_buff *skb) SHS_TRACE_LOW(RMNET_SHS_DELIVER_SKB, RMNET_SHS_DELIVER_SKB_START, 0xDEF, 0xDEF, 0xDEF, 0xDEF, skb, NULL); + rmnet_shs_out_count++; priv = netdev_priv(skb->dev); gro_cells_receive(&priv->gro_cells, skb); @@ -460,6 +477,7 @@ static void rmnet_shs_deliver_skb_segmented(struct sk_buff *in_skb, SHS_TRACE_LOW(RMNET_SHS_DELIVER_SKB, RMNET_SHS_DELIVER_SKB_START, 0x1, 0xDEF, 0xDEF, 0xDEF, in_skb, NULL); + rmnet_shs_out_count++; segs = rmnet_shs_skb_partial_segment(in_skb, segs_per_skb); if (segs == NULL) { @@ -822,6 +840,7 @@ int rmnet_shs_node_can_flush_pkts(struct rmnet_shs_skbn_s *node, u8 force_flush) int new_cpu; struct rmnet_shs_cpu_node_s *cpun; u8 map = rmnet_shs_cfg.map_mask; + u32 old_cpu_qlen; cpu_map_index = rmnet_shs_get_hash_map_idx_to_stamp(node); do { @@ -848,9 +867,9 @@ int rmnet_shs_node_can_flush_pkts(struct rmnet_shs_skbn_s *node, u8 force_flush) cur_cpu_qhead = rmnet_shs_get_cpu_qhead(node->map_cpu); node_qhead = node->queue_head; cpu_num = node->map_cpu; + old_cpu_qlen = GET_PQUEUE(cpu_num).qlen + GET_IQUEUE(cpu_num).qlen; - if ((cur_cpu_qhead >= node_qhead) || - (force_flush)) { + if ((cur_cpu_qhead >= node_qhead) || force_flush || (!old_cpu_qlen && ++rmnet_shs_flush_reason[RMNET_SHS_FLUSH_Z_QUEUE_FLUSH])) { if (rmnet_shs_switch_cores) { /* Move the amount parked to other core's count @@ -892,6 +911,7 @@ int rmnet_shs_node_can_flush_pkts(struct rmnet_shs_skbn_s *node, u8 force_flush) cpun = &rmnet_shs_cpu_node_tbl[node->map_cpu]; rmnet_shs_update_cpu_proc_q_all_cpus(); node->queue_head = cpun->qhead; + rmnet_shs_cpu_node_move(node, &cpun->node_list_id, cpu_num); @@ -1281,7 +1301,7 @@ void rmnet_shs_flush_lock_table(u8 flsh, u8 ctxt) if ((rmnet_shs_cfg.num_bytes_parked <= 0) || (rmnet_shs_cfg.num_pkts_parked <= 0)) { - + rmnet_shs_cfg.ff_flag = 0; rmnet_shs_cfg.num_bytes_parked = 0; rmnet_shs_cfg.num_pkts_parked = 0; rmnet_shs_cfg.is_pkt_parked = 0; @@ -1290,9 +1310,7 @@ void rmnet_shs_flush_lock_table(u8 flsh, u8 ctxt) if (hrtimer_active(&rmnet_shs_cfg.hrtimer_shs)) hrtimer_cancel(&rmnet_shs_cfg.hrtimer_shs); } - } - } void rmnet_shs_flush_table(u8 flsh, u8 ctxt) @@ -1314,6 +1332,12 @@ void rmnet_shs_flush_table(u8 flsh, u8 ctxt) hrtimer_start(&rmnet_shs_cfg.hrtimer_shs, ns_to_ktime(rmnet_shs_timeout * NS_IN_MS), HRTIMER_MODE_REL); + if (rmnet_shs_fall_back_timer && + rmnet_shs_cfg.num_bytes_parked && + rmnet_shs_cfg.num_pkts_parked){ + rmnet_shs_cfg.ff_flag++; + } + } rmnet_shs_flush_reason[RMNET_SHS_FLUSH_WQ_FB_FLUSH]++; } @@ -1389,23 +1413,27 @@ void rmnet_shs_chain_to_skb_list(struct sk_buff *skb, */ static void rmnet_flush_buffered(struct work_struct *work) { - u8 is_force_flush = 0; SHS_TRACE_HIGH(RMNET_SHS_FLUSH, - RMNET_SHS_FLUSH_DELAY_WQ_START, is_force_flush, + RMNET_SHS_FLUSH_DELAY_WQ_START, rmnet_shs_cfg.ff_flag, rmnet_shs_cfg.force_flush_state, 0xDEF, 0xDEF, NULL, NULL); if (rmnet_shs_cfg.num_pkts_parked && rmnet_shs_cfg.force_flush_state == RMNET_SHS_FLUSH_ON) { local_bh_disable(); - rmnet_shs_flush_table(is_force_flush, + if (rmnet_shs_cfg.ff_flag >= rmnet_shs_wq_fb_limit) { + rmnet_shs_flush_reason[RMNET_SHS_FLUSH_WQ_FB_FF_FLUSH]++; + + } + rmnet_shs_flush_table(rmnet_shs_cfg.ff_flag >= rmnet_shs_wq_fb_limit, RMNET_WQ_CTXT); + local_bh_enable(); } SHS_TRACE_HIGH(RMNET_SHS_FLUSH, RMNET_SHS_FLUSH_DELAY_WQ_END, - is_force_flush, 0xDEF, 0xDEF, 0xDEF, NULL, NULL); + rmnet_shs_cfg.ff_flag, 0xDEF, 0xDEF, 0xDEF, NULL, NULL); } /* Invoked when the flushing timer has expired. * Upon first expiry, we set the flag that will trigger force flushing of all @@ -1602,7 +1630,6 @@ void rmnet_shs_dl_trl_handler_v2(struct rmnet_map_dl_ind_trl *dltrl, void rmnet_shs_dl_trl_handler(struct rmnet_map_dl_ind_trl *dltrl) { - SHS_TRACE_HIGH(RMNET_SHS_DL_MRK, RMNET_SHS_FLUSH_DL_MRK_TRLR_HDLR_START, rmnet_shs_cfg.num_pkts_parked, 0, @@ -1740,12 +1767,14 @@ void rmnet_shs_assign(struct sk_buff *skb, struct rmnet_port *port) u8 is_shs_reqd = 0; struct rmnet_shs_cpu_node_s *cpu_node_tbl_p; + rmnet_shs_in_count++; + /*deliver non TCP/UDP packets right away*/ if (!rmnet_shs_is_skb_stamping_reqd(skb)) { + rmnet_shs_deliver_skb(skb); return; } - if ((unlikely(!map)) || !rmnet_shs_cfg.rmnet_shs_init_complete) { rmnet_shs_deliver_skb(skb); SHS_TRACE_ERR(RMNET_SHS_ASSIGN, |