Merge tag 'LA.UM.9.14.r1-19500-LAHAINA.QSSI12.0' of https://git.codelinaro.org/clo/la/platform/vendor/qcom/opensource/datarmnet into android12-5.4-lahaina

"LA.UM.9.14.r1-19500-LAHAINA.QSSI12.0"

* tag 'LA.UM.9.14.r1-19500-LAHAINA.QSSI12.0' of https://git.codelinaro.org/clo/la/platform/vendor/qcom/opensource/datarmnet:
  datarmnet: Remove monaco_go and monaco_go_aon from BOARD_PLATFORM_LIST
  rmnet_core: fix race condition in rmnet_get_packets
  dfc: fix use-after-free
  dfc: reset tx queue
  dfc: not caching grant for removed bearers
  datarmnet: compilation fix for ks sync path

Change-Id: I0dd004839cd3afd62a4a2b691e7b58efa17876cf
This commit is contained in:
Michael Bestas 2022-05-19 00:38:41 +03:00
commit 81c6b026e6
No known key found for this signature in database
GPG Key ID: CC95044519BE6669
10 changed files with 91 additions and 43 deletions

View File

@ -2,14 +2,16 @@ ifneq ($(TARGET_PRODUCT),qssi)
RMNET_CORE_DLKM_PLATFORMS_LIST := lahaina RMNET_CORE_DLKM_PLATFORMS_LIST := lahaina
RMNET_CORE_DLKM_PLATFORMS_LIST += holi RMNET_CORE_DLKM_PLATFORMS_LIST += holi
RMNET_CORE_DLKM_PLATFORMS_LIST += monaco RMNET_CORE_DLKM_PLATFORMS_LIST += monaco
RMNET_CORE_DLKM_PLATFORMS_LIST += monaco_go
RMNET_CORE_DLKM_PLATFORMS_LIST += monaco_go_aon
ifeq ($(call is-board-platform-in-list, $(RMNET_CORE_DLKM_PLATFORMS_LIST)),true) ifeq ($(call is-board-platform-in-list, $(RMNET_CORE_DLKM_PLATFORMS_LIST)),true)
#Make file to create RMNET_CORE DLKM #Make file to create RMNET_CORE DLKM
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
ifeq ($(BOARD_COMMON_DIR),)
BOARD_COMMON_DIR := device/qcom/common
endif
LOCAL_CFLAGS := -Wno-macro-redefined -Wno-unused-function -Wall -Werror LOCAL_CFLAGS := -Wno-macro-redefined -Wno-unused-function -Wall -Werror
LOCAL_CLANG :=true LOCAL_CLANG :=true
@ -30,7 +32,7 @@ LOCAL_SRC_FILES := \
wda_qmi.c wda_qmi.c
RMNET_BLD_DIR := ../../vendor/qcom/opensource/datarmnet/core RMNET_BLD_DIR := ../../vendor/qcom/opensource/datarmnet/core
DLKM_DIR := $(TOP)/device/qcom/common/dlkm DLKM_DIR := $(TOP)/$(BOARD_COMMON_DIR)/dlkm
KBUILD_OPTIONS := $(RMNET_BLD_DIR) KBUILD_OPTIONS := $(RMNET_BLD_DIR)
@ -51,7 +53,7 @@ LOCAL_SRC_FILES := \
rmnet_ctl_ipa.c rmnet_ctl_ipa.c
RMNET_BLD_DIR := ../../vendor/qcom/opensource/datarmnet/core RMNET_BLD_DIR := ../../vendor/qcom/opensource/datarmnet/core
DLKM_DIR := $(TOP)/device/qcom/common/dlkm DLKM_DIR := $(TOP)/$(BOARD_COMMON_DIR)/dlkm
KBUILD_OPTIONS := $(RMNET_BLD_DIR) KBUILD_OPTIONS := $(RMNET_BLD_DIR)

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* /*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <net/pkt_sched.h> #include <net/pkt_sched.h>
@ -139,11 +140,13 @@ static void dfc_qmap_send_cmd(struct sk_buff *skb)
{ {
trace_dfc_qmap(skb->data, skb->len, false); trace_dfc_qmap(skb->data, skb->len, false);
if (unlikely(!rmnet_ctl || !rmnet_ctl->send) || if (unlikely(!rmnet_ctl || !rmnet_ctl->send)) {
rmnet_ctl->send(rmnet_ctl_handle, skb)) {
pr_err("Failed to send to rmnet ctl\n");
kfree_skb(skb); kfree_skb(skb);
return;
} }
if (rmnet_ctl->send(rmnet_ctl_handle, skb))
pr_err("Failed to send to rmnet ctl\n");
} }
static void dfc_qmap_send_inband_ack(struct dfc_qmi_data *dfc, static void dfc_qmap_send_inband_ack(struct dfc_qmi_data *dfc,

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -1003,7 +1004,9 @@ static int dfc_update_fc_map(struct net_device *dev, struct qos_info *qos,
u32 adjusted_grant; u32 adjusted_grant;
itm = qmi_rmnet_get_bearer_map(qos, fc_info->bearer_id); itm = qmi_rmnet_get_bearer_map(qos, fc_info->bearer_id);
if (!itm)
/* cache the bearer assuming it is a new bearer */
if (unlikely(!itm && !is_query && fc_info->num_bytes))
itm = qmi_rmnet_get_bearer_noref(qos, fc_info->bearer_id); itm = qmi_rmnet_get_bearer_noref(qos, fc_info->bearer_id);
if (itm) { if (itm) {

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -221,21 +222,6 @@ int qmi_rmnet_flow_control(struct net_device *dev, u32 mq_idx, int enable)
return 0; 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 * qmi_rmnet_watchdog_fn - watchdog timer func
*/ */
@ -361,17 +347,15 @@ static void __qmi_rmnet_bearer_put(struct net_device *dev,
continue; continue;
mq->bearer = NULL; mq->bearer = NULL;
if (reset) { mq->drop_on_remove = reset;
qmi_rmnet_reset_txq(dev, i); smp_mb();
qmi_rmnet_flow_control(dev, i, 1);
qmi_rmnet_flow_control(dev, i, 1);
if (dfc_mode == DFC_MODE_SA) { if (dfc_mode == DFC_MODE_SA) {
j = i + ACK_MQ_OFFSET; j = i + ACK_MQ_OFFSET;
qmi_rmnet_reset_txq(dev, j);
qmi_rmnet_flow_control(dev, j, 1); qmi_rmnet_flow_control(dev, j, 1);
} }
} }
}
/* Remove from bearer map */ /* Remove from bearer map */
list_del(&bearer->list); list_del(&bearer->list);
@ -393,6 +377,8 @@ static void __qmi_rmnet_update_mq(struct net_device *dev,
mq = &qos_info->mq[itm->mq_idx]; mq = &qos_info->mq[itm->mq_idx];
if (!mq->bearer) { if (!mq->bearer) {
mq->bearer = bearer; mq->bearer = bearer;
mq->drop_on_remove = false;
smp_mb();
if (dfc_mode == DFC_MODE_SA) { if (dfc_mode == DFC_MODE_SA) {
bearer->mq_idx = itm->mq_idx; bearer->mq_idx = itm->mq_idx;
@ -401,12 +387,15 @@ static void __qmi_rmnet_update_mq(struct net_device *dev,
bearer->mq_idx = itm->mq_idx; bearer->mq_idx = itm->mq_idx;
} }
qmi_rmnet_flow_control(dev, itm->mq_idx, /* Always enable flow for the newly associated bearer */
bearer->grant_size > 0 ? 1 : 0); if (!bearer->grant_size) {
bearer->grant_size = DEFAULT_GRANT;
bearer->grant_thresh =
qmi_rmnet_grant_per(DEFAULT_GRANT);
}
qmi_rmnet_flow_control(dev, itm->mq_idx, 1);
if (dfc_mode == DFC_MODE_SA) if (dfc_mode == DFC_MODE_SA)
qmi_rmnet_flow_control(dev, bearer->ack_mq_idx, qmi_rmnet_flow_control(dev, bearer->ack_mq_idx, 1);
bearer->grant_size > 0 ? 1 : 0);
} }
} }
@ -873,6 +862,26 @@ bool qmi_rmnet_all_flows_enabled(struct net_device *dev)
EXPORT_SYMBOL(qmi_rmnet_all_flows_enabled); EXPORT_SYMBOL(qmi_rmnet_all_flows_enabled);
#ifdef CONFIG_QTI_QMI_DFC #ifdef CONFIG_QTI_QMI_DFC
bool qmi_rmnet_get_flow_state(struct net_device *dev, struct sk_buff *skb,
bool *drop)
{
struct qos_info *qos = rmnet_get_qos_pt(dev);
int txq = skb->queue_mapping;
if (txq > ACK_MQ_OFFSET)
txq -= ACK_MQ_OFFSET;
if (unlikely(!qos || txq >= MAX_MQ_NUM))
return false;
/* 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));
return true;
}
EXPORT_SYMBOL(qmi_rmnet_get_flow_state);
void qmi_rmnet_burst_fc_check(struct net_device *dev, void qmi_rmnet_burst_fc_check(struct net_device *dev,
int ip_type, u32 mark, unsigned int len) int ip_type, u32 mark, unsigned int len)
{ {

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -59,6 +60,8 @@ void *qmi_rmnet_qos_init(struct net_device *real_dev,
struct net_device *vnd_dev, u8 mux_id); struct net_device *vnd_dev, u8 mux_id);
void qmi_rmnet_qos_exit_pre(void *qos); void qmi_rmnet_qos_exit_pre(void *qos);
void qmi_rmnet_qos_exit_post(void); void qmi_rmnet_qos_exit_post(void);
bool qmi_rmnet_get_flow_state(struct net_device *dev, struct sk_buff *skb,
bool *drop);
void qmi_rmnet_burst_fc_check(struct net_device *dev, void qmi_rmnet_burst_fc_check(struct net_device *dev,
int ip_type, u32 mark, unsigned int len); int ip_type, u32 mark, unsigned int len);
int qmi_rmnet_get_queue(struct net_device *dev, struct sk_buff *skb); int qmi_rmnet_get_queue(struct net_device *dev, struct sk_buff *skb);
@ -78,6 +81,13 @@ static inline void qmi_rmnet_qos_exit_post(void)
{ {
} }
static inline bool qmi_rmnet_get_flow_state(struct net_device *dev,
struct sk_buff *skb,
bool *drop)
{
return false;
}
static inline void static inline void
qmi_rmnet_burst_fc_check(struct net_device *dev, qmi_rmnet_burst_fc_check(struct net_device *dev,
int ip_type, u32 mark, unsigned int len) int ip_type, u32 mark, unsigned int len)

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -82,6 +83,7 @@ struct svc_info {
struct mq_map { struct mq_map {
struct rmnet_bearer_map *bearer; struct rmnet_bearer_map *bearer;
bool drop_on_remove;
}; };
struct qos_info { struct qos_info {

View File

@ -1,4 +1,5 @@
/* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -641,6 +642,7 @@ EXPORT_SYMBOL(rmnet_init_qmi_pt);
void rmnet_get_packets(void *port, u64 *rx, u64 *tx) void rmnet_get_packets(void *port, u64 *rx, u64 *tx)
{ {
struct net_device *dev;
struct rmnet_priv *priv; struct rmnet_priv *priv;
struct rmnet_pcpu_stats *ps; struct rmnet_pcpu_stats *ps;
unsigned int cpu, start; unsigned int cpu, start;
@ -654,8 +656,12 @@ void rmnet_get_packets(void *port, u64 *rx, u64 *tx)
*tx = 0; *tx = 0;
*rx = 0; *rx = 0;
rcu_read_lock(); rcu_read_lock();
hash_for_each(((struct rmnet_port *)port)->muxed_ep, bkt, ep, hlnode) { hash_for_each_rcu(((struct rmnet_port *)port)->muxed_ep, bkt, ep,
priv = netdev_priv(ep->egress_dev); hlnode) {
dev = ep->egress_dev;
if (!dev)
continue;
priv = netdev_priv(dev);
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
ps = per_cpu_ptr(priv->pcpu_stats, cpu); ps = per_cpu_ptr(priv->pcpu_stats, cpu);
do { do {

View File

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. /* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* *
* RMNET_CTL client handlers * RMNET_CTL client handlers
* *
@ -171,8 +172,10 @@ int rmnet_ctl_send_client(void *handle, struct sk_buff *skb)
struct rmnet_ctl_dev *dev; struct rmnet_ctl_dev *dev;
int rc = -EINVAL; int rc = -EINVAL;
if (client != rcu_dereference(ctl_ep.client)) if (client != rcu_dereference(ctl_ep.client)) {
kfree_skb(skb);
return rc; return rc;
}
rmnet_ctl_log_info("TX", skb->data, skb->len); rmnet_ctl_log_info("TX", skb->data, skb->len);
@ -181,11 +184,13 @@ int rmnet_ctl_send_client(void *handle, struct sk_buff *skb)
dev = rcu_dereference(ctl_ep.dev); dev = rcu_dereference(ctl_ep.dev);
if (dev && dev->xmit) if (dev && dev->xmit)
rc = dev->xmit(dev, skb); rc = dev->xmit(dev, skb);
else
kfree_skb(skb);
rcu_read_unlock(); rcu_read_unlock();
if (rc) if (rc)
rmnet_ctl_log_err("TXE", rc, skb->data, skb->len); rmnet_ctl_log_err("TXE", rc, NULL, 0);
return rc; return rc;
} }

View File

@ -1,4 +1,5 @@
/* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and
@ -68,6 +69,7 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
int ip_type; int ip_type;
u32 mark; u32 mark;
unsigned int len; unsigned int len;
bool need_to_drop = false;
priv = netdev_priv(dev); priv = netdev_priv(dev);
if (priv->real_dev) { if (priv->real_dev) {
@ -76,6 +78,14 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
mark = skb->mark; mark = skb->mark;
len = skb->len; len = skb->len;
trace_rmnet_xmit_skb(skb); trace_rmnet_xmit_skb(skb);
qmi_rmnet_get_flow_state(dev, skb, &need_to_drop);
if (unlikely(need_to_drop)) {
this_cpu_inc(priv->pcpu_stats->stats.tx_drops);
kfree_skb(skb);
return NETDEV_TX_OK;
}
rmnet_egress_handler(skb); rmnet_egress_handler(skb);
qmi_rmnet_burst_fc_check(dev, ip_type, mark, len); qmi_rmnet_burst_fc_check(dev, ip_type, mark, len);
qmi_rmnet_work_maybe_restart(rmnet_get_rmnet_port(dev)); qmi_rmnet_work_maybe_restart(rmnet_get_rmnet_port(dev));

View File

@ -2,8 +2,6 @@
DATA_DLKM_BOARD_PLATFORMS_LIST := lahaina DATA_DLKM_BOARD_PLATFORMS_LIST := lahaina
DATA_DLKM_BOARD_PLATFORMS_LIST += holi DATA_DLKM_BOARD_PLATFORMS_LIST += holi
DATA_DLKM_BOARD_PLATFORMS_LIST += monaco DATA_DLKM_BOARD_PLATFORMS_LIST += monaco
DATA_DLKM_BOARD_PLATFORMS_LIST += monaco_go
DATA_DLKM_BOARD_PLATFORMS_LIST += monaco_go_aon
ifneq ($(TARGET_BOARD_AUTO),true) ifneq ($(TARGET_BOARD_AUTO),true)
ifeq ($(call is-board-platform-in-list,$(DATA_DLKM_BOARD_PLATFORMS_LIST)),true) ifeq ($(call is-board-platform-in-list,$(DATA_DLKM_BOARD_PLATFORMS_LIST)),true)
BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/rmnet_core.ko BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/rmnet_core.ko