Commit 48f58ba9 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Pull more networking fixes from David Miller:

 1) Fix brcmfmac build with older gcc, from Arend van Spriel.

 2) IRQ values unintentionally truncated to u8 in mlx5 driver, from
    Doron Tsur.

 3) Fix build warnings wrt tcp cgroup changes, from Geert Uytterhoeven.

 4) Limit deep recursion in ovs stack, from Hannes Frederic Sowa.

 5) at803x phy driver bug fixes from, Martin Blumenstingl.

 6) Fix TSO handling in hns driver, from Daode Huang

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (22 commits)
  ovs: limit ovs recursions in ovs_execute_actions to not corrupt stack
  team: Replace rcu_read_lock with a mutex in team_vlan_rx_kill_vid
  net: hns: bug fix about hisilicon TSO BD mode
  brcmfmac: fix BRCMF_FW_NVRAM_DEF macro for older gcc compilers
  net: phy: at803x: Add the interrupt register bit definitions
  net: phy: at803x: Clean up duplicate register definitions
  net: phy: at803x: Allow specifying the RGMII RX clock delay via phy mode
  net: phy: at803x: Don't set gbit features for the AR8030 phy
  arm64: bpf: add extra pass to handle faulty codegen
  arm64: insn: remove BUG_ON from codegen
  sctp: the temp asoc's transports should not be hashed/unhashed
  net/mlx5_core: Fix trimming down IRQ number
  tcp_memcontrol: Forward declare cgroup_subsys and mem_cgroup stucts
  batman-adv: Drop immediate orig_node free function
  batman-adv: Drop immediate batadv_hard_iface free function
  batman-adv: Drop immediate neigh_ifinfo free function
  batman-adv: Drop immediate batadv_hardif_neigh_node free function
  batman-adv: Drop immediate batadv_neigh_node free function
  batman-adv: Drop immediate batadv_orig_ifinfo free function
  batman-adv: Avoid recursive call_rcu for batadv_nc_node
  ...
parents 7f36f1b2 b064d0d8
This diff is collapsed.
/*
* BPF JIT compiler for ARM64
*
* Copyright (C) 2014-2015 Zi Shen Lim <zlim.lnx@gmail.com>
* Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -737,6 +737,20 @@ static int build_body(struct jit_ctx *ctx)
return 0;
}
static int validate_code(struct jit_ctx *ctx)
{
int i;
for (i = 0; i < ctx->idx; i++) {
u32 a64_insn = le32_to_cpu(ctx->image[i]);
if (a64_insn == AARCH64_BREAK_FAULT)
return -1;
}
return 0;
}
static inline void bpf_flush_icache(void *start, void *end)
{
flush_icache_range((unsigned long)start, (unsigned long)end);
......@@ -799,6 +813,12 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
build_epilogue(&ctx);
/* 3. Extra pass to validate JITed code. */
if (validate_code(&ctx)) {
bpf_jit_binary_free(header);
goto out;
}
/* And we're done. */
if (bpf_jit_enable > 1)
bpf_jit_dump(prog->len, image_size, 2, ctx.image);
......
......@@ -756,7 +756,7 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev,
int uninitialized_var(index);
int uninitialized_var(inlen);
int cqe_size;
int irqn;
unsigned int irqn;
int eqn;
int err;
......
......@@ -542,39 +542,50 @@ bnad_cq_drop_packet(struct bnad *bnad, struct bna_rcb *rcb,
}
static void
bnad_cq_setup_skb_frags(struct bna_rcb *rcb, struct sk_buff *skb,
u32 sop_ci, u32 nvecs, u32 last_fraglen)
bnad_cq_setup_skb_frags(struct bna_ccb *ccb, struct sk_buff *skb, u32 nvecs)
{
struct bna_rcb *rcb;
struct bnad *bnad;
u32 ci, vec, len, totlen = 0;
struct bnad_rx_unmap_q *unmap_q;
struct bnad_rx_unmap *unmap;
struct bna_cq_entry *cq, *cmpl;
u32 ci, pi, totlen = 0;
cq = ccb->sw_q;
pi = ccb->producer_index;
cmpl = &cq[pi];
rcb = bna_is_small_rxq(cmpl->rxq_id) ? ccb->rcb[1] : ccb->rcb[0];
unmap_q = rcb->unmap_q;
bnad = rcb->bnad;
ci = rcb->consumer_index;
/* prefetch header */
prefetch(page_address(unmap_q->unmap[sop_ci].page) +
unmap_q->unmap[sop_ci].page_offset);
prefetch(page_address(unmap_q->unmap[ci].page) +
unmap_q->unmap[ci].page_offset);
while (nvecs--) {
struct bnad_rx_unmap *unmap;
u32 len;
for (vec = 1, ci = sop_ci; vec <= nvecs; vec++) {
unmap = &unmap_q->unmap[ci];
BNA_QE_INDX_INC(ci, rcb->q_depth);
dma_unmap_page(&bnad->pcidev->dev,
dma_unmap_addr(&unmap->vector, dma_addr),
unmap->vector.len, DMA_FROM_DEVICE);
dma_unmap_addr(&unmap->vector, dma_addr),
unmap->vector.len, DMA_FROM_DEVICE);
len = (vec == nvecs) ?
last_fraglen : unmap->vector.len;
len = ntohs(cmpl->length);
skb->truesize += unmap->vector.len;
totlen += len;
skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
unmap->page, unmap->page_offset, len);
unmap->page, unmap->page_offset, len);
unmap->page = NULL;
unmap->vector.len = 0;
BNA_QE_INDX_INC(pi, ccb->q_depth);
cmpl = &cq[pi];
}
skb->len += totlen;
......@@ -704,7 +715,7 @@ bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget)
if (BNAD_RXBUF_IS_SK_BUFF(unmap_q->type))
bnad_cq_setup_skb(bnad, skb, unmap, len);
else
bnad_cq_setup_skb_frags(rcb, skb, sop_ci, nvecs, len);
bnad_cq_setup_skb_frags(ccb, skb, nvecs);
rcb->rxq->rx_packets++;
rcb->rxq->rx_bytes += totlen;
......
......@@ -369,8 +369,17 @@ int hns_rcb_common_init_hw(struct rcb_common_cb *rcb_common)
dsaf_write_dev(rcb_common, RCB_COM_CFG_ENDIAN_REG,
HNS_RCB_COMMON_ENDIAN);
dsaf_write_dev(rcb_common, RCB_COM_CFG_FNA_REG, 0x0);
dsaf_write_dev(rcb_common, RCB_COM_CFG_FA_REG, 0x1);
if (AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver)) {
dsaf_write_dev(rcb_common, RCB_COM_CFG_FNA_REG, 0x0);
dsaf_write_dev(rcb_common, RCB_COM_CFG_FA_REG, 0x1);
} else {
dsaf_set_dev_bit(rcb_common, RCBV2_COM_CFG_USER_REG,
RCB_COM_CFG_FNA_B, false);
dsaf_set_dev_bit(rcb_common, RCBV2_COM_CFG_USER_REG,
RCB_COM_CFG_FA_B, true);
dsaf_set_dev_bit(rcb_common, RCBV2_COM_CFG_TSO_MODE_REG,
RCB_COM_TSO_MODE_B, HNS_TSO_MODE_8BD_32K);
}
return 0;
}
......
......@@ -54,6 +54,9 @@ struct rcb_common_cb;
#define HNS_DUMP_REG_NUM 500
#define HNS_STATIC_REG_NUM 12
#define HNS_TSO_MODE_8BD_32K 1
#define HNS_TSO_MDOE_4BD_16K 0
enum rcb_int_flag {
RCB_INT_FLAG_TX = 0x1,
RCB_INT_FLAG_RX = (0x1 << 1),
......
......@@ -363,6 +363,8 @@
#define RCB_COM_CFG_FA_REG 0x3C
#define RCB_COM_CFG_PKT_TC_BP_REG 0x40
#define RCB_COM_CFG_PPE_TNL_CLKEN_REG 0x44
#define RCBV2_COM_CFG_USER_REG 0x30
#define RCBV2_COM_CFG_TSO_MODE_REG 0x50
#define RCB_COM_INTMSK_TX_PKT_REG 0x3A0
#define RCB_COM_RINT_TX_PKT_REG 0x3A8
......@@ -860,6 +862,9 @@
#define PPE_COMMON_CNT_CLR_CE_B 0
#define PPE_COMMON_CNT_CLR_SNAP_EN_B 1
#define RCB_COM_TSO_MODE_B 0
#define RCB_COM_CFG_FNA_B 1
#define RCB_COM_CFG_FA_B 0
#define GMAC_DUPLEX_TYPE_B 0
......
......@@ -752,7 +752,7 @@ static int mlx5e_create_cq(struct mlx5e_channel *c,
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5_core_cq *mcq = &cq->mcq;
int eqn_not_used;
int irqn;
unsigned int irqn;
int err;
u32 i;
......@@ -806,7 +806,7 @@ static int mlx5e_enable_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
void *in;
void *cqc;
int inlen;
int irqn_not_used;
unsigned int irqn_not_used;
int eqn;
int err;
......@@ -1517,7 +1517,7 @@ static int mlx5e_create_drop_cq(struct mlx5e_priv *priv,
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5_core_cq *mcq = &cq->mcq;
int eqn_not_used;
int irqn;
unsigned int irqn;
int err;
err = mlx5_cqwq_create(mdev, &param->wq, param->cqc, &cq->wq,
......
......@@ -585,7 +585,8 @@ static void mlx5_irq_clear_affinity_hints(struct mlx5_core_dev *mdev)
mlx5_irq_clear_affinity_hint(mdev, i);
}
int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, int *irqn)
int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
unsigned int *irqn)
{
struct mlx5_eq_table *table = &dev->priv.eq_table;
struct mlx5_eq *eq, *n;
......
......@@ -20,10 +20,21 @@
#include <linux/gpio/consumer.h>
#define AT803X_INTR_ENABLE 0x12
#define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15)
#define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14)
#define AT803X_INTR_ENABLE_DUPLEX_CHANGED BIT(13)
#define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12)
#define AT803X_INTR_ENABLE_LINK_FAIL BIT(11)
#define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10)
#define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5)
#define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1)
#define AT803X_INTR_ENABLE_WOL BIT(0)
#define AT803X_INTR_STATUS 0x13
#define AT803X_SMART_SPEED 0x14
#define AT803X_LED_CONTROL 0x18
#define AT803X_WOL_ENABLE 0x01
#define AT803X_DEVICE_ADDR 0x03
#define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C
#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B
......@@ -31,13 +42,15 @@
#define AT803X_MMD_ACCESS_CONTROL 0x0D
#define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E
#define AT803X_FUNC_DATA 0x4003
#define AT803X_INER 0x0012
#define AT803X_INER_INIT 0xec00
#define AT803X_INSR 0x0013
#define AT803X_DEBUG_ADDR 0x1D
#define AT803X_DEBUG_DATA 0x1E
#define AT803X_DEBUG_SYSTEM_MODE_CTRL 0x05
#define AT803X_DEBUG_RGMII_TX_CLK_DLY BIT(8)
#define AT803X_DEBUG_REG_0 0x00
#define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15)
#define AT803X_DEBUG_REG_5 0x05
#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8)
#define ATH8030_PHY_ID 0x004dd076
#define ATH8031_PHY_ID 0x004dd074
......@@ -61,6 +74,46 @@ struct at803x_context {
u16 led_control;
};
static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
{
int ret;
ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
if (ret < 0)
return ret;
return phy_read(phydev, AT803X_DEBUG_DATA);
}
static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
u16 clear, u16 set)
{
u16 val;
int ret;
ret = at803x_debug_reg_read(phydev, reg);
if (ret < 0)
return ret;
val = ret & 0xffff;
val &= ~clear;
val |= set;
return phy_write(phydev, AT803X_DEBUG_DATA, val);
}
static inline int at803x_enable_rx_delay(struct phy_device *phydev)
{
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
AT803X_DEBUG_RX_CLK_DLY_EN);
}
static inline int at803x_enable_tx_delay(struct phy_device *phydev)
{
return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
AT803X_DEBUG_TX_CLK_DLY_EN);
}
/* save relevant PHY registers to private copy */
static void at803x_context_save(struct phy_device *phydev,
struct at803x_context *context)
......@@ -119,14 +172,14 @@ static int at803x_set_wol(struct phy_device *phydev,
}
value = phy_read(phydev, AT803X_INTR_ENABLE);
value |= AT803X_WOL_ENABLE;
value |= AT803X_INTR_ENABLE_WOL;
ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
if (ret)
return ret;
value = phy_read(phydev, AT803X_INTR_STATUS);
} else {
value = phy_read(phydev, AT803X_INTR_ENABLE);
value &= (~AT803X_WOL_ENABLE);
value &= (~AT803X_INTR_ENABLE_WOL);
ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
if (ret)
return ret;
......@@ -145,7 +198,7 @@ static void at803x_get_wol(struct phy_device *phydev,
wol->wolopts = 0;
value = phy_read(phydev, AT803X_INTR_ENABLE);
if (value & AT803X_WOL_ENABLE)
if (value & AT803X_INTR_ENABLE_WOL)
wol->wolopts |= WAKE_MAGIC;
}
......@@ -157,7 +210,7 @@ static int at803x_suspend(struct phy_device *phydev)
mutex_lock(&phydev->lock);
value = phy_read(phydev, AT803X_INTR_ENABLE);
wol_enabled = value & AT803X_WOL_ENABLE;
wol_enabled = value & AT803X_INTR_ENABLE_WOL;
value = phy_read(phydev, MII_BMCR);
......@@ -217,14 +270,17 @@ static int at803x_config_init(struct phy_device *phydev)
if (ret < 0)
return ret;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
ret = phy_write(phydev, AT803X_DEBUG_ADDR,
AT803X_DEBUG_SYSTEM_MODE_CTRL);
if (ret)
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
ret = at803x_enable_rx_delay(phydev);
if (ret < 0)
return ret;
ret = phy_write(phydev, AT803X_DEBUG_DATA,
AT803X_DEBUG_RGMII_TX_CLK_DLY);
if (ret)
}
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
ret = at803x_enable_tx_delay(phydev);
if (ret < 0)
return ret;
}
......@@ -235,7 +291,7 @@ static int at803x_ack_interrupt(struct phy_device *phydev)
{
int err;
err = phy_read(phydev, AT803X_INSR);
err = phy_read(phydev, AT803X_INTR_STATUS);
return (err < 0) ? err : 0;
}
......@@ -245,13 +301,19 @@ static int at803x_config_intr(struct phy_device *phydev)
int err;
int value;
value = phy_read(phydev, AT803X_INER);
value = phy_read(phydev, AT803X_INTR_ENABLE);
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
value |= AT803X_INTR_ENABLE_AUTONEG_ERR;
value |= AT803X_INTR_ENABLE_SPEED_CHANGED;
value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
value |= AT803X_INTR_ENABLE_LINK_FAIL;
value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
err = phy_write(phydev, AT803X_INER,
value | AT803X_INER_INIT);
err = phy_write(phydev, AT803X_INTR_ENABLE, value);
}
else
err = phy_write(phydev, AT803X_INER, 0);
err = phy_write(phydev, AT803X_INTR_ENABLE, 0);
return err;
}
......@@ -322,7 +384,7 @@ static struct phy_driver at803x_driver[] = {
.get_wol = at803x_get_wol,
.suspend = at803x_suspend,
.resume = at803x_resume,
.features = PHY_GBIT_FEATURES,
.features = PHY_BASIC_FEATURES,
.flags = PHY_HAS_INTERRUPT,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
......
......@@ -1872,10 +1872,10 @@ static int team_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
struct team *team = netdev_priv(dev);
struct team_port *port;
rcu_read_lock();
list_for_each_entry_rcu(port, &team->port_list, list)
mutex_lock(&team->lock);
list_for_each_entry(port, &team->port_list, list)
vlan_vid_del(port->dev, proto, vid);
rcu_read_unlock();
mutex_unlock(&team->lock);
return 0;
}
......
......@@ -47,8 +47,7 @@ static const char BRCM_ ## fw_nvram_name ## _FIRMWARE_NAME[] = \
BRCMF_FW_DEFAULT_PATH fw; \
static const char BRCM_ ## fw_nvram_name ## _NVRAM_NAME[] = \
BRCMF_FW_DEFAULT_PATH nvram; \
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw); \
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH nvram)
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw);
#define BRCMF_FW_DEF(fw_name, fw) \
static const char BRCM_ ## fw_name ## _FIRMWARE_NAME[] = \
......
......@@ -45,7 +45,7 @@ struct mlx5_core_cq {
atomic_t refcount;
struct completion free;
unsigned vector;
int irqn;
unsigned int irqn;
void (*comp) (struct mlx5_core_cq *);
void (*event) (struct mlx5_core_cq *, enum mlx5_event);
struct mlx5_uar *uar;
......
......@@ -303,7 +303,7 @@ struct mlx5_eq {
u32 cons_index;
struct mlx5_buf buf;
int size;
u8 irqn;
unsigned int irqn;
u8 eqn;
int nent;
u64 mask;
......@@ -783,7 +783,8 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
int mlx5_destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
int mlx5_start_eqs(struct mlx5_core_dev *dev);
int mlx5_stop_eqs(struct mlx5_core_dev *dev);
int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, int *irqn);
int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
unsigned int *irqn);
int mlx5_core_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn);
int mlx5_core_detach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid, u32 qpn);
......
#ifndef _TCP_MEMCG_H
#define _TCP_MEMCG_H
struct cgroup_subsys;
struct mem_cgroup;
int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss);
void tcp_destroy_cgroup(struct mem_cgroup *memcg);
#endif /* _TCP_MEMCG_H */
......@@ -127,21 +127,17 @@ batadv_backbone_gw_free_ref(struct batadv_bla_backbone_gw *backbone_gw)
}
/* finally deinitialize the claim */
static void batadv_claim_free_rcu(struct rcu_head *rcu)
static void batadv_claim_release(struct batadv_bla_claim *claim)
{
struct batadv_bla_claim *claim;
claim = container_of(rcu, struct batadv_bla_claim, rcu);
batadv_backbone_gw_free_ref(claim->backbone_gw);
kfree(claim);
kfree_rcu(claim, rcu);
}
/* free a claim, call claim_free_rcu if its the last reference */
static void batadv_claim_free_ref(struct batadv_bla_claim *claim)
{
if (atomic_dec_and_test(&claim->refcount))
call_rcu(&claim->rcu, batadv_claim_free_rcu);
batadv_claim_release(claim);
}
/**
......
......@@ -75,18 +75,6 @@ batadv_hardif_free_ref(struct batadv_hard_iface *hard_iface)
call_rcu(&hard_iface->rcu, batadv_hardif_free_rcu);
}
/**
* batadv_hardif_free_ref_now - decrement the hard interface refcounter and
* possibly free it (without rcu callback)
* @hard_iface: the hard interface to free
*/
static inline void
batadv_hardif_free_ref_now(struct batadv_hard_iface *hard_iface)
{
if (atomic_dec_and_test(&hard_iface->refcount))
batadv_hardif_free_rcu(&hard_iface->rcu);
}
static inline struct batadv_hard_iface *
batadv_primary_if_get_selected(struct batadv_priv *bat_priv)
{
......
......@@ -203,28 +203,25 @@ void batadv_nc_init_orig(struct batadv_orig_node *orig_node)
}
/**
* batadv_nc_node_free_rcu - rcu callback to free an nc node and remove
* its refcount on the orig_node
* @rcu: rcu pointer of the nc node
* batadv_nc_node_release - release nc_node from lists and queue for free after
* rcu grace period
* @nc_node: the nc node to free
*/
static void batadv_nc_node_free_rcu(struct rcu_head *rcu)
static void batadv_nc_node_release(struct batadv_nc_node *nc_node)
{
struct batadv_nc_node *nc_node;
nc_node = container_of(rcu, struct batadv_nc_node, rcu);
batadv_orig_node_free_ref(nc_node->orig_node);
kfree(nc_node);
kfree_rcu(nc_node, rcu);
}
/**
* batadv_nc_node_free_ref - decrements the nc node refcounter and possibly
* frees it
* batadv_nc_node_free_ref - decrement the nc node refcounter and possibly
* release it
* @nc_node: the nc node to free
*/
static void batadv_nc_node_free_ref(struct batadv_nc_node *nc_node)
{
if (atomic_dec_and_test(&nc_node->refcount))
call_rcu(&nc_node->rcu, batadv_nc_node_free_rcu);
batadv_nc_node_release(nc_node);
}
/**
......
This diff is collapsed.
......@@ -38,7 +38,6 @@ int batadv_originator_init(struct batadv_priv *bat_priv);
void batadv_originator_free(struct batadv_priv *bat_priv);
void batadv_purge_orig_ref(struct batadv_priv *bat_priv);
void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node);
void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node);
struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
const u8 *addr);
struct batadv_hardif_neigh_node *
......
......@@ -240,20 +240,6 @@ int batadv_tt_global_hash_count(struct batadv_priv *bat_priv,
return count;
}
static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
{
struct batadv_tt_orig_list_entry *orig_entry;
orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu);
/* We are in an rcu callback here, therefore we cannot use
* batadv_orig_node_free_ref() and its call_rcu():
* An rcu_barrier() wouldn't wait for that to finish
*/
batadv_orig_node_free_ref_now(orig_entry->orig_node);
kfree(orig_entry);
}
/**
* batadv_tt_local_size_mod - change the size by v of the local table identified
* by vid
......@@ -349,13 +335,25 @@ static void batadv_tt_global_size_dec(struct batadv_orig_node *orig_node,
batadv_tt_global_size_mod(orig_node, vid, -1);
}
/**
* batadv_tt_orig_list_entry_release - release tt orig entry from lists and
* queue for free after rcu grace period
* @orig_entry: tt orig entry to be free'd
*/
static void
batadv_tt_orig_list_entry_release(struct batadv_tt_orig_list_entry *orig_entry)
{
batadv_orig_node_free_ref(orig_entry->orig_node);
kfree_rcu(orig_entry, rcu);
}
static void
batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
{
if (!atomic_dec_and_test(&orig_entry->refcount))
return;
call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
batadv_tt_orig_list_entry_release(orig_entry);
}
/**
......
......@@ -1160,17 +1160,26 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
const struct sw_flow_actions *acts,
struct sw_flow_key *key)
{
int level = this_cpu_read(exec_actions_level);
int err;
static const int ovs_recursion_limit = 5;
int err, level;
level = __this_cpu_inc_return(exec_actions_level);
if (unlikely(level > ovs_recursion_limit)) {
net_crit_ratelimited("ovs: recursion limit reached on datapath %s, probable configuration error\n",
ovs_dp_name(dp));
kfree_skb(skb);
err = -ENETDOWN;
goto out;
}
this_cpu_inc(exec_actions_level);
err = do_execute_actions(dp, skb, key,
acts->actions, acts->actions_len);
if (!level)
if (level == 1)
process_deferred_actions(dp);
this_cpu_dec(exec_actions_level);
out:
__this_cpu_dec(exec_actions_level);
return err;
}
......
......@@ -333,7 +333,7 @@ struct sctp_association *sctp_endpoint_lookup_assoc(
if (!ep->base.bind_addr.port)
goto out;
t = sctp_epaddr_lookup_transport(ep, paddr);
if (!t || t->asoc->temp)
if (!t)
goto out;
*transport = t;
......
......@@ -874,6 +874,9 @@ void sctp_hash_transport(struct sctp_transport *t)
{
struct sctp_hash_cmp_arg arg;
if (t->asoc->temp)
return;
arg.ep = t->asoc->ep;
arg.paddr = &t->ipaddr;
arg.net = sock_net(t->asoc->base.sk);
......@@ -886,6 +889,9 @@ void sctp_hash_transport(struct sctp_transport *t)
void sctp_unhash_transport(struct sctp_transport *t)
{
if (t->asoc->temp)
return;
rhashtable_remove_fast(&sctp_transport_hashtable, &t->node,
sctp_hash_params);
}
......@@ -931,7 +937,7 @@ static struct sctp_association *__sctp_lookup_association(
struct sctp_transport *t;
t = sctp_addrs_lookup_transport(net, local, peer);
if (!t || t->dead || t->asoc->temp)
if (!t || t->dead)
return NULL;
sctp_association_hold(t->asoc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment