Files
android_kernel_samsung_sm86…/core/rmnet_qmi.h
Subash Abhinov Kasiviswanathan ef13a42ae2 dfc: fix spinlock leak
In the DFC powersave work, the separate spin lock and unlock
of multiple qos structures could be out of sync during SSR
and results in spinlock leak after exiting the work.

This change consolidated the spinlock operations to avoid
multiple locking and unlocking, and fixed below issue:

BUG: workqueue leaked lock or atomic: kworker/0:9/0x00000201/1361
     last function: qmi_rmnet_check_stats_2.cfi_jt [rmnet_core]
1 lock held by kworker/0:9/1361:
(&qos->qos_lock){....}-{2:2}, at: rmnet_lock_unlock_all_flows+0xa4/0xdc

Change-Id: I10c1687a4f9993363dc631dee0b347faaa1067ab
Acked-by: Weiyi Chen <weiyic@qti.qualcomm.com>
Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
2021-08-18 09:59:34 -07:00

102 lines
2.4 KiB
C

/*
* 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
* 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.
*/
#ifndef _RMNET_QMI_H
#define _RMNET_QMI_H
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#define CONFIG_QTI_QMI_RMNET 1
void rmnet_map_tx_qmap_cmd(struct sk_buff *qmap_skb, u8 ch, bool flush);
#ifdef CONFIG_QTI_QMI_RMNET
void *rmnet_get_qmi_pt(void *port);
void *rmnet_get_qos_pt(struct net_device *dev);
void *rmnet_get_rmnet_port(struct net_device *dev);
struct net_device *rmnet_get_rmnet_dev(void *port, u8 mux_id);
void rmnet_reset_qmi_pt(void *port);
void rmnet_init_qmi_pt(void *port, void *qmi);
void rmnet_enable_all_flows(void *port);
bool rmnet_all_flows_enabled(void *port);
void rmnet_set_powersave_format(void *port);
void rmnet_clear_powersave_format(void *port);
void rmnet_get_packets(void *port, u64 *rx, u64 *tx);
int rmnet_get_powersave_notif(void *port);
struct net_device *rmnet_get_real_dev(void *port);
int rmnet_get_dlmarker_info(void *port);
void rmnet_prepare_ps_bearers(void *port, u8 *num_bearers, u8 *bearer_id);
#else
static inline void *rmnet_get_qmi_pt(void *port)
{
return NULL;
}
static inline void *rmnet_get_qos_pt(struct net_device *dev)
{
return NULL;
}
static inline void *rmnet_get_rmnet_port(struct net_device *dev)
{
return NULL;
}
static inline struct net_device *rmnet_get_rmnet_dev(void *port,
u8 mux_id)
{
return NULL;
}
static inline void rmnet_reset_qmi_pt(void *port)
{
}
static inline void rmnet_init_qmi_pt(void *port, void *qmi)
{
}
static inline void rmnet_enable_all_flows(void *port)
{
}
static inline bool rmnet_all_flows_enabled(void *port)
{
return true;
}
static inline void rmnet_set_port_format(void *port)
{
}
static inline void rmnet_get_packets(void *port, u64 *rx, u64 *tx)
{
}
static inline int rmnet_get_powersave_notif(void *port)
{
return 0;
}
static inline struct net_device *rmnet_get_real_dev(void *port)
{
return NULL;
}
static inline int rmnet_get_dlmarker_info(void *port)
{
return 0;
}
#endif /* CONFIG_QTI_QMI_RMNET */
#endif /*_RMNET_QMI_H*/