diff options
author | qctecmdr <qctecmdr@localhost> | 2021-10-07 20:18:55 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2021-10-07 20:18:55 -0700 |
commit | 16c9dc0982b49612805402907c0769d6422bb7a4 (patch) | |
tree | 58e5d1b9d5142f35d701ef7527689649c7314638 | |
parent | 7a327bbae72ee16ec254399244e16ff536545162 (diff) | |
parent | c6de1facb0f1b6feb384617eeeaa3546aa21ff64 (diff) | |
download | datarmnet-16c9dc0982b49612805402907c0769d6422bb7a4.tar.gz |
Merge "dfc: reset tx queue"
-rw-r--r-- | core/qmi_rmnet.c | 47 | ||||
-rw-r--r-- | core/qmi_rmnet.h | 10 | ||||
-rw-r--r-- | core/qmi_rmnet_i.h | 1 | ||||
-rw-r--r-- | core/rmnet_vnd.c | 12 |
4 files changed, 36 insertions, 34 deletions
diff --git a/core/qmi_rmnet.c b/core/qmi_rmnet.c index 6ae7fb6..909ebd5 100644 --- a/core/qmi_rmnet.c +++ b/core/qmi_rmnet.c @@ -226,21 +226,6 @@ int qmi_rmnet_flow_control(struct net_device *dev, u32 mq_idx, int enable) return 0; } -static void qmi_rmnet_reset_txq(struct net_device *dev, unsigned int txq) -{ - struct Qdisc *qdisc; - - if (unlikely(txq >= dev->num_tx_queues)) - return; - - qdisc = rtnl_dereference(netdev_get_tx_queue(dev, txq)->qdisc); - if (qdisc) { - spin_lock_bh(qdisc_lock(qdisc)); - qdisc_reset(qdisc); - spin_unlock_bh(qdisc_lock(qdisc)); - } -} - /** * qmi_rmnet_watchdog_fn - watchdog timer func */ @@ -371,15 +356,13 @@ static void __qmi_rmnet_bearer_put(struct net_device *dev, mq->bearer = NULL; mq->is_ll_ch = false; - if (reset) { - qmi_rmnet_reset_txq(dev, i); - qmi_rmnet_flow_control(dev, i, 1); - - if (dfc_mode == DFC_MODE_SA) { - j = i + ACK_MQ_OFFSET; - qmi_rmnet_reset_txq(dev, j); - qmi_rmnet_flow_control(dev, j, 1); - } + mq->drop_on_remove = reset; + smp_mb(); + + qmi_rmnet_flow_control(dev, i, 1); + if (dfc_mode == DFC_MODE_SA) { + j = i + ACK_MQ_OFFSET; + qmi_rmnet_flow_control(dev, j, 1); } } @@ -404,6 +387,8 @@ static void __qmi_rmnet_update_mq(struct net_device *dev, if (!mq->bearer) { mq->bearer = bearer; mq->is_ll_ch = bearer->ch_switch.current_ch; + mq->drop_on_remove = false; + smp_mb(); if (dfc_mode == DFC_MODE_SA) { bearer->mq_idx = itm->mq_idx; @@ -958,8 +943,8 @@ void qmi_rmnet_prepare_ps_bearers(struct net_device *dev, u8 *num_bearers, EXPORT_SYMBOL(qmi_rmnet_prepare_ps_bearers); #ifdef CONFIG_QTI_QMI_DFC -bool qmi_rmnet_flow_is_low_latency(struct net_device *dev, - struct sk_buff *skb) +bool qmi_rmnet_get_flow_state(struct net_device *dev, struct sk_buff *skb, + bool *drop, bool *is_low_latency) { struct qos_info *qos = rmnet_get_qos_pt(dev); int txq = skb->queue_mapping; @@ -970,9 +955,15 @@ bool qmi_rmnet_flow_is_low_latency(struct net_device *dev, if (unlikely(!qos || txq >= MAX_MQ_NUM)) return false; - return qos->mq[txq].is_ll_ch; + /* If the bearer is gone, packets may need to be dropped */ + *drop = (txq != DEFAULT_MQ_NUM && !READ_ONCE(qos->mq[txq].bearer) && + READ_ONCE(qos->mq[txq].drop_on_remove)); + + *is_low_latency = READ_ONCE(qos->mq[txq].is_ll_ch); + + return true; } -EXPORT_SYMBOL(qmi_rmnet_flow_is_low_latency); +EXPORT_SYMBOL(qmi_rmnet_get_flow_state); void qmi_rmnet_burst_fc_check(struct net_device *dev, int ip_type, u32 mark, unsigned int len) diff --git a/core/qmi_rmnet.h b/core/qmi_rmnet.h index 3833011..ae961c0 100644 --- a/core/qmi_rmnet.h +++ b/core/qmi_rmnet.h @@ -72,8 +72,8 @@ void *qmi_rmnet_qos_init(struct net_device *real_dev, struct net_device *vnd_dev, u8 mux_id); void qmi_rmnet_qos_exit_pre(void *qos); void qmi_rmnet_qos_exit_post(void); -bool qmi_rmnet_flow_is_low_latency(struct net_device *dev, - struct sk_buff *skb); +bool qmi_rmnet_get_flow_state(struct net_device *dev, struct sk_buff *skb, + bool *drop, bool *is_low_latency); void qmi_rmnet_burst_fc_check(struct net_device *dev, int ip_type, u32 mark, unsigned int len); int qmi_rmnet_get_queue(struct net_device *dev, struct sk_buff *skb); @@ -93,8 +93,10 @@ static inline void qmi_rmnet_qos_exit_post(void) { } -static inline bool qmi_rmnet_flow_is_low_latency(struct net_device *dev, - struct sk_buff *skb) +static inline bool qmi_rmnet_get_flow_state(struct net_device *dev, + struct sk_buff *skb, + bool *drop, + bool *is_low_latency) { return false; } diff --git a/core/qmi_rmnet_i.h b/core/qmi_rmnet_i.h index 77759c3..a3946fd 100644 --- a/core/qmi_rmnet_i.h +++ b/core/qmi_rmnet_i.h @@ -114,6 +114,7 @@ struct svc_info { struct mq_map { struct rmnet_bearer_map *bearer; bool is_ll_ch; + bool drop_on_remove; }; struct qos_info { diff --git a/core/rmnet_vnd.c b/core/rmnet_vnd.c index 0e339ed..f0bf679 100644 --- a/core/rmnet_vnd.c +++ b/core/rmnet_vnd.c @@ -79,7 +79,8 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb, u32 mark; unsigned int len; rmnet_perf_tether_egress_hook_t rmnet_perf_tether_egress; - bool low_latency; + bool low_latency = false; + bool need_to_drop = false; priv = netdev_priv(dev); if (priv->real_dev) { @@ -92,7 +93,14 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb, if (rmnet_perf_tether_egress) { rmnet_perf_tether_egress(skb); } - low_latency = qmi_rmnet_flow_is_low_latency(dev, skb); + + qmi_rmnet_get_flow_state(dev, skb, &need_to_drop, &low_latency); + if (unlikely(need_to_drop)) { + this_cpu_inc(priv->pcpu_stats->stats.tx_drops); + kfree_skb(skb); + return NETDEV_TX_OK; + } + if (low_latency && skb_is_gso(skb)) { netdev_features_t features; struct sk_buff *segs, *tmp; |