Merge branch 'linus'
This commit is contained in:
commit
ec6624452e
|
@ -271,7 +271,7 @@ poll cycle or the number of packets processed reaches netdev_budget.
|
|||
netdev_max_backlog
|
||||
------------------
|
||||
|
||||
Maximum number of packets, queued on the INPUT side, when the interface
|
||||
Maximum number of packets, queued on the INPUT side, when the interface
|
||||
receives packets faster than kernel can process them.
|
||||
|
||||
netdev_rss_key
|
||||
|
|
|
@ -3679,6 +3679,7 @@ F: Documentation/networking/bonding.rst
|
|||
F: drivers/net/bonding/
|
||||
F: include/net/bond*
|
||||
F: include/uapi/linux/if_bonding.h
|
||||
F: tools/testing/selftests/drivers/net/bonding/
|
||||
|
||||
BOSCH SENSORTEC BMA400 ACCELEROMETER IIO DRIVER
|
||||
M: Dan Robertson <dan@dlrobertson.com>
|
||||
|
|
|
@ -630,7 +630,7 @@ static int __init dmi_smbios3_present(const u8 *buf)
|
|||
{
|
||||
if (memcmp(buf, "_SM3_", 5) == 0 &&
|
||||
buf[6] < 32 && dmi_checksum(buf, buf[6])) {
|
||||
dmi_ver = get_unaligned_be32(buf + 6) & 0xFFFFFF;
|
||||
dmi_ver = get_unaligned_be24(buf + 7);
|
||||
dmi_num = 0; /* No longer specified */
|
||||
dmi_len = get_unaligned_le32(buf + 12);
|
||||
dmi_base = get_unaligned_le64(buf + 16);
|
||||
|
|
|
@ -84,7 +84,8 @@ enum ad_link_speed_type {
|
|||
static const u8 null_mac_addr[ETH_ALEN + 2] __long_aligned = {
|
||||
0, 0, 0, 0, 0, 0
|
||||
};
|
||||
static u16 ad_ticks_per_sec;
|
||||
|
||||
static const u16 ad_ticks_per_sec = 1000 / AD_TIMER_INTERVAL;
|
||||
static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000;
|
||||
|
||||
static const u8 lacpdu_mcast_addr[ETH_ALEN + 2] __long_aligned =
|
||||
|
@ -2001,36 +2002,24 @@ void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout)
|
|||
/**
|
||||
* bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures
|
||||
* @bond: bonding struct to work on
|
||||
* @tick_resolution: tick duration (millisecond resolution)
|
||||
*
|
||||
* Can be called only after the mac address of the bond is set.
|
||||
*/
|
||||
void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution)
|
||||
void bond_3ad_initialize(struct bonding *bond)
|
||||
{
|
||||
/* check that the bond is not initialized yet */
|
||||
if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr),
|
||||
bond->dev->dev_addr)) {
|
||||
BOND_AD_INFO(bond).aggregator_identifier = 0;
|
||||
BOND_AD_INFO(bond).system.sys_priority =
|
||||
bond->params.ad_actor_sys_prio;
|
||||
if (is_zero_ether_addr(bond->params.ad_actor_system))
|
||||
BOND_AD_INFO(bond).system.sys_mac_addr =
|
||||
*((struct mac_addr *)bond->dev->dev_addr);
|
||||
else
|
||||
BOND_AD_INFO(bond).system.sys_mac_addr =
|
||||
*((struct mac_addr *)bond->params.ad_actor_system);
|
||||
|
||||
BOND_AD_INFO(bond).aggregator_identifier = 0;
|
||||
|
||||
BOND_AD_INFO(bond).system.sys_priority =
|
||||
bond->params.ad_actor_sys_prio;
|
||||
if (is_zero_ether_addr(bond->params.ad_actor_system))
|
||||
BOND_AD_INFO(bond).system.sys_mac_addr =
|
||||
*((struct mac_addr *)bond->dev->dev_addr);
|
||||
else
|
||||
BOND_AD_INFO(bond).system.sys_mac_addr =
|
||||
*((struct mac_addr *)bond->params.ad_actor_system);
|
||||
|
||||
/* initialize how many times this module is called in one
|
||||
* second (should be about every 100ms)
|
||||
*/
|
||||
ad_ticks_per_sec = tick_resolution;
|
||||
|
||||
bond_3ad_initiate_agg_selection(bond,
|
||||
AD_AGGREGATOR_SELECTION_TIMER *
|
||||
ad_ticks_per_sec);
|
||||
}
|
||||
bond_3ad_initiate_agg_selection(bond,
|
||||
AD_AGGREGATOR_SELECTION_TIMER *
|
||||
ad_ticks_per_sec);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2081,7 +2081,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
|
|||
/* Initialize AD with the number of times that the AD timer is called in 1 second
|
||||
* can be called only after the mac address of the bond is set
|
||||
*/
|
||||
bond_3ad_initialize(bond, 1000/AD_TIMER_INTERVAL);
|
||||
bond_3ad_initialize(bond);
|
||||
} else {
|
||||
SLAVE_AD_INFO(new_slave)->id =
|
||||
SLAVE_AD_INFO(prev_slave)->id + 1;
|
||||
|
|
|
@ -803,9 +803,15 @@ static void ksz_phylink_get_caps(struct dsa_switch *ds, int port,
|
|||
if (dev->info->supports_rgmii[port])
|
||||
phy_interface_set_rgmii(config->supported_interfaces);
|
||||
|
||||
if (dev->info->internal_phy[port])
|
||||
if (dev->info->internal_phy[port]) {
|
||||
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
config->supported_interfaces);
|
||||
/* Compatibility for phylib's default interface type when the
|
||||
* phy-mode property is absent
|
||||
*/
|
||||
__set_bit(PHY_INTERFACE_MODE_GMII,
|
||||
config->supported_interfaces);
|
||||
}
|
||||
|
||||
if (dev->dev_ops->get_caps)
|
||||
dev->dev_ops->get_caps(dev, port, config);
|
||||
|
@ -962,6 +968,7 @@ static void ksz_update_port_member(struct ksz_device *dev, int port)
|
|||
static int ksz_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct ksz_device *dev = ds->priv;
|
||||
struct ksz_port *p;
|
||||
const u16 *regs;
|
||||
int ret;
|
||||
|
||||
|
@ -1001,6 +1008,14 @@ static int ksz_setup(struct dsa_switch *ds)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Start with learning disabled on standalone user ports, and enabled
|
||||
* on the CPU port. In lack of other finer mechanisms, learning on the
|
||||
* CPU port will avoid flooding bridge local addresses on the network
|
||||
* in some cases.
|
||||
*/
|
||||
p = &dev->ports[dev->cpu_port];
|
||||
p->learning = true;
|
||||
|
||||
/* start switch */
|
||||
regmap_update_bits(dev->regmap[0], regs[S_START_CTRL],
|
||||
SW_START, SW_START);
|
||||
|
@ -1277,6 +1292,8 @@ void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
|
|||
ksz_pread8(dev, port, regs[P_STP_CTRL], &data);
|
||||
data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE);
|
||||
|
||||
p = &dev->ports[port];
|
||||
|
||||
switch (state) {
|
||||
case BR_STATE_DISABLED:
|
||||
data |= PORT_LEARN_DISABLE;
|
||||
|
@ -1286,9 +1303,13 @@ void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
|
|||
break;
|
||||
case BR_STATE_LEARNING:
|
||||
data |= PORT_RX_ENABLE;
|
||||
if (!p->learning)
|
||||
data |= PORT_LEARN_DISABLE;
|
||||
break;
|
||||
case BR_STATE_FORWARDING:
|
||||
data |= (PORT_TX_ENABLE | PORT_RX_ENABLE);
|
||||
if (!p->learning)
|
||||
data |= PORT_LEARN_DISABLE;
|
||||
break;
|
||||
case BR_STATE_BLOCKING:
|
||||
data |= PORT_LEARN_DISABLE;
|
||||
|
@ -1300,12 +1321,38 @@ void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
|
|||
|
||||
ksz_pwrite8(dev, port, regs[P_STP_CTRL], data);
|
||||
|
||||
p = &dev->ports[port];
|
||||
p->stp_state = state;
|
||||
|
||||
ksz_update_port_member(dev, port);
|
||||
}
|
||||
|
||||
static int ksz_port_pre_bridge_flags(struct dsa_switch *ds, int port,
|
||||
struct switchdev_brport_flags flags,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (flags.mask & ~BR_LEARNING)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ksz_port_bridge_flags(struct dsa_switch *ds, int port,
|
||||
struct switchdev_brport_flags flags,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct ksz_device *dev = ds->priv;
|
||||
struct ksz_port *p = &dev->ports[port];
|
||||
|
||||
if (flags.mask & BR_LEARNING) {
|
||||
p->learning = !!(flags.val & BR_LEARNING);
|
||||
|
||||
/* Make the change take effect immediately */
|
||||
ksz_port_stp_state_set(ds, port, p->stp_state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds,
|
||||
int port,
|
||||
enum dsa_tag_protocol mp)
|
||||
|
@ -1719,6 +1766,8 @@ static const struct dsa_switch_ops ksz_switch_ops = {
|
|||
.port_bridge_join = ksz_port_bridge_join,
|
||||
.port_bridge_leave = ksz_port_bridge_leave,
|
||||
.port_stp_state_set = ksz_port_stp_state_set,
|
||||
.port_pre_bridge_flags = ksz_port_pre_bridge_flags,
|
||||
.port_bridge_flags = ksz_port_bridge_flags,
|
||||
.port_fast_age = ksz_port_fast_age,
|
||||
.port_vlan_filtering = ksz_port_vlan_filtering,
|
||||
.port_vlan_add = ksz_port_vlan_add,
|
||||
|
|
|
@ -65,6 +65,7 @@ struct ksz_chip_data {
|
|||
|
||||
struct ksz_port {
|
||||
bool remove_tag; /* Remove Tag flag set, for ksz8795 only */
|
||||
bool learning;
|
||||
int stp_state;
|
||||
struct phy_device phydev;
|
||||
|
||||
|
|
|
@ -11178,10 +11178,7 @@ static netdev_features_t bnxt_fix_features(struct net_device *dev,
|
|||
if ((features & NETIF_F_NTUPLE) && !bnxt_rfs_capable(bp))
|
||||
features &= ~NETIF_F_NTUPLE;
|
||||
|
||||
if (bp->flags & BNXT_FLAG_NO_AGG_RINGS)
|
||||
features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
|
||||
|
||||
if (!(bp->flags & BNXT_FLAG_TPA))
|
||||
if ((bp->flags & BNXT_FLAG_NO_AGG_RINGS) || bp->xdp_prog)
|
||||
features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
|
||||
|
||||
if (!(features & NETIF_F_GRO))
|
||||
|
|
|
@ -2130,6 +2130,7 @@ struct bnxt {
|
|||
#define BNXT_DUMP_CRASH 1
|
||||
|
||||
struct bpf_prog *xdp_prog;
|
||||
u8 xdp_has_frags;
|
||||
|
||||
struct bnxt_ptp_cfg *ptp_cfg;
|
||||
u8 ptp_all_rx_tstamp;
|
||||
|
|
|
@ -1306,6 +1306,7 @@ int bnxt_dl_register(struct bnxt *bp)
|
|||
if (rc)
|
||||
goto err_dl_port_unreg;
|
||||
|
||||
devlink_set_features(dl, DEVLINK_F_RELOAD);
|
||||
out:
|
||||
devlink_register(dl);
|
||||
return 0;
|
||||
|
|
|
@ -623,7 +623,7 @@ static int bnxt_hwrm_func_vf_resc_cfg(struct bnxt *bp, int num_vfs, bool reset)
|
|||
hw_resc->max_stat_ctxs -= le16_to_cpu(req->min_stat_ctx) * n;
|
||||
hw_resc->max_vnics -= le16_to_cpu(req->min_vnics) * n;
|
||||
if (bp->flags & BNXT_FLAG_CHIP_P5)
|
||||
hw_resc->max_irqs -= vf_msix * n;
|
||||
hw_resc->max_nqs -= vf_msix;
|
||||
|
||||
rc = pf->active_vfs;
|
||||
}
|
||||
|
|
|
@ -181,6 +181,7 @@ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
|||
struct xdp_buff *xdp)
|
||||
{
|
||||
struct bnxt_sw_rx_bd *rx_buf;
|
||||
u32 buflen = PAGE_SIZE;
|
||||
struct pci_dev *pdev;
|
||||
dma_addr_t mapping;
|
||||
u32 offset;
|
||||
|
@ -192,7 +193,10 @@ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
|||
mapping = rx_buf->mapping - bp->rx_dma_offset;
|
||||
dma_sync_single_for_cpu(&pdev->dev, mapping + offset, *len, bp->rx_dir);
|
||||
|
||||
xdp_init_buff(xdp, BNXT_PAGE_MODE_BUF_SIZE + offset, &rxr->xdp_rxq);
|
||||
if (bp->xdp_has_frags)
|
||||
buflen = BNXT_PAGE_MODE_BUF_SIZE + offset;
|
||||
|
||||
xdp_init_buff(xdp, buflen, &rxr->xdp_rxq);
|
||||
xdp_prepare_buff(xdp, *data_ptr - offset, offset, *len, false);
|
||||
}
|
||||
|
||||
|
@ -397,8 +401,10 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
|
|||
netdev_warn(dev, "ethtool rx/tx channels must be combined to support XDP.\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
if (prog)
|
||||
if (prog) {
|
||||
tx_xdp = bp->rx_nr_rings;
|
||||
bp->xdp_has_frags = prog->aux->xdp_has_frags;
|
||||
}
|
||||
|
||||
tc = netdev_get_num_tc(dev);
|
||||
if (!tc)
|
||||
|
|
|
@ -2886,6 +2886,7 @@ static void dpaa_adjust_link(struct net_device *net_dev)
|
|||
|
||||
/* The Aquantia PHYs are capable of performing rate adaptation */
|
||||
#define PHY_VEND_AQUANTIA 0x03a1b400
|
||||
#define PHY_VEND_AQUANTIA2 0x31c31c00
|
||||
|
||||
static int dpaa_phy_init(struct net_device *net_dev)
|
||||
{
|
||||
|
@ -2893,6 +2894,7 @@ static int dpaa_phy_init(struct net_device *net_dev)
|
|||
struct mac_device *mac_dev;
|
||||
struct phy_device *phy_dev;
|
||||
struct dpaa_priv *priv;
|
||||
u32 phy_vendor;
|
||||
|
||||
priv = netdev_priv(net_dev);
|
||||
mac_dev = priv->mac_dev;
|
||||
|
@ -2905,9 +2907,11 @@ static int dpaa_phy_init(struct net_device *net_dev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
phy_vendor = phy_dev->drv->phy_id & GENMASK(31, 10);
|
||||
/* Unless the PHY is capable of rate adaptation */
|
||||
if (mac_dev->phy_if != PHY_INTERFACE_MODE_XGMII ||
|
||||
((phy_dev->drv->phy_id & GENMASK(31, 10)) != PHY_VEND_AQUANTIA)) {
|
||||
(phy_vendor != PHY_VEND_AQUANTIA &&
|
||||
phy_vendor != PHY_VEND_AQUANTIA2)) {
|
||||
/* remove any features not supported by the controller */
|
||||
ethtool_convert_legacy_u32_to_link_mode(mask,
|
||||
mac_dev->if_support);
|
||||
|
|
|
@ -634,6 +634,13 @@ struct fec_enet_private {
|
|||
int pps_enable;
|
||||
unsigned int next_counter;
|
||||
|
||||
struct {
|
||||
struct timespec64 ts_phc;
|
||||
u64 ns_sys;
|
||||
u32 at_corr;
|
||||
u8 at_inc_corr;
|
||||
} ptp_saved_state;
|
||||
|
||||
u64 ethtool_stats[];
|
||||
};
|
||||
|
||||
|
@ -644,5 +651,8 @@ void fec_ptp_disable_hwts(struct net_device *ndev);
|
|||
int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr);
|
||||
int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr);
|
||||
|
||||
void fec_ptp_save_state(struct fec_enet_private *fep);
|
||||
int fec_ptp_restore_state(struct fec_enet_private *fep);
|
||||
|
||||
/****************************************************************************/
|
||||
#endif /* FEC_H */
|
||||
|
|
|
@ -285,8 +285,11 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
|
|||
#define FEC_MMFR_TA (2 << 16)
|
||||
#define FEC_MMFR_DATA(v) (v & 0xffff)
|
||||
/* FEC ECR bits definition */
|
||||
#define FEC_ECR_MAGICEN (1 << 2)
|
||||
#define FEC_ECR_SLEEP (1 << 3)
|
||||
#define FEC_ECR_RESET BIT(0)
|
||||
#define FEC_ECR_ETHEREN BIT(1)
|
||||
#define FEC_ECR_MAGICEN BIT(2)
|
||||
#define FEC_ECR_SLEEP BIT(3)
|
||||
#define FEC_ECR_EN1588 BIT(4)
|
||||
|
||||
#define FEC_MII_TIMEOUT 30000 /* us */
|
||||
|
||||
|
@ -982,6 +985,9 @@ fec_restart(struct net_device *ndev)
|
|||
u32 temp_mac[2];
|
||||
u32 rcntl = OPT_FRAME_SIZE | 0x04;
|
||||
u32 ecntl = 0x2; /* ETHEREN */
|
||||
struct ptp_clock_request ptp_rq = { .type = PTP_CLK_REQ_PPS };
|
||||
|
||||
fec_ptp_save_state(fep);
|
||||
|
||||
/* Whack a reset. We should wait for this.
|
||||
* For i.MX6SX SOC, enet use AXI bus, we use disable MAC
|
||||
|
@ -1135,7 +1141,7 @@ fec_restart(struct net_device *ndev)
|
|||
}
|
||||
|
||||
if (fep->bufdesc_ex)
|
||||
ecntl |= (1 << 4);
|
||||
ecntl |= FEC_ECR_EN1588;
|
||||
|
||||
if (fep->quirks & FEC_QUIRK_DELAYED_CLKS_SUPPORT &&
|
||||
fep->rgmii_txc_dly)
|
||||
|
@ -1156,6 +1162,14 @@ fec_restart(struct net_device *ndev)
|
|||
if (fep->bufdesc_ex)
|
||||
fec_ptp_start_cyclecounter(ndev);
|
||||
|
||||
/* Restart PPS if needed */
|
||||
if (fep->pps_enable) {
|
||||
/* Clear flag so fec_ptp_enable_pps() doesn't return immediately */
|
||||
fep->pps_enable = 0;
|
||||
fec_ptp_restore_state(fep);
|
||||
fep->ptp_caps.enable(&fep->ptp_caps, &ptp_rq, 1);
|
||||
}
|
||||
|
||||
/* Enable interrupts we wish to service */
|
||||
if (fep->link)
|
||||
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
|
||||
|
@ -1206,6 +1220,8 @@ fec_stop(struct net_device *ndev)
|
|||
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||
u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8);
|
||||
u32 val;
|
||||
struct ptp_clock_request ptp_rq = { .type = PTP_CLK_REQ_PPS };
|
||||
u32 ecntl = 0;
|
||||
|
||||
/* We cannot expect a graceful transmit stop without link !!! */
|
||||
if (fep->link) {
|
||||
|
@ -1215,6 +1231,8 @@ fec_stop(struct net_device *ndev)
|
|||
netdev_err(ndev, "Graceful transmit stop did not complete!\n");
|
||||
}
|
||||
|
||||
fec_ptp_save_state(fep);
|
||||
|
||||
/* Whack a reset. We should wait for this.
|
||||
* For i.MX6SX SOC, enet use AXI bus, we use disable MAC
|
||||
* instead of reset MAC itself.
|
||||
|
@ -1234,12 +1252,28 @@ fec_stop(struct net_device *ndev)
|
|||
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
|
||||
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
|
||||
|
||||
if (fep->bufdesc_ex)
|
||||
ecntl |= FEC_ECR_EN1588;
|
||||
|
||||
/* We have to keep ENET enabled to have MII interrupt stay working */
|
||||
if (fep->quirks & FEC_QUIRK_ENET_MAC &&
|
||||
!(fep->wol_flag & FEC_WOL_FLAG_SLEEP_ON)) {
|
||||
writel(2, fep->hwp + FEC_ECNTRL);
|
||||
ecntl |= FEC_ECR_ETHEREN;
|
||||
writel(rmii_mode, fep->hwp + FEC_R_CNTRL);
|
||||
}
|
||||
|
||||
writel(ecntl, fep->hwp + FEC_ECNTRL);
|
||||
|
||||
if (fep->bufdesc_ex)
|
||||
fec_ptp_start_cyclecounter(ndev);
|
||||
|
||||
/* Restart PPS if needed */
|
||||
if (fep->pps_enable) {
|
||||
/* Clear flag so fec_ptp_enable_pps() doesn't return immediately */
|
||||
fep->pps_enable = 0;
|
||||
fec_ptp_restore_state(fep);
|
||||
fep->ptp_caps.enable(&fep->ptp_caps, &ptp_rq, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -633,7 +633,36 @@ void fec_ptp_stop(struct platform_device *pdev)
|
|||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct fec_enet_private *fep = netdev_priv(ndev);
|
||||
|
||||
if (fep->pps_enable)
|
||||
fec_ptp_enable_pps(fep, 0);
|
||||
|
||||
cancel_delayed_work_sync(&fep->time_keep);
|
||||
if (fep->ptp_clock)
|
||||
ptp_clock_unregister(fep->ptp_clock);
|
||||
}
|
||||
|
||||
void fec_ptp_save_state(struct fec_enet_private *fep)
|
||||
{
|
||||
u32 atime_inc_corr;
|
||||
|
||||
fec_ptp_gettime(&fep->ptp_caps, &fep->ptp_saved_state.ts_phc);
|
||||
fep->ptp_saved_state.ns_sys = ktime_get_ns();
|
||||
|
||||
fep->ptp_saved_state.at_corr = readl(fep->hwp + FEC_ATIME_CORR);
|
||||
atime_inc_corr = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_CORR_MASK;
|
||||
fep->ptp_saved_state.at_inc_corr = (u8)(atime_inc_corr >> FEC_T_INC_CORR_OFFSET);
|
||||
}
|
||||
|
||||
int fec_ptp_restore_state(struct fec_enet_private *fep)
|
||||
{
|
||||
u32 atime_inc = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_MASK;
|
||||
u64 ns_sys;
|
||||
|
||||
writel(fep->ptp_saved_state.at_corr, fep->hwp + FEC_ATIME_CORR);
|
||||
atime_inc |= ((u32)fep->ptp_saved_state.at_inc_corr) << FEC_T_INC_CORR_OFFSET;
|
||||
writel(atime_inc, fep->hwp + FEC_ATIME_INC);
|
||||
|
||||
ns_sys = ktime_get_ns() - fep->ptp_saved_state.ns_sys;
|
||||
timespec64_add_ns(&fep->ptp_saved_state.ts_phc, ns_sys);
|
||||
return fec_ptp_settime(&fep->ptp_caps, &fep->ptp_saved_state.ts_phc);
|
||||
}
|
||||
|
|
|
@ -4485,7 +4485,7 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi,
|
|||
(struct in6_addr *)&ipv6_full_mask))
|
||||
new_mask |= I40E_L3_V6_DST_MASK;
|
||||
else if (ipv6_addr_any((struct in6_addr *)
|
||||
&usr_ip6_spec->ip6src))
|
||||
&usr_ip6_spec->ip6dst))
|
||||
new_mask &= ~I40E_L3_V6_DST_MASK;
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
|
|
|
@ -684,8 +684,8 @@ static inline void ice_set_ring_xdp(struct ice_tx_ring *ring)
|
|||
* ice_xsk_pool - get XSK buffer pool bound to a ring
|
||||
* @ring: Rx ring to use
|
||||
*
|
||||
* Returns a pointer to xdp_umem structure if there is a buffer pool present,
|
||||
* NULL otherwise.
|
||||
* Returns a pointer to xsk_buff_pool structure if there is a buffer pool
|
||||
* present, NULL otherwise.
|
||||
*/
|
||||
static inline struct xsk_buff_pool *ice_xsk_pool(struct ice_rx_ring *ring)
|
||||
{
|
||||
|
@ -699,23 +699,33 @@ static inline struct xsk_buff_pool *ice_xsk_pool(struct ice_rx_ring *ring)
|
|||
}
|
||||
|
||||
/**
|
||||
* ice_tx_xsk_pool - get XSK buffer pool bound to a ring
|
||||
* @ring: Tx ring to use
|
||||
* ice_tx_xsk_pool - assign XSK buff pool to XDP ring
|
||||
* @vsi: pointer to VSI
|
||||
* @qid: index of a queue to look at XSK buff pool presence
|
||||
*
|
||||
* Returns a pointer to xdp_umem structure if there is a buffer pool present,
|
||||
* NULL otherwise. Tx equivalent of ice_xsk_pool.
|
||||
* Sets XSK buff pool pointer on XDP ring.
|
||||
*
|
||||
* XDP ring is picked from Rx ring, whereas Rx ring is picked based on provided
|
||||
* queue id. Reason for doing so is that queue vectors might have assigned more
|
||||
* than one XDP ring, e.g. when user reduced the queue count on netdev; Rx ring
|
||||
* carries a pointer to one of these XDP rings for its own purposes, such as
|
||||
* handling XDP_TX action, therefore we can piggyback here on the
|
||||
* rx_ring->xdp_ring assignment that was done during XDP rings initialization.
|
||||
*/
|
||||
static inline struct xsk_buff_pool *ice_tx_xsk_pool(struct ice_tx_ring *ring)
|
||||
static inline void ice_tx_xsk_pool(struct ice_vsi *vsi, u16 qid)
|
||||
{
|
||||
struct ice_vsi *vsi = ring->vsi;
|
||||
u16 qid;
|
||||
struct ice_tx_ring *ring;
|
||||
|
||||
qid = ring->q_index - vsi->alloc_txq;
|
||||
ring = vsi->rx_rings[qid]->xdp_ring;
|
||||
if (!ring)
|
||||
return;
|
||||
|
||||
if (!ice_is_xdp_ena_vsi(vsi) || !test_bit(qid, vsi->af_xdp_zc_qps))
|
||||
return NULL;
|
||||
if (!ice_is_xdp_ena_vsi(vsi) || !test_bit(qid, vsi->af_xdp_zc_qps)) {
|
||||
ring->xsk_pool = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
return xsk_get_pool_from_qid(vsi->netdev, qid);
|
||||
ring->xsk_pool = xsk_get_pool_from_qid(vsi->netdev, qid);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1986,8 +1986,8 @@ int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ice_for_each_xdp_txq(vsi, i)
|
||||
vsi->xdp_rings[i]->xsk_pool = ice_tx_xsk_pool(vsi->xdp_rings[i]);
|
||||
ice_for_each_rxq(vsi, i)
|
||||
ice_tx_xsk_pool(vsi, i);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -2581,7 +2581,6 @@ static int ice_xdp_alloc_setup_rings(struct ice_vsi *vsi)
|
|||
if (ice_setup_tx_ring(xdp_ring))
|
||||
goto free_xdp_rings;
|
||||
ice_set_ring_xdp(xdp_ring);
|
||||
xdp_ring->xsk_pool = ice_tx_xsk_pool(xdp_ring);
|
||||
spin_lock_init(&xdp_ring->tx_lock);
|
||||
for (j = 0; j < xdp_ring->count; j++) {
|
||||
tx_desc = ICE_TX_DESC(xdp_ring, j);
|
||||
|
@ -2589,13 +2588,6 @@ static int ice_xdp_alloc_setup_rings(struct ice_vsi *vsi)
|
|||
}
|
||||
}
|
||||
|
||||
ice_for_each_rxq(vsi, i) {
|
||||
if (static_key_enabled(&ice_xdp_locking_key))
|
||||
vsi->rx_rings[i]->xdp_ring = vsi->xdp_rings[i % vsi->num_xdp_txq];
|
||||
else
|
||||
vsi->rx_rings[i]->xdp_ring = vsi->xdp_rings[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
free_xdp_rings:
|
||||
|
@ -2685,6 +2677,23 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
|
|||
xdp_rings_rem -= xdp_rings_per_v;
|
||||
}
|
||||
|
||||
ice_for_each_rxq(vsi, i) {
|
||||
if (static_key_enabled(&ice_xdp_locking_key)) {
|
||||
vsi->rx_rings[i]->xdp_ring = vsi->xdp_rings[i % vsi->num_xdp_txq];
|
||||
} else {
|
||||
struct ice_q_vector *q_vector = vsi->rx_rings[i]->q_vector;
|
||||
struct ice_tx_ring *ring;
|
||||
|
||||
ice_for_each_tx_ring(ring, q_vector->tx) {
|
||||
if (ice_ring_is_xdp(ring)) {
|
||||
vsi->rx_rings[i]->xdp_ring = ring;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ice_tx_xsk_pool(vsi, i);
|
||||
}
|
||||
|
||||
/* omit the scheduler update if in reset path; XDP queues will be
|
||||
* taken into account at the end of ice_vsi_rebuild, where
|
||||
* ice_cfg_vsi_lan is being called
|
||||
|
|
|
@ -243,7 +243,7 @@ static int ice_qp_ena(struct ice_vsi *vsi, u16 q_idx)
|
|||
if (err)
|
||||
goto free_buf;
|
||||
ice_set_ring_xdp(xdp_ring);
|
||||
xdp_ring->xsk_pool = ice_tx_xsk_pool(xdp_ring);
|
||||
ice_tx_xsk_pool(vsi, q_idx);
|
||||
}
|
||||
|
||||
err = ice_vsi_cfg_rxq(rx_ring);
|
||||
|
@ -329,6 +329,12 @@ int ice_xsk_pool_setup(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid)
|
|||
bool if_running, pool_present = !!pool;
|
||||
int ret = 0, pool_failure = 0;
|
||||
|
||||
if (qid >= vsi->num_rxq || qid >= vsi->num_txq) {
|
||||
netdev_err(vsi->netdev, "Please use queue id in scope of combined queues count\n");
|
||||
pool_failure = -EINVAL;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (!is_power_of_2(vsi->rx_rings[qid]->count) ||
|
||||
!is_power_of_2(vsi->tx_rings[qid]->count)) {
|
||||
netdev_err(vsi->netdev, "Please align ring sizes to power of 2\n");
|
||||
|
@ -353,7 +359,7 @@ xsk_pool_if_up:
|
|||
if (if_running) {
|
||||
ret = ice_qp_ena(vsi, qid);
|
||||
if (!ret && pool_present)
|
||||
napi_schedule(&vsi->xdp_rings[qid]->q_vector->napi);
|
||||
napi_schedule(&vsi->rx_rings[qid]->xdp_ring->q_vector->napi);
|
||||
else if (ret)
|
||||
netdev_err(vsi->netdev, "ice_qp_ena error = %d\n", ret);
|
||||
}
|
||||
|
@ -944,13 +950,13 @@ ice_xsk_wakeup(struct net_device *netdev, u32 queue_id,
|
|||
if (!ice_is_xdp_ena_vsi(vsi))
|
||||
return -EINVAL;
|
||||
|
||||
if (queue_id >= vsi->num_txq)
|
||||
if (queue_id >= vsi->num_txq || queue_id >= vsi->num_rxq)
|
||||
return -EINVAL;
|
||||
|
||||
if (!vsi->xdp_rings[queue_id]->xsk_pool)
|
||||
return -EINVAL;
|
||||
ring = vsi->rx_rings[queue_id]->xdp_ring;
|
||||
|
||||
ring = vsi->xdp_rings[queue_id];
|
||||
if (!ring->xsk_pool)
|
||||
return -EINVAL;
|
||||
|
||||
/* The idea here is that if NAPI is running, mark a miss, so
|
||||
* it will run again. If not, trigger an interrupt and
|
||||
|
|
|
@ -1214,7 +1214,6 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
|
|||
struct cyclecounter cc;
|
||||
unsigned long flags;
|
||||
u32 incval = 0;
|
||||
u32 tsauxc = 0;
|
||||
u32 fuse0 = 0;
|
||||
|
||||
/* For some of the boards below this mask is technically incorrect.
|
||||
|
@ -1249,18 +1248,6 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
|
|||
case ixgbe_mac_x550em_a:
|
||||
case ixgbe_mac_X550:
|
||||
cc.read = ixgbe_ptp_read_X550;
|
||||
|
||||
/* enable SYSTIME counter */
|
||||
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0);
|
||||
tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_TSAUXC,
|
||||
tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC);
|
||||
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
break;
|
||||
case ixgbe_mac_X540:
|
||||
cc.read = ixgbe_ptp_read_82599;
|
||||
|
@ -1292,6 +1279,50 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
|
|||
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_ptp_init_systime - Initialize SYSTIME registers
|
||||
* @adapter: the ixgbe private board structure
|
||||
*
|
||||
* Initialize and start the SYSTIME registers.
|
||||
*/
|
||||
static void ixgbe_ptp_init_systime(struct ixgbe_adapter *adapter)
|
||||
{
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
u32 tsauxc;
|
||||
|
||||
switch (hw->mac.type) {
|
||||
case ixgbe_mac_X550EM_x:
|
||||
case ixgbe_mac_x550em_a:
|
||||
case ixgbe_mac_X550:
|
||||
tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC);
|
||||
|
||||
/* Reset SYSTIME registers to 0 */
|
||||
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0);
|
||||
|
||||
/* Reset interrupt settings */
|
||||
IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC);
|
||||
|
||||
/* Activate the SYSTIME counter */
|
||||
IXGBE_WRITE_REG(hw, IXGBE_TSAUXC,
|
||||
tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME);
|
||||
break;
|
||||
case ixgbe_mac_X540:
|
||||
case ixgbe_mac_82599EB:
|
||||
/* Reset SYSTIME registers to 0 */
|
||||
IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0);
|
||||
break;
|
||||
default:
|
||||
/* Other devices aren't supported */
|
||||
return;
|
||||
};
|
||||
|
||||
IXGBE_WRITE_FLUSH(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_ptp_reset
|
||||
* @adapter: the ixgbe private board structure
|
||||
|
@ -1318,6 +1349,8 @@ void ixgbe_ptp_reset(struct ixgbe_adapter *adapter)
|
|||
|
||||
ixgbe_ptp_start_cyclecounter(adapter);
|
||||
|
||||
ixgbe_ptp_init_systime(adapter);
|
||||
|
||||
spin_lock_irqsave(&adapter->tmreg_lock, flags);
|
||||
timecounter_init(&adapter->hw_tc, &adapter->hw_cc,
|
||||
ktime_to_ns(ktime_get_real()));
|
||||
|
|
|
@ -193,6 +193,7 @@ static int xrx200_alloc_buf(struct xrx200_chan *ch, void *(*alloc)(unsigned int
|
|||
|
||||
ch->rx_buff[ch->dma.desc] = alloc(priv->rx_skb_size);
|
||||
if (!ch->rx_buff[ch->dma.desc]) {
|
||||
ch->rx_buff[ch->dma.desc] = buf;
|
||||
ret = -ENOMEM;
|
||||
goto skip;
|
||||
}
|
||||
|
@ -239,6 +240,12 @@ static int xrx200_hw_receive(struct xrx200_chan *ch)
|
|||
}
|
||||
|
||||
skb = build_skb(buf, priv->rx_skb_size);
|
||||
if (!skb) {
|
||||
skb_free_frag(buf);
|
||||
net_dev->stats.rx_dropped++;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
skb_reserve(skb, NET_SKB_PAD);
|
||||
skb_put(skb, len);
|
||||
|
||||
|
@ -288,7 +295,7 @@ static int xrx200_poll_rx(struct napi_struct *napi, int budget)
|
|||
if (ret == XRX200_DMA_PACKET_IN_PROGRESS)
|
||||
continue;
|
||||
if (ret != XRX200_DMA_PACKET_COMPLETE)
|
||||
return ret;
|
||||
break;
|
||||
rx++;
|
||||
} else {
|
||||
break;
|
||||
|
|
|
@ -1891,10 +1891,19 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
|
|||
skb->dev = netdev;
|
||||
bytes += skb->len;
|
||||
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
|
||||
if (hash != MTK_RXD5_FOE_ENTRY)
|
||||
skb_set_hash(skb, jhash_1word(hash, 0),
|
||||
PKT_HASH_TYPE_L4);
|
||||
rxdcsum = &trxd.rxd3;
|
||||
else
|
||||
} else {
|
||||
hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY;
|
||||
if (hash != MTK_RXD4_FOE_ENTRY)
|
||||
skb_set_hash(skb, jhash_1word(hash, 0),
|
||||
PKT_HASH_TYPE_L4);
|
||||
rxdcsum = &trxd.rxd4;
|
||||
}
|
||||
|
||||
if (*rxdcsum & eth->soc->txrx.rx_dma_l4_valid)
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
@ -1902,16 +1911,9 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
|
|||
skb_checksum_none_assert(skb);
|
||||
skb->protocol = eth_type_trans(skb, netdev);
|
||||
|
||||
hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY;
|
||||
if (hash != MTK_RXD4_FOE_ENTRY) {
|
||||
hash = jhash_1word(hash, 0);
|
||||
skb_set_hash(skb, hash, PKT_HASH_TYPE_L4);
|
||||
}
|
||||
|
||||
reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4);
|
||||
if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
|
||||
mtk_ppe_check_skb(eth->ppe, skb,
|
||||
trxd.rxd4 & MTK_RXD4_FOE_ENTRY);
|
||||
mtk_ppe_check_skb(eth->ppe, skb, hash);
|
||||
|
||||
if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
|
|
|
@ -314,6 +314,11 @@
|
|||
#define RX_DMA_L4_VALID_PDMA BIT(30) /* when PDMA is used */
|
||||
#define RX_DMA_SPECIAL_TAG BIT(22)
|
||||
|
||||
/* PDMA descriptor rxd5 */
|
||||
#define MTK_RXD5_FOE_ENTRY GENMASK(14, 0)
|
||||
#define MTK_RXD5_PPE_CPU_REASON GENMASK(22, 18)
|
||||
#define MTK_RXD5_SRC_PORT GENMASK(29, 26)
|
||||
|
||||
#define RX_DMA_GET_SPORT(x) (((x) >> 19) & 0xf)
|
||||
#define RX_DMA_GET_SPORT_V2(x) (((x) >> 26) & 0x7)
|
||||
|
||||
|
|
|
@ -79,6 +79,10 @@ tc_act_police_offload(struct mlx5e_priv *priv,
|
|||
struct mlx5e_flow_meter_handle *meter;
|
||||
int err = 0;
|
||||
|
||||
err = mlx5e_policer_validate(&fl_act->action, act, fl_act->extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = fill_meter_params_from_act(act, ¶ms);
|
||||
if (err)
|
||||
return err;
|
||||
|
|
|
@ -246,7 +246,7 @@ static void mlx5e_tls_priv_tx_cleanup(struct mlx5e_ktls_offload_context_tx *priv
|
|||
static void mlx5e_tls_priv_tx_list_cleanup(struct mlx5_core_dev *mdev,
|
||||
struct list_head *list, int size)
|
||||
{
|
||||
struct mlx5e_ktls_offload_context_tx *obj;
|
||||
struct mlx5e_ktls_offload_context_tx *obj, *n;
|
||||
struct mlx5e_async_ctx *bulk_async;
|
||||
int i;
|
||||
|
||||
|
@ -255,7 +255,7 @@ static void mlx5e_tls_priv_tx_list_cleanup(struct mlx5_core_dev *mdev,
|
|||
return;
|
||||
|
||||
i = 0;
|
||||
list_for_each_entry(obj, list, list_node) {
|
||||
list_for_each_entry_safe(obj, n, list, list_node) {
|
||||
mlx5e_tls_priv_tx_cleanup(obj, &bulk_async[i]);
|
||||
i++;
|
||||
}
|
||||
|
|
|
@ -1395,10 +1395,11 @@ struct mlx5e_flow_steering *mlx5e_fs_init(const struct mlx5e_profile *profile,
|
|||
}
|
||||
|
||||
return fs;
|
||||
err_free_fs:
|
||||
kvfree(fs);
|
||||
|
||||
err_free_vlan:
|
||||
mlx5e_fs_vlan_free(fs);
|
||||
err_free_fs:
|
||||
kvfree(fs);
|
||||
err:
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -3682,7 +3682,9 @@ static int set_feature_hw_tc(struct net_device *netdev, bool enable)
|
|||
int err = 0;
|
||||
|
||||
#if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
|
||||
if (!enable && mlx5e_tc_num_filters(priv, MLX5_TC_FLAG(NIC_OFFLOAD))) {
|
||||
int tc_flag = mlx5e_is_uplink_rep(priv) ? MLX5_TC_FLAG(ESW_OFFLOAD) :
|
||||
MLX5_TC_FLAG(NIC_OFFLOAD);
|
||||
if (!enable && mlx5e_tc_num_filters(priv, tc_flag)) {
|
||||
netdev_err(netdev,
|
||||
"Active offloaded tc filters, can't turn hw_tc_offload off\n");
|
||||
return -EINVAL;
|
||||
|
@ -4769,14 +4771,6 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16
|
|||
/* RQ */
|
||||
mlx5e_build_rq_params(mdev, params);
|
||||
|
||||
/* HW LRO */
|
||||
if (MLX5_CAP_ETH(mdev, lro_cap) &&
|
||||
params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
|
||||
/* No XSK params: checking the availability of striding RQ in general. */
|
||||
if (!mlx5e_rx_mpwqe_is_linear_skb(mdev, params, NULL))
|
||||
params->packet_merge.type = slow_pci_heuristic(mdev) ?
|
||||
MLX5E_PACKET_MERGE_NONE : MLX5E_PACKET_MERGE_LRO;
|
||||
}
|
||||
params->packet_merge.timeout = mlx5e_choose_lro_timeout(mdev, MLX5E_DEFAULT_LRO_TIMEOUT);
|
||||
|
||||
/* CQ moderation params */
|
||||
|
|
|
@ -662,6 +662,8 @@ static void mlx5e_build_rep_params(struct net_device *netdev)
|
|||
|
||||
params->mqprio.num_tc = 1;
|
||||
params->tunneled_offload_en = false;
|
||||
if (rep->vport != MLX5_VPORT_UPLINK)
|
||||
params->vlan_strip_disable = true;
|
||||
|
||||
mlx5_query_min_inline(mdev, ¶ms->tx_min_inline_mode);
|
||||
}
|
||||
|
|
|
@ -427,7 +427,8 @@ esw_setup_vport_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_act *f
|
|||
dest[dest_idx].vport.vhca_id =
|
||||
MLX5_CAP_GEN(esw_attr->dests[attr_idx].mdev, vhca_id);
|
||||
dest[dest_idx].vport.flags |= MLX5_FLOW_DEST_VPORT_VHCA_ID;
|
||||
if (mlx5_lag_mpesw_is_activated(esw->dev))
|
||||
if (dest[dest_idx].vport.num == MLX5_VPORT_UPLINK &&
|
||||
mlx5_lag_mpesw_is_activated(esw->dev))
|
||||
dest[dest_idx].type = MLX5_FLOW_DESTINATION_TYPE_UPLINK;
|
||||
}
|
||||
if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP) {
|
||||
|
@ -3115,8 +3116,10 @@ esw_vfs_changed_event_handler(struct mlx5_eswitch *esw, const u32 *out)
|
|||
|
||||
err = mlx5_eswitch_load_vf_vports(esw, new_num_vfs,
|
||||
MLX5_VPORT_UC_ADDR_CHANGE);
|
||||
if (err)
|
||||
if (err) {
|
||||
devl_unlock(devlink);
|
||||
return;
|
||||
}
|
||||
}
|
||||
esw->esw_funcs.num_vfs = new_num_vfs;
|
||||
devl_unlock(devlink);
|
||||
|
|
|
@ -1067,30 +1067,32 @@ static void mlx5_ldev_add_netdev(struct mlx5_lag *ldev,
|
|||
struct net_device *netdev)
|
||||
{
|
||||
unsigned int fn = mlx5_get_dev_index(dev);
|
||||
unsigned long flags;
|
||||
|
||||
if (fn >= ldev->ports)
|
||||
return;
|
||||
|
||||
spin_lock(&lag_lock);
|
||||
spin_lock_irqsave(&lag_lock, flags);
|
||||
ldev->pf[fn].netdev = netdev;
|
||||
ldev->tracker.netdev_state[fn].link_up = 0;
|
||||
ldev->tracker.netdev_state[fn].tx_enabled = 0;
|
||||
spin_unlock(&lag_lock);
|
||||
spin_unlock_irqrestore(&lag_lock, flags);
|
||||
}
|
||||
|
||||
static void mlx5_ldev_remove_netdev(struct mlx5_lag *ldev,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
spin_lock(&lag_lock);
|
||||
spin_lock_irqsave(&lag_lock, flags);
|
||||
for (i = 0; i < ldev->ports; i++) {
|
||||
if (ldev->pf[i].netdev == netdev) {
|
||||
ldev->pf[i].netdev = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&lag_lock);
|
||||
spin_unlock_irqrestore(&lag_lock, flags);
|
||||
}
|
||||
|
||||
static void mlx5_ldev_add_mdev(struct mlx5_lag *ldev,
|
||||
|
@ -1234,7 +1236,7 @@ void mlx5_lag_add_netdev(struct mlx5_core_dev *dev,
|
|||
mlx5_ldev_add_netdev(ldev, dev, netdev);
|
||||
|
||||
for (i = 0; i < ldev->ports; i++)
|
||||
if (!ldev->pf[i].dev)
|
||||
if (!ldev->pf[i].netdev)
|
||||
break;
|
||||
|
||||
if (i >= ldev->ports)
|
||||
|
@ -1246,12 +1248,13 @@ void mlx5_lag_add_netdev(struct mlx5_core_dev *dev,
|
|||
bool mlx5_lag_is_roce(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_lag *ldev;
|
||||
unsigned long flags;
|
||||
bool res;
|
||||
|
||||
spin_lock(&lag_lock);
|
||||
spin_lock_irqsave(&lag_lock, flags);
|
||||
ldev = mlx5_lag_dev(dev);
|
||||
res = ldev && __mlx5_lag_is_roce(ldev);
|
||||
spin_unlock(&lag_lock);
|
||||
spin_unlock_irqrestore(&lag_lock, flags);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -1260,12 +1263,13 @@ EXPORT_SYMBOL(mlx5_lag_is_roce);
|
|||
bool mlx5_lag_is_active(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_lag *ldev;
|
||||
unsigned long flags;
|
||||
bool res;
|
||||
|
||||
spin_lock(&lag_lock);
|
||||
spin_lock_irqsave(&lag_lock, flags);
|
||||
ldev = mlx5_lag_dev(dev);
|
||||
res = ldev && __mlx5_lag_is_active(ldev);
|
||||
spin_unlock(&lag_lock);
|
||||
spin_unlock_irqrestore(&lag_lock, flags);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -1274,13 +1278,14 @@ EXPORT_SYMBOL(mlx5_lag_is_active);
|
|||
bool mlx5_lag_is_master(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_lag *ldev;
|
||||
unsigned long flags;
|
||||
bool res;
|
||||
|
||||
spin_lock(&lag_lock);
|
||||
spin_lock_irqsave(&lag_lock, flags);
|
||||
ldev = mlx5_lag_dev(dev);
|
||||
res = ldev && __mlx5_lag_is_active(ldev) &&
|
||||
dev == ldev->pf[MLX5_LAG_P1].dev;
|
||||
spin_unlock(&lag_lock);
|
||||
spin_unlock_irqrestore(&lag_lock, flags);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -1289,12 +1294,13 @@ EXPORT_SYMBOL(mlx5_lag_is_master);
|
|||
bool mlx5_lag_is_sriov(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_lag *ldev;
|
||||
unsigned long flags;
|
||||
bool res;
|
||||
|
||||
spin_lock(&lag_lock);
|
||||
spin_lock_irqsave(&lag_lock, flags);
|
||||
ldev = mlx5_lag_dev(dev);
|
||||
res = ldev && __mlx5_lag_is_sriov(ldev);
|
||||
spin_unlock(&lag_lock);
|
||||
spin_unlock_irqrestore(&lag_lock, flags);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -1303,13 +1309,14 @@ EXPORT_SYMBOL(mlx5_lag_is_sriov);
|
|||
bool mlx5_lag_is_shared_fdb(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_lag *ldev;
|
||||
unsigned long flags;
|
||||
bool res;
|
||||
|
||||
spin_lock(&lag_lock);
|
||||
spin_lock_irqsave(&lag_lock, flags);
|
||||
ldev = mlx5_lag_dev(dev);
|
||||
res = ldev && __mlx5_lag_is_sriov(ldev) &&
|
||||
test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &ldev->mode_flags);
|
||||
spin_unlock(&lag_lock);
|
||||
spin_unlock_irqrestore(&lag_lock, flags);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -1352,9 +1359,10 @@ struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev)
|
|||
{
|
||||
struct net_device *ndev = NULL;
|
||||
struct mlx5_lag *ldev;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
spin_lock(&lag_lock);
|
||||
spin_lock_irqsave(&lag_lock, flags);
|
||||
ldev = mlx5_lag_dev(dev);
|
||||
|
||||
if (!(ldev && __mlx5_lag_is_roce(ldev)))
|
||||
|
@ -1373,7 +1381,7 @@ struct net_device *mlx5_lag_get_roce_netdev(struct mlx5_core_dev *dev)
|
|||
dev_hold(ndev);
|
||||
|
||||
unlock:
|
||||
spin_unlock(&lag_lock);
|
||||
spin_unlock_irqrestore(&lag_lock, flags);
|
||||
|
||||
return ndev;
|
||||
}
|
||||
|
@ -1383,10 +1391,11 @@ u8 mlx5_lag_get_slave_port(struct mlx5_core_dev *dev,
|
|||
struct net_device *slave)
|
||||
{
|
||||
struct mlx5_lag *ldev;
|
||||
unsigned long flags;
|
||||
u8 port = 0;
|
||||
int i;
|
||||
|
||||
spin_lock(&lag_lock);
|
||||
spin_lock_irqsave(&lag_lock, flags);
|
||||
ldev = mlx5_lag_dev(dev);
|
||||
if (!(ldev && __mlx5_lag_is_roce(ldev)))
|
||||
goto unlock;
|
||||
|
@ -1401,7 +1410,7 @@ u8 mlx5_lag_get_slave_port(struct mlx5_core_dev *dev,
|
|||
port = ldev->v2p_map[port * ldev->buckets];
|
||||
|
||||
unlock:
|
||||
spin_unlock(&lag_lock);
|
||||
spin_unlock_irqrestore(&lag_lock, flags);
|
||||
return port;
|
||||
}
|
||||
EXPORT_SYMBOL(mlx5_lag_get_slave_port);
|
||||
|
@ -1422,8 +1431,9 @@ struct mlx5_core_dev *mlx5_lag_get_peer_mdev(struct mlx5_core_dev *dev)
|
|||
{
|
||||
struct mlx5_core_dev *peer_dev = NULL;
|
||||
struct mlx5_lag *ldev;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock(&lag_lock);
|
||||
spin_lock_irqsave(&lag_lock, flags);
|
||||
ldev = mlx5_lag_dev(dev);
|
||||
if (!ldev)
|
||||
goto unlock;
|
||||
|
@ -1433,7 +1443,7 @@ struct mlx5_core_dev *mlx5_lag_get_peer_mdev(struct mlx5_core_dev *dev)
|
|||
ldev->pf[MLX5_LAG_P1].dev;
|
||||
|
||||
unlock:
|
||||
spin_unlock(&lag_lock);
|
||||
spin_unlock_irqrestore(&lag_lock, flags);
|
||||
return peer_dev;
|
||||
}
|
||||
EXPORT_SYMBOL(mlx5_lag_get_peer_mdev);
|
||||
|
@ -1446,6 +1456,7 @@ int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev,
|
|||
int outlen = MLX5_ST_SZ_BYTES(query_cong_statistics_out);
|
||||
struct mlx5_core_dev **mdev;
|
||||
struct mlx5_lag *ldev;
|
||||
unsigned long flags;
|
||||
int num_ports;
|
||||
int ret, i, j;
|
||||
void *out;
|
||||
|
@ -1462,7 +1473,7 @@ int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev,
|
|||
|
||||
memset(values, 0, sizeof(*values) * num_counters);
|
||||
|
||||
spin_lock(&lag_lock);
|
||||
spin_lock_irqsave(&lag_lock, flags);
|
||||
ldev = mlx5_lag_dev(dev);
|
||||
if (ldev && __mlx5_lag_is_active(ldev)) {
|
||||
num_ports = ldev->ports;
|
||||
|
@ -1472,7 +1483,7 @@ int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev,
|
|||
num_ports = 1;
|
||||
mdev[MLX5_LAG_P1] = dev;
|
||||
}
|
||||
spin_unlock(&lag_lock);
|
||||
spin_unlock_irqrestore(&lag_lock, flags);
|
||||
|
||||
for (i = 0; i < num_ports; ++i) {
|
||||
u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = {};
|
||||
|
|
|
@ -1530,7 +1530,9 @@ int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx)
|
|||
memcpy(&dev->profile, &profile[profile_idx], sizeof(dev->profile));
|
||||
INIT_LIST_HEAD(&priv->ctx_list);
|
||||
spin_lock_init(&priv->ctx_lock);
|
||||
lockdep_register_key(&dev->lock_key);
|
||||
mutex_init(&dev->intf_state_mutex);
|
||||
lockdep_set_class(&dev->intf_state_mutex, &dev->lock_key);
|
||||
|
||||
mutex_init(&priv->bfregs.reg_head.lock);
|
||||
mutex_init(&priv->bfregs.wc_head.lock);
|
||||
|
@ -1597,6 +1599,7 @@ err_timeout_init:
|
|||
mutex_destroy(&priv->bfregs.wc_head.lock);
|
||||
mutex_destroy(&priv->bfregs.reg_head.lock);
|
||||
mutex_destroy(&dev->intf_state_mutex);
|
||||
lockdep_unregister_key(&dev->lock_key);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1618,6 +1621,7 @@ void mlx5_mdev_uninit(struct mlx5_core_dev *dev)
|
|||
mutex_destroy(&priv->bfregs.wc_head.lock);
|
||||
mutex_destroy(&priv->bfregs.reg_head.lock);
|
||||
mutex_destroy(&dev->intf_state_mutex);
|
||||
lockdep_unregister_key(&dev->lock_key);
|
||||
}
|
||||
|
||||
static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
|
|
|
@ -376,8 +376,8 @@ retry:
|
|||
goto out_dropped;
|
||||
}
|
||||
}
|
||||
err = mlx5_cmd_check(dev, err, in, out);
|
||||
if (err) {
|
||||
err = mlx5_cmd_check(dev, err, in, out);
|
||||
mlx5_core_warn(dev, "func_id 0x%x, npages %d, err %d\n",
|
||||
func_id, npages, err);
|
||||
goto out_dropped;
|
||||
|
@ -524,10 +524,13 @@ static int reclaim_pages(struct mlx5_core_dev *dev, u16 func_id, int npages,
|
|||
dev->priv.reclaim_pages_discard += npages;
|
||||
}
|
||||
/* if triggered by FW event and failed by FW then ignore */
|
||||
if (event && err == -EREMOTEIO)
|
||||
if (event && err == -EREMOTEIO) {
|
||||
err = 0;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
err = mlx5_cmd_check(dev, err, in, out);
|
||||
if (err) {
|
||||
err = mlx5_cmd_check(dev, err, in, out);
|
||||
mlx5_core_err(dev, "failed reclaiming pages: err %d\n", err);
|
||||
goto out_free;
|
||||
}
|
||||
|
|
|
@ -159,11 +159,11 @@ static int mlx5_sriov_enable(struct pci_dev *pdev, int num_vfs)
|
|||
|
||||
devl_lock(devlink);
|
||||
err = mlx5_device_enable_sriov(dev, num_vfs);
|
||||
devl_unlock(devlink);
|
||||
if (err) {
|
||||
mlx5_core_warn(dev, "mlx5_device_enable_sriov failed : %d\n", err);
|
||||
return err;
|
||||
}
|
||||
devl_unlock(devlink);
|
||||
|
||||
err = pci_enable_sriov(pdev, num_vfs);
|
||||
if (err) {
|
||||
|
|
|
@ -71,11 +71,6 @@ static int moxart_set_mac_address(struct net_device *ndev, void *addr)
|
|||
static void moxart_mac_free_memory(struct net_device *ndev)
|
||||
{
|
||||
struct moxart_mac_priv_t *priv = netdev_priv(ndev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RX_DESC_NUM; i++)
|
||||
dma_unmap_single(&priv->pdev->dev, priv->rx_mapping[i],
|
||||
priv->rx_buf_size, DMA_FROM_DEVICE);
|
||||
|
||||
if (priv->tx_desc_base)
|
||||
dma_free_coherent(&priv->pdev->dev,
|
||||
|
@ -187,6 +182,7 @@ static int moxart_mac_open(struct net_device *ndev)
|
|||
static int moxart_mac_stop(struct net_device *ndev)
|
||||
{
|
||||
struct moxart_mac_priv_t *priv = netdev_priv(ndev);
|
||||
int i;
|
||||
|
||||
napi_disable(&priv->napi);
|
||||
|
||||
|
@ -198,6 +194,11 @@ static int moxart_mac_stop(struct net_device *ndev)
|
|||
/* disable all functions */
|
||||
writel(0, priv->base + REG_MAC_CTRL);
|
||||
|
||||
/* unmap areas mapped in moxart_mac_setup_desc_ring() */
|
||||
for (i = 0; i < RX_DESC_NUM; i++)
|
||||
dma_unmap_single(&priv->pdev->dev, priv->rx_mapping[i],
|
||||
priv->rx_buf_size, DMA_FROM_DEVICE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1564,8 +1564,67 @@ static int ionic_set_features(struct net_device *netdev,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int ionic_set_attr_mac(struct ionic_lif *lif, u8 *mac)
|
||||
{
|
||||
struct ionic_admin_ctx ctx = {
|
||||
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
|
||||
.cmd.lif_setattr = {
|
||||
.opcode = IONIC_CMD_LIF_SETATTR,
|
||||
.index = cpu_to_le16(lif->index),
|
||||
.attr = IONIC_LIF_ATTR_MAC,
|
||||
},
|
||||
};
|
||||
|
||||
ether_addr_copy(ctx.cmd.lif_setattr.mac, mac);
|
||||
return ionic_adminq_post_wait(lif, &ctx);
|
||||
}
|
||||
|
||||
static int ionic_get_attr_mac(struct ionic_lif *lif, u8 *mac_addr)
|
||||
{
|
||||
struct ionic_admin_ctx ctx = {
|
||||
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
|
||||
.cmd.lif_getattr = {
|
||||
.opcode = IONIC_CMD_LIF_GETATTR,
|
||||
.index = cpu_to_le16(lif->index),
|
||||
.attr = IONIC_LIF_ATTR_MAC,
|
||||
},
|
||||
};
|
||||
int err;
|
||||
|
||||
err = ionic_adminq_post_wait(lif, &ctx);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ether_addr_copy(mac_addr, ctx.comp.lif_getattr.mac);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ionic_program_mac(struct ionic_lif *lif, u8 *mac)
|
||||
{
|
||||
u8 get_mac[ETH_ALEN];
|
||||
int err;
|
||||
|
||||
err = ionic_set_attr_mac(lif, mac);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = ionic_get_attr_mac(lif, get_mac);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* To deal with older firmware that silently ignores the set attr mac:
|
||||
* doesn't actually change the mac and doesn't return an error, so we
|
||||
* do the get attr to verify whether or not the set actually happened
|
||||
*/
|
||||
if (!ether_addr_equal(get_mac, mac))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ionic_set_mac_address(struct net_device *netdev, void *sa)
|
||||
{
|
||||
struct ionic_lif *lif = netdev_priv(netdev);
|
||||
struct sockaddr *addr = sa;
|
||||
u8 *mac;
|
||||
int err;
|
||||
|
@ -1574,6 +1633,14 @@ static int ionic_set_mac_address(struct net_device *netdev, void *sa)
|
|||
if (ether_addr_equal(netdev->dev_addr, mac))
|
||||
return 0;
|
||||
|
||||
err = ionic_program_mac(lif, mac);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (err > 0)
|
||||
netdev_dbg(netdev, "%s: SET and GET ATTR Mac are not equal-due to old FW running\n",
|
||||
__func__);
|
||||
|
||||
err = eth_prepare_mac_addr_change(netdev, addr);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -2963,6 +3030,9 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
|
|||
|
||||
mutex_lock(&lif->queue_lock);
|
||||
|
||||
if (test_and_clear_bit(IONIC_LIF_F_BROKEN, lif->state))
|
||||
dev_info(ionic->dev, "FW Up: clearing broken state\n");
|
||||
|
||||
err = ionic_qcqs_alloc(lif);
|
||||
if (err)
|
||||
goto err_unlock;
|
||||
|
@ -3169,6 +3239,7 @@ static int ionic_station_set(struct ionic_lif *lif)
|
|||
.attr = IONIC_LIF_ATTR_MAC,
|
||||
},
|
||||
};
|
||||
u8 mac_address[ETH_ALEN];
|
||||
struct sockaddr addr;
|
||||
int err;
|
||||
|
||||
|
@ -3177,8 +3248,23 @@ static int ionic_station_set(struct ionic_lif *lif)
|
|||
return err;
|
||||
netdev_dbg(lif->netdev, "found initial MAC addr %pM\n",
|
||||
ctx.comp.lif_getattr.mac);
|
||||
if (is_zero_ether_addr(ctx.comp.lif_getattr.mac))
|
||||
return 0;
|
||||
ether_addr_copy(mac_address, ctx.comp.lif_getattr.mac);
|
||||
|
||||
if (is_zero_ether_addr(mac_address)) {
|
||||
eth_hw_addr_random(netdev);
|
||||
netdev_dbg(netdev, "Random Mac generated: %pM\n", netdev->dev_addr);
|
||||
ether_addr_copy(mac_address, netdev->dev_addr);
|
||||
|
||||
err = ionic_program_mac(lif, mac_address);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (err > 0) {
|
||||
netdev_dbg(netdev, "%s:SET/GET ATTR Mac are not same-due to old FW running\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_zero_ether_addr(netdev->dev_addr)) {
|
||||
/* If the netdev mac is non-zero and doesn't match the default
|
||||
|
@ -3186,12 +3272,11 @@ static int ionic_station_set(struct ionic_lif *lif)
|
|||
* likely here again after a fw-upgrade reset. We need to be
|
||||
* sure the netdev mac is in our filter list.
|
||||
*/
|
||||
if (!ether_addr_equal(ctx.comp.lif_getattr.mac,
|
||||
netdev->dev_addr))
|
||||
if (!ether_addr_equal(mac_address, netdev->dev_addr))
|
||||
ionic_lif_addr_add(lif, netdev->dev_addr);
|
||||
} else {
|
||||
/* Update the netdev mac with the device's mac */
|
||||
memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len);
|
||||
ether_addr_copy(addr.sa_data, mac_address);
|
||||
addr.sa_family = AF_INET;
|
||||
err = eth_prepare_mac_addr_change(netdev, &addr);
|
||||
if (err) {
|
||||
|
|
|
@ -474,8 +474,8 @@ try_again:
|
|||
ionic_opcode_to_str(opcode), opcode,
|
||||
ionic_error_to_str(err), err);
|
||||
|
||||
msleep(1000);
|
||||
iowrite32(0, &idev->dev_cmd_regs->done);
|
||||
msleep(1000);
|
||||
iowrite32(1, &idev->dev_cmd_regs->doorbell);
|
||||
goto try_again;
|
||||
}
|
||||
|
@ -488,6 +488,8 @@ try_again:
|
|||
return ionic_error_to_errno(err);
|
||||
}
|
||||
|
||||
ionic_dev_cmd_clean(ionic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -258,14 +258,18 @@ EXPORT_SYMBOL_GPL(stmmac_set_mac_addr);
|
|||
/* Enable disable MAC RX/TX */
|
||||
void stmmac_set_mac(void __iomem *ioaddr, bool enable)
|
||||
{
|
||||
u32 value = readl(ioaddr + MAC_CTRL_REG);
|
||||
u32 old_val, value;
|
||||
|
||||
old_val = readl(ioaddr + MAC_CTRL_REG);
|
||||
value = old_val;
|
||||
|
||||
if (enable)
|
||||
value |= MAC_ENABLE_RX | MAC_ENABLE_TX;
|
||||
else
|
||||
value &= ~(MAC_ENABLE_TX | MAC_ENABLE_RX);
|
||||
|
||||
writel(value, ioaddr + MAC_CTRL_REG);
|
||||
if (value != old_val)
|
||||
writel(value, ioaddr + MAC_CTRL_REG);
|
||||
}
|
||||
|
||||
void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
|
||||
|
|
|
@ -986,10 +986,10 @@ static void stmmac_mac_link_up(struct phylink_config *config,
|
|||
bool tx_pause, bool rx_pause)
|
||||
{
|
||||
struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
|
||||
u32 ctrl;
|
||||
u32 old_ctrl, ctrl;
|
||||
|
||||
ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
|
||||
ctrl &= ~priv->hw->link.speed_mask;
|
||||
old_ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
|
||||
ctrl = old_ctrl & ~priv->hw->link.speed_mask;
|
||||
|
||||
if (interface == PHY_INTERFACE_MODE_USXGMII) {
|
||||
switch (speed) {
|
||||
|
@ -1064,7 +1064,8 @@ static void stmmac_mac_link_up(struct phylink_config *config,
|
|||
if (tx_pause && rx_pause)
|
||||
stmmac_mac_flow_ctrl(priv, duplex);
|
||||
|
||||
writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
|
||||
if (ctrl != old_ctrl)
|
||||
writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
|
||||
|
||||
stmmac_mac_set(priv, priv->ioaddr, true);
|
||||
if (phy && priv->dma_cap.eee) {
|
||||
|
|
|
@ -568,7 +568,7 @@ static int ipa_smem_init(struct ipa *ipa, u32 item, size_t size)
|
|||
}
|
||||
|
||||
/* Align the address down and the size up to a page boundary */
|
||||
addr = qcom_smem_virt_to_phys(virt) & PAGE_MASK;
|
||||
addr = qcom_smem_virt_to_phys(virt);
|
||||
phys = addr & PAGE_MASK;
|
||||
size = PAGE_ALIGN(size + addr - phys);
|
||||
iova = phys; /* We just want a direct mapping */
|
||||
|
|
|
@ -194,7 +194,7 @@ static struct notifier_block ipvtap_notifier_block __read_mostly = {
|
|||
.notifier_call = ipvtap_device_event,
|
||||
};
|
||||
|
||||
static int ipvtap_init(void)
|
||||
static int __init ipvtap_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -228,7 +228,7 @@ out1:
|
|||
}
|
||||
module_init(ipvtap_init);
|
||||
|
||||
static void ipvtap_exit(void)
|
||||
static void __exit ipvtap_exit(void)
|
||||
{
|
||||
rtnl_link_unregister(&ipvtap_link_ops);
|
||||
unregister_netdevice_notifier(&ipvtap_notifier_block);
|
||||
|
|
|
@ -462,11 +462,6 @@ static struct macsec_eth_header *macsec_ethhdr(struct sk_buff *skb)
|
|||
return (struct macsec_eth_header *)skb_mac_header(skb);
|
||||
}
|
||||
|
||||
static sci_t dev_to_sci(struct net_device *dev, __be16 port)
|
||||
{
|
||||
return make_sci(dev->dev_addr, port);
|
||||
}
|
||||
|
||||
static void __macsec_pn_wrapped(struct macsec_secy *secy,
|
||||
struct macsec_tx_sa *tx_sa)
|
||||
{
|
||||
|
@ -3661,7 +3656,6 @@ static int macsec_set_mac_address(struct net_device *dev, void *p)
|
|||
|
||||
out:
|
||||
eth_hw_addr_set(dev, addr->sa_data);
|
||||
macsec->secy.sci = dev_to_sci(dev, MACSEC_PORT_ES);
|
||||
|
||||
/* If h/w offloading is available, propagate to the device */
|
||||
if (macsec_is_offloaded(macsec)) {
|
||||
|
@ -4000,6 +3994,11 @@ static bool sci_exists(struct net_device *dev, sci_t sci)
|
|||
return false;
|
||||
}
|
||||
|
||||
static sci_t dev_to_sci(struct net_device *dev, __be16 port)
|
||||
{
|
||||
return make_sci(dev->dev_addr, port);
|
||||
}
|
||||
|
||||
static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len)
|
||||
{
|
||||
struct macsec_dev *macsec = macsec_priv(dev);
|
||||
|
|
|
@ -316,11 +316,11 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
|
|||
|
||||
phydev->suspended_by_mdio_bus = 0;
|
||||
|
||||
/* If we managed to get here with the PHY state machine in a state other
|
||||
* than PHY_HALTED this is an indication that something went wrong and
|
||||
* we should most likely be using MAC managed PM and we are not.
|
||||
/* If we manged to get here with the PHY state machine in a state neither
|
||||
* PHY_HALTED nor PHY_READY this is an indication that something went wrong
|
||||
* and we should most likely be using MAC managed PM and we are not.
|
||||
*/
|
||||
WARN_ON(phydev->state != PHY_HALTED && !phydev->mac_managed_pm);
|
||||
WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY);
|
||||
|
||||
ret = phy_init_hw(phydev);
|
||||
if (ret < 0)
|
||||
|
|
|
@ -5906,6 +5906,11 @@ static void r8153_enter_oob(struct r8152 *tp)
|
|||
ocp_data &= ~NOW_IS_OOB;
|
||||
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
|
||||
|
||||
/* RX FIFO settings for OOB */
|
||||
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_OOB);
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, RXFIFO_THR2_OOB);
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_OOB);
|
||||
|
||||
rtl_disable(tp);
|
||||
rtl_reset_bmu(tp);
|
||||
|
||||
|
@ -6431,21 +6436,8 @@ static void r8156_fc_parameter(struct r8152 *tp)
|
|||
u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp);
|
||||
u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp);
|
||||
|
||||
switch (tp->version) {
|
||||
case RTL_VER_10:
|
||||
case RTL_VER_11:
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 8);
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 8);
|
||||
break;
|
||||
case RTL_VER_12:
|
||||
case RTL_VER_13:
|
||||
case RTL_VER_15:
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16);
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16);
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16);
|
||||
}
|
||||
|
||||
static void rtl8156_change_mtu(struct r8152 *tp)
|
||||
|
@ -6557,6 +6549,11 @@ static void rtl8156_down(struct r8152 *tp)
|
|||
ocp_data &= ~NOW_IS_OOB;
|
||||
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
|
||||
|
||||
/* RX FIFO settings for OOB */
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, 64 / 16);
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, 1024 / 16);
|
||||
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, 4096 / 16);
|
||||
|
||||
rtl_disable(tp);
|
||||
rtl_reset_bmu(tp);
|
||||
|
||||
|
|
|
@ -310,6 +310,7 @@ static void pn532_uart_remove(struct serdev_device *serdev)
|
|||
pn53x_unregister_nfc(pn532->priv);
|
||||
serdev_device_close(serdev);
|
||||
pn53x_common_clean(pn532->priv);
|
||||
del_timer_sync(&pn532->cmd_timeout);
|
||||
kfree_skb(pn532->recv_skb);
|
||||
kfree(pn532);
|
||||
}
|
||||
|
|
14
fs/inode.c
14
fs/inode.c
|
@ -2018,23 +2018,25 @@ static int __file_remove_privs(struct file *file, unsigned int flags)
|
|||
{
|
||||
struct dentry *dentry = file_dentry(file);
|
||||
struct inode *inode = file_inode(file);
|
||||
int error;
|
||||
int error = 0;
|
||||
int kill;
|
||||
|
||||
if (IS_NOSEC(inode) || !S_ISREG(inode->i_mode))
|
||||
return 0;
|
||||
|
||||
kill = dentry_needs_remove_privs(dentry);
|
||||
if (kill <= 0)
|
||||
if (kill < 0)
|
||||
return kill;
|
||||
|
||||
if (flags & IOCB_NOWAIT)
|
||||
return -EAGAIN;
|
||||
if (kill) {
|
||||
if (flags & IOCB_NOWAIT)
|
||||
return -EAGAIN;
|
||||
|
||||
error = __remove_privs(file_mnt_user_ns(file), dentry, kill);
|
||||
}
|
||||
|
||||
error = __remove_privs(file_mnt_user_ns(file), dentry, kill);
|
||||
if (!error)
|
||||
inode_has_no_xattr(inode);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -734,11 +734,6 @@ static inline struct cgroup *cgroup_parent(struct cgroup *cgrp)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct psi_group *cgroup_psi(struct cgroup *cgrp)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool cgroup_psi_enabled(void)
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -779,6 +779,7 @@ struct mlx5_core_dev {
|
|||
enum mlx5_device_state state;
|
||||
/* sync interface state */
|
||||
struct mutex intf_state_mutex;
|
||||
struct lock_class_key lock_key;
|
||||
unsigned long intf_state;
|
||||
struct mlx5_priv priv;
|
||||
struct mlx5_profile profile;
|
||||
|
|
|
@ -640,9 +640,23 @@ extern int sysctl_devconf_inherit_init_net;
|
|||
*/
|
||||
static inline bool net_has_fallback_tunnels(const struct net *net)
|
||||
{
|
||||
return !IS_ENABLED(CONFIG_SYSCTL) ||
|
||||
!sysctl_fb_tunnels_only_for_init_net ||
|
||||
(net == &init_net && sysctl_fb_tunnels_only_for_init_net == 1);
|
||||
#if IS_ENABLED(CONFIG_SYSCTL)
|
||||
int fb_tunnels_only_for_init_net = READ_ONCE(sysctl_fb_tunnels_only_for_init_net);
|
||||
|
||||
return !fb_tunnels_only_for_init_net ||
|
||||
(net_eq(net, &init_net) && fb_tunnels_only_for_init_net == 1);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int net_inherit_devconf(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_SYSCTL)
|
||||
return READ_ONCE(sysctl_devconf_inherit_init_net);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int netdev_queue_numa_node_read(const struct netdev_queue *q)
|
||||
|
|
|
@ -94,10 +94,6 @@ struct ebt_table {
|
|||
struct ebt_replace_kernel *table;
|
||||
unsigned int valid_hooks;
|
||||
rwlock_t lock;
|
||||
/* e.g. could be the table explicitly only allows certain
|
||||
* matches, targets, ... 0 == let it in */
|
||||
int (*check)(const struct ebt_table_info *info,
|
||||
unsigned int valid_hooks);
|
||||
/* the data used by the kernel */
|
||||
struct ebt_table_info *private;
|
||||
struct nf_hook_ops *ops;
|
||||
|
|
|
@ -27,7 +27,7 @@ void psi_memstall_leave(unsigned long *flags);
|
|||
|
||||
int psi_show(struct seq_file *s, struct psi_group *group, enum psi_res res);
|
||||
struct psi_trigger *psi_trigger_create(struct psi_group *group,
|
||||
char *buf, size_t nbytes, enum psi_res res);
|
||||
char *buf, enum psi_res res);
|
||||
void psi_trigger_destroy(struct psi_trigger *t);
|
||||
|
||||
__poll_t psi_trigger_poll(void **trigger_ptr, struct file *file,
|
||||
|
|
|
@ -290,7 +290,7 @@ static inline const char *bond_3ad_churn_desc(churn_state_t state)
|
|||
}
|
||||
|
||||
/* ========== AD Exported functions to the main bonding code ========== */
|
||||
void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution);
|
||||
void bond_3ad_initialize(struct bonding *bond);
|
||||
void bond_3ad_bind_slave(struct slave *slave);
|
||||
void bond_3ad_unbind_slave(struct slave *slave);
|
||||
void bond_3ad_state_machine_handler(struct work_struct *);
|
||||
|
|
|
@ -33,7 +33,7 @@ extern unsigned int sysctl_net_busy_poll __read_mostly;
|
|||
|
||||
static inline bool net_busy_loop_on(void)
|
||||
{
|
||||
return sysctl_net_busy_poll;
|
||||
return READ_ONCE(sysctl_net_busy_poll);
|
||||
}
|
||||
|
||||
static inline bool sk_can_busy_loop(const struct sock *sk)
|
||||
|
|
|
@ -439,7 +439,7 @@ static inline void gro_normal_one(struct napi_struct *napi, struct sk_buff *skb,
|
|||
{
|
||||
list_add_tail(&skb->list, &napi->rx_list);
|
||||
napi->rx_count += segs;
|
||||
if (napi->rx_count >= gro_normal_batch)
|
||||
if (napi->rx_count >= READ_ONCE(gro_normal_batch))
|
||||
gro_normal_list(napi);
|
||||
}
|
||||
|
||||
|
|
|
@ -270,6 +270,7 @@ void flow_offload_refresh(struct nf_flowtable *flow_table,
|
|||
|
||||
struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table,
|
||||
struct flow_offload_tuple *tuple);
|
||||
void nf_flow_table_gc_run(struct nf_flowtable *flow_table);
|
||||
void nf_flow_table_gc_cleanup(struct nf_flowtable *flowtable,
|
||||
struct net_device *dev);
|
||||
void nf_flow_table_cleanup(struct net_device *dev);
|
||||
|
@ -306,6 +307,8 @@ void nf_flow_offload_stats(struct nf_flowtable *flowtable,
|
|||
struct flow_offload *flow);
|
||||
|
||||
void nf_flow_table_offload_flush(struct nf_flowtable *flowtable);
|
||||
void nf_flow_table_offload_flush_cleanup(struct nf_flowtable *flowtable);
|
||||
|
||||
int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
|
||||
struct net_device *dev,
|
||||
enum flow_block_command cmd);
|
||||
|
|
|
@ -1652,6 +1652,7 @@ struct nftables_pernet {
|
|||
struct list_head module_list;
|
||||
struct list_head notify_list;
|
||||
struct mutex commit_mutex;
|
||||
u64 table_handle;
|
||||
unsigned int base_seq;
|
||||
u8 validate_state;
|
||||
};
|
||||
|
|
|
@ -296,7 +296,7 @@ enum xfrm_attr_type_t {
|
|||
XFRMA_ETIMER_THRESH,
|
||||
XFRMA_SRCADDR, /* xfrm_address_t */
|
||||
XFRMA_COADDR, /* xfrm_address_t */
|
||||
XFRMA_LASTUSED, /* unsigned long */
|
||||
XFRMA_LASTUSED, /* __u64 */
|
||||
XFRMA_POLICY_TYPE, /* struct xfrm_userpolicy_type */
|
||||
XFRMA_MIGRATE,
|
||||
XFRMA_ALG_AEAD, /* struct xfrm_algo_aead */
|
||||
|
|
|
@ -102,6 +102,7 @@ struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pa
|
|||
|
||||
ret = fsnotify_add_inode_mark(&audit_mark->mark, inode, 0);
|
||||
if (ret < 0) {
|
||||
audit_mark->path = NULL;
|
||||
fsnotify_put_mark(&audit_mark->mark);
|
||||
audit_mark = ERR_PTR(ret);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk)
|
|||
int retval = 0;
|
||||
|
||||
mutex_lock(&cgroup_mutex);
|
||||
cpus_read_lock();
|
||||
percpu_down_write(&cgroup_threadgroup_rwsem);
|
||||
for_each_root(root) {
|
||||
struct cgroup *from_cgrp;
|
||||
|
@ -72,6 +73,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk)
|
|||
break;
|
||||
}
|
||||
percpu_up_write(&cgroup_threadgroup_rwsem);
|
||||
cpus_read_unlock();
|
||||
mutex_unlock(&cgroup_mutex);
|
||||
|
||||
return retval;
|
||||
|
|
|
@ -1820,6 +1820,7 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask)
|
|||
|
||||
if (ss->css_rstat_flush) {
|
||||
list_del_rcu(&css->rstat_css_node);
|
||||
synchronize_rcu();
|
||||
list_add_rcu(&css->rstat_css_node,
|
||||
&dcgrp->rstat_css_list);
|
||||
}
|
||||
|
@ -2369,6 +2370,47 @@ int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(task_cgroup_path);
|
||||
|
||||
/**
|
||||
* cgroup_attach_lock - Lock for ->attach()
|
||||
* @lock_threadgroup: whether to down_write cgroup_threadgroup_rwsem
|
||||
*
|
||||
* cgroup migration sometimes needs to stabilize threadgroups against forks and
|
||||
* exits by write-locking cgroup_threadgroup_rwsem. However, some ->attach()
|
||||
* implementations (e.g. cpuset), also need to disable CPU hotplug.
|
||||
* Unfortunately, letting ->attach() operations acquire cpus_read_lock() can
|
||||
* lead to deadlocks.
|
||||
*
|
||||
* Bringing up a CPU may involve creating and destroying tasks which requires
|
||||
* read-locking threadgroup_rwsem, so threadgroup_rwsem nests inside
|
||||
* cpus_read_lock(). If we call an ->attach() which acquires the cpus lock while
|
||||
* write-locking threadgroup_rwsem, the locking order is reversed and we end up
|
||||
* waiting for an on-going CPU hotplug operation which in turn is waiting for
|
||||
* the threadgroup_rwsem to be released to create new tasks. For more details:
|
||||
*
|
||||
* http://lkml.kernel.org/r/20220711174629.uehfmqegcwn2lqzu@wubuntu
|
||||
*
|
||||
* Resolve the situation by always acquiring cpus_read_lock() before optionally
|
||||
* write-locking cgroup_threadgroup_rwsem. This allows ->attach() to assume that
|
||||
* CPU hotplug is disabled on entry.
|
||||
*/
|
||||
static void cgroup_attach_lock(bool lock_threadgroup)
|
||||
{
|
||||
cpus_read_lock();
|
||||
if (lock_threadgroup)
|
||||
percpu_down_write(&cgroup_threadgroup_rwsem);
|
||||
}
|
||||
|
||||
/**
|
||||
* cgroup_attach_unlock - Undo cgroup_attach_lock()
|
||||
* @lock_threadgroup: whether to up_write cgroup_threadgroup_rwsem
|
||||
*/
|
||||
static void cgroup_attach_unlock(bool lock_threadgroup)
|
||||
{
|
||||
if (lock_threadgroup)
|
||||
percpu_up_write(&cgroup_threadgroup_rwsem);
|
||||
cpus_read_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* cgroup_migrate_add_task - add a migration target task to a migration context
|
||||
* @task: target task
|
||||
|
@ -2841,8 +2883,7 @@ int cgroup_attach_task(struct cgroup *dst_cgrp, struct task_struct *leader,
|
|||
}
|
||||
|
||||
struct task_struct *cgroup_procs_write_start(char *buf, bool threadgroup,
|
||||
bool *locked)
|
||||
__acquires(&cgroup_threadgroup_rwsem)
|
||||
bool *threadgroup_locked)
|
||||
{
|
||||
struct task_struct *tsk;
|
||||
pid_t pid;
|
||||
|
@ -2859,12 +2900,8 @@ struct task_struct *cgroup_procs_write_start(char *buf, bool threadgroup,
|
|||
* Therefore, we can skip the global lock.
|
||||
*/
|
||||
lockdep_assert_held(&cgroup_mutex);
|
||||
if (pid || threadgroup) {
|
||||
percpu_down_write(&cgroup_threadgroup_rwsem);
|
||||
*locked = true;
|
||||
} else {
|
||||
*locked = false;
|
||||
}
|
||||
*threadgroup_locked = pid || threadgroup;
|
||||
cgroup_attach_lock(*threadgroup_locked);
|
||||
|
||||
rcu_read_lock();
|
||||
if (pid) {
|
||||
|
@ -2895,17 +2932,14 @@ struct task_struct *cgroup_procs_write_start(char *buf, bool threadgroup,
|
|||
goto out_unlock_rcu;
|
||||
|
||||
out_unlock_threadgroup:
|
||||
if (*locked) {
|
||||
percpu_up_write(&cgroup_threadgroup_rwsem);
|
||||
*locked = false;
|
||||
}
|
||||
cgroup_attach_unlock(*threadgroup_locked);
|
||||
*threadgroup_locked = false;
|
||||
out_unlock_rcu:
|
||||
rcu_read_unlock();
|
||||
return tsk;
|
||||
}
|
||||
|
||||
void cgroup_procs_write_finish(struct task_struct *task, bool locked)
|
||||
__releases(&cgroup_threadgroup_rwsem)
|
||||
void cgroup_procs_write_finish(struct task_struct *task, bool threadgroup_locked)
|
||||
{
|
||||
struct cgroup_subsys *ss;
|
||||
int ssid;
|
||||
|
@ -2913,8 +2947,8 @@ void cgroup_procs_write_finish(struct task_struct *task, bool locked)
|
|||
/* release reference from cgroup_procs_write_start() */
|
||||
put_task_struct(task);
|
||||
|
||||
if (locked)
|
||||
percpu_up_write(&cgroup_threadgroup_rwsem);
|
||||
cgroup_attach_unlock(threadgroup_locked);
|
||||
|
||||
for_each_subsys(ss, ssid)
|
||||
if (ss->post_attach)
|
||||
ss->post_attach();
|
||||
|
@ -3000,8 +3034,7 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp)
|
|||
* write-locking can be skipped safely.
|
||||
*/
|
||||
has_tasks = !list_empty(&mgctx.preloaded_src_csets);
|
||||
if (has_tasks)
|
||||
percpu_down_write(&cgroup_threadgroup_rwsem);
|
||||
cgroup_attach_lock(has_tasks);
|
||||
|
||||
/* NULL dst indicates self on default hierarchy */
|
||||
ret = cgroup_migrate_prepare_dst(&mgctx);
|
||||
|
@ -3022,8 +3055,7 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp)
|
|||
ret = cgroup_migrate_execute(&mgctx);
|
||||
out_finish:
|
||||
cgroup_migrate_finish(&mgctx);
|
||||
if (has_tasks)
|
||||
percpu_up_write(&cgroup_threadgroup_rwsem);
|
||||
cgroup_attach_unlock(has_tasks);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3698,7 +3730,7 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, char *buf,
|
|||
}
|
||||
|
||||
psi = cgroup_ino(cgrp) == 1 ? &psi_system : cgrp->psi;
|
||||
new = psi_trigger_create(psi, buf, nbytes, res);
|
||||
new = psi_trigger_create(psi, buf, res);
|
||||
if (IS_ERR(new)) {
|
||||
cgroup_put(cgrp);
|
||||
return PTR_ERR(new);
|
||||
|
@ -4971,13 +5003,13 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf,
|
|||
struct task_struct *task;
|
||||
const struct cred *saved_cred;
|
||||
ssize_t ret;
|
||||
bool locked;
|
||||
bool threadgroup_locked;
|
||||
|
||||
dst_cgrp = cgroup_kn_lock_live(of->kn, false);
|
||||
if (!dst_cgrp)
|
||||
return -ENODEV;
|
||||
|
||||
task = cgroup_procs_write_start(buf, threadgroup, &locked);
|
||||
task = cgroup_procs_write_start(buf, threadgroup, &threadgroup_locked);
|
||||
ret = PTR_ERR_OR_ZERO(task);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
@ -5003,7 +5035,7 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf,
|
|||
ret = cgroup_attach_task(dst_cgrp, task, threadgroup);
|
||||
|
||||
out_finish:
|
||||
cgroup_procs_write_finish(task, locked);
|
||||
cgroup_procs_write_finish(task, threadgroup_locked);
|
||||
out_unlock:
|
||||
cgroup_kn_unlock(of->kn);
|
||||
|
||||
|
|
|
@ -2289,7 +2289,7 @@ static void cpuset_attach(struct cgroup_taskset *tset)
|
|||
cgroup_taskset_first(tset, &css);
|
||||
cs = css_cs(css);
|
||||
|
||||
cpus_read_lock();
|
||||
lockdep_assert_cpus_held(); /* see cgroup_attach_lock() */
|
||||
percpu_down_write(&cpuset_rwsem);
|
||||
|
||||
guarantee_online_mems(cs, &cpuset_attach_nodemask_to);
|
||||
|
@ -2343,7 +2343,6 @@ static void cpuset_attach(struct cgroup_taskset *tset)
|
|||
wake_up(&cpuset_attach_wq);
|
||||
|
||||
percpu_up_write(&cpuset_rwsem);
|
||||
cpus_read_unlock();
|
||||
}
|
||||
|
||||
/* The various types of files and directories in a cpuset file system */
|
||||
|
|
|
@ -190,12 +190,8 @@ static void group_init(struct psi_group *group)
|
|||
/* Init trigger-related members */
|
||||
mutex_init(&group->trigger_lock);
|
||||
INIT_LIST_HEAD(&group->triggers);
|
||||
memset(group->nr_triggers, 0, sizeof(group->nr_triggers));
|
||||
group->poll_states = 0;
|
||||
group->poll_min_period = U32_MAX;
|
||||
memset(group->polling_total, 0, sizeof(group->polling_total));
|
||||
group->polling_next_update = ULLONG_MAX;
|
||||
group->polling_until = 0;
|
||||
init_waitqueue_head(&group->poll_wait);
|
||||
timer_setup(&group->poll_timer, poll_timer_fn, 0);
|
||||
rcu_assign_pointer(group->poll_task, NULL);
|
||||
|
@ -957,7 +953,7 @@ int psi_cgroup_alloc(struct cgroup *cgroup)
|
|||
if (static_branch_likely(&psi_disabled))
|
||||
return 0;
|
||||
|
||||
cgroup->psi = kmalloc(sizeof(struct psi_group), GFP_KERNEL);
|
||||
cgroup->psi = kzalloc(sizeof(struct psi_group), GFP_KERNEL);
|
||||
if (!cgroup->psi)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1091,7 +1087,7 @@ int psi_show(struct seq_file *m, struct psi_group *group, enum psi_res res)
|
|||
}
|
||||
|
||||
struct psi_trigger *psi_trigger_create(struct psi_group *group,
|
||||
char *buf, size_t nbytes, enum psi_res res)
|
||||
char *buf, enum psi_res res)
|
||||
{
|
||||
struct psi_trigger *t;
|
||||
enum psi_states state;
|
||||
|
@ -1320,7 +1316,7 @@ static ssize_t psi_write(struct file *file, const char __user *user_buf,
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
new = psi_trigger_create(&psi_system, buf, nbytes, res);
|
||||
new = psi_trigger_create(&psi_system, buf, res);
|
||||
if (IS_ERR(new)) {
|
||||
mutex_unlock(&seq->lock);
|
||||
return PTR_ERR(new);
|
||||
|
|
|
@ -1861,8 +1861,6 @@ static void ftrace_hash_rec_enable_modify(struct ftrace_ops *ops,
|
|||
ftrace_hash_rec_update_modify(ops, filter_hash, 1);
|
||||
}
|
||||
|
||||
static bool ops_references_ip(struct ftrace_ops *ops, unsigned long ip);
|
||||
|
||||
/*
|
||||
* Try to update IPMODIFY flag on each ftrace_rec. Return 0 if it is OK
|
||||
* or no-needed to update, -EBUSY if it detects a conflict of the flag
|
||||
|
@ -3118,49 +3116,6 @@ static inline int ops_traces_mod(struct ftrace_ops *ops)
|
|||
ftrace_hash_empty(ops->func_hash->notrace_hash);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the current ops references the given ip.
|
||||
*
|
||||
* If the ops traces all functions, then it was already accounted for.
|
||||
* If the ops does not trace the current record function, skip it.
|
||||
* If the ops ignores the function via notrace filter, skip it.
|
||||
*/
|
||||
static bool
|
||||
ops_references_ip(struct ftrace_ops *ops, unsigned long ip)
|
||||
{
|
||||
/* If ops isn't enabled, ignore it */
|
||||
if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
|
||||
return false;
|
||||
|
||||
/* If ops traces all then it includes this function */
|
||||
if (ops_traces_mod(ops))
|
||||
return true;
|
||||
|
||||
/* The function must be in the filter */
|
||||
if (!ftrace_hash_empty(ops->func_hash->filter_hash) &&
|
||||
!__ftrace_lookup_ip(ops->func_hash->filter_hash, ip))
|
||||
return false;
|
||||
|
||||
/* If in notrace hash, we ignore it too */
|
||||
if (ftrace_lookup_ip(ops->func_hash->notrace_hash, ip))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the current ops references the record.
|
||||
*
|
||||
* If the ops traces all functions, then it was already accounted for.
|
||||
* If the ops does not trace the current record function, skip it.
|
||||
* If the ops ignores the function via notrace filter, skip it.
|
||||
*/
|
||||
static bool
|
||||
ops_references_rec(struct ftrace_ops *ops, struct dyn_ftrace *rec)
|
||||
{
|
||||
return ops_references_ip(ops, rec->ip);
|
||||
}
|
||||
|
||||
static int ftrace_update_code(struct module *mod, struct ftrace_page *new_pgs)
|
||||
{
|
||||
bool init_nop = ftrace_need_init_nop();
|
||||
|
@ -6822,6 +6777,38 @@ static int ftrace_get_trampoline_kallsym(unsigned int symnum,
|
|||
return -ERANGE;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS) || defined(CONFIG_MODULES)
|
||||
/*
|
||||
* Check if the current ops references the given ip.
|
||||
*
|
||||
* If the ops traces all functions, then it was already accounted for.
|
||||
* If the ops does not trace the current record function, skip it.
|
||||
* If the ops ignores the function via notrace filter, skip it.
|
||||
*/
|
||||
static bool
|
||||
ops_references_ip(struct ftrace_ops *ops, unsigned long ip)
|
||||
{
|
||||
/* If ops isn't enabled, ignore it */
|
||||
if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
|
||||
return false;
|
||||
|
||||
/* If ops traces all then it includes this function */
|
||||
if (ops_traces_mod(ops))
|
||||
return true;
|
||||
|
||||
/* The function must be in the filter */
|
||||
if (!ftrace_hash_empty(ops->func_hash->filter_hash) &&
|
||||
!__ftrace_lookup_ip(ops->func_hash->filter_hash, ip))
|
||||
return false;
|
||||
|
||||
/* If in notrace hash, we ignore it too */
|
||||
if (ftrace_lookup_ip(ops->func_hash->notrace_hash, ip))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
|
||||
#define next_to_ftrace_page(p) container_of(p, struct ftrace_page, next)
|
||||
|
@ -6834,7 +6821,7 @@ static int referenced_filters(struct dyn_ftrace *rec)
|
|||
int cnt = 0;
|
||||
|
||||
for (ops = ftrace_ops_list; ops != &ftrace_list_end; ops = ops->next) {
|
||||
if (ops_references_rec(ops, rec)) {
|
||||
if (ops_references_ip(ops, rec->ip)) {
|
||||
if (WARN_ON_ONCE(ops->flags & FTRACE_OPS_FL_DIRECT))
|
||||
continue;
|
||||
if (WARN_ON_ONCE(ops->flags & FTRACE_OPS_FL_IPMODIFY))
|
||||
|
|
|
@ -26,10 +26,16 @@
|
|||
*/
|
||||
int ___ratelimit(struct ratelimit_state *rs, const char *func)
|
||||
{
|
||||
/* Paired with WRITE_ONCE() in .proc_handler().
|
||||
* Changing two values seperately could be inconsistent
|
||||
* and some message could be lost. (See: net_ratelimit_state).
|
||||
*/
|
||||
int interval = READ_ONCE(rs->interval);
|
||||
int burst = READ_ONCE(rs->burst);
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (!rs->interval)
|
||||
if (!interval)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
|
@ -44,7 +50,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
|
|||
if (!rs->begin)
|
||||
rs->begin = jiffies;
|
||||
|
||||
if (time_is_before_jiffies(rs->begin + rs->interval)) {
|
||||
if (time_is_before_jiffies(rs->begin + interval)) {
|
||||
if (rs->missed) {
|
||||
if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) {
|
||||
printk_deferred(KERN_WARNING
|
||||
|
@ -56,7 +62,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
|
|||
rs->begin = jiffies;
|
||||
rs->printed = 0;
|
||||
}
|
||||
if (rs->burst && rs->burst > rs->printed) {
|
||||
if (burst && burst > rs->printed) {
|
||||
rs->printed++;
|
||||
ret = 1;
|
||||
} else {
|
||||
|
|
|
@ -36,18 +36,10 @@ static struct ebt_replace_kernel initial_table = {
|
|||
.entries = (char *)&initial_chain,
|
||||
};
|
||||
|
||||
static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
|
||||
{
|
||||
if (valid_hooks & ~(1 << NF_BR_BROUTING))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ebt_table broute_table = {
|
||||
.name = "broute",
|
||||
.table = &initial_table,
|
||||
.valid_hooks = 1 << NF_BR_BROUTING,
|
||||
.check = check,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
|
|
@ -43,18 +43,10 @@ static struct ebt_replace_kernel initial_table = {
|
|||
.entries = (char *)initial_chains,
|
||||
};
|
||||
|
||||
static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
|
||||
{
|
||||
if (valid_hooks & ~FILTER_VALID_HOOKS)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ebt_table frame_filter = {
|
||||
.name = "filter",
|
||||
.table = &initial_table,
|
||||
.valid_hooks = FILTER_VALID_HOOKS,
|
||||
.check = check,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
|
|
@ -43,18 +43,10 @@ static struct ebt_replace_kernel initial_table = {
|
|||
.entries = (char *)initial_chains,
|
||||
};
|
||||
|
||||
static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
|
||||
{
|
||||
if (valid_hooks & ~NAT_VALID_HOOKS)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ebt_table frame_nat = {
|
||||
.name = "nat",
|
||||
.table = &initial_table,
|
||||
.valid_hooks = NAT_VALID_HOOKS,
|
||||
.check = check,
|
||||
.me = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
|
|
@ -1040,8 +1040,7 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
|
|||
goto free_iterate;
|
||||
}
|
||||
|
||||
/* the table doesn't like it */
|
||||
if (t->check && (ret = t->check(newinfo, repl->valid_hooks)))
|
||||
if (repl->valid_hooks != t->valid_hooks)
|
||||
goto free_unlock;
|
||||
|
||||
if (repl->num_counters && repl->num_counters != t->private->nentries) {
|
||||
|
@ -1231,11 +1230,6 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
|
|||
if (ret != 0)
|
||||
goto free_chainstack;
|
||||
|
||||
if (table->check && table->check(newinfo, table->valid_hooks)) {
|
||||
ret = -EINVAL;
|
||||
goto free_chainstack;
|
||||
}
|
||||
|
||||
table->private = newinfo;
|
||||
rwlock_init(&table->lock);
|
||||
mutex_lock(&ebt_mutex);
|
||||
|
|
|
@ -310,11 +310,12 @@ BPF_CALL_2(bpf_sk_storage_delete, struct bpf_map *, map, struct sock *, sk)
|
|||
static int bpf_sk_storage_charge(struct bpf_local_storage_map *smap,
|
||||
void *owner, u32 size)
|
||||
{
|
||||
int optmem_max = READ_ONCE(sysctl_optmem_max);
|
||||
struct sock *sk = (struct sock *)owner;
|
||||
|
||||
/* same check as in sock_kmalloc() */
|
||||
if (size <= sysctl_optmem_max &&
|
||||
atomic_read(&sk->sk_omem_alloc) + size < sysctl_optmem_max) {
|
||||
if (size <= optmem_max &&
|
||||
atomic_read(&sk->sk_omem_alloc) + size < optmem_max) {
|
||||
atomic_add(size, &sk->sk_omem_alloc);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4624,7 +4624,7 @@ static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen)
|
|||
struct softnet_data *sd;
|
||||
unsigned int old_flow, new_flow;
|
||||
|
||||
if (qlen < (netdev_max_backlog >> 1))
|
||||
if (qlen < (READ_ONCE(netdev_max_backlog) >> 1))
|
||||
return false;
|
||||
|
||||
sd = this_cpu_ptr(&softnet_data);
|
||||
|
@ -4672,7 +4672,7 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu,
|
|||
if (!netif_running(skb->dev))
|
||||
goto drop;
|
||||
qlen = skb_queue_len(&sd->input_pkt_queue);
|
||||
if (qlen <= netdev_max_backlog && !skb_flow_limit(skb, qlen)) {
|
||||
if (qlen <= READ_ONCE(netdev_max_backlog) && !skb_flow_limit(skb, qlen)) {
|
||||
if (qlen) {
|
||||
enqueue:
|
||||
__skb_queue_tail(&sd->input_pkt_queue, skb);
|
||||
|
@ -4928,7 +4928,7 @@ static int netif_rx_internal(struct sk_buff *skb)
|
|||
{
|
||||
int ret;
|
||||
|
||||
net_timestamp_check(netdev_tstamp_prequeue, skb);
|
||||
net_timestamp_check(READ_ONCE(netdev_tstamp_prequeue), skb);
|
||||
|
||||
trace_netif_rx(skb);
|
||||
|
||||
|
@ -5281,7 +5281,7 @@ static int __netif_receive_skb_core(struct sk_buff **pskb, bool pfmemalloc,
|
|||
int ret = NET_RX_DROP;
|
||||
__be16 type;
|
||||
|
||||
net_timestamp_check(!netdev_tstamp_prequeue, skb);
|
||||
net_timestamp_check(!READ_ONCE(netdev_tstamp_prequeue), skb);
|
||||
|
||||
trace_netif_receive_skb(skb);
|
||||
|
||||
|
@ -5664,7 +5664,7 @@ static int netif_receive_skb_internal(struct sk_buff *skb)
|
|||
{
|
||||
int ret;
|
||||
|
||||
net_timestamp_check(netdev_tstamp_prequeue, skb);
|
||||
net_timestamp_check(READ_ONCE(netdev_tstamp_prequeue), skb);
|
||||
|
||||
if (skb_defer_rx_timestamp(skb))
|
||||
return NET_RX_SUCCESS;
|
||||
|
@ -5694,7 +5694,7 @@ void netif_receive_skb_list_internal(struct list_head *head)
|
|||
|
||||
INIT_LIST_HEAD(&sublist);
|
||||
list_for_each_entry_safe(skb, next, head, list) {
|
||||
net_timestamp_check(netdev_tstamp_prequeue, skb);
|
||||
net_timestamp_check(READ_ONCE(netdev_tstamp_prequeue), skb);
|
||||
skb_list_del_init(skb);
|
||||
if (!skb_defer_rx_timestamp(skb))
|
||||
list_add_tail(&skb->list, &sublist);
|
||||
|
@ -5918,7 +5918,7 @@ static int process_backlog(struct napi_struct *napi, int quota)
|
|||
net_rps_action_and_irq_enable(sd);
|
||||
}
|
||||
|
||||
napi->weight = dev_rx_weight;
|
||||
napi->weight = READ_ONCE(dev_rx_weight);
|
||||
while (again) {
|
||||
struct sk_buff *skb;
|
||||
|
||||
|
@ -6665,8 +6665,8 @@ static __latent_entropy void net_rx_action(struct softirq_action *h)
|
|||
{
|
||||
struct softnet_data *sd = this_cpu_ptr(&softnet_data);
|
||||
unsigned long time_limit = jiffies +
|
||||
usecs_to_jiffies(netdev_budget_usecs);
|
||||
int budget = netdev_budget;
|
||||
usecs_to_jiffies(READ_ONCE(netdev_budget_usecs));
|
||||
int budget = READ_ONCE(netdev_budget);
|
||||
LIST_HEAD(list);
|
||||
LIST_HEAD(repoll);
|
||||
|
||||
|
@ -10284,7 +10284,7 @@ static struct net_device *netdev_wait_allrefs_any(struct list_head *list)
|
|||
return dev;
|
||||
|
||||
if (time_after(jiffies, warning_time +
|
||||
netdev_unregister_timeout_secs * HZ)) {
|
||||
READ_ONCE(netdev_unregister_timeout_secs) * HZ)) {
|
||||
list_for_each_entry(dev, list, todo_list) {
|
||||
pr_emerg("unregister_netdevice: waiting for %s to become free. Usage count = %d\n",
|
||||
dev->name, netdev_refcnt_read(dev));
|
||||
|
|
|
@ -1214,10 +1214,11 @@ void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)
|
|||
static bool __sk_filter_charge(struct sock *sk, struct sk_filter *fp)
|
||||
{
|
||||
u32 filter_size = bpf_prog_size(fp->prog->len);
|
||||
int optmem_max = READ_ONCE(sysctl_optmem_max);
|
||||
|
||||
/* same check as in sock_kmalloc() */
|
||||
if (filter_size <= sysctl_optmem_max &&
|
||||
atomic_read(&sk->sk_omem_alloc) + filter_size < sysctl_optmem_max) {
|
||||
if (filter_size <= optmem_max &&
|
||||
atomic_read(&sk->sk_omem_alloc) + filter_size < optmem_max) {
|
||||
atomic_add(filter_size, &sk->sk_omem_alloc);
|
||||
return true;
|
||||
}
|
||||
|
@ -1548,7 +1549,7 @@ int sk_reuseport_attach_filter(struct sock_fprog *fprog, struct sock *sk)
|
|||
if (IS_ERR(prog))
|
||||
return PTR_ERR(prog);
|
||||
|
||||
if (bpf_prog_size(prog->len) > sysctl_optmem_max)
|
||||
if (bpf_prog_size(prog->len) > READ_ONCE(sysctl_optmem_max))
|
||||
err = -ENOMEM;
|
||||
else
|
||||
err = reuseport_attach_prog(sk, prog);
|
||||
|
@ -1615,7 +1616,7 @@ int sk_reuseport_attach_bpf(u32 ufd, struct sock *sk)
|
|||
}
|
||||
} else {
|
||||
/* BPF_PROG_TYPE_SOCKET_FILTER */
|
||||
if (bpf_prog_size(prog->len) > sysctl_optmem_max) {
|
||||
if (bpf_prog_size(prog->len) > READ_ONCE(sysctl_optmem_max)) {
|
||||
err = -ENOMEM;
|
||||
goto err_prog_put;
|
||||
}
|
||||
|
@ -5034,14 +5035,14 @@ static int __bpf_setsockopt(struct sock *sk, int level, int optname,
|
|||
/* Only some socketops are supported */
|
||||
switch (optname) {
|
||||
case SO_RCVBUF:
|
||||
val = min_t(u32, val, sysctl_rmem_max);
|
||||
val = min_t(u32, val, READ_ONCE(sysctl_rmem_max));
|
||||
val = min_t(int, val, INT_MAX / 2);
|
||||
sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
|
||||
WRITE_ONCE(sk->sk_rcvbuf,
|
||||
max_t(int, val * 2, SOCK_MIN_RCVBUF));
|
||||
break;
|
||||
case SO_SNDBUF:
|
||||
val = min_t(u32, val, sysctl_wmem_max);
|
||||
val = min_t(u32, val, READ_ONCE(sysctl_wmem_max));
|
||||
val = min_t(int, val, INT_MAX / 2);
|
||||
sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
|
||||
WRITE_ONCE(sk->sk_sndbuf,
|
||||
|
|
|
@ -26,7 +26,7 @@ int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
|
|||
|
||||
cell = this_cpu_ptr(gcells->cells);
|
||||
|
||||
if (skb_queue_len(&cell->napi_skbs) > netdev_max_backlog) {
|
||||
if (skb_queue_len(&cell->napi_skbs) > READ_ONCE(netdev_max_backlog)) {
|
||||
drop:
|
||||
dev_core_stats_rx_dropped_inc(dev);
|
||||
kfree_skb(skb);
|
||||
|
|
|
@ -309,14 +309,17 @@ static int neigh_del_timer(struct neighbour *n)
|
|||
|
||||
static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net)
|
||||
{
|
||||
struct sk_buff_head tmp;
|
||||
unsigned long flags;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb_queue_head_init(&tmp);
|
||||
spin_lock_irqsave(&list->lock, flags);
|
||||
skb = skb_peek(list);
|
||||
while (skb != NULL) {
|
||||
struct sk_buff *skb_next = skb_peek_next(skb, list);
|
||||
struct net_device *dev = skb->dev;
|
||||
|
||||
if (net == NULL || net_eq(dev_net(dev), net)) {
|
||||
struct in_device *in_dev;
|
||||
|
||||
|
@ -326,13 +329,16 @@ static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net)
|
|||
in_dev->arp_parms->qlen--;
|
||||
rcu_read_unlock();
|
||||
__skb_unlink(skb, list);
|
||||
|
||||
dev_put(dev);
|
||||
kfree_skb(skb);
|
||||
__skb_queue_tail(&tmp, skb);
|
||||
}
|
||||
skb = skb_next;
|
||||
}
|
||||
spin_unlock_irqrestore(&list->lock, flags);
|
||||
|
||||
while ((skb = __skb_dequeue(&tmp))) {
|
||||
dev_put(skb->dev);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
|
||||
static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev,
|
||||
|
|
|
@ -4205,9 +4205,8 @@ normal:
|
|||
SKB_GSO_CB(nskb)->csum_start =
|
||||
skb_headroom(nskb) + doffset;
|
||||
} else {
|
||||
skb_copy_bits(head_skb, offset,
|
||||
skb_put(nskb, len),
|
||||
len);
|
||||
if (skb_copy_bits(head_skb, offset, skb_put(nskb, len), len))
|
||||
goto err;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -4798,7 +4797,7 @@ static bool skb_may_tx_timestamp(struct sock *sk, bool tsonly)
|
|||
{
|
||||
bool ret;
|
||||
|
||||
if (likely(sysctl_tstamp_allow_data || tsonly))
|
||||
if (likely(READ_ONCE(sysctl_tstamp_allow_data) || tsonly))
|
||||
return true;
|
||||
|
||||
read_lock_bh(&sk->sk_callback_lock);
|
||||
|
|
|
@ -1101,7 +1101,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
|
|||
* play 'guess the biggest size' games. RCVBUF/SNDBUF
|
||||
* are treated in BSD as hints
|
||||
*/
|
||||
val = min_t(u32, val, sysctl_wmem_max);
|
||||
val = min_t(u32, val, READ_ONCE(sysctl_wmem_max));
|
||||
set_sndbuf:
|
||||
/* Ensure val * 2 fits into an int, to prevent max_t()
|
||||
* from treating it as a negative value.
|
||||
|
@ -1133,7 +1133,7 @@ set_sndbuf:
|
|||
* play 'guess the biggest size' games. RCVBUF/SNDBUF
|
||||
* are treated in BSD as hints
|
||||
*/
|
||||
__sock_set_rcvbuf(sk, min_t(u32, val, sysctl_rmem_max));
|
||||
__sock_set_rcvbuf(sk, min_t(u32, val, READ_ONCE(sysctl_rmem_max)));
|
||||
break;
|
||||
|
||||
case SO_RCVBUFFORCE:
|
||||
|
@ -2536,7 +2536,7 @@ struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size,
|
|||
|
||||
/* small safe race: SKB_TRUESIZE may differ from final skb->truesize */
|
||||
if (atomic_read(&sk->sk_omem_alloc) + SKB_TRUESIZE(size) >
|
||||
sysctl_optmem_max)
|
||||
READ_ONCE(sysctl_optmem_max))
|
||||
return NULL;
|
||||
|
||||
skb = alloc_skb(size, priority);
|
||||
|
@ -2554,8 +2554,10 @@ struct sk_buff *sock_omalloc(struct sock *sk, unsigned long size,
|
|||
*/
|
||||
void *sock_kmalloc(struct sock *sk, int size, gfp_t priority)
|
||||
{
|
||||
if ((unsigned int)size <= sysctl_optmem_max &&
|
||||
atomic_read(&sk->sk_omem_alloc) + size < sysctl_optmem_max) {
|
||||
int optmem_max = READ_ONCE(sysctl_optmem_max);
|
||||
|
||||
if ((unsigned int)size <= optmem_max &&
|
||||
atomic_read(&sk->sk_omem_alloc) + size < optmem_max) {
|
||||
void *mem;
|
||||
/* First do the add, to avoid the race if kmalloc
|
||||
* might sleep.
|
||||
|
@ -3309,8 +3311,8 @@ void sock_init_data(struct socket *sock, struct sock *sk)
|
|||
timer_setup(&sk->sk_timer, NULL, 0);
|
||||
|
||||
sk->sk_allocation = GFP_KERNEL;
|
||||
sk->sk_rcvbuf = sysctl_rmem_default;
|
||||
sk->sk_sndbuf = sysctl_wmem_default;
|
||||
sk->sk_rcvbuf = READ_ONCE(sysctl_rmem_default);
|
||||
sk->sk_sndbuf = READ_ONCE(sysctl_wmem_default);
|
||||
sk->sk_state = TCP_CLOSE;
|
||||
sk_set_socket(sk, sock);
|
||||
|
||||
|
@ -3365,7 +3367,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
|
|||
|
||||
#ifdef CONFIG_NET_RX_BUSY_POLL
|
||||
sk->sk_napi_id = 0;
|
||||
sk->sk_ll_usec = sysctl_net_busy_read;
|
||||
sk->sk_ll_usec = READ_ONCE(sysctl_net_busy_read);
|
||||
#endif
|
||||
|
||||
sk->sk_max_pacing_rate = ~0UL;
|
||||
|
|
|
@ -234,14 +234,17 @@ static int set_default_qdisc(struct ctl_table *table, int write,
|
|||
static int proc_do_dev_weight(struct ctl_table *table, int write,
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
static DEFINE_MUTEX(dev_weight_mutex);
|
||||
int ret, weight;
|
||||
|
||||
mutex_lock(&dev_weight_mutex);
|
||||
ret = proc_dointvec(table, write, buffer, lenp, ppos);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
dev_rx_weight = weight_p * dev_weight_rx_bias;
|
||||
dev_tx_weight = weight_p * dev_weight_tx_bias;
|
||||
if (!ret && write) {
|
||||
weight = READ_ONCE(weight_p);
|
||||
WRITE_ONCE(dev_rx_weight, weight * dev_weight_rx_bias);
|
||||
WRITE_ONCE(dev_tx_weight, weight * dev_weight_tx_bias);
|
||||
}
|
||||
mutex_unlock(&dev_weight_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -2484,7 +2484,7 @@ static int dsa_slave_changeupper(struct net_device *dev,
|
|||
if (!err)
|
||||
dsa_bridge_mtu_normalization(dp);
|
||||
if (err == -EOPNOTSUPP) {
|
||||
if (!extack->_msg)
|
||||
if (extack && !extack->_msg)
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Offloading not supported");
|
||||
err = 0;
|
||||
|
|
|
@ -2682,23 +2682,27 @@ static __net_init int devinet_init_net(struct net *net)
|
|||
#endif
|
||||
|
||||
if (!net_eq(net, &init_net)) {
|
||||
if (IS_ENABLED(CONFIG_SYSCTL) &&
|
||||
sysctl_devconf_inherit_init_net == 3) {
|
||||
switch (net_inherit_devconf()) {
|
||||
case 3:
|
||||
/* copy from the current netns */
|
||||
memcpy(all, current->nsproxy->net_ns->ipv4.devconf_all,
|
||||
sizeof(ipv4_devconf));
|
||||
memcpy(dflt,
|
||||
current->nsproxy->net_ns->ipv4.devconf_dflt,
|
||||
sizeof(ipv4_devconf_dflt));
|
||||
} else if (!IS_ENABLED(CONFIG_SYSCTL) ||
|
||||
sysctl_devconf_inherit_init_net != 2) {
|
||||
/* inherit == 0 or 1: copy from init_net */
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
/* copy from init_net */
|
||||
memcpy(all, init_net.ipv4.devconf_all,
|
||||
sizeof(ipv4_devconf));
|
||||
memcpy(dflt, init_net.ipv4.devconf_dflt,
|
||||
sizeof(ipv4_devconf_dflt));
|
||||
break;
|
||||
case 2:
|
||||
/* use compiled values */
|
||||
break;
|
||||
}
|
||||
/* else inherit == 2: use compiled values */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
|
|
|
@ -1730,7 +1730,7 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
|
|||
|
||||
sk->sk_protocol = ip_hdr(skb)->protocol;
|
||||
sk->sk_bound_dev_if = arg->bound_dev_if;
|
||||
sk->sk_sndbuf = sysctl_wmem_default;
|
||||
sk->sk_sndbuf = READ_ONCE(sysctl_wmem_default);
|
||||
ipc.sockc.mark = fl4.flowi4_mark;
|
||||
err = ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base,
|
||||
len, 0, &ipc, &rt, MSG_DONTWAIT);
|
||||
|
|
|
@ -772,7 +772,7 @@ static int ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval, int optlen)
|
|||
|
||||
if (optlen < GROUP_FILTER_SIZE(0))
|
||||
return -EINVAL;
|
||||
if (optlen > sysctl_optmem_max)
|
||||
if (optlen > READ_ONCE(sysctl_optmem_max))
|
||||
return -ENOBUFS;
|
||||
|
||||
gsf = memdup_sockptr(optval, optlen);
|
||||
|
@ -808,7 +808,7 @@ static int compat_ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval,
|
|||
|
||||
if (optlen < size0)
|
||||
return -EINVAL;
|
||||
if (optlen > sysctl_optmem_max - 4)
|
||||
if (optlen > READ_ONCE(sysctl_optmem_max) - 4)
|
||||
return -ENOBUFS;
|
||||
|
||||
p = kmalloc(optlen + 4, GFP_KERNEL);
|
||||
|
@ -1233,7 +1233,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, int optname,
|
|||
|
||||
if (optlen < IP_MSFILTER_SIZE(0))
|
||||
goto e_inval;
|
||||
if (optlen > sysctl_optmem_max) {
|
||||
if (optlen > READ_ONCE(sysctl_optmem_max)) {
|
||||
err = -ENOBUFS;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1000,7 +1000,7 @@ new_segment:
|
|||
|
||||
i = skb_shinfo(skb)->nr_frags;
|
||||
can_coalesce = skb_can_coalesce(skb, i, page, offset);
|
||||
if (!can_coalesce && i >= sysctl_max_skb_frags) {
|
||||
if (!can_coalesce && i >= READ_ONCE(sysctl_max_skb_frags)) {
|
||||
tcp_mark_push(tp, skb);
|
||||
goto new_segment;
|
||||
}
|
||||
|
@ -1354,7 +1354,7 @@ new_segment:
|
|||
|
||||
if (!skb_can_coalesce(skb, i, pfrag->page,
|
||||
pfrag->offset)) {
|
||||
if (i >= sysctl_max_skb_frags) {
|
||||
if (i >= READ_ONCE(sysctl_max_skb_frags)) {
|
||||
tcp_mark_push(tp, skb);
|
||||
goto new_segment;
|
||||
}
|
||||
|
|
|
@ -239,7 +239,7 @@ void tcp_select_initial_window(const struct sock *sk, int __space, __u32 mss,
|
|||
if (wscale_ok) {
|
||||
/* Set window scaling on max possible window */
|
||||
space = max_t(u32, space, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2]));
|
||||
space = max_t(u32, space, sysctl_rmem_max);
|
||||
space = max_t(u32, space, READ_ONCE(sysctl_rmem_max));
|
||||
space = min_t(u32, space, *window_clamp);
|
||||
*rcv_wscale = clamp_t(int, ilog2(space) - 15,
|
||||
0, TCP_MAX_WSCALE);
|
||||
|
|
|
@ -7162,9 +7162,8 @@ static int __net_init addrconf_init_net(struct net *net)
|
|||
if (!dflt)
|
||||
goto err_alloc_dflt;
|
||||
|
||||
if (IS_ENABLED(CONFIG_SYSCTL) &&
|
||||
!net_eq(net, &init_net)) {
|
||||
switch (sysctl_devconf_inherit_init_net) {
|
||||
if (!net_eq(net, &init_net)) {
|
||||
switch (net_inherit_devconf()) {
|
||||
case 1: /* copy from init_net */
|
||||
memcpy(all, init_net.ipv6.devconf_all,
|
||||
sizeof(ipv6_devconf));
|
||||
|
|
|
@ -210,7 +210,7 @@ static int ipv6_set_mcast_msfilter(struct sock *sk, sockptr_t optval,
|
|||
|
||||
if (optlen < GROUP_FILTER_SIZE(0))
|
||||
return -EINVAL;
|
||||
if (optlen > sysctl_optmem_max)
|
||||
if (optlen > READ_ONCE(sysctl_optmem_max))
|
||||
return -ENOBUFS;
|
||||
|
||||
gsf = memdup_sockptr(optval, optlen);
|
||||
|
@ -244,7 +244,7 @@ static int compat_ipv6_set_mcast_msfilter(struct sock *sk, sockptr_t optval,
|
|||
|
||||
if (optlen < size0)
|
||||
return -EINVAL;
|
||||
if (optlen > sysctl_optmem_max - 4)
|
||||
if (optlen > READ_ONCE(sysctl_optmem_max) - 4)
|
||||
return -ENOBUFS;
|
||||
|
||||
p = kmalloc(optlen + 4, GFP_KERNEL);
|
||||
|
|
|
@ -86,7 +86,6 @@ static int nf_ct_frag6_sysctl_register(struct net *net)
|
|||
table[1].extra2 = &nf_frag->fqdir->high_thresh;
|
||||
table[2].data = &nf_frag->fqdir->high_thresh;
|
||||
table[2].extra1 = &nf_frag->fqdir->low_thresh;
|
||||
table[2].extra2 = &nf_frag->fqdir->high_thresh;
|
||||
|
||||
hdr = register_net_sysctl(net, "net/netfilter", table);
|
||||
if (hdr == NULL)
|
||||
|
|
|
@ -1697,9 +1697,12 @@ static int pfkey_register(struct sock *sk, struct sk_buff *skb, const struct sad
|
|||
pfk->registered |= (1<<hdr->sadb_msg_satype);
|
||||
}
|
||||
|
||||
mutex_lock(&pfkey_mutex);
|
||||
xfrm_probe_algs();
|
||||
|
||||
supp_skb = compose_sadb_supported(hdr, GFP_KERNEL | __GFP_ZERO);
|
||||
mutex_unlock(&pfkey_mutex);
|
||||
|
||||
if (!supp_skb) {
|
||||
if (hdr->sadb_msg_satype != SADB_SATYPE_UNSPEC)
|
||||
pfk->registered &= ~(1<<hdr->sadb_msg_satype);
|
||||
|
|
|
@ -1263,7 +1263,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
|
|||
|
||||
i = skb_shinfo(skb)->nr_frags;
|
||||
can_coalesce = skb_can_coalesce(skb, i, dfrag->page, offset);
|
||||
if (!can_coalesce && i >= sysctl_max_skb_frags) {
|
||||
if (!can_coalesce && i >= READ_ONCE(sysctl_max_skb_frags)) {
|
||||
tcp_mark_push(tcp_sk(ssk), skb);
|
||||
goto alloc_skb;
|
||||
}
|
||||
|
|
|
@ -1280,12 +1280,12 @@ static void set_sock_size(struct sock *sk, int mode, int val)
|
|||
lock_sock(sk);
|
||||
if (mode) {
|
||||
val = clamp_t(int, val, (SOCK_MIN_SNDBUF + 1) / 2,
|
||||
sysctl_wmem_max);
|
||||
READ_ONCE(sysctl_wmem_max));
|
||||
sk->sk_sndbuf = val * 2;
|
||||
sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
|
||||
} else {
|
||||
val = clamp_t(int, val, (SOCK_MIN_RCVBUF + 1) / 2,
|
||||
sysctl_rmem_max);
|
||||
READ_ONCE(sysctl_rmem_max));
|
||||
sk->sk_rcvbuf = val * 2;
|
||||
sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
|
||||
}
|
||||
|
|
|
@ -655,6 +655,37 @@ static bool tcp_in_window(struct nf_conn *ct,
|
|||
tn->tcp_be_liberal)
|
||||
res = true;
|
||||
if (!res) {
|
||||
bool seq_ok = before(seq, sender->td_maxend + 1);
|
||||
|
||||
if (!seq_ok) {
|
||||
u32 overshot = end - sender->td_maxend + 1;
|
||||
bool ack_ok;
|
||||
|
||||
ack_ok = after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1);
|
||||
|
||||
if (in_recv_win &&
|
||||
ack_ok &&
|
||||
overshot <= receiver->td_maxwin &&
|
||||
before(sack, receiver->td_end + 1)) {
|
||||
/* Work around TCPs that send more bytes than allowed by
|
||||
* the receive window.
|
||||
*
|
||||
* If the (marked as invalid) packet is allowed to pass by
|
||||
* the ruleset and the peer acks this data, then its possible
|
||||
* all future packets will trigger 'ACK is over upper bound' check.
|
||||
*
|
||||
* Thus if only the sequence check fails then do update td_end so
|
||||
* possible ACK for this data can update internal state.
|
||||
*/
|
||||
sender->td_end = end;
|
||||
sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
|
||||
|
||||
nf_ct_l4proto_log_invalid(skb, ct, hook_state,
|
||||
"%u bytes more than expected", overshot);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
nf_ct_l4proto_log_invalid(skb, ct, hook_state,
|
||||
"%s",
|
||||
before(seq, sender->td_maxend + 1) ?
|
||||
|
|
|
@ -437,12 +437,17 @@ static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table,
|
|||
}
|
||||
}
|
||||
|
||||
void nf_flow_table_gc_run(struct nf_flowtable *flow_table)
|
||||
{
|
||||
nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL);
|
||||
}
|
||||
|
||||
static void nf_flow_offload_work_gc(struct work_struct *work)
|
||||
{
|
||||
struct nf_flowtable *flow_table;
|
||||
|
||||
flow_table = container_of(work, struct nf_flowtable, gc_work.work);
|
||||
nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL);
|
||||
nf_flow_table_gc_run(flow_table);
|
||||
queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ);
|
||||
}
|
||||
|
||||
|
@ -600,11 +605,11 @@ void nf_flow_table_free(struct nf_flowtable *flow_table)
|
|||
mutex_unlock(&flowtable_lock);
|
||||
|
||||
cancel_delayed_work_sync(&flow_table->gc_work);
|
||||
nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL);
|
||||
nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL);
|
||||
nf_flow_table_offload_flush(flow_table);
|
||||
if (nf_flowtable_hw_offload(flow_table))
|
||||
nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL);
|
||||
/* ... no more pending work after this stage ... */
|
||||
nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL);
|
||||
nf_flow_table_gc_run(flow_table);
|
||||
nf_flow_table_offload_flush_cleanup(flow_table);
|
||||
rhashtable_destroy(&flow_table->rhashtable);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_flow_table_free);
|
||||
|
|
|
@ -1074,6 +1074,14 @@ void nf_flow_offload_stats(struct nf_flowtable *flowtable,
|
|||
flow_offload_queue_work(offload);
|
||||
}
|
||||
|
||||
void nf_flow_table_offload_flush_cleanup(struct nf_flowtable *flowtable)
|
||||
{
|
||||
if (nf_flowtable_hw_offload(flowtable)) {
|
||||
flush_workqueue(nf_flow_offload_del_wq);
|
||||
nf_flow_table_gc_run(flowtable);
|
||||
}
|
||||
}
|
||||
|
||||
void nf_flow_table_offload_flush(struct nf_flowtable *flowtable)
|
||||
{
|
||||
if (nf_flowtable_hw_offload(flowtable)) {
|
||||
|
|
|
@ -32,7 +32,6 @@ static LIST_HEAD(nf_tables_objects);
|
|||
static LIST_HEAD(nf_tables_flowtables);
|
||||
static LIST_HEAD(nf_tables_destroy_list);
|
||||
static DEFINE_SPINLOCK(nf_tables_destroy_list_lock);
|
||||
static u64 table_handle;
|
||||
|
||||
enum {
|
||||
NFT_VALIDATE_SKIP = 0,
|
||||
|
@ -1235,7 +1234,7 @@ static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info,
|
|||
INIT_LIST_HEAD(&table->flowtables);
|
||||
table->family = family;
|
||||
table->flags = flags;
|
||||
table->handle = ++table_handle;
|
||||
table->handle = ++nft_net->table_handle;
|
||||
if (table->flags & NFT_TABLE_F_OWNER)
|
||||
table->nlpid = NETLINK_CB(skb).portid;
|
||||
|
||||
|
@ -2196,9 +2195,9 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
|
|||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
const struct nlattr * const *nla = ctx->nla;
|
||||
struct nft_stats __percpu *stats = NULL;
|
||||
struct nft_table *table = ctx->table;
|
||||
struct nft_base_chain *basechain;
|
||||
struct nft_stats __percpu *stats;
|
||||
struct net *net = ctx->net;
|
||||
char name[NFT_NAME_MAXLEN];
|
||||
struct nft_rule_blob *blob;
|
||||
|
@ -2236,7 +2235,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
|
|||
return PTR_ERR(stats);
|
||||
}
|
||||
rcu_assign_pointer(basechain->stats, stats);
|
||||
static_branch_inc(&nft_counters_enabled);
|
||||
}
|
||||
|
||||
err = nft_basechain_init(basechain, family, &hook, flags);
|
||||
|
@ -2319,6 +2317,9 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
|
|||
goto err_unregister_hook;
|
||||
}
|
||||
|
||||
if (stats)
|
||||
static_branch_inc(&nft_counters_enabled);
|
||||
|
||||
table->use++;
|
||||
|
||||
return 0;
|
||||
|
@ -2574,6 +2575,9 @@ static int nf_tables_newchain(struct sk_buff *skb, const struct nfnl_info *info,
|
|||
nft_ctx_init(&ctx, net, skb, info->nlh, family, table, chain, nla);
|
||||
|
||||
if (chain != NULL) {
|
||||
if (chain->flags & NFT_CHAIN_BINDING)
|
||||
return -EINVAL;
|
||||
|
||||
if (info->nlh->nlmsg_flags & NLM_F_EXCL) {
|
||||
NL_SET_BAD_ATTR(extack, attr);
|
||||
return -EEXIST;
|
||||
|
@ -9707,6 +9711,8 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
|
|||
return PTR_ERR(chain);
|
||||
if (nft_is_base_chain(chain))
|
||||
return -EOPNOTSUPP;
|
||||
if (nft_chain_is_bound(chain))
|
||||
return -EINVAL;
|
||||
if (desc->flags & NFT_DATA_DESC_SETELEM &&
|
||||
chain->flags & NFT_CHAIN_BINDING)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -115,9 +115,21 @@ static int nft_osf_validate(const struct nft_ctx *ctx,
|
|||
const struct nft_expr *expr,
|
||||
const struct nft_data **data)
|
||||
{
|
||||
return nft_chain_validate_hooks(ctx->chain, (1 << NF_INET_LOCAL_IN) |
|
||||
(1 << NF_INET_PRE_ROUTING) |
|
||||
(1 << NF_INET_FORWARD));
|
||||
unsigned int hooks;
|
||||
|
||||
switch (ctx->family) {
|
||||
case NFPROTO_IPV4:
|
||||
case NFPROTO_IPV6:
|
||||
case NFPROTO_INET:
|
||||
hooks = (1 << NF_INET_LOCAL_IN) |
|
||||
(1 << NF_INET_PRE_ROUTING) |
|
||||
(1 << NF_INET_FORWARD);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return nft_chain_validate_hooks(ctx->chain, hooks);
|
||||
}
|
||||
|
||||
static bool nft_osf_reduce(struct nft_regs_track *track,
|
||||
|
|
|
@ -740,17 +740,23 @@ static int nft_payload_set_init(const struct nft_ctx *ctx,
|
|||
const struct nlattr * const tb[])
|
||||
{
|
||||
struct nft_payload_set *priv = nft_expr_priv(expr);
|
||||
u32 csum_offset, csum_type = NFT_PAYLOAD_CSUM_NONE;
|
||||
int err;
|
||||
|
||||
priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
|
||||
priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
|
||||
priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
|
||||
|
||||
if (tb[NFTA_PAYLOAD_CSUM_TYPE])
|
||||
priv->csum_type =
|
||||
ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_TYPE]));
|
||||
if (tb[NFTA_PAYLOAD_CSUM_OFFSET])
|
||||
priv->csum_offset =
|
||||
ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_OFFSET]));
|
||||
csum_type = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_CSUM_TYPE]));
|
||||
if (tb[NFTA_PAYLOAD_CSUM_OFFSET]) {
|
||||
err = nft_parse_u32_check(tb[NFTA_PAYLOAD_CSUM_OFFSET], U8_MAX,
|
||||
&csum_offset);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
priv->csum_offset = csum_offset;
|
||||
}
|
||||
if (tb[NFTA_PAYLOAD_CSUM_FLAGS]) {
|
||||
u32 flags;
|
||||
|
||||
|
@ -761,7 +767,7 @@ static int nft_payload_set_init(const struct nft_ctx *ctx,
|
|||
priv->csum_flags = flags;
|
||||
}
|
||||
|
||||
switch (priv->csum_type) {
|
||||
switch (csum_type) {
|
||||
case NFT_PAYLOAD_CSUM_NONE:
|
||||
case NFT_PAYLOAD_CSUM_INET:
|
||||
break;
|
||||
|
@ -775,6 +781,7 @@ static int nft_payload_set_init(const struct nft_ctx *ctx,
|
|||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
priv->csum_type = csum_type;
|
||||
|
||||
return nft_parse_register_load(tb[NFTA_PAYLOAD_SREG], &priv->sreg,
|
||||
priv->len);
|
||||
|
@ -833,6 +840,7 @@ nft_payload_select_ops(const struct nft_ctx *ctx,
|
|||
{
|
||||
enum nft_payload_bases base;
|
||||
unsigned int offset, len;
|
||||
int err;
|
||||
|
||||
if (tb[NFTA_PAYLOAD_BASE] == NULL ||
|
||||
tb[NFTA_PAYLOAD_OFFSET] == NULL ||
|
||||
|
@ -859,8 +867,13 @@ nft_payload_select_ops(const struct nft_ctx *ctx,
|
|||
if (tb[NFTA_PAYLOAD_DREG] == NULL)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
|
||||
len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
|
||||
err = nft_parse_u32_check(tb[NFTA_PAYLOAD_OFFSET], U8_MAX, &offset);
|
||||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
|
||||
err = nft_parse_u32_check(tb[NFTA_PAYLOAD_LEN], U8_MAX, &len);
|
||||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
|
||||
if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) &&
|
||||
base != NFT_PAYLOAD_LL_HEADER && base != NFT_PAYLOAD_INNER_HEADER)
|
||||
|
|
|
@ -312,6 +312,13 @@ static int nft_tproxy_dump(struct sk_buff *skb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int nft_tproxy_validate(const struct nft_ctx *ctx,
|
||||
const struct nft_expr *expr,
|
||||
const struct nft_data **data)
|
||||
{
|
||||
return nft_chain_validate_hooks(ctx->chain, 1 << NF_INET_PRE_ROUTING);
|
||||
}
|
||||
|
||||
static struct nft_expr_type nft_tproxy_type;
|
||||
static const struct nft_expr_ops nft_tproxy_ops = {
|
||||
.type = &nft_tproxy_type,
|
||||
|
@ -321,6 +328,7 @@ static const struct nft_expr_ops nft_tproxy_ops = {
|
|||
.destroy = nft_tproxy_destroy,
|
||||
.dump = nft_tproxy_dump,
|
||||
.reduce = NFT_REDUCE_READONLY,
|
||||
.validate = nft_tproxy_validate,
|
||||
};
|
||||
|
||||
static struct nft_expr_type nft_tproxy_type __read_mostly = {
|
||||
|
|
|
@ -161,6 +161,7 @@ static const struct nft_expr_ops nft_tunnel_get_ops = {
|
|||
|
||||
static struct nft_expr_type nft_tunnel_type __read_mostly = {
|
||||
.name = "tunnel",
|
||||
.family = NFPROTO_NETDEV,
|
||||
.ops = &nft_tunnel_get_ops,
|
||||
.policy = nft_tunnel_policy,
|
||||
.maxattr = NFTA_TUNNEL_MAX,
|
||||
|
|
|
@ -96,7 +96,8 @@ static void rose_loopback_timer(struct timer_list *unused)
|
|||
}
|
||||
|
||||
if (frametype == ROSE_CALL_REQUEST) {
|
||||
if (!rose_loopback_neigh->dev) {
|
||||
if (!rose_loopback_neigh->dev &&
|
||||
!rose_loopback_neigh->loopback) {
|
||||
kfree_skb(skb);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -285,8 +285,10 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
|
|||
_enter("%p,%lx", rx, p->user_call_ID);
|
||||
|
||||
limiter = rxrpc_get_call_slot(p, gfp);
|
||||
if (!limiter)
|
||||
if (!limiter) {
|
||||
release_sock(&rx->sk);
|
||||
return ERR_PTR(-ERESTARTSYS);
|
||||
}
|
||||
|
||||
call = rxrpc_alloc_client_call(rx, srx, gfp, debug_id);
|
||||
if (IS_ERR(call)) {
|
||||
|
|
|
@ -51,10 +51,7 @@ static int rxrpc_wait_for_tx_window_intr(struct rxrpc_sock *rx,
|
|||
return sock_intr_errno(*timeo);
|
||||
|
||||
trace_rxrpc_transmit(call, rxrpc_transmit_wait);
|
||||
mutex_unlock(&call->user_mutex);
|
||||
*timeo = schedule_timeout(*timeo);
|
||||
if (mutex_lock_interruptible(&call->user_mutex) < 0)
|
||||
return sock_intr_errno(*timeo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,37 +287,48 @@ out:
|
|||
static int rxrpc_send_data(struct rxrpc_sock *rx,
|
||||
struct rxrpc_call *call,
|
||||
struct msghdr *msg, size_t len,
|
||||
rxrpc_notify_end_tx_t notify_end_tx)
|
||||
rxrpc_notify_end_tx_t notify_end_tx,
|
||||
bool *_dropped_lock)
|
||||
{
|
||||
struct rxrpc_skb_priv *sp;
|
||||
struct sk_buff *skb;
|
||||
struct sock *sk = &rx->sk;
|
||||
enum rxrpc_call_state state;
|
||||
long timeo;
|
||||
bool more;
|
||||
int ret, copied;
|
||||
bool more = msg->msg_flags & MSG_MORE;
|
||||
int ret, copied = 0;
|
||||
|
||||
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
|
||||
|
||||
/* this should be in poll */
|
||||
sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
|
||||
|
||||
reload:
|
||||
ret = -EPIPE;
|
||||
if (sk->sk_shutdown & SEND_SHUTDOWN)
|
||||
return -EPIPE;
|
||||
|
||||
more = msg->msg_flags & MSG_MORE;
|
||||
goto maybe_error;
|
||||
state = READ_ONCE(call->state);
|
||||
ret = -ESHUTDOWN;
|
||||
if (state >= RXRPC_CALL_COMPLETE)
|
||||
goto maybe_error;
|
||||
ret = -EPROTO;
|
||||
if (state != RXRPC_CALL_CLIENT_SEND_REQUEST &&
|
||||
state != RXRPC_CALL_SERVER_ACK_REQUEST &&
|
||||
state != RXRPC_CALL_SERVER_SEND_REPLY)
|
||||
goto maybe_error;
|
||||
|
||||
ret = -EMSGSIZE;
|
||||
if (call->tx_total_len != -1) {
|
||||
if (len > call->tx_total_len)
|
||||
return -EMSGSIZE;
|
||||
if (!more && len != call->tx_total_len)
|
||||
return -EMSGSIZE;
|
||||
if (len - copied > call->tx_total_len)
|
||||
goto maybe_error;
|
||||
if (!more && len - copied != call->tx_total_len)
|
||||
goto maybe_error;
|
||||
}
|
||||
|
||||
skb = call->tx_pending;
|
||||
call->tx_pending = NULL;
|
||||
rxrpc_see_skb(skb, rxrpc_skb_seen);
|
||||
|
||||
copied = 0;
|
||||
do {
|
||||
/* Check to see if there's a ping ACK to reply to. */
|
||||
if (call->ackr_reason == RXRPC_ACK_PING_RESPONSE)
|
||||
|
@ -331,16 +339,8 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
|
|||
|
||||
_debug("alloc");
|
||||
|
||||
if (!rxrpc_check_tx_space(call, NULL)) {
|
||||
ret = -EAGAIN;
|
||||
if (msg->msg_flags & MSG_DONTWAIT)
|
||||
goto maybe_error;
|
||||
ret = rxrpc_wait_for_tx_window(rx, call,
|
||||
&timeo,
|
||||
msg->msg_flags & MSG_WAITALL);
|
||||
if (ret < 0)
|
||||
goto maybe_error;
|
||||
}
|
||||
if (!rxrpc_check_tx_space(call, NULL))
|
||||
goto wait_for_space;
|
||||
|
||||
/* Work out the maximum size of a packet. Assume that
|
||||
* the security header is going to be in the padded
|
||||
|
@ -468,6 +468,27 @@ maybe_error:
|
|||
efault:
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
|
||||
wait_for_space:
|
||||
ret = -EAGAIN;
|
||||
if (msg->msg_flags & MSG_DONTWAIT)
|
||||
goto maybe_error;
|
||||
mutex_unlock(&call->user_mutex);
|
||||
*_dropped_lock = true;
|
||||
ret = rxrpc_wait_for_tx_window(rx, call, &timeo,
|
||||
msg->msg_flags & MSG_WAITALL);
|
||||
if (ret < 0)
|
||||
goto maybe_error;
|
||||
if (call->interruptibility == RXRPC_INTERRUPTIBLE) {
|
||||
if (mutex_lock_interruptible(&call->user_mutex) < 0) {
|
||||
ret = sock_intr_errno(timeo);
|
||||
goto maybe_error;
|
||||
}
|
||||
} else {
|
||||
mutex_lock(&call->user_mutex);
|
||||
}
|
||||
*_dropped_lock = false;
|
||||
goto reload;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -629,6 +650,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
|
|||
enum rxrpc_call_state state;
|
||||
struct rxrpc_call *call;
|
||||
unsigned long now, j;
|
||||
bool dropped_lock = false;
|
||||
int ret;
|
||||
|
||||
struct rxrpc_send_params p = {
|
||||
|
@ -737,21 +759,13 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
|
|||
ret = rxrpc_send_abort_packet(call);
|
||||
} else if (p.command != RXRPC_CMD_SEND_DATA) {
|
||||
ret = -EINVAL;
|
||||
} else if (rxrpc_is_client_call(call) &&
|
||||
state != RXRPC_CALL_CLIENT_SEND_REQUEST) {
|
||||
/* request phase complete for this client call */
|
||||
ret = -EPROTO;
|
||||
} else if (rxrpc_is_service_call(call) &&
|
||||
state != RXRPC_CALL_SERVER_ACK_REQUEST &&
|
||||
state != RXRPC_CALL_SERVER_SEND_REPLY) {
|
||||
/* Reply phase not begun or not complete for service call. */
|
||||
ret = -EPROTO;
|
||||
} else {
|
||||
ret = rxrpc_send_data(rx, call, msg, len, NULL);
|
||||
ret = rxrpc_send_data(rx, call, msg, len, NULL, &dropped_lock);
|
||||
}
|
||||
|
||||
out_put_unlock:
|
||||
mutex_unlock(&call->user_mutex);
|
||||
if (!dropped_lock)
|
||||
mutex_unlock(&call->user_mutex);
|
||||
error_put:
|
||||
rxrpc_put_call(call, rxrpc_call_put);
|
||||
_leave(" = %d", ret);
|
||||
|
@ -779,6 +793,7 @@ int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call,
|
|||
struct msghdr *msg, size_t len,
|
||||
rxrpc_notify_end_tx_t notify_end_tx)
|
||||
{
|
||||
bool dropped_lock = false;
|
||||
int ret;
|
||||
|
||||
_enter("{%d,%s},", call->debug_id, rxrpc_call_states[call->state]);
|
||||
|
@ -796,7 +811,7 @@ int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call,
|
|||
case RXRPC_CALL_SERVER_ACK_REQUEST:
|
||||
case RXRPC_CALL_SERVER_SEND_REPLY:
|
||||
ret = rxrpc_send_data(rxrpc_sk(sock->sk), call, msg, len,
|
||||
notify_end_tx);
|
||||
notify_end_tx, &dropped_lock);
|
||||
break;
|
||||
case RXRPC_CALL_COMPLETE:
|
||||
read_lock_bh(&call->state_lock);
|
||||
|
@ -810,7 +825,8 @@ int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call,
|
|||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&call->user_mutex);
|
||||
if (!dropped_lock)
|
||||
mutex_unlock(&call->user_mutex);
|
||||
_leave(" = %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue