Merge 220883fba3 ("HID: hid-thrustmaster: Fix warning in thrustmaster_probe by adding endpoint check") into android14-6.1-lts

Steps on the way to 6.1.129

Change-Id: I12ddac7329f6db60e21f195f3e500ac786f2db7c
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2025-03-06 08:48:15 +00:00
43 changed files with 244 additions and 277 deletions

View File

@@ -27,7 +27,7 @@ properties:
description: |
For multicolor LED support this property should be defined as either
LED_COLOR_ID_RGB or LED_COLOR_ID_MULTI which can be found in
include/linux/leds/common.h.
include/dt-bindings/leds/common.h.
enum: [ 8, 9 ]
required:

View File

@@ -50,15 +50,15 @@ properties:
minimum: 0
maximum: 1
rohm,charger-sense-resistor-ohms:
minimum: 10000000
maximum: 50000000
rohm,charger-sense-resistor-micro-ohms:
minimum: 10000
maximum: 50000
description: |
BD71827 and BD71828 have SAR ADC for measuring charging currents.
External sense resistor (RSENSE in data sheet) should be used. If
something other but 30MOhm resistor is used the resistance value
should be given here in Ohms.
default: 30000000
BD71815 has SAR ADC for measuring charging currents. External sense
resistor (RSENSE in data sheet) should be used. If something other
but a 30 mOhm resistor is used the resistance value should be given
here in micro Ohms.
default: 30000
regulators:
$ref: ../regulator/rohm,bd71815-regulator.yaml
@@ -67,7 +67,7 @@ properties:
gpio-reserved-ranges:
description: |
Usage of BD71828 GPIO pins can be changed via OTP. This property can be
Usage of BD71815 GPIO pins can be changed via OTP. This property can be
used to mark the pins which should not be configured for GPIO. Please see
the ../gpio/gpio.txt for more information.
@@ -113,7 +113,7 @@ examples:
gpio-controller;
#gpio-cells = <2>;
rohm,charger-sense-resistor-ohms = <10000000>;
rohm,charger-sense-resistor-micro-ohms = <10000>;
regulators {
buck1: buck1 {

View File

@@ -25,7 +25,7 @@ properties:
"#address-cells":
const: 1
description: |
The cell is the slot ID if a function subnode is used.
The cell is the SDIO function number if a function subnode is used.
"#size-cells":
const: 0

View File

@@ -31,10 +31,6 @@ properties:
$ref: "regulator.yaml#"
unevaluatedProperties: false
properties:
regulator-compatible:
pattern: "^vbuck[1-4]$"
additionalProperties: false
required:
@@ -52,7 +48,6 @@ examples:
regulators {
vbuck1 {
regulator-compatible = "vbuck1";
regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1193750>;
regulator-enable-ramp-delay = <256>;
@@ -60,7 +55,6 @@ examples:
};
vbuck3 {
regulator-compatible = "vbuck3";
regulator-min-microvolt = <300000>;
regulator-max-microvolt = <1193750>;
regulator-enable-ramp-delay = <256>;

View File

@@ -366,19 +366,25 @@ static int acpi_fan_probe(struct platform_device *pdev)
result = sysfs_create_link(&pdev->dev.kobj,
&cdev->device.kobj,
"thermal_cooling");
if (result)
if (result) {
dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n");
goto err_unregister;
}
result = sysfs_create_link(&cdev->device.kobj,
&pdev->dev.kobj,
"device");
if (result) {
dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n");
goto err_end;
goto err_remove_link;
}
return 0;
err_remove_link:
sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling");
err_unregister:
thermal_cooling_device_unregister(cdev);
err_end:
if (fan->acpi4)
acpi_fan_delete_attributes(device);

View File

@@ -321,6 +321,9 @@ static int ipmb_probe(struct i2c_client *client)
ipmb_dev->miscdev.name = devm_kasprintf(&client->dev, GFP_KERNEL,
"%s%d", "ipmb-",
client->adapter->nr);
if (!ipmb_dev->miscdev.name)
return -ENOMEM;
ipmb_dev->miscdev.fops = &ipmb_fops;
ipmb_dev->miscdev.parent = &client->dev;
ret = misc_register(&ipmb_dev->miscdev);

View File

@@ -398,8 +398,9 @@ static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_r
static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
"dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
"arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
"dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
"arm_pll_out", "sys_pll1_out", "sys_pll2_out",
"sys_pll3_out", "dummy", "dummy", "osc_24m",
"dummy", "osc_32k"};
static struct clk_hw **hws;
static struct clk_hw_onecell_data *clk_hw_data;

View File

@@ -455,7 +455,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
.name = "gcc_qupv3_wrap0_s0_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
@@ -471,7 +471,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
.name = "gcc_qupv3_wrap0_s1_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
@@ -487,7 +487,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
.name = "gcc_qupv3_wrap0_s2_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
@@ -503,7 +503,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
.name = "gcc_qupv3_wrap0_s3_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
@@ -519,7 +519,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
.name = "gcc_qupv3_wrap0_s4_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
@@ -535,7 +535,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
.name = "gcc_qupv3_wrap0_s5_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
@@ -551,7 +551,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = {
.name = "gcc_qupv3_wrap0_s6_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
@@ -567,7 +567,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = {
.name = "gcc_qupv3_wrap0_s7_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
@@ -583,7 +583,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
.name = "gcc_qupv3_wrap1_s0_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
@@ -599,7 +599,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
.name = "gcc_qupv3_wrap1_s1_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
@@ -615,7 +615,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
.name = "gcc_qupv3_wrap1_s2_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
@@ -631,7 +631,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
.name = "gcc_qupv3_wrap1_s3_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
@@ -647,7 +647,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
.name = "gcc_qupv3_wrap1_s4_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
@@ -663,7 +663,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
.name = "gcc_qupv3_wrap1_s5_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
@@ -679,7 +679,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = {
.name = "gcc_qupv3_wrap1_s6_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
@@ -695,7 +695,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = {
.name = "gcc_qupv3_wrap1_s7_clk_src",
.parent_data = gcc_parent_data_0,
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
.ops = &clk_rcg2_shared_ops,
.ops = &clk_rcg2_ops,
};
static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {

View File

@@ -2072,7 +2072,7 @@ static const struct hid_device_id mt_devices[] = {
I2C_DEVICE_ID_GOODIX_01E8) },
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX,
I2C_DEVICE_ID_GOODIX_01E8) },
I2C_DEVICE_ID_GOODIX_01E9) },
/* GoodTouch panels */
{ .driver_data = MT_CLS_NSMU,

View File

@@ -170,6 +170,14 @@ static void thrustmaster_interrupts(struct hid_device *hdev)
ep = &usbif->cur_altsetting->endpoint[1];
b_ep = ep->desc.bEndpointAddress;
/* Are the expected endpoints present? */
u8 ep_addr[1] = {b_ep};
if (!usb_check_int_endpoints(usbif, ep_addr)) {
hid_err(hdev, "Unexpected non-int endpoint\n");
return;
}
for (i = 0; i < ARRAY_SIZE(setup_arr); ++i) {
memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]);

View File

@@ -440,6 +440,7 @@ static int netxbig_leds_get_of_pdata(struct device *dev,
}
gpio_ext_pdev = of_find_device_by_node(gpio_ext_np);
if (!gpio_ext_pdev) {
of_node_put(gpio_ext_np);
dev_err(dev, "Failed to find platform device for gpio-ext\n");
return -ENODEV;
}

View File

@@ -1171,6 +1171,13 @@ static int team_port_add(struct team *team, struct net_device *port_dev,
return -EBUSY;
}
if (netdev_has_upper_dev(port_dev, dev)) {
NL_SET_ERR_MSG(extack, "Device is already a lower device of the team interface");
netdev_err(dev, "Device %s is already a lower device of the team interface\n",
portname);
return -EBUSY;
}
if (port_dev->features & NETIF_F_VLAN_CHALLENGED &&
vlan_uses_dev(dev)) {
NL_SET_ERR_MSG(extack, "Device is VLAN challenged and team device has VLAN set up");

View File

@@ -3795,6 +3795,7 @@ int ath11k_dp_process_rx_err(struct ath11k_base *ab, struct napi_struct *napi,
ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,
&rbm);
if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST &&
rbm != HAL_RX_BUF_RBM_SW1_BM &&
rbm != HAL_RX_BUF_RBM_SW3_BM) {
ab->soc_stats.invalid_rbm++;
ath11k_warn(ab, "invalid return buffer manager %d\n", rbm);

View File

@@ -371,7 +371,8 @@ int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc,
ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
wbm_desc->buf_addr_info.info1);
if (ret_buf_mgr != HAL_RX_BUF_RBM_SW3_BM) {
if (ret_buf_mgr != HAL_RX_BUF_RBM_SW1_BM &&
ret_buf_mgr != HAL_RX_BUF_RBM_SW3_BM) {
ab->soc_stats.invalid_rbm++;
return -EINVAL;
}

View File

@@ -1585,7 +1585,10 @@ static int wcn36xx_probe(struct platform_device *pdev)
}
n_channels = wcn_band_2ghz.n_channels + wcn_band_5ghz.n_channels;
wcn->chan_survey = devm_kmalloc(wcn->dev, n_channels, GFP_KERNEL);
wcn->chan_survey = devm_kcalloc(wcn->dev,
n_channels,
sizeof(struct wcn36xx_chan_survey),
GFP_KERNEL);
if (!wcn->chan_survey) {
ret = -ENOMEM;
goto out_wq;

View File

@@ -452,8 +452,7 @@ static int _rtl_init_deferred_work(struct ieee80211_hw *hw)
/* <1> timer */
timer_setup(&rtlpriv->works.watchdog_timer,
rtl_watch_dog_timer_callback, 0);
timer_setup(&rtlpriv->works.dualmac_easyconcurrent_retrytimer,
rtl_easy_concurrent_retrytimer_callback, 0);
/* <2> work queue */
rtlpriv->works.hw = hw;
rtlpriv->works.rtl_wq = wq;
@@ -576,9 +575,15 @@ static void rtl_free_entries_from_ack_queue(struct ieee80211_hw *hw,
void rtl_deinit_core(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
rtl_c2hcmd_launcher(hw, 0);
rtl_free_entries_from_scan_list(hw);
rtl_free_entries_from_ack_queue(hw, false);
if (rtlpriv->works.rtl_wq) {
destroy_workqueue(rtlpriv->works.rtl_wq);
rtlpriv->works.rtl_wq = NULL;
}
}
EXPORT_SYMBOL_GPL(rtl_deinit_core);
@@ -2366,19 +2371,6 @@ static void rtl_c2hcmd_wq_callback(struct work_struct *work)
rtl_c2hcmd_launcher(hw, 1);
}
void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t)
{
struct rtl_priv *rtlpriv =
from_timer(rtlpriv, t, works.dualmac_easyconcurrent_retrytimer);
struct ieee80211_hw *hw = rtlpriv->hw;
struct rtl_priv *buddy_priv = rtlpriv->buddy_priv;
if (buddy_priv == NULL)
return;
rtlpriv->cfg->ops->dualmac_easy_concurrent(hw);
}
/*********************************************************
*
* frame process functions
@@ -2724,9 +2716,6 @@ MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
struct rtl_global_var rtl_global_var = {};
EXPORT_SYMBOL_GPL(rtl_global_var);
static int __init rtl_core_module_init(void)
{
BUILD_BUG_ON(TX_PWR_BY_RATE_NUM_RATE < TX_PWR_BY_RATE_NUM_SECTION);
@@ -2740,10 +2729,6 @@ static int __init rtl_core_module_init(void)
/* add debugfs */
rtl_debugfs_add_topdir();
/* init some global vars */
INIT_LIST_HEAD(&rtl_global_var.glb_priv_list);
spin_lock_init(&rtl_global_var.glb_list_lock);
return 0;
}

View File

@@ -124,8 +124,6 @@ int rtl_send_smps_action(struct ieee80211_hw *hw,
u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
u8 rtl_tid_to_ac(u8 tid);
void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t);
extern struct rtl_global_var rtl_global_var;
void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
#endif

View File

@@ -295,46 +295,6 @@ static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
return status;
}
static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw,
struct rtl_priv **buddy_priv)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
struct rtl_priv *tpriv = NULL, *iter;
struct rtl_pci_priv *tpcipriv = NULL;
if (!list_empty(&rtlpriv->glb_var->glb_priv_list)) {
list_for_each_entry(iter, &rtlpriv->glb_var->glb_priv_list,
list) {
tpcipriv = (struct rtl_pci_priv *)iter->priv;
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
"pcipriv->ndis_adapter.funcnumber %x\n",
pcipriv->ndis_adapter.funcnumber);
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
"tpcipriv->ndis_adapter.funcnumber %x\n",
tpcipriv->ndis_adapter.funcnumber);
if (pcipriv->ndis_adapter.busnumber ==
tpcipriv->ndis_adapter.busnumber &&
pcipriv->ndis_adapter.devnumber ==
tpcipriv->ndis_adapter.devnumber &&
pcipriv->ndis_adapter.funcnumber !=
tpcipriv->ndis_adapter.funcnumber) {
tpriv = iter;
break;
}
}
}
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
"find_buddy_priv %d\n", tpriv != NULL);
if (tpriv)
*buddy_priv = tpriv;
return tpriv != NULL;
}
static void rtl_pci_parse_configuration(struct pci_dev *pdev,
struct ieee80211_hw *hw)
{
@@ -443,11 +403,6 @@ static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw)
if (!rtlpriv->rtlhal.earlymode_enable)
return;
if (rtlpriv->dm.supp_phymode_switch &&
(rtlpriv->easy_concurrent_ctl.switch_in_process ||
(rtlpriv->buddy_priv &&
rtlpriv->buddy_priv->easy_concurrent_ctl.switch_in_process)))
return;
/* we just use em for BE/BK/VI/VO */
for (tid = 7; tid >= 0; tid--) {
u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(tid)];
@@ -1702,8 +1657,6 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw)
synchronize_irq(rtlpci->pdev->irq);
tasklet_kill(&rtlpriv->works.irq_tasklet);
cancel_work_sync(&rtlpriv->works.lps_change_work);
destroy_workqueue(rtlpriv->works.rtl_wq);
}
static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
@@ -2018,7 +1971,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
pcipriv->ndis_adapter.amd_l1_patch);
rtl_pci_parse_configuration(pdev, hw);
list_add_tail(&rtlpriv->list, &rtlpriv->glb_var->glb_priv_list);
return true;
}
@@ -2165,7 +2117,6 @@ int rtl_pci_probe(struct pci_dev *pdev,
rtlpriv->rtlhal.interface = INTF_PCI;
rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
rtlpriv->intf_ops = &rtl_pci_ops;
rtlpriv->glb_var = &rtl_global_var;
rtl_efuse_ops_init(hw);
/* MEM map */
@@ -2216,7 +2167,7 @@ int rtl_pci_probe(struct pci_dev *pdev,
if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
pr_err("Can't init_sw_vars\n");
err = -ENODEV;
goto fail3;
goto fail2;
}
rtlpriv->cfg->ops->init_sw_leds(hw);
@@ -2234,14 +2185,14 @@ int rtl_pci_probe(struct pci_dev *pdev,
err = rtl_pci_init(hw, pdev);
if (err) {
pr_err("Failed to init PCI\n");
goto fail3;
goto fail4;
}
err = ieee80211_register_hw(hw);
if (err) {
pr_err("Can't register mac80211 hw.\n");
err = -ENODEV;
goto fail3;
goto fail5;
}
rtlpriv->mac80211.mac80211_registered = 1;
@@ -2264,16 +2215,19 @@ int rtl_pci_probe(struct pci_dev *pdev,
set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
return 0;
fail3:
pci_set_drvdata(pdev, NULL);
fail5:
rtl_pci_deinit(hw);
fail4:
rtl_deinit_core(hw);
fail3:
wait_for_completion(&rtlpriv->firmware_loading_complete);
rtlpriv->cfg->ops->deinit_sw_vars(hw);
fail2:
if (rtlpriv->io.pci_mem_start != 0)
pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
pci_release_regions(pdev);
complete(&rtlpriv->firmware_loading_complete);
fail1:
if (hw)
@@ -2324,7 +2278,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
if (rtlpci->using_msi)
pci_disable_msi(rtlpci->pdev);
list_del(&rtlpriv->list);
if (rtlpriv->io.pci_mem_start != 0) {
pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
pci_release_regions(pdev);
@@ -2384,7 +2337,6 @@ const struct rtl_intf_ops rtl_pci_ops = {
.read_efuse_byte = read_efuse_byte,
.adapter_start = rtl_pci_start,
.adapter_stop = rtl_pci_stop,
.check_buddy_priv = rtl_pci_check_buddy_priv,
.adapter_tx = rtl_pci_tx,
.flush = rtl_pci_flush,
.reset_trx_ring = rtl_pci_reset_trx_ring,

View File

@@ -67,22 +67,23 @@ static void rtl92se_fw_cb(const struct firmware *firmware, void *context)
rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
"Firmware callback routine entered!\n");
complete(&rtlpriv->firmware_loading_complete);
if (!firmware) {
pr_err("Firmware %s not available\n", fw_name);
rtlpriv->max_fw_size = 0;
return;
goto exit;
}
if (firmware->size > rtlpriv->max_fw_size) {
pr_err("Firmware is too big!\n");
rtlpriv->max_fw_size = 0;
release_firmware(firmware);
return;
goto exit;
}
pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
pfirmware->sz_fw_tmpbufferlen = firmware->size;
release_firmware(firmware);
exit:
complete(&rtlpriv->firmware_loading_complete);
}
static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)

View File

@@ -679,11 +679,6 @@ static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw)
tasklet_kill(&rtlusb->rx_work_tasklet);
cancel_work_sync(&rtlpriv->works.lps_change_work);
if (rtlpriv->works.rtl_wq) {
destroy_workqueue(rtlpriv->works.rtl_wq);
rtlpriv->works.rtl_wq = NULL;
}
skb_queue_purge(&rtlusb->rx_queue);
while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) {
@@ -1073,19 +1068,22 @@ int rtl_usb_probe(struct usb_interface *intf,
err = ieee80211_register_hw(hw);
if (err) {
pr_err("Can't register mac80211 hw.\n");
goto error_out;
goto error_init_vars;
}
rtlpriv->mac80211.mac80211_registered = 1;
set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
return 0;
error_init_vars:
wait_for_completion(&rtlpriv->firmware_loading_complete);
rtlpriv->cfg->ops->deinit_sw_vars(hw);
error_out:
rtl_usb_deinit(hw);
rtl_deinit_core(hw);
error_out2:
_rtl_usb_io_handler_release(hw);
usb_put_dev(udev);
complete(&rtlpriv->firmware_loading_complete);
kfree(rtlpriv->usb_data);
ieee80211_free_hw(hw);
return -ENODEV;

View File

@@ -2300,7 +2300,6 @@ struct rtl_hal_ops {
u32 regaddr, u32 bitmask, u32 data);
void (*linked_set_reg)(struct ieee80211_hw *hw);
void (*chk_switch_dmdp)(struct ieee80211_hw *hw);
void (*dualmac_easy_concurrent)(struct ieee80211_hw *hw);
void (*dualmac_switch_to_dmdp)(struct ieee80211_hw *hw);
bool (*phy_rf6052_config)(struct ieee80211_hw *hw);
void (*phy_rf6052_set_cck_txpower)(struct ieee80211_hw *hw,
@@ -2336,8 +2335,6 @@ struct rtl_intf_ops {
void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);
int (*adapter_start)(struct ieee80211_hw *hw);
void (*adapter_stop)(struct ieee80211_hw *hw);
bool (*check_buddy_priv)(struct ieee80211_hw *hw,
struct rtl_priv **buddy_priv);
int (*adapter_tx)(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
@@ -2465,7 +2462,6 @@ struct rtl_works {
/*timer */
struct timer_list watchdog_timer;
struct timer_list dualmac_easyconcurrent_retrytimer;
struct timer_list fw_clockoff_timer;
struct timer_list fast_antenna_training_timer;
/*task */
@@ -2498,14 +2494,6 @@ struct rtl_debug {
#define MIMO_PS_DYNAMIC 1
#define MIMO_PS_NOLIMIT 3
struct rtl_dualmac_easy_concurrent_ctl {
enum band_type currentbandtype_backfordmdp;
bool close_bbandrf_for_dmsp;
bool change_to_dmdp;
bool change_to_dmsp;
bool switch_in_process;
};
struct rtl_dmsp_ctl {
bool activescan_for_slaveofdmsp;
bool scan_for_anothermac_fordmsp;
@@ -2590,14 +2578,6 @@ struct dig_t {
u32 rssi_max;
};
struct rtl_global_var {
/* from this list we can get
* other adapter's rtl_priv
*/
struct list_head glb_priv_list;
spinlock_t glb_list_lock;
};
#define IN_4WAY_TIMEOUT_TIME (30 * MSEC_PER_SEC) /* 30 seconds */
struct rtl_btc_info {
@@ -2743,10 +2723,7 @@ struct rtl_scan_list {
struct rtl_priv {
struct ieee80211_hw *hw;
struct completion firmware_loading_complete;
struct list_head list;
struct rtl_priv *buddy_priv;
struct rtl_global_var *glb_var;
struct rtl_dualmac_easy_concurrent_ctl easy_concurrent_ctl;
struct rtl_dmsp_ctl dmsp_ctl;
struct rtl_locks locks;
struct rtl_works works;

View File

@@ -950,7 +950,7 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table,
ret = _of_opp_alloc_required_opps(opp_table, new_opp);
if (ret)
goto free_opp;
goto put_node;
if (!of_property_read_u32(np, "clock-latency-ns", &val))
new_opp->clock_latency_ns = val;
@@ -1003,6 +1003,8 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table,
free_required_opps:
_of_opp_free_required_opps(opp_table, new_opp);
put_node:
of_node_put(np);
free_opp:
_opp_free(new_opp);

View File

@@ -169,8 +169,12 @@ static int stm32_pwm_lp_get_state(struct pwm_chip *chip,
regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val);
/* Keep PWM counter clock refcount in sync with PWM initial state */
if (state->enabled)
clk_enable(priv->clk);
if (state->enabled) {
int ret = clk_enable(priv->clk);
if (ret)
return ret;
}
regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val);
presc = FIELD_GET(STM32_LPTIM_PRESC, val);

View File

@@ -435,7 +435,7 @@ int of_regulator_match(struct device *dev, struct device_node *node,
"failed to parse DT for regulator %pOFn\n",
child);
of_node_put(child);
return -EINVAL;
goto err_put;
}
match->of_node = of_node_get(child);
count++;
@@ -444,6 +444,18 @@ int of_regulator_match(struct device *dev, struct device_node *node,
}
return count;
err_put:
for (i = 0; i < num_matches; i++) {
struct of_regulator_match *match = &matches[i];
match->init_data = NULL;
if (match->of_node) {
of_node_put(match->of_node);
match->of_node = NULL;
}
}
return -EINVAL;
}
EXPORT_SYMBOL_GPL(of_regulator_match);

View File

@@ -379,12 +379,21 @@ static int zynq_qspi_setup_op(struct spi_device *spi)
{
struct spi_controller *ctlr = spi->master;
struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr);
int ret;
if (ctlr->busy)
return -EBUSY;
clk_enable(qspi->refclk);
clk_enable(qspi->pclk);
ret = clk_enable(qspi->refclk);
if (ret)
return ret;
ret = clk_enable(qspi->pclk);
if (ret) {
clk_disable(qspi->refclk);
return ret;
}
zynq_qspi_write(qspi, ZYNQ_QSPI_ENABLE_OFFSET,
ZYNQ_QSPI_ENABLE_ENABLE_MASK);

View File

@@ -2203,7 +2203,7 @@ struct net_device {
void *atalk_ptr;
#endif
#if IS_ENABLED(CONFIG_AX25)
void *ax25_ptr;
struct ax25_dev __rcu *ax25_ptr;
#endif
/* Android KMI hack to allow vendors to have their own wifi changes in modules */
#ifdef __GENKSYMS__

View File

@@ -229,6 +229,7 @@ typedef struct ax25_dev {
#endif
refcount_t refcount;
bool device_up;
struct rcu_head rcu;
} ax25_dev;
typedef struct ax25_cb {
@@ -291,9 +292,8 @@ static inline void ax25_dev_hold(ax25_dev *ax25_dev)
static inline void ax25_dev_put(ax25_dev *ax25_dev)
{
if (refcount_dec_and_test(&ax25_dev->refcount)) {
kfree(ax25_dev);
}
if (refcount_dec_and_test(&ax25_dev->refcount))
kfree_rcu(ax25_dev, rcu);
}
static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
{
@@ -336,9 +336,9 @@ void ax25_digi_invert(const ax25_digi *, ax25_digi *);
extern spinlock_t ax25_dev_lock;
#if IS_ENABLED(CONFIG_AX25)
static inline ax25_dev *ax25_dev_ax25dev(struct net_device *dev)
static inline ax25_dev *ax25_dev_ax25dev(const struct net_device *dev)
{
return dev->ax25_ptr;
return rcu_dereference_rtnl(dev->ax25_ptr);
}
#endif

View File

@@ -96,30 +96,28 @@ static inline struct in6_addr *inetpeer_get_addr_v6(struct inetpeer_addr *iaddr)
/* can be called with or without local BH being disabled */
struct inet_peer *inet_getpeer(struct inet_peer_base *base,
const struct inetpeer_addr *daddr,
int create);
const struct inetpeer_addr *daddr);
static inline struct inet_peer *inet_getpeer_v4(struct inet_peer_base *base,
__be32 v4daddr,
int vif, int create)
int vif)
{
struct inetpeer_addr daddr;
daddr.a4.addr = v4daddr;
daddr.a4.vif = vif;
daddr.family = AF_INET;
return inet_getpeer(base, &daddr, create);
return inet_getpeer(base, &daddr);
}
static inline struct inet_peer *inet_getpeer_v6(struct inet_peer_base *base,
const struct in6_addr *v6daddr,
int create)
const struct in6_addr *v6daddr)
{
struct inetpeer_addr daddr;
daddr.a6 = *v6daddr;
daddr.family = AF_INET6;
return inet_getpeer(base, &daddr, create);
return inet_getpeer(base, &daddr);
}
static inline int inetpeer_addr_cmp(const struct inetpeer_addr *a,

View File

@@ -86,7 +86,7 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
if (unlikely(sg_policy->limits_changed)) {
sg_policy->limits_changed = false;
sg_policy->need_freq_update = true;
sg_policy->need_freq_update = cpufreq_driver_test_flags(CPUFREQ_NEED_UPDATE_LIMITS);
return true;
}
@@ -99,7 +99,7 @@ static bool sugov_update_next_freq(struct sugov_policy *sg_policy, u64 time,
unsigned int next_freq)
{
if (sg_policy->need_freq_update)
sg_policy->need_freq_update = cpufreq_driver_test_flags(CPUFREQ_NEED_UPDATE_LIMITS);
sg_policy->need_freq_update = false;
else if (sg_policy->next_freq == next_freq)
return false;

View File

@@ -467,7 +467,7 @@ einval_put:
goto out_put;
}
static void ax25_fillin_cb_from_dev(ax25_cb *ax25, ax25_dev *ax25_dev)
static void ax25_fillin_cb_from_dev(ax25_cb *ax25, const ax25_dev *ax25_dev)
{
ax25->rtt = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]) / 2;
ax25->t1 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]);
@@ -677,22 +677,22 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
break;
}
rtnl_lock();
dev = __dev_get_by_name(&init_net, devname);
rcu_read_lock();
dev = dev_get_by_name_rcu(&init_net, devname);
if (!dev) {
rtnl_unlock();
rcu_read_unlock();
res = -ENODEV;
break;
}
ax25->ax25_dev = ax25_dev_ax25dev(dev);
if (!ax25->ax25_dev) {
rtnl_unlock();
rcu_read_unlock();
res = -ENODEV;
break;
}
ax25_fillin_cb(ax25, ax25->ax25_dev);
rtnl_unlock();
rcu_read_unlock();
break;
default:

View File

@@ -87,7 +87,7 @@ void ax25_dev_device_up(struct net_device *dev)
spin_lock_bh(&ax25_dev_lock);
list_add(&ax25_dev->list, &ax25_dev_list);
dev->ax25_ptr = ax25_dev;
rcu_assign_pointer(dev->ax25_ptr, ax25_dev);
spin_unlock_bh(&ax25_dev_lock);
ax25_register_dev_sysctl(ax25_dev);
@@ -122,7 +122,7 @@ void ax25_dev_device_down(struct net_device *dev)
}
}
dev->ax25_ptr = NULL;
RCU_INIT_POINTER(dev->ax25_ptr, NULL);
spin_unlock_bh(&ax25_dev_lock);
netdev_put(dev, &ax25_dev->dev_tracker);
ax25_dev_put(ax25_dev);

View File

@@ -122,6 +122,7 @@ netdev_tx_t ax25_ip_xmit(struct sk_buff *skb)
if (dev == NULL)
dev = skb->dev;
rcu_read_lock();
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) {
kfree_skb(skb);
goto put;
@@ -202,7 +203,7 @@ netdev_tx_t ax25_ip_xmit(struct sk_buff *skb)
ax25_queue_xmit(skb, dev);
put:
rcu_read_unlock();
ax25_route_lock_unuse();
return NETDEV_TX_OK;
}

View File

@@ -39,10 +39,14 @@ ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, const ax25_address *sr
* specified.
*/
if (paclen == 0) {
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
rcu_read_lock();
ax25_dev = ax25_dev_ax25dev(dev);
if (!ax25_dev) {
rcu_read_unlock();
return NULL;
}
paclen = ax25_dev->values[AX25_VALUES_PACLEN];
rcu_read_unlock();
}
/*
@@ -53,13 +57,19 @@ ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, const ax25_address *sr
return ax25; /* It already existed */
}
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
rcu_read_lock();
ax25_dev = ax25_dev_ax25dev(dev);
if (!ax25_dev) {
rcu_read_unlock();
return NULL;
}
if ((ax25 = ax25_create_cb()) == NULL)
if ((ax25 = ax25_create_cb()) == NULL) {
rcu_read_unlock();
return NULL;
}
ax25_fillin_cb(ax25, ax25_dev);
rcu_read_unlock();
ax25->source_addr = *src;
ax25->dest_addr = *dest;
@@ -358,7 +368,9 @@ void ax25_queue_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned char *ptr;
rcu_read_lock();
skb->protocol = ax25_type_trans(skb, ax25_fwd_dev(dev));
rcu_read_unlock();
ptr = skb_push(skb, 1);
*ptr = 0x00; /* KISS */

View File

@@ -406,6 +406,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
ax25_route_lock_unuse();
return -EHOSTUNREACH;
}
rcu_read_lock();
if ((ax25->ax25_dev = ax25_dev_ax25dev(ax25_rt->dev)) == NULL) {
err = -EHOSTUNREACH;
goto put;
@@ -442,6 +443,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
}
put:
rcu_read_unlock();
ax25_route_lock_unuse();
return err;
}

View File

@@ -310,7 +310,6 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
struct dst_entry *dst = &rt->dst;
struct inet_peer *peer;
bool rc = true;
int vif;
if (icmpv4_mask_allow(net, type, code))
goto out;
@@ -319,12 +318,12 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt,
if (dst->dev && (dst->dev->flags&IFF_LOOPBACK))
goto out;
vif = l3mdev_master_ifindex(dst->dev);
peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, vif, 1);
rcu_read_lock();
peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr,
l3mdev_master_ifindex_rcu(dst->dev));
rc = inet_peer_xrlim_allow(peer,
READ_ONCE(net->ipv4.sysctl_icmp_ratelimit));
if (peer)
inet_putpeer(peer);
rcu_read_unlock();
out:
return rc;
}

View File

@@ -98,6 +98,7 @@ static struct inet_peer *lookup(const struct inetpeer_addr *daddr,
{
struct rb_node **pp, *parent, *next;
struct inet_peer *p;
u32 now;
pp = &base->rb_root.rb_node;
parent = NULL;
@@ -111,8 +112,9 @@ static struct inet_peer *lookup(const struct inetpeer_addr *daddr,
p = rb_entry(parent, struct inet_peer, rb_node);
cmp = inetpeer_addr_cmp(daddr, &p->daddr);
if (cmp == 0) {
if (!refcount_inc_not_zero(&p->refcnt))
break;
now = jiffies;
if (READ_ONCE(p->dtime) != now)
WRITE_ONCE(p->dtime, now);
return p;
}
if (gc_stack) {
@@ -158,9 +160,6 @@ static void inet_peer_gc(struct inet_peer_base *base,
for (i = 0; i < gc_cnt; i++) {
p = gc_stack[i];
/* The READ_ONCE() pairs with the WRITE_ONCE()
* in inet_putpeer()
*/
delta = (__u32)jiffies - READ_ONCE(p->dtime);
if (delta < ttl || !refcount_dec_if_one(&p->refcnt))
@@ -176,31 +175,23 @@ static void inet_peer_gc(struct inet_peer_base *base,
}
}
/* Must be called under RCU : No refcount change is done here. */
struct inet_peer *inet_getpeer(struct inet_peer_base *base,
const struct inetpeer_addr *daddr,
int create)
const struct inetpeer_addr *daddr)
{
struct inet_peer *p, *gc_stack[PEER_MAX_GC];
struct rb_node **pp, *parent;
unsigned int gc_cnt, seq;
int invalidated;
/* Attempt a lockless lookup first.
* Because of a concurrent writer, we might not find an existing entry.
*/
rcu_read_lock();
seq = read_seqbegin(&base->lock);
p = lookup(daddr, base, seq, NULL, &gc_cnt, &parent, &pp);
invalidated = read_seqretry(&base->lock, seq);
rcu_read_unlock();
if (p)
return p;
/* If no writer did a change during our lookup, we can return early. */
if (!create && !invalidated)
return NULL;
/* retry an exact lookup, taking the lock before.
* At least, nodes should be hot in our cache.
*/
@@ -209,12 +200,12 @@ struct inet_peer *inet_getpeer(struct inet_peer_base *base,
gc_cnt = 0;
p = lookup(daddr, base, seq, gc_stack, &gc_cnt, &parent, &pp);
if (!p && create) {
if (!p) {
p = kmem_cache_alloc(peer_cachep, GFP_ATOMIC);
if (p) {
p->daddr = *daddr;
p->dtime = (__u32)jiffies;
refcount_set(&p->refcnt, 2);
refcount_set(&p->refcnt, 1);
atomic_set(&p->rid, 0);
p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW;
p->rate_tokens = 0;
@@ -239,15 +230,9 @@ EXPORT_SYMBOL_GPL(inet_getpeer);
void inet_putpeer(struct inet_peer *p)
{
/* The WRITE_ONCE() pairs with itself (we run lockless)
* and the READ_ONCE() in inet_peer_gc()
*/
WRITE_ONCE(p->dtime, (__u32)jiffies);
if (refcount_dec_and_test(&p->refcnt))
call_rcu(&p->rcu, inetpeer_free_rcu);
}
EXPORT_SYMBOL_GPL(inet_putpeer);
/*
* Check transmit rate limitation for given message.

View File

@@ -82,15 +82,20 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *skb,
static void ip4_frag_init(struct inet_frag_queue *q, const void *a)
{
struct ipq *qp = container_of(q, struct ipq, q);
struct net *net = q->fqdir->net;
const struct frag_v4_compare_key *key = a;
struct net *net = q->fqdir->net;
struct inet_peer *p = NULL;
q->key.v4 = *key;
qp->ecn = 0;
qp->peer = q->fqdir->max_dist ?
inet_getpeer_v4(net->ipv4.peers, key->saddr, key->vif, 1) :
NULL;
if (q->fqdir->max_dist) {
rcu_read_lock();
p = inet_getpeer_v4(net->ipv4.peers, key->saddr, key->vif);
if (p && !refcount_inc_not_zero(&p->refcnt))
p = NULL;
rcu_read_unlock();
}
qp->peer = p;
}
static void ip4_frag_free(struct inet_frag_queue *q)

View File

@@ -882,11 +882,11 @@ void ip_rt_send_redirect(struct sk_buff *skb)
}
log_martians = IN_DEV_LOG_MARTIANS(in_dev);
vif = l3mdev_master_ifindex_rcu(rt->dst.dev);
rcu_read_unlock();
net = dev_net(rt->dst.dev);
peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, vif, 1);
peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, vif);
if (!peer) {
rcu_read_unlock();
icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST,
rt_nexthop(rt, ip_hdr(skb)->daddr));
return;
@@ -905,7 +905,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
*/
if (peer->n_redirects >= ip_rt_redirect_number) {
peer->rate_last = jiffies;
goto out_put_peer;
goto out_unlock;
}
/* Check for load limit; set rate_last to the latest sent
@@ -926,8 +926,8 @@ void ip_rt_send_redirect(struct sk_buff *skb)
&ip_hdr(skb)->saddr, inet_iif(skb),
&ip_hdr(skb)->daddr, &gw);
}
out_put_peer:
inet_putpeer(peer);
out_unlock:
rcu_read_unlock();
}
static int ip_error(struct sk_buff *skb)
@@ -987,9 +987,9 @@ static int ip_error(struct sk_buff *skb)
break;
}
rcu_read_lock();
peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr,
l3mdev_master_ifindex(skb->dev), 1);
l3mdev_master_ifindex_rcu(skb->dev));
send = true;
if (peer) {
now = jiffies;
@@ -1001,8 +1001,9 @@ static int ip_error(struct sk_buff *skb)
peer->rate_tokens -= ip_rt_error_cost;
else
send = false;
inet_putpeer(peer);
}
rcu_read_unlock();
if (send)
icmp_send(skb, ICMP_DEST_UNREACH, code, 0);

View File

@@ -219,10 +219,10 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
if (rt->rt6i_dst.plen < 128)
tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr, 1);
rcu_read_lock();
peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr);
res = inet_peer_xrlim_allow(peer, tmo);
if (peer)
inet_putpeer(peer);
rcu_read_unlock();
}
dst_release(dst);
return res;

View File

@@ -610,15 +610,15 @@ int ip6_forward(struct sk_buff *skb)
else
target = &hdr->daddr;
peer = inet_getpeer_v6(net->ipv6.peers, &hdr->daddr, 1);
rcu_read_lock();
peer = inet_getpeer_v6(net->ipv6.peers, &hdr->daddr);
/* Limit redirects both by destination (here)
and by source (inside ndisc_send_redirect)
*/
if (inet_peer_xrlim_allow(peer, 1*HZ))
ndisc_send_redirect(skb, target);
if (peer)
inet_putpeer(peer);
rcu_read_unlock();
} else {
int addrtype = ipv6_addr_type(&hdr->saddr);

View File

@@ -1721,10 +1721,12 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
"Redirect: destination is not a neighbour\n");
goto release;
}
peer = inet_getpeer_v6(net->ipv6.peers, &ipv6_hdr(skb)->saddr, 1);
rcu_read_lock();
peer = inet_getpeer_v6(net->ipv6.peers, &ipv6_hdr(skb)->saddr);
ret = inet_peer_xrlim_allow(peer, 1*HZ);
if (peer)
inet_putpeer(peer);
rcu_read_unlock();
if (!ret)
goto release;

View File

@@ -77,12 +77,6 @@
#define SFQ_EMPTY_SLOT 0xffff
#define SFQ_DEFAULT_HASH_DIVISOR 1024
/* We use 16 bits to store allot, and want to handle packets up to 64K
* Scale allot by 8 (1<<3) so that no overflow occurs.
*/
#define SFQ_ALLOT_SHIFT 3
#define SFQ_ALLOT_SIZE(X) DIV_ROUND_UP(X, 1 << SFQ_ALLOT_SHIFT)
/* This type should contain at least SFQ_MAX_DEPTH + 1 + SFQ_MAX_FLOWS values */
typedef u16 sfq_index;
@@ -104,7 +98,7 @@ struct sfq_slot {
sfq_index next; /* next slot in sfq RR chain */
struct sfq_head dep; /* anchor in dep[] chains */
unsigned short hash; /* hash value (index in ht[]) */
short allot; /* credit for this slot */
int allot; /* credit for this slot */
unsigned int backlog;
struct red_vars vars;
@@ -120,7 +114,6 @@ struct sfq_sched_data {
siphash_key_t perturbation;
u8 cur_depth; /* depth of longest slot */
u8 flags;
unsigned short scaled_quantum; /* SFQ_ALLOT_SIZE(quantum) */
struct tcf_proto __rcu *filter_list;
struct tcf_block *block;
sfq_index *ht; /* Hash table ('divisor' slots) */
@@ -456,7 +449,7 @@ enqueue:
*/
q->tail = slot;
/* We could use a bigger initial quantum for new flows */
slot->allot = q->scaled_quantum;
slot->allot = q->quantum;
}
if (++sch->q.qlen <= q->limit)
return NET_XMIT_SUCCESS;
@@ -493,7 +486,7 @@ next_slot:
slot = &q->slots[a];
if (slot->allot <= 0) {
q->tail = slot;
slot->allot += q->scaled_quantum;
slot->allot += q->quantum;
goto next_slot;
}
skb = slot_dequeue_head(slot);
@@ -512,7 +505,7 @@ next_slot:
}
q->tail->next = next_a;
} else {
slot->allot -= SFQ_ALLOT_SIZE(qdisc_pkt_len(skb));
slot->allot -= qdisc_pkt_len(skb);
}
return skb;
}
@@ -595,7 +588,7 @@ drop:
q->tail->next = x;
}
q->tail = slot;
slot->allot = q->scaled_quantum;
slot->allot = q->quantum;
}
}
sch->q.qlen -= dropped;
@@ -608,6 +601,7 @@ static void sfq_perturbation(struct timer_list *t)
struct Qdisc *sch = q->sch;
spinlock_t *root_lock;
siphash_key_t nkey;
int period;
get_random_bytes(&nkey, sizeof(nkey));
rcu_read_lock();
@@ -618,12 +612,17 @@ static void sfq_perturbation(struct timer_list *t)
sfq_rehash(sch);
spin_unlock(root_lock);
if (q->perturb_period)
mod_timer(&q->perturb_timer, jiffies + q->perturb_period);
/* q->perturb_period can change under us from
* sfq_change() and sfq_destroy().
*/
period = READ_ONCE(q->perturb_period);
if (period)
mod_timer(&q->perturb_timer, jiffies + period);
rcu_read_unlock();
}
static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
struct sfq_sched_data *q = qdisc_priv(sch);
struct tc_sfq_qopt *ctl = nla_data(opt);
@@ -641,14 +640,10 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
(!is_power_of_2(ctl->divisor) || ctl->divisor > 65536))
return -EINVAL;
/* slot->allot is a short, make sure quantum is not too big. */
if (ctl->quantum) {
unsigned int scaled = SFQ_ALLOT_SIZE(ctl->quantum);
if (scaled <= 0 || scaled > SHRT_MAX)
return -EINVAL;
if ((int)ctl->quantum < 0) {
NL_SET_ERR_MSG_MOD(extack, "invalid quantum");
return -EINVAL;
}
if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max,
ctl_v1->Wlog, ctl_v1->Scell_log, NULL))
return -EINVAL;
@@ -657,12 +652,14 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
if (!p)
return -ENOMEM;
}
sch_tree_lock(sch);
if (ctl->quantum) {
q->quantum = ctl->quantum;
q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
if (ctl->limit == 1) {
NL_SET_ERR_MSG_MOD(extack, "invalid limit");
return -EINVAL;
}
q->perturb_period = ctl->perturb_period * HZ;
sch_tree_lock(sch);
if (ctl->quantum)
q->quantum = ctl->quantum;
WRITE_ONCE(q->perturb_period, ctl->perturb_period * HZ);
if (ctl->flows)
q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS);
if (ctl->divisor) {
@@ -724,7 +721,7 @@ static void sfq_destroy(struct Qdisc *sch)
struct sfq_sched_data *q = qdisc_priv(sch);
tcf_block_put(q->block);
q->perturb_period = 0;
WRITE_ONCE(q->perturb_period, 0);
del_timer_sync(&q->perturb_timer);
sfq_free(q->ht);
sfq_free(q->slots);
@@ -757,12 +754,11 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt,
q->divisor = SFQ_DEFAULT_HASH_DIVISOR;
q->maxflows = SFQ_DEFAULT_FLOWS;
q->quantum = psched_mtu(qdisc_dev(sch));
q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
q->perturb_period = 0;
get_random_bytes(&q->perturbation, sizeof(q->perturbation));
if (opt) {
int err = sfq_change(sch, opt);
int err = sfq_change(sch, opt, extack);
if (err)
return err;
}
@@ -873,7 +869,7 @@ static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
if (idx != SFQ_EMPTY_SLOT) {
const struct sfq_slot *slot = &q->slots[idx];
xstats.allot = slot->allot << SFQ_ALLOT_SHIFT;
xstats.allot = slot->allot;
qs.qlen = slot->qlen;
qs.backlog = slot->backlog;
}

View File

@@ -33,7 +33,7 @@ static int mperf_get_count_percent(unsigned int self_id, double *percent,
unsigned int cpu);
static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
unsigned int cpu);
static struct timespec time_start, time_end;
static struct timespec *time_start, *time_end;
static cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = {
{
@@ -174,7 +174,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent,
dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n",
mperf_cstates[id].name, mperf_diff, tsc_diff);
} else if (max_freq_mode == MAX_FREQ_SYSFS) {
timediff = max_frequency * timespec_diff_us(time_start, time_end);
timediff = max_frequency * timespec_diff_us(time_start[cpu], time_end[cpu]);
*percent = 100.0 * mperf_diff / timediff;
dprint("%s: MAXFREQ - mperf_diff: %llu, time_diff: %llu\n",
mperf_cstates[id].name, mperf_diff, timediff);
@@ -207,7 +207,7 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count,
if (max_freq_mode == MAX_FREQ_TSC_REF) {
/* Calculate max_freq from TSC count */
tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu];
time_diff = timespec_diff_us(time_start, time_end);
time_diff = timespec_diff_us(time_start[cpu], time_end[cpu]);
max_frequency = tsc_diff / time_diff;
}
@@ -226,9 +226,8 @@ static int mperf_start(void)
{
int cpu;
clock_gettime(CLOCK_REALTIME, &time_start);
for (cpu = 0; cpu < cpu_count; cpu++) {
clock_gettime(CLOCK_REALTIME, &time_start[cpu]);
mperf_get_tsc(&tsc_at_measure_start[cpu]);
mperf_init_stats(cpu);
}
@@ -243,9 +242,9 @@ static int mperf_stop(void)
for (cpu = 0; cpu < cpu_count; cpu++) {
mperf_measure_stats(cpu);
mperf_get_tsc(&tsc_at_measure_end[cpu]);
clock_gettime(CLOCK_REALTIME, &time_end[cpu]);
}
clock_gettime(CLOCK_REALTIME, &time_end);
return 0;
}
@@ -349,6 +348,8 @@ struct cpuidle_monitor *mperf_register(void)
aperf_current_count = calloc(cpu_count, sizeof(unsigned long long));
tsc_at_measure_start = calloc(cpu_count, sizeof(unsigned long long));
tsc_at_measure_end = calloc(cpu_count, sizeof(unsigned long long));
time_start = calloc(cpu_count, sizeof(struct timespec));
time_end = calloc(cpu_count, sizeof(struct timespec));
mperf_monitor.name_len = strlen(mperf_monitor.name);
return &mperf_monitor;
}
@@ -361,6 +362,8 @@ void mperf_unregister(void)
free(aperf_current_count);
free(tsc_at_measure_start);
free(tsc_at_measure_end);
free(time_start);
free(time_end);
free(is_valid);
}