mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-16 17:57:38 -04:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Merge in late fixes in preparation for the net-next PR. Conflicts: net/tls/tls_sw.c406e8a651a("net: skmsg: preserve sg.copy across SG transforms")79511603a6("tls: remove dead sockmap (psock) handling from the SW path") drivers/net/ethernet/microsoft/mana/mana_en.cf8fd56977e("net: mana: guard TX wq object destroy with INVALID_MANA_HANDLE check")d07efe5a6e("net: mana: Use per-queue allocation for tx_qp to reduce allocation size") https://lore.kernel.org/ajAPXu-C_PuTgV-a@sirena.org.uk No adjacent changes. Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
1
.mailmap
1
.mailmap
@@ -402,6 +402,7 @@ Jesper Dangaard Brouer <hawk@kernel.org> <hawk@comx.dk>
|
||||
Jesper Dangaard Brouer <hawk@kernel.org> <jbrouer@redhat.com>
|
||||
Jesper Dangaard Brouer <hawk@kernel.org> <jdb@comx.dk>
|
||||
Jesper Dangaard Brouer <hawk@kernel.org> <netoptimizer@brouer.com>
|
||||
Jesse Brandeburg <jbrandeb@kernel.org> <jesse.brandeburg@intel.com>
|
||||
Jessica Zhang <jesszhan0024@gmail.com> <jesszhan@codeaurora.org>
|
||||
Jessica Zhang <jesszhan0024@gmail.com> <quic_jesszhan@quicinc.com>
|
||||
Jessica Zhang <jesszhan0024@gmail.com> <jessica.zhang@oss.qualcomm.com>
|
||||
|
||||
@@ -67,7 +67,7 @@ examples:
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <ð0_pins>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
|
||||
local-mac-address = [04 05 06 01 02 03];
|
||||
spi-max-frequency = <15000000>;
|
||||
};
|
||||
|
||||
@@ -429,7 +429,8 @@ qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int p
|
||||
init_data.fwnode = led;
|
||||
init_data.devname_mandatory = true;
|
||||
init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d",
|
||||
priv->internal_mdio_bus->id,
|
||||
priv->internal_mdio_bus ?
|
||||
priv->internal_mdio_bus->id : priv->bus->id,
|
||||
port_num);
|
||||
if (!init_data.devicename) {
|
||||
fwnode_handle_put(led);
|
||||
|
||||
@@ -361,7 +361,7 @@ static void airoha_fe_pse_ports_init(struct airoha_eth *eth)
|
||||
PSE_QUEUE_RSV_PAGES);
|
||||
/* PPE1 */
|
||||
for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_PPE1]; q++) {
|
||||
if (q < pse_port_num_queues[FE_PSE_PORT_PPE1])
|
||||
if (q < pse_port_num_queues[FE_PSE_PORT_PPE1] / 2)
|
||||
airoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q,
|
||||
PSE_QUEUE_RSV_PAGES);
|
||||
else
|
||||
@@ -1331,7 +1331,7 @@ static void airoha_qdma_init_qos_stats(struct airoha_qdma *qdma)
|
||||
FIELD_PREP(CNTR_CHAN_MASK, i));
|
||||
/* Tx-fwd transferred count */
|
||||
airoha_qdma_wr(qdma, REG_CNTR_VAL((i << 1) + 1), 0);
|
||||
airoha_qdma_wr(qdma, REG_CNTR_CFG(i << 1),
|
||||
airoha_qdma_wr(qdma, REG_CNTR_CFG((i << 1) + 1),
|
||||
CNTR_EN_MASK | CNTR_ALL_QUEUE_EN_MASK |
|
||||
CNTR_ALL_DSCP_RING_EN_MASK |
|
||||
FIELD_PREP(CNTR_SRC_MASK, 1) |
|
||||
|
||||
@@ -1354,7 +1354,7 @@ static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe)
|
||||
{
|
||||
u32 sram_num_entries = airoha_ppe_get_total_sram_num_entries(ppe);
|
||||
struct airoha_foe_entry *hwe = ppe->foe;
|
||||
int i, err = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sram_num_entries; i++) {
|
||||
int err;
|
||||
@@ -1362,10 +1362,10 @@ static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe)
|
||||
memset(&hwe[i], 0, sizeof(*hwe));
|
||||
err = airoha_ppe_foe_commit_sram_entry(ppe, i);
|
||||
if (err)
|
||||
break;
|
||||
return err;
|
||||
}
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth)
|
||||
|
||||
@@ -121,8 +121,6 @@ static int airoha_ppe_debugfs_foe_show(struct seq_file *m, void *private,
|
||||
case PPE_PKT_TYPE_IPV4_DSLITE:
|
||||
src_port = &hwe->ipv4.new_tuple.src_port;
|
||||
dest_port = &hwe->ipv4.new_tuple.dest_port;
|
||||
fallthrough;
|
||||
case PPE_PKT_TYPE_IPV4_ROUTE:
|
||||
src_addr = &hwe->ipv4.new_tuple.src_ip;
|
||||
dest_addr = &hwe->ipv4.new_tuple.dest_ip;
|
||||
seq_puts(m, " new=");
|
||||
|
||||
@@ -1011,6 +1011,7 @@ int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
||||
mapping += bp->rx_dma_offset;
|
||||
rx_buf->data = page;
|
||||
rx_buf->data_ptr = page_address(page) + offset + bp->rx_offset;
|
||||
rx_buf->offset = offset;
|
||||
} else {
|
||||
u8 *data = __bnxt_alloc_rx_frag(bp, &mapping, rxr, gfp);
|
||||
|
||||
@@ -1019,6 +1020,7 @@ int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
||||
|
||||
rx_buf->data = data;
|
||||
rx_buf->data_ptr = data + bp->rx_offset;
|
||||
rx_buf->offset = 0;
|
||||
}
|
||||
rx_buf->mapping = mapping;
|
||||
|
||||
@@ -1040,6 +1042,7 @@ void bnxt_reuse_rx_data(struct bnxt_rx_ring_info *rxr, u16 cons, void *data)
|
||||
prod_rx_buf->data_ptr = cons_rx_buf->data_ptr;
|
||||
|
||||
prod_rx_buf->mapping = cons_rx_buf->mapping;
|
||||
prod_rx_buf->offset = cons_rx_buf->offset;
|
||||
|
||||
prod_bd = &rxr->rx_desc_ring[RX_RING(bp, prod)][RX_IDX(prod)];
|
||||
cons_bd = &rxr->rx_desc_ring[RX_RING(bp, cons)][RX_IDX(cons)];
|
||||
@@ -1175,8 +1178,11 @@ static struct sk_buff *bnxt_rx_multi_page_skb(struct bnxt *bp,
|
||||
struct page *page = data;
|
||||
u16 prod = rxr->rx_prod;
|
||||
struct sk_buff *skb;
|
||||
void *frag_start;
|
||||
int err;
|
||||
|
||||
frag_start = page_address(page) + rxr->rx_buf_ring[cons].offset;
|
||||
|
||||
err = bnxt_alloc_rx_data(bp, rxr, prod, GFP_ATOMIC);
|
||||
if (unlikely(err)) {
|
||||
bnxt_reuse_rx_data(rxr, cons, data);
|
||||
@@ -1185,13 +1191,13 @@ static struct sk_buff *bnxt_rx_multi_page_skb(struct bnxt *bp,
|
||||
dma_addr -= bp->rx_dma_offset;
|
||||
dma_sync_single_for_cpu(&bp->pdev->dev, dma_addr, rxr->rx_page_size,
|
||||
bp->rx_dir);
|
||||
skb = napi_build_skb(data_ptr - bp->rx_offset, rxr->rx_page_size);
|
||||
skb = napi_build_skb(frag_start, rxr->rx_page_size);
|
||||
if (!skb) {
|
||||
page_pool_recycle_direct(rxr->page_pool, page);
|
||||
return NULL;
|
||||
}
|
||||
skb_mark_for_recycle(skb);
|
||||
skb_reserve(skb, bp->rx_offset);
|
||||
skb_reserve(skb, data_ptr - (u8 *)frag_start);
|
||||
__skb_put(skb, len);
|
||||
|
||||
return skb;
|
||||
|
||||
@@ -911,6 +911,7 @@ struct bnxt_sw_rx_bd {
|
||||
void *data;
|
||||
u8 *data_ptr;
|
||||
dma_addr_t mapping;
|
||||
unsigned int offset;
|
||||
};
|
||||
|
||||
struct bnxt_sw_rx_agg_bd {
|
||||
|
||||
@@ -40,9 +40,8 @@
|
||||
|
||||
#include "bcmgenet.h"
|
||||
|
||||
/* Default highest priority queue for multi queue support */
|
||||
#define GENET_Q1_PRIORITY 0
|
||||
#define GENET_Q0_PRIORITY 1
|
||||
#define GENET_Q0_WEIGHT 1
|
||||
#define GENET_Q1_WEIGHT 4
|
||||
|
||||
#define GENET_Q0_RX_BD_CNT \
|
||||
(TOTAL_DESC - priv->hw_params->rx_queues * priv->hw_params->rx_bds_per_q)
|
||||
@@ -2126,13 +2125,6 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
int i;
|
||||
|
||||
index = skb_get_queue_mapping(skb);
|
||||
/* Mapping strategy:
|
||||
* queue_mapping = 0, unclassified, packet xmited through ring 0
|
||||
* queue_mapping = 1, goes to ring 1. (highest priority queue)
|
||||
* queue_mapping = 2, goes to ring 2.
|
||||
* queue_mapping = 3, goes to ring 3.
|
||||
* queue_mapping = 4, goes to ring 4.
|
||||
*/
|
||||
ring = &priv->tx_rings[index];
|
||||
txq = netdev_get_tx_queue(dev, index);
|
||||
|
||||
@@ -2921,8 +2913,9 @@ static int bcmgenet_rdma_disable(struct bcmgenet_priv *priv)
|
||||
|
||||
/* Initialize Tx queues
|
||||
*
|
||||
* Queues 1-4 are priority-based, each one has 32 descriptors,
|
||||
* with queue 1 being the highest priority queue.
|
||||
* Queues 1-4 are the priority queues, each one has 32 descriptors.
|
||||
* The weighted round-robin arbiter gives them a larger share of TX
|
||||
* bandwidth than the default queue 0.
|
||||
*
|
||||
* Queue 0 is the default Tx queue with
|
||||
* GENET_Q0_TX_BD_CNT = 256 - 4 * 32 = 128 descriptors.
|
||||
@@ -2940,8 +2933,8 @@ static void bcmgenet_init_tx_queues(struct net_device *dev)
|
||||
unsigned int start = 0, end = GENET_Q0_TX_BD_CNT;
|
||||
u32 i, ring_mask, dma_priority[3] = {0, 0, 0};
|
||||
|
||||
/* Enable strict priority arbiter mode */
|
||||
bcmgenet_tdma_writel(priv, DMA_ARBITER_SP, DMA_ARB_CTRL);
|
||||
/* Enable Weighted Round-Robin arbiter mode */
|
||||
bcmgenet_tdma_writel(priv, DMA_ARBITER_WRR, DMA_ARB_CTRL);
|
||||
|
||||
/* Initialize Tx priority queues */
|
||||
for (i = 0; i <= priv->hw_params->tx_queues; i++) {
|
||||
@@ -2949,7 +2942,7 @@ static void bcmgenet_init_tx_queues(struct net_device *dev)
|
||||
start = end;
|
||||
end += priv->hw_params->tx_bds_per_q;
|
||||
dma_priority[DMA_PRIO_REG_INDEX(i)] |=
|
||||
(i ? GENET_Q1_PRIORITY : GENET_Q0_PRIORITY)
|
||||
(i ? GENET_Q1_WEIGHT : GENET_Q0_WEIGHT)
|
||||
<< DMA_PRIO_REG_SHIFT(i);
|
||||
}
|
||||
|
||||
|
||||
@@ -1572,13 +1572,15 @@ VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_ptp_get_vport_tx_tstamp_latches);
|
||||
* struct virtchnl2_ptp_get_dev_clk_time - Associated with message
|
||||
* VIRTCHNL2_OP_PTP_GET_DEV_CLK_TIME.
|
||||
* @dev_time_ns: Device clock time value in nanoseconds
|
||||
* @pad: Padding for future extensions
|
||||
*
|
||||
* PF/VF sends this message to receive the time from the main timer.
|
||||
*/
|
||||
struct virtchnl2_ptp_get_dev_clk_time {
|
||||
__le64 dev_time_ns;
|
||||
u8 pad[8];
|
||||
};
|
||||
VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_ptp_get_dev_clk_time);
|
||||
VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_ptp_get_dev_clk_time);
|
||||
|
||||
/**
|
||||
* struct virtchnl2_ptp_get_cross_time: Associated with message
|
||||
@@ -1586,26 +1588,30 @@ VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_ptp_get_dev_clk_time);
|
||||
* @sys_time_ns: System counter value expressed in nanoseconds, read
|
||||
* synchronously with device time
|
||||
* @dev_time_ns: Device clock time value expressed in nanoseconds
|
||||
* @pad: Padding for future extensions
|
||||
*
|
||||
* PF/VF sends this message to receive the cross time.
|
||||
*/
|
||||
struct virtchnl2_ptp_get_cross_time {
|
||||
__le64 sys_time_ns;
|
||||
__le64 dev_time_ns;
|
||||
u8 pad[8];
|
||||
};
|
||||
VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_ptp_get_cross_time);
|
||||
VIRTCHNL2_CHECK_STRUCT_LEN(24, virtchnl2_ptp_get_cross_time);
|
||||
|
||||
/**
|
||||
* struct virtchnl2_ptp_set_dev_clk_time: Associated with message
|
||||
* VIRTCHNL2_OP_PTP_SET_DEV_CLK_TIME.
|
||||
* @dev_time_ns: Device time value expressed in nanoseconds to set
|
||||
* @pad: Padding for future extensions
|
||||
*
|
||||
* PF/VF sends this message to set the time of the main timer.
|
||||
*/
|
||||
struct virtchnl2_ptp_set_dev_clk_time {
|
||||
__le64 dev_time_ns;
|
||||
u8 pad[8];
|
||||
};
|
||||
VIRTCHNL2_CHECK_STRUCT_LEN(8, virtchnl2_ptp_set_dev_clk_time);
|
||||
VIRTCHNL2_CHECK_STRUCT_LEN(16, virtchnl2_ptp_set_dev_clk_time);
|
||||
|
||||
/**
|
||||
* struct virtchnl2_ptp_adj_dev_clk_fine: Associated with message
|
||||
|
||||
@@ -2649,7 +2649,7 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
|
||||
}
|
||||
|
||||
if (igc_fpe_is_pmac_enabled(adapter) &&
|
||||
igc_fpe_handle_mpacket(adapter, rx_desc, size, pktbuf)) {
|
||||
igc_fpe_handle_mpacket(adapter, rx_desc, size, pktbuf + pkt_offset)) {
|
||||
/* Advance the ring next-to-clean */
|
||||
igc_is_non_eop(rx_ring, rx_desc);
|
||||
cleaned_count++;
|
||||
|
||||
@@ -3958,7 +3958,8 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
|
||||
}
|
||||
|
||||
/* initialize XPS */
|
||||
if (!test_and_set_bit(__IXGBE_TX_XPS_INIT_DONE, ring->state)) {
|
||||
if (!ring_is_xdp(ring) &&
|
||||
!test_and_set_bit(__IXGBE_TX_XPS_INIT_DONE, ring->state)) {
|
||||
struct ixgbe_q_vector *q_vector = ring->q_vector;
|
||||
|
||||
if (q_vector)
|
||||
|
||||
@@ -283,31 +283,30 @@ M(NPC_GET_FIELD_HASH_INFO, 0x6013, npc_get_field_hash_info,
|
||||
M(NPC_GET_FIELD_STATUS, 0x6014, npc_get_field_status, \
|
||||
npc_get_field_status_req, \
|
||||
npc_get_field_status_rsp) \
|
||||
M(NPC_CN20K_MCAM_GET_FREE_COUNT, 0x6015, npc_cn20k_get_fcnt, \
|
||||
msg_req, npc_cn20k_get_fcnt_rsp) \
|
||||
M(NPC_CN20K_GET_KEX_CFG, 0x6016, npc_cn20k_get_kex_cfg, \
|
||||
M(NPC_MCAM_DEFRAG, 0x6016, npc_defrag, \
|
||||
msg_req, \
|
||||
msg_rsp) \
|
||||
M(NPC_CN20K_GET_KEX_CFG, 0x6017, npc_cn20k_get_kex_cfg, \
|
||||
msg_req, npc_cn20k_get_kex_cfg_rsp) \
|
||||
M(NPC_CN20K_MCAM_WRITE_ENTRY, 0x6017, npc_cn20k_mcam_write_entry, \
|
||||
npc_cn20k_mcam_write_entry_req, msg_rsp) \
|
||||
M(NPC_CN20K_MCAM_ALLOC_AND_WRITE_ENTRY, 0x6018, \
|
||||
npc_cn20k_mcam_alloc_and_write_entry, \
|
||||
M(NPC_CN20K_MCAM_GET_FREE_COUNT, 0x6018, npc_cn20k_get_fcnt, \
|
||||
msg_req, npc_cn20k_get_fcnt_rsp) \
|
||||
M(NPC_CN20K_MCAM_WRITE_ENTRY, 0x6019, npc_cn20k_mcam_write_entry, \
|
||||
npc_cn20k_mcam_write_entry_req, msg_rsp) \
|
||||
M(NPC_CN20K_MCAM_ALLOC_AND_WRITE_ENTRY, 0x601a, npc_cn20k_mcam_alloc_and_write_entry, \
|
||||
npc_cn20k_mcam_alloc_and_write_entry_req, \
|
||||
npc_mcam_alloc_and_write_entry_rsp) \
|
||||
M(NPC_CN20K_MCAM_READ_ENTRY, 0x6019, npc_cn20k_mcam_read_entry, \
|
||||
M(NPC_CN20K_MCAM_READ_ENTRY, 0x601b, npc_cn20k_mcam_read_entry, \
|
||||
npc_mcam_read_entry_req, \
|
||||
npc_cn20k_mcam_read_entry_rsp) \
|
||||
M(NPC_CN20K_MCAM_READ_BASE_RULE, 0x601a, npc_cn20k_read_base_steer_rule, \
|
||||
msg_req, npc_cn20k_mcam_read_base_rule_rsp) \
|
||||
M(NPC_MCAM_DEFRAG, 0x601b, npc_defrag, \
|
||||
msg_req, \
|
||||
msg_rsp) \
|
||||
M(NPC_MCAM_GET_NUM_KWS, 0x601c, npc_get_num_kws, \
|
||||
M(NPC_CN20K_MCAM_READ_BASE_RULE, 0x601c, npc_cn20k_read_base_steer_rule, \
|
||||
msg_req, npc_cn20k_mcam_read_base_rule_rsp) \
|
||||
M(NPC_MCAM_GET_NUM_KWS, 0x601d, npc_get_num_kws, \
|
||||
npc_get_num_kws_req, \
|
||||
npc_get_num_kws_rsp) \
|
||||
M(NPC_MCAM_GET_DFT_RL_IDXS, 0x601d, npc_get_dft_rl_idxs, \
|
||||
M(NPC_MCAM_GET_DFT_RL_IDXS, 0x601e, npc_get_dft_rl_idxs, \
|
||||
msg_req, \
|
||||
npc_get_dft_rl_idxs_rsp)\
|
||||
M(NPC_MCAM_GET_NPC_PFL_INFO, 0x601e, npc_get_pfl_info, \
|
||||
M(NPC_MCAM_GET_NPC_PFL_INFO, 0x601f, npc_get_pfl_info, \
|
||||
msg_req, \
|
||||
npc_get_pfl_info_rsp) \
|
||||
/* NIX mbox IDs (range 0x8000 - 0xFFFF) */ \
|
||||
|
||||
@@ -2476,7 +2476,7 @@ int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
|
||||
/* Alloc memory for MCAM entry to counter mapping and for tracking
|
||||
* counter's reference count.
|
||||
*/
|
||||
mcam->entry2cntr_map = kcalloc(mcam->bmap_entries, sizeof(u16),
|
||||
mcam->entry2cntr_map = kcalloc(mcam->total_entries, sizeof(u16),
|
||||
GFP_KERNEL);
|
||||
if (!mcam->entry2cntr_map)
|
||||
goto free_cntr_map;
|
||||
@@ -2492,10 +2492,11 @@ int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
|
||||
if (!mcam->entry2target_pffunc)
|
||||
goto free_cntr_refcnt;
|
||||
|
||||
for (index = 0; index < mcam->bmap_entries; index++) {
|
||||
for (index = 0; index < mcam->bmap_entries; index++)
|
||||
mcam->entry2pfvf_map[index] = NPC_MCAM_INVALID_MAP;
|
||||
|
||||
for (index = 0; index < mcam->total_entries; index++)
|
||||
mcam->entry2cntr_map[index] = NPC_MCAM_INVALID_MAP;
|
||||
}
|
||||
|
||||
for (cntr = 0; cntr < mcam->counters.max; cntr++)
|
||||
mcam->cntr2pfvf_map[cntr] = NPC_MCAM_INVALID_MAP;
|
||||
@@ -3829,7 +3830,7 @@ static int __npc_mcam_free_counter(struct rvu *rvu,
|
||||
struct msg_rsp *rsp)
|
||||
{
|
||||
struct npc_mcam *mcam = &rvu->hw->mcam;
|
||||
u16 index, entry = 0;
|
||||
u16 index;
|
||||
int blkaddr, err;
|
||||
|
||||
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
|
||||
@@ -3845,20 +3846,16 @@ static int __npc_mcam_free_counter(struct rvu *rvu,
|
||||
mcam->cntr2pfvf_map[req->cntr] = NPC_MCAM_INVALID_MAP;
|
||||
rvu_free_rsrc(&mcam->counters, req->cntr);
|
||||
|
||||
/* Disable all MCAM entry's stats which are using this counter */
|
||||
while (entry < mcam->bmap_entries) {
|
||||
/* Disable all MCAM entry's stats which are using this counter.
|
||||
* Scan the full MCAM index range: AF-reserved rules (e.g. CPT pass-2)
|
||||
*/
|
||||
for (index = 0; index < mcam->total_entries; index++) {
|
||||
if (!mcam->cntr_refcnt[req->cntr])
|
||||
break;
|
||||
|
||||
index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry);
|
||||
if (index >= mcam->bmap_entries)
|
||||
break;
|
||||
entry = index + 1;
|
||||
if (mcam->entry2cntr_map[index] != req->cntr)
|
||||
continue;
|
||||
|
||||
npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr,
|
||||
index, req->cntr);
|
||||
npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, index,
|
||||
req->cntr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -3929,7 +3926,7 @@ int rvu_mbox_handler_npc_mcam_unmap_counter(struct rvu *rvu,
|
||||
struct npc_mcam_unmap_counter_req *req, struct msg_rsp *rsp)
|
||||
{
|
||||
struct npc_mcam *mcam = &rvu->hw->mcam;
|
||||
u16 index, entry = 0;
|
||||
u16 index;
|
||||
int blkaddr, rc;
|
||||
|
||||
/* Counter is not supported for CN20K */
|
||||
@@ -3956,20 +3953,13 @@ int rvu_mbox_handler_npc_mcam_unmap_counter(struct rvu *rvu,
|
||||
}
|
||||
|
||||
/* Disable all MCAM entry's stats which are using this counter */
|
||||
while (entry < mcam->bmap_entries) {
|
||||
for (index = 0; index < mcam->total_entries; index++) {
|
||||
if (!mcam->cntr_refcnt[req->cntr])
|
||||
break;
|
||||
|
||||
index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry);
|
||||
if (index >= mcam->bmap_entries)
|
||||
break;
|
||||
entry = index + 1;
|
||||
|
||||
if (mcam->entry2cntr_map[index] != req->cntr)
|
||||
continue;
|
||||
|
||||
npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr,
|
||||
index, req->cntr);
|
||||
npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, index,
|
||||
req->cntr);
|
||||
}
|
||||
exit:
|
||||
mutex_unlock(&mcam->lock);
|
||||
|
||||
@@ -1118,9 +1118,16 @@ int otx2_register_mbox_intr(struct otx2_nic *pf, bool probe_af)
|
||||
{
|
||||
struct otx2_hw *hw = &pf->hw;
|
||||
struct msg_req *req;
|
||||
u64 mbox_int_mask;
|
||||
char *irq_name;
|
||||
int err;
|
||||
|
||||
mbox_int_mask = !is_cn20k(pf->pdev) ? BIT_ULL(0) :
|
||||
BIT_ULL(0) | BIT_ULL(1);
|
||||
|
||||
/* Clear stale mailbox interrupt state before installing the handler. */
|
||||
otx2_write64(pf, RVU_PF_INT, mbox_int_mask);
|
||||
|
||||
/* Register mailbox interrupt handler */
|
||||
if (!is_cn20k(pf->pdev)) {
|
||||
irq_name = &hw->irq_name[RVU_PF_INT_VEC_AFPF_MBOX * NAME_SIZE];
|
||||
@@ -1146,17 +1153,8 @@ int otx2_register_mbox_intr(struct otx2_nic *pf, bool probe_af)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Enable mailbox interrupt for msgs coming from AF.
|
||||
* First clear to avoid spurious interrupts, if any.
|
||||
*/
|
||||
if (!is_cn20k(pf->pdev)) {
|
||||
otx2_write64(pf, RVU_PF_INT, BIT_ULL(0));
|
||||
otx2_write64(pf, RVU_PF_INT_ENA_W1S, BIT_ULL(0));
|
||||
} else {
|
||||
otx2_write64(pf, RVU_PF_INT, BIT_ULL(0) | BIT_ULL(1));
|
||||
otx2_write64(pf, RVU_PF_INT_ENA_W1S, BIT_ULL(0) |
|
||||
BIT_ULL(1));
|
||||
}
|
||||
/* Enable mailbox interrupt for msgs coming from AF. */
|
||||
otx2_write64(pf, RVU_PF_INT_ENA_W1S, mbox_int_mask);
|
||||
|
||||
if (!probe_af)
|
||||
return 0;
|
||||
|
||||
@@ -251,9 +251,17 @@ static int otx2vf_register_mbox_intr(struct otx2_nic *vf, bool probe_pf)
|
||||
{
|
||||
struct otx2_hw *hw = &vf->hw;
|
||||
struct msg_req *req;
|
||||
u64 mbox_int_mask;
|
||||
char *irq_name;
|
||||
int err;
|
||||
|
||||
mbox_int_mask = !is_cn20k(vf->pdev) ? BIT_ULL(0) :
|
||||
BIT_ULL(0) | BIT_ULL(1) |
|
||||
BIT_ULL(2) | BIT_ULL(3);
|
||||
|
||||
/* Clear stale mailbox interrupt state before installing the handler. */
|
||||
otx2_write64(vf, RVU_VF_INT, mbox_int_mask);
|
||||
|
||||
/* Register mailbox interrupt handler */
|
||||
irq_name = &hw->irq_name[RVU_VF_INT_VEC_MBOX * NAME_SIZE];
|
||||
snprintf(irq_name, NAME_SIZE, "RVUVF%d AFVF Mbox", ((vf->pcifunc &
|
||||
@@ -274,18 +282,8 @@ static int otx2vf_register_mbox_intr(struct otx2_nic *vf, bool probe_pf)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Enable mailbox interrupt for msgs coming from PF.
|
||||
* First clear to avoid spurious interrupts, if any.
|
||||
*/
|
||||
if (!is_cn20k(vf->pdev)) {
|
||||
otx2_write64(vf, RVU_VF_INT, BIT_ULL(0));
|
||||
otx2_write64(vf, RVU_VF_INT_ENA_W1S, BIT_ULL(0));
|
||||
} else {
|
||||
otx2_write64(vf, RVU_VF_INT, BIT_ULL(0) | BIT_ULL(1) |
|
||||
BIT_ULL(2) | BIT_ULL(3));
|
||||
otx2_write64(vf, RVU_VF_INT_ENA_W1S, BIT_ULL(0) |
|
||||
BIT_ULL(1) | BIT_ULL(2) | BIT_ULL(3));
|
||||
}
|
||||
/* Enable mailbox interrupt for msgs coming from PF. */
|
||||
otx2_write64(vf, RVU_VF_INT_ENA_W1S, mbox_int_mask);
|
||||
|
||||
if (!probe_pf)
|
||||
return 0;
|
||||
|
||||
@@ -310,9 +310,9 @@ wed_amsdu_show(struct seq_file *s, void *data)
|
||||
WED_AMSDU_ENG_MAX_QGPP_CNT),
|
||||
DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(1),
|
||||
WED_AMSDU_ENG_CUR_ENTRY),
|
||||
DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
|
||||
DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(1),
|
||||
WED_AMSDU_ENG_MAX_BUF_MERGED),
|
||||
DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2),
|
||||
DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(1),
|
||||
WED_AMSDU_ENG_MAX_MSDU_MERGED),
|
||||
|
||||
DUMP_STR("WED AMDSU ENG2 INFO"),
|
||||
@@ -414,7 +414,7 @@ wed_amsdu_show(struct seq_file *s, void *data)
|
||||
WED_AMSDU_ENG_CUR_ENTRY),
|
||||
DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7),
|
||||
WED_AMSDU_ENG_MAX_BUF_MERGED),
|
||||
DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4),
|
||||
DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7),
|
||||
WED_AMSDU_ENG_MAX_MSDU_MERGED),
|
||||
|
||||
DUMP_STR("WED AMDSU ENG8 INFO"),
|
||||
|
||||
@@ -367,8 +367,12 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
|
||||
/* wo firmware reset */
|
||||
wo_w32(MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00);
|
||||
|
||||
val = wo_r32(MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) |
|
||||
MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK;
|
||||
val = wo_r32(MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR);
|
||||
|
||||
if (!mtk_wed_is_v3_or_greater(wo->hw) && wo->hw->index)
|
||||
val |= MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK;
|
||||
else
|
||||
val |= MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK;
|
||||
wo_w32(MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
|
||||
out:
|
||||
release_firmware(fw);
|
||||
|
||||
@@ -527,7 +527,6 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
|
||||
{
|
||||
struct mlx5_profile *prof = &dev->profile;
|
||||
void *set_hca_cap;
|
||||
int max_uc_list;
|
||||
int err;
|
||||
|
||||
err = mlx5_core_get_caps(dev, MLX5_CAP_GENERAL);
|
||||
@@ -613,10 +612,13 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
|
||||
MLX5_SET(cmd_hca_cap, set_hca_cap, roce,
|
||||
mlx5_is_roce_on(dev));
|
||||
|
||||
max_uc_list = max_uc_list_get_devlink_param(dev);
|
||||
if (max_uc_list > 0)
|
||||
MLX5_SET(cmd_hca_cap, set_hca_cap, log_max_current_uc_list,
|
||||
ilog2(max_uc_list));
|
||||
if (MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list)) {
|
||||
int max_uc_list = max_uc_list_get_devlink_param(dev);
|
||||
|
||||
if (max_uc_list > 0)
|
||||
MLX5_SET(cmd_hca_cap, set_hca_cap,
|
||||
log_max_current_uc_list, ilog2(max_uc_list));
|
||||
}
|
||||
|
||||
/* enable absolute native port num */
|
||||
if (MLX5_CAP_GEN_MAX(dev, abs_native_port_num))
|
||||
|
||||
@@ -1267,6 +1267,8 @@ int mana_gd_create_mana_wq_cq(struct gdma_dev *gd,
|
||||
if (!queue)
|
||||
return -ENOMEM;
|
||||
|
||||
queue->id = INVALID_QUEUE_ID;
|
||||
|
||||
gmi = &queue->mem_info;
|
||||
err = mana_gd_alloc_memory(gc, spec->queue_size, gmi);
|
||||
if (err) {
|
||||
|
||||
@@ -2401,7 +2401,9 @@ static void mana_destroy_txq(struct mana_port_context *apc)
|
||||
netif_napi_del_locked(napi);
|
||||
apc->tx_qp[i]->txq.napi_initialized = false;
|
||||
}
|
||||
mana_destroy_wq_obj(apc, GDMA_SQ, apc->tx_qp[i]->tx_object);
|
||||
|
||||
if (apc->tx_qp[i]->tx_object != INVALID_MANA_HANDLE)
|
||||
mana_destroy_wq_obj(apc, GDMA_SQ, apc->tx_qp[i]->tx_object);
|
||||
|
||||
mana_deinit_cq(apc, &apc->tx_qp[i]->tx_cq);
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/oa_tc6.h>
|
||||
@@ -44,6 +45,8 @@
|
||||
#define INT_MASK0_LOSS_OF_FRAME_ERR_MASK BIT(4)
|
||||
#define INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK BIT(3)
|
||||
#define INT_MASK0_TX_PROTOCOL_ERR_MASK BIT(0)
|
||||
#define INT_MASK0_ALL_INTERRUPTS (GENMASK(5, 0) | \
|
||||
GENMASK(12, 7))
|
||||
|
||||
/* PHY Clause 22 registers base address and mask */
|
||||
#define OA_TC6_PHY_STD_REG_ADDR_BASE 0xFF00
|
||||
@@ -107,7 +110,6 @@
|
||||
|
||||
/* Internal structure for MAC-PHY drivers */
|
||||
struct oa_tc6 {
|
||||
struct device *dev;
|
||||
struct net_device *netdev;
|
||||
struct phy_device *phydev;
|
||||
struct mii_bus *mdiobus;
|
||||
@@ -121,14 +123,13 @@ struct oa_tc6 {
|
||||
struct sk_buff *ongoing_tx_skb;
|
||||
struct sk_buff *waiting_tx_skb;
|
||||
struct sk_buff *rx_skb;
|
||||
struct task_struct *spi_thread;
|
||||
wait_queue_head_t spi_wq;
|
||||
u16 tx_skb_offset;
|
||||
u16 spi_data_tx_buf_offset;
|
||||
u16 tx_credits;
|
||||
u8 rx_chunks_available;
|
||||
bool rx_buf_overflow;
|
||||
bool int_flag;
|
||||
bool disable_traffic;
|
||||
};
|
||||
|
||||
enum oa_tc6_header_type {
|
||||
@@ -518,7 +519,7 @@ static int oa_tc6_mdiobus_register(struct oa_tc6 *tc6)
|
||||
tc6->mdiobus->read_c45 = oa_tc6_mdiobus_read_c45;
|
||||
tc6->mdiobus->write_c45 = oa_tc6_mdiobus_write_c45;
|
||||
tc6->mdiobus->name = "oa-tc6-mdiobus";
|
||||
tc6->mdiobus->parent = tc6->dev;
|
||||
tc6->mdiobus->parent = &tc6->spi->dev;
|
||||
|
||||
snprintf(tc6->mdiobus->id, ARRAY_SIZE(tc6->mdiobus->id), "%s",
|
||||
dev_name(&tc6->spi->dev));
|
||||
@@ -669,6 +670,38 @@ static void oa_tc6_cleanup_ongoing_tx_skb(struct oa_tc6 *tc6)
|
||||
}
|
||||
}
|
||||
|
||||
static void oa_tc6_cleanup_waiting_tx_skb(struct oa_tc6 *tc6)
|
||||
{
|
||||
if (tc6->waiting_tx_skb) {
|
||||
tc6->netdev->stats.tx_dropped++;
|
||||
kfree_skb(tc6->waiting_tx_skb);
|
||||
tc6->waiting_tx_skb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void oa_tc6_free_pending_skbs(struct oa_tc6 *tc6)
|
||||
{
|
||||
oa_tc6_cleanup_ongoing_tx_skb(tc6);
|
||||
oa_tc6_cleanup_ongoing_rx_skb(tc6);
|
||||
oa_tc6_cleanup_waiting_tx_skb(tc6);
|
||||
}
|
||||
|
||||
/* If the failure is at SPI interface level, masking and clearing
|
||||
* the interrupt of the device won't work. Since SPI interrupt is
|
||||
* disabled, it should stop the repeated interrupts.
|
||||
*/
|
||||
static void oa_tc6_disable_traffic(struct oa_tc6 *tc6)
|
||||
{
|
||||
u32 regval = INT_MASK0_ALL_INTERRUPTS;
|
||||
|
||||
tc6->disable_traffic = true;
|
||||
oa_tc6_free_pending_skbs(tc6);
|
||||
oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
|
||||
oa_tc6_read_register(tc6, OA_TC6_REG_STATUS0, ®val);
|
||||
oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, regval);
|
||||
dev_err(&tc6->spi->dev, "Device interrupt disabled to avoid interrupt storm");
|
||||
}
|
||||
|
||||
static int oa_tc6_process_extended_status(struct oa_tc6 *tc6)
|
||||
{
|
||||
u32 value;
|
||||
@@ -752,6 +785,17 @@ static int oa_tc6_process_rx_chunk_footer(struct oa_tc6 *tc6, u32 footer)
|
||||
|
||||
static void oa_tc6_submit_rx_skb(struct oa_tc6 *tc6)
|
||||
{
|
||||
/* MAC-PHY delivers each frame with its Ethernet FCS attached.
|
||||
* Strip it before handing over to the stack, unless the user
|
||||
* has asked to keep it via NETIF_F_RXFCS. Keeping the FCS
|
||||
* in the frame is harmless for IP traffic, but is parsed as
|
||||
* a (malformed) suffix TLV by PTP, which makes ptp4l reject
|
||||
* every message with "bad message" error.
|
||||
*/
|
||||
if (!(tc6->netdev->features & NETIF_F_RXFCS) &&
|
||||
tc6->rx_skb->len > ETH_FCS_LEN)
|
||||
skb_trim(tc6->rx_skb, tc6->rx_skb->len - ETH_FCS_LEN);
|
||||
|
||||
tc6->rx_skb->protocol = eth_type_trans(tc6->rx_skb, tc6->netdev);
|
||||
tc6->netdev->stats.rx_packets++;
|
||||
tc6->netdev->stats.rx_bytes += tc6->rx_skb->len;
|
||||
@@ -1105,29 +1149,29 @@ static int oa_tc6_try_spi_transfer(struct oa_tc6 *tc6)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int oa_tc6_spi_thread_handler(void *data)
|
||||
static irqreturn_t oa_tc6_macphy_threaded_irq(int irq, void *data)
|
||||
{
|
||||
struct oa_tc6 *tc6 = data;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
while (likely(!kthread_should_stop())) {
|
||||
/* This kthread will be waken up if there is a tx skb or mac-phy
|
||||
* interrupt to perform spi transfer with tx chunks.
|
||||
*/
|
||||
wait_event_interruptible(tc6->spi_wq, tc6->int_flag ||
|
||||
(tc6->waiting_tx_skb &&
|
||||
tc6->tx_credits) ||
|
||||
kthread_should_stop());
|
||||
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
|
||||
ret = oa_tc6_try_spi_transfer(tc6);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* It is possible that interrupt woke the thread before it is
|
||||
* disabled. Until we come up with good recovery mechanism,
|
||||
* no need to attempt spi transfer, once it fails. Pending skbs
|
||||
* are already freed.
|
||||
*/
|
||||
if (!tc6->disable_traffic) {
|
||||
while (tc6->int_flag ||
|
||||
(tc6->waiting_tx_skb && tc6->tx_credits)) {
|
||||
ret = oa_tc6_try_spi_transfer(tc6);
|
||||
if (ret) {
|
||||
disable_irq_nosync(tc6->spi->irq);
|
||||
oa_tc6_disable_traffic(tc6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int oa_tc6_update_buffer_status_from_register(struct oa_tc6 *tc6)
|
||||
@@ -1161,11 +1205,15 @@ static irqreturn_t oa_tc6_macphy_isr(int irq, void *data)
|
||||
* the previous rx footer.
|
||||
* - extended status event not reported in the previous rx footer.
|
||||
*/
|
||||
tc6->int_flag = true;
|
||||
/* Wake spi kthread to perform spi transfer */
|
||||
wake_up_interruptible(&tc6->spi_wq);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
if (tc6->disable_traffic)
|
||||
disable_irq_nosync(tc6->spi->irq);
|
||||
else
|
||||
tc6->int_flag = true;
|
||||
/* Wake IRQ thread to perform spi transfer . In case
|
||||
* disable_traffic is set, threaded irq may run again
|
||||
* one more time.
|
||||
*/
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1202,7 +1250,7 @@ EXPORT_SYMBOL_GPL(oa_tc6_zero_align_receive_frame_enable);
|
||||
*/
|
||||
netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6, struct sk_buff *skb)
|
||||
{
|
||||
if (tc6->waiting_tx_skb) {
|
||||
if (tc6->disable_traffic || tc6->waiting_tx_skb) {
|
||||
netif_stop_queue(tc6->netdev);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
@@ -1217,8 +1265,8 @@ netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6, struct sk_buff *skb)
|
||||
tc6->waiting_tx_skb = skb;
|
||||
spin_unlock_bh(&tc6->tx_skb_lock);
|
||||
|
||||
/* Wake spi kthread to perform spi transfer */
|
||||
wake_up_interruptible(&tc6->spi_wq);
|
||||
/* Wake the threaded IRQ to perform spi transfer. */
|
||||
irq_wake_thread(tc6->spi->irq, tc6);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
@@ -1311,24 +1359,15 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev)
|
||||
goto phy_exit;
|
||||
}
|
||||
|
||||
init_waitqueue_head(&tc6->spi_wq);
|
||||
|
||||
tc6->spi_thread = kthread_run(oa_tc6_spi_thread_handler, tc6,
|
||||
"oa-tc6-spi-thread");
|
||||
if (IS_ERR(tc6->spi_thread)) {
|
||||
dev_err(&tc6->spi->dev, "Failed to create SPI thread\n");
|
||||
goto phy_exit;
|
||||
}
|
||||
|
||||
sched_set_fifo(tc6->spi_thread);
|
||||
|
||||
ret = devm_request_irq(&tc6->spi->dev, tc6->spi->irq, oa_tc6_macphy_isr,
|
||||
IRQF_TRIGGER_FALLING, dev_name(&tc6->spi->dev),
|
||||
tc6);
|
||||
ret = devm_request_threaded_irq(&tc6->spi->dev, tc6->spi->irq,
|
||||
oa_tc6_macphy_isr,
|
||||
oa_tc6_macphy_threaded_irq,
|
||||
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
||||
dev_name(&tc6->spi->dev), tc6);
|
||||
if (ret) {
|
||||
dev_err(&tc6->spi->dev, "Failed to request macphy isr %d\n",
|
||||
ret);
|
||||
goto kthread_stop;
|
||||
goto phy_exit;
|
||||
}
|
||||
|
||||
/* oa_tc6_sw_reset_macphy() function resets and clears the MAC-PHY reset
|
||||
@@ -1338,12 +1377,10 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev)
|
||||
* 7.7 and 9.2.8.8 in the OPEN Alliance specification for more details.
|
||||
*/
|
||||
tc6->int_flag = true;
|
||||
wake_up_interruptible(&tc6->spi_wq);
|
||||
irq_wake_thread(tc6->spi->irq, tc6);
|
||||
|
||||
return tc6;
|
||||
|
||||
kthread_stop:
|
||||
kthread_stop(tc6->spi_thread);
|
||||
phy_exit:
|
||||
oa_tc6_phy_exit(tc6);
|
||||
return NULL;
|
||||
@@ -1356,11 +1393,10 @@ EXPORT_SYMBOL_GPL(oa_tc6_init);
|
||||
*/
|
||||
void oa_tc6_exit(struct oa_tc6 *tc6)
|
||||
{
|
||||
tc6->disable_traffic = true;
|
||||
disable_irq(tc6->spi->irq);
|
||||
oa_tc6_phy_exit(tc6);
|
||||
kthread_stop(tc6->spi_thread);
|
||||
dev_kfree_skb_any(tc6->ongoing_tx_skb);
|
||||
dev_kfree_skb_any(tc6->waiting_tx_skb);
|
||||
dev_kfree_skb_any(tc6->rx_skb);
|
||||
oa_tc6_free_pending_skbs(tc6);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(oa_tc6_exit);
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
|
||||
struct xdp_desc xdp_desc;
|
||||
int num_tx = 0, pkt_len;
|
||||
int descs_avail, ret;
|
||||
u32 dst_tag_id;
|
||||
u32 *epib;
|
||||
int i;
|
||||
|
||||
@@ -137,9 +138,17 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
|
||||
epib[0] = 0;
|
||||
epib[1] = 0;
|
||||
cppi5_hdesc_set_pktlen(host_desc, pkt_len);
|
||||
cppi5_desc_set_tags_ids(&host_desc->hdr, 0,
|
||||
(emac->port_id | (q_idx << 8)));
|
||||
dst_tag_id = emac->port_id | (q_idx << 8);
|
||||
|
||||
if (emac->prueth->is_hsr_offload_mode &&
|
||||
(ndev->features & NETIF_F_HW_HSR_DUP))
|
||||
dst_tag_id = PRUETH_UNDIRECTED_PKT_DST_TAG;
|
||||
|
||||
if (emac->prueth->is_hsr_offload_mode &&
|
||||
(ndev->features & NETIF_F_HW_HSR_TAG_INS))
|
||||
epib[1] |= PRUETH_UNDIRECTED_PKT_TAG_INS;
|
||||
|
||||
cppi5_desc_set_tags_ids(&host_desc->hdr, 0, dst_tag_id);
|
||||
k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &dma_buf);
|
||||
cppi5_hdesc_attach_buf(host_desc, dma_buf, pkt_len, dma_buf,
|
||||
pkt_len);
|
||||
@@ -696,6 +705,7 @@ u32 emac_xmit_xdp_frame(struct prueth_emac *emac,
|
||||
dma_addr_t desc_dma, buf_dma;
|
||||
struct prueth_swdata *swdata;
|
||||
struct page *page;
|
||||
u32 dst_tag_id;
|
||||
u32 *epib;
|
||||
int ret;
|
||||
|
||||
@@ -737,9 +747,25 @@ u32 emac_xmit_xdp_frame(struct prueth_emac *emac,
|
||||
|
||||
/* set dst tag to indicate internal qid at the firmware which is at
|
||||
* bit8..bit15. bit0..bit7 indicates port num for directed
|
||||
* packets in case of switch mode operation
|
||||
* packets in case of switch mode operation and port num 0
|
||||
* for undirected packets in case of HSR offload mode.
|
||||
*
|
||||
* XDP_TX frames arrive on a slave port with the HSR tag already
|
||||
* stripped by the PRU firmware. Like skb TX via hsr0, they must
|
||||
* be sent as undirected so the PRU duplicates them to both ports
|
||||
* and re-inserts the HSR sequence tag.
|
||||
*/
|
||||
cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (emac->port_id | (q_idx << 8)));
|
||||
dst_tag_id = emac->port_id | (q_idx << 8);
|
||||
|
||||
if (emac->prueth->is_hsr_offload_mode &&
|
||||
(ndev->features & NETIF_F_HW_HSR_DUP))
|
||||
dst_tag_id = PRUETH_UNDIRECTED_PKT_DST_TAG;
|
||||
|
||||
if (emac->prueth->is_hsr_offload_mode &&
|
||||
(ndev->features & NETIF_F_HW_HSR_TAG_INS))
|
||||
epib[1] |= PRUETH_UNDIRECTED_PKT_TAG_INS;
|
||||
|
||||
cppi5_desc_set_tags_ids(&first_desc->hdr, 0, dst_tag_id);
|
||||
k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma);
|
||||
cppi5_hdesc_attach_buf(first_desc, buf_dma, xdpf->len, buf_dma, xdpf->len);
|
||||
swdata = cppi5_hdesc_get_swdata(first_desc);
|
||||
@@ -927,6 +953,7 @@ static int emac_rx_packet_zc(struct prueth_emac *emac, u32 flow_id,
|
||||
struct cppi5_host_desc_t *desc_rx;
|
||||
struct prueth_swdata *swdata;
|
||||
dma_addr_t desc_dma, buf_dma;
|
||||
int avail_desc, alloc_budget;
|
||||
struct xdp_buff *xdp;
|
||||
int xdp_status = 0;
|
||||
int count = 0;
|
||||
@@ -993,16 +1020,13 @@ static int emac_rx_packet_zc(struct prueth_emac *emac, u32 flow_id,
|
||||
if (xdp_status & ICSSG_XDP_REDIR)
|
||||
xdp_do_flush();
|
||||
|
||||
/* Allocate xsk buffers from the pool for the "count" number of
|
||||
* packets processed in order to be able to receive more packets.
|
||||
*/
|
||||
ret = prueth_rx_alloc_zc(emac, count);
|
||||
avail_desc = k3_cppi_desc_pool_avail(rx_chn->desc_pool);
|
||||
alloc_budget = min_t(int, budget, avail_desc);
|
||||
|
||||
ret = prueth_rx_alloc_zc(emac, alloc_budget);
|
||||
|
||||
if (xsk_uses_need_wakeup(rx_chn->xsk_pool)) {
|
||||
/* If the user space doesn't provide enough buffers then it must
|
||||
* explicitly wake up the kernel when new buffers are available
|
||||
*/
|
||||
if (ret < count)
|
||||
if (ret < alloc_budget)
|
||||
xsk_set_rx_need_wakeup(rx_chn->xsk_pool);
|
||||
else
|
||||
xsk_clear_rx_need_wakeup(rx_chn->xsk_pool);
|
||||
|
||||
@@ -148,6 +148,7 @@ static void pfcp_link_setup(struct net_device *dev)
|
||||
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
|
||||
dev->priv_flags |= IFF_NO_QUEUE;
|
||||
|
||||
dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
|
||||
netif_keep_dst(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -6222,6 +6222,19 @@ static void virtnet_free_irq_moder(struct virtnet_info *vi)
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
static netdev_features_t virtnet_features_check(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
/* Inner csum offload is only available for GSO packets. */
|
||||
if (skb->encapsulation &&
|
||||
(!skb_is_gso(skb) || netif_needs_gso(skb, features)))
|
||||
return features & ~NETIF_F_CSUM_MASK;
|
||||
|
||||
/* Passthru. */
|
||||
return features;
|
||||
}
|
||||
|
||||
static const struct net_device_ops virtnet_netdev = {
|
||||
.ndo_open = virtnet_open,
|
||||
.ndo_stop = virtnet_close,
|
||||
@@ -6235,7 +6248,7 @@ static const struct net_device_ops virtnet_netdev = {
|
||||
.ndo_bpf = virtnet_xdp,
|
||||
.ndo_xdp_xmit = virtnet_xdp_xmit,
|
||||
.ndo_xsk_wakeup = virtnet_xsk_wakeup,
|
||||
.ndo_features_check = passthru_features_check,
|
||||
.ndo_features_check = virtnet_features_check,
|
||||
.ndo_get_phys_port_name = virtnet_get_phys_port_name,
|
||||
.ndo_set_features = virtnet_set_features,
|
||||
.ndo_tx_timeout = virtnet_tx_timeout,
|
||||
|
||||
@@ -106,6 +106,8 @@ static int t7xx_port_ctrl_tx(struct t7xx_port *port, struct sk_buff *skb)
|
||||
|
||||
while (cur) {
|
||||
cloned = skb_clone(cur, GFP_KERNEL);
|
||||
if (!cloned)
|
||||
return cnt ? cnt : -ENOMEM;
|
||||
cloned->len = skb_headlen(cur);
|
||||
ret = t7xx_port_send_skb(port, cloned, 0, 0);
|
||||
if (ret) {
|
||||
|
||||
@@ -127,6 +127,7 @@ void afs_close_socket(struct afs_net *net)
|
||||
{
|
||||
_enter("");
|
||||
|
||||
cancel_work_sync(&net->charge_preallocation_work);
|
||||
kernel_listen(net->socket, 0);
|
||||
flush_workqueue(afs_async_calls);
|
||||
|
||||
@@ -742,7 +743,7 @@ void afs_charge_preallocation(struct work_struct *work)
|
||||
container_of(work, struct afs_net, charge_preallocation_work);
|
||||
struct afs_call *call = net->spare_incoming_call;
|
||||
|
||||
for (;;) {
|
||||
while (READ_ONCE(net->live)) {
|
||||
if (!call) {
|
||||
call = afs_alloc_call(net, &afs_RXCMxxxx, GFP_KERNEL);
|
||||
if (!call)
|
||||
@@ -792,7 +793,8 @@ static void afs_rx_new_call(struct sock *sk, struct rxrpc_call *rxcall,
|
||||
if (!call->server)
|
||||
trace_afs_cm_no_server(call, rxrpc_kernel_remote_srx(call->peer));
|
||||
|
||||
queue_work(afs_wq, &net->charge_preallocation_work);
|
||||
if (net->live)
|
||||
queue_work(afs_wq, &net->charge_preallocation_work);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1993,6 +1993,8 @@ enum netdev_reg_state {
|
||||
* @qdisc_hash: qdisc hash table
|
||||
* @watchdog_timeo: Represents the timeout that is used by
|
||||
* the watchdog (see dev_watchdog())
|
||||
* @watchdog_lock: protect watchdog_ref_held
|
||||
* @watchdog_ref_held: True if the watchdog device ref is taken.
|
||||
* @watchdog_timer: List of timers
|
||||
*
|
||||
* @proto_down_reason: reason a netdev interface is held down
|
||||
@@ -2404,6 +2406,8 @@ struct net_device {
|
||||
/* These may be needed for future network-power-down code. */
|
||||
struct timer_list watchdog_timer;
|
||||
int watchdog_timeo;
|
||||
spinlock_t watchdog_lock;
|
||||
bool watchdog_ref_held;
|
||||
|
||||
u32 proto_down_reason;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#ifndef _LINUX_SKMSG_H
|
||||
#define _LINUX_SKMSG_H
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/scatterlist.h>
|
||||
@@ -199,11 +200,14 @@ static inline void sk_msg_xfer(struct sk_msg *dst, struct sk_msg *src,
|
||||
int which, u32 size)
|
||||
{
|
||||
dst->sg.data[which] = src->sg.data[which];
|
||||
__assign_bit(which, dst->sg.copy, test_bit(which, src->sg.copy));
|
||||
dst->sg.data[which].length = size;
|
||||
dst->sg.size += size;
|
||||
src->sg.size -= size;
|
||||
src->sg.data[which].length -= size;
|
||||
src->sg.data[which].offset += size;
|
||||
if (!src->sg.data[which].length)
|
||||
__clear_bit(which, src->sg.copy);
|
||||
}
|
||||
|
||||
static inline void sk_msg_xfer_full(struct sk_msg *dst, struct sk_msg *src)
|
||||
@@ -273,16 +277,19 @@ static inline void sk_msg_page_add(struct sk_msg *msg, struct page *page,
|
||||
static inline void sk_msg_sg_copy(struct sk_msg *msg, u32 i, bool copy_state)
|
||||
{
|
||||
do {
|
||||
if (copy_state)
|
||||
__set_bit(i, msg->sg.copy);
|
||||
else
|
||||
__clear_bit(i, msg->sg.copy);
|
||||
__assign_bit(i, msg->sg.copy, copy_state);
|
||||
sk_msg_iter_var_next(i);
|
||||
if (i == msg->sg.end)
|
||||
break;
|
||||
} while (1);
|
||||
}
|
||||
|
||||
static inline void sk_msg_sg_copy_assign(struct sk_msg *dst, u32 dst_i,
|
||||
const struct sk_msg *src, u32 src_i)
|
||||
{
|
||||
__assign_bit(dst_i, dst->sg.copy, test_bit(src_i, src->sg.copy));
|
||||
}
|
||||
|
||||
static inline void sk_msg_sg_copy_set(struct sk_msg *msg, u32 start)
|
||||
{
|
||||
sk_msg_sg_copy(msg, start, true);
|
||||
|
||||
@@ -111,6 +111,11 @@ static inline void fib_rule_get(struct fib_rule *rule)
|
||||
refcount_inc(&rule->refcnt);
|
||||
}
|
||||
|
||||
static inline bool fib_rule_get_safe(struct fib_rule *rule)
|
||||
{
|
||||
return refcount_inc_not_zero(&rule->refcnt);
|
||||
}
|
||||
|
||||
static inline void fib_rule_put(struct fib_rule *rule)
|
||||
{
|
||||
if (refcount_dec_and_test(&rule->refcnt))
|
||||
|
||||
@@ -628,6 +628,11 @@ static inline void fib_info_hold(struct fib_info *fi)
|
||||
refcount_inc(&fi->fib_clntref);
|
||||
}
|
||||
|
||||
static inline bool fib_info_hold_safe(struct fib_info *fi)
|
||||
{
|
||||
return refcount_inc_not_zero(&fi->fib_clntref);
|
||||
}
|
||||
|
||||
static inline void fib_info_put(struct fib_info *fi)
|
||||
{
|
||||
if (refcount_dec_and_test(&fi->fib_clntref))
|
||||
|
||||
@@ -2925,6 +2925,11 @@ static inline int tcp_call_bpf_3arg(struct sock *sk, int op, u32 arg1, u32 arg2,
|
||||
return tcp_call_bpf(sk, op, 3, args);
|
||||
}
|
||||
|
||||
static inline void tcp_clear_sock_ops_cb_flags(struct sock *sk)
|
||||
{
|
||||
tcp_sk(sk)->bpf_sock_ops_cb_flags = 0;
|
||||
}
|
||||
|
||||
#else
|
||||
static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
|
||||
{
|
||||
@@ -2942,6 +2947,10 @@ static inline int tcp_call_bpf_3arg(struct sock *sk, int op, u32 arg1, u32 arg2,
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline void tcp_clear_sock_ops_cb_flags(struct sock *sk)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline u32 tcp_timeout_init(struct sock *sk)
|
||||
|
||||
@@ -117,9 +117,9 @@ int lowpan_nhc_do_uncompression(struct sk_buff *skb,
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
spin_unlock_bh(&lowpan_nhc_lock);
|
||||
netdev_warn(dev, "received nhc id for %s which is not implemented.\n",
|
||||
nhc->name);
|
||||
spin_unlock_bh(&lowpan_nhc_lock);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -670,6 +670,8 @@ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
|
||||
static int check_tp(const struct atm_trafprm *tp)
|
||||
{
|
||||
/* @@@ Should be merged with adjust_tp */
|
||||
if (tp->traffic_class > ATM_ANYCLASS)
|
||||
return -EINVAL;
|
||||
if (!tp->traffic_class || tp->traffic_class == ATM_ANYCLASS)
|
||||
return 0;
|
||||
if (tp->traffic_class != ATM_UBR && !tp->min_pcr && !tp->pcr &&
|
||||
|
||||
@@ -805,6 +805,12 @@ int br_cfm_cc_ccm_tx(struct net_bridge *br, const u32 instance,
|
||||
goto save;
|
||||
}
|
||||
|
||||
if (!interval_to_us(mep->cc_config.exp_interval)) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Invalid CCM interval");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Start delayed work to transmit CCM frames. It is done with zero delay
|
||||
* to send first frame immediately
|
||||
*/
|
||||
|
||||
@@ -34,7 +34,9 @@ br_cfm_cc_config_policy[IFLA_BRIDGE_CFM_CC_CONFIG_MAX + 1] = {
|
||||
[IFLA_BRIDGE_CFM_CC_CONFIG_UNSPEC] = { .type = NLA_REJECT },
|
||||
[IFLA_BRIDGE_CFM_CC_CONFIG_INSTANCE] = { .type = NLA_U32 },
|
||||
[IFLA_BRIDGE_CFM_CC_CONFIG_ENABLE] = { .type = NLA_U32 },
|
||||
[IFLA_BRIDGE_CFM_CC_CONFIG_EXP_INTERVAL] = { .type = NLA_U32 },
|
||||
[IFLA_BRIDGE_CFM_CC_CONFIG_EXP_INTERVAL] =
|
||||
NLA_POLICY_RANGE(NLA_U32, BR_CFM_CCM_INTERVAL_3_3_MS,
|
||||
BR_CFM_CCM_INTERVAL_10_MIN),
|
||||
[IFLA_BRIDGE_CFM_CC_CONFIG_EXP_MAID] = {
|
||||
.type = NLA_BINARY, .len = CFM_MAID_LENGTH },
|
||||
};
|
||||
|
||||
@@ -11230,7 +11230,8 @@ static int netif_alloc_netdev_queues(struct net_device *dev)
|
||||
|
||||
netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL);
|
||||
spin_lock_init(&dev->tx_global_lock);
|
||||
|
||||
spin_lock_init(&dev->watchdog_lock);
|
||||
dev->watchdog_ref_held = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -349,7 +349,7 @@ int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
|
||||
|
||||
if (err != -EAGAIN) {
|
||||
if ((arg->flags & FIB_LOOKUP_NOREF) ||
|
||||
likely(refcount_inc_not_zero(&rule->refcnt))) {
|
||||
likely(fib_rule_get_safe(rule))) {
|
||||
arg->rule = rule;
|
||||
goto out;
|
||||
}
|
||||
@@ -410,8 +410,12 @@ int fib_rules_dump(struct net *net, struct notifier_block *nb, int family,
|
||||
if (!ops)
|
||||
return -EAFNOSUPPORT;
|
||||
list_for_each_entry_rcu(rule, &ops->rules_list, list) {
|
||||
if (!fib_rule_get_safe(rule))
|
||||
continue;
|
||||
|
||||
err = call_fib_rule_notifier(nb, FIB_EVENT_RULE_ADD,
|
||||
rule, family, extack);
|
||||
fib_rule_put(rule);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2733,11 +2733,13 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_msg *, msg, u32, start,
|
||||
poffset += len;
|
||||
sge->length = 0;
|
||||
put_page(sg_page(sge));
|
||||
__clear_bit(i, msg->sg.copy);
|
||||
|
||||
sk_msg_iter_var_next(i);
|
||||
} while (i != last_sge);
|
||||
|
||||
sg_set_page(&msg->sg.data[first_sge], page, copy, 0);
|
||||
__clear_bit(first_sge, msg->sg.copy);
|
||||
|
||||
/* To repair sg ring we need to shift entries. If we only
|
||||
* had a single entry though we can just replace it and
|
||||
@@ -2763,9 +2765,11 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_msg *, msg, u32, start,
|
||||
break;
|
||||
|
||||
msg->sg.data[i] = msg->sg.data[move_from];
|
||||
sk_msg_sg_copy_assign(msg, i, msg, move_from);
|
||||
msg->sg.data[move_from].length = 0;
|
||||
msg->sg.data[move_from].page_link = 0;
|
||||
msg->sg.data[move_from].offset = 0;
|
||||
__clear_bit(move_from, msg->sg.copy);
|
||||
sk_msg_iter_var_next(i);
|
||||
} while (1);
|
||||
|
||||
@@ -2794,6 +2798,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
|
||||
{
|
||||
struct scatterlist sge, nsge, nnsge, rsge = {0}, *psge;
|
||||
u32 new, i = 0, l = 0, space, copy = 0, offset = 0;
|
||||
bool sge_copy, nsge_copy, nnsge_copy, rsge_copy = false;
|
||||
u8 *raw, *to, *from;
|
||||
struct page *page;
|
||||
|
||||
@@ -2866,6 +2871,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
|
||||
sk_msg_iter_var_prev(i);
|
||||
psge = sk_msg_elem(msg, i);
|
||||
rsge = sk_msg_elem_cpy(msg, i);
|
||||
rsge_copy = test_bit(i, msg->sg.copy);
|
||||
|
||||
psge->length = start - offset;
|
||||
rsge.length -= psge->length;
|
||||
@@ -2890,24 +2896,32 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
|
||||
|
||||
/* Shift one or two slots as needed */
|
||||
sge = sk_msg_elem_cpy(msg, new);
|
||||
sge_copy = test_bit(new, msg->sg.copy);
|
||||
sg_unmark_end(&sge);
|
||||
|
||||
nsge = sk_msg_elem_cpy(msg, i);
|
||||
nsge_copy = test_bit(i, msg->sg.copy);
|
||||
if (rsge.length) {
|
||||
sk_msg_iter_var_next(i);
|
||||
nnsge = sk_msg_elem_cpy(msg, i);
|
||||
nnsge_copy = test_bit(i, msg->sg.copy);
|
||||
sk_msg_iter_next(msg, end);
|
||||
}
|
||||
|
||||
while (i != msg->sg.end) {
|
||||
msg->sg.data[i] = sge;
|
||||
__assign_bit(i, msg->sg.copy, sge_copy);
|
||||
sge = nsge;
|
||||
sge_copy = nsge_copy;
|
||||
sk_msg_iter_var_next(i);
|
||||
if (rsge.length) {
|
||||
nsge = nnsge;
|
||||
nsge_copy = nnsge_copy;
|
||||
nnsge = sk_msg_elem_cpy(msg, i);
|
||||
nnsge_copy = test_bit(i, msg->sg.copy);
|
||||
} else {
|
||||
nsge = sk_msg_elem_cpy(msg, i);
|
||||
nsge_copy = test_bit(i, msg->sg.copy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2921,6 +2935,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
|
||||
get_page(sg_page(&rsge));
|
||||
sk_msg_iter_var_next(new);
|
||||
msg->sg.data[new] = rsge;
|
||||
__assign_bit(new, msg->sg.copy, rsge_copy);
|
||||
}
|
||||
|
||||
sk_msg_reset_curr(msg);
|
||||
@@ -2948,25 +2963,33 @@ static void sk_msg_shift_left(struct sk_msg *msg, int i)
|
||||
prev = i;
|
||||
sk_msg_iter_var_next(i);
|
||||
msg->sg.data[prev] = msg->sg.data[i];
|
||||
sk_msg_sg_copy_assign(msg, prev, msg, i);
|
||||
} while (i != msg->sg.end);
|
||||
|
||||
sk_msg_iter_prev(msg, end);
|
||||
__clear_bit(msg->sg.end, msg->sg.copy);
|
||||
}
|
||||
|
||||
static void sk_msg_shift_right(struct sk_msg *msg, int i)
|
||||
{
|
||||
struct scatterlist tmp, sge;
|
||||
bool tmp_copy, sge_copy;
|
||||
|
||||
sk_msg_iter_next(msg, end);
|
||||
sge = sk_msg_elem_cpy(msg, i);
|
||||
sge_copy = test_bit(i, msg->sg.copy);
|
||||
sk_msg_iter_var_next(i);
|
||||
tmp = sk_msg_elem_cpy(msg, i);
|
||||
tmp_copy = test_bit(i, msg->sg.copy);
|
||||
|
||||
while (i != msg->sg.end) {
|
||||
msg->sg.data[i] = sge;
|
||||
__assign_bit(i, msg->sg.copy, sge_copy);
|
||||
sk_msg_iter_var_next(i);
|
||||
sge = tmp;
|
||||
sge_copy = tmp_copy;
|
||||
tmp = sk_msg_elem_cpy(msg, i);
|
||||
tmp_copy = test_bit(i, msg->sg.copy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3026,6 +3049,8 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
|
||||
struct scatterlist *nsge, *sge = sk_msg_elem(msg, i);
|
||||
int a = start - offset;
|
||||
int b = sge->length - pop - a;
|
||||
u32 sge_i = i;
|
||||
bool sge_copy = test_bit(i, msg->sg.copy);
|
||||
|
||||
sk_msg_iter_var_next(i);
|
||||
|
||||
@@ -3038,6 +3063,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
|
||||
sg_set_page(nsge,
|
||||
sg_page(sge),
|
||||
b, sge->offset + pop + a);
|
||||
__assign_bit(i, msg->sg.copy, sge_copy);
|
||||
} else {
|
||||
struct page *page, *orig;
|
||||
u8 *to, *from;
|
||||
@@ -3054,6 +3080,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
|
||||
memcpy(to, from, a);
|
||||
memcpy(to + a, from + a + pop, b);
|
||||
sg_set_page(sge, page, a + b, 0);
|
||||
__clear_bit(sge_i, msg->sg.copy);
|
||||
put_page(orig);
|
||||
}
|
||||
pop = 0;
|
||||
|
||||
@@ -338,12 +338,12 @@ void __netif_mp_uninstall_rxq(struct netdev_rx_queue *rxq,
|
||||
void netif_rxq_cleanup_unlease(struct netdev_rx_queue *phys_rxq,
|
||||
struct netdev_rx_queue *virt_rxq)
|
||||
{
|
||||
struct pp_memory_provider_params *p = &phys_rxq->mp_params;
|
||||
unsigned int rxq_idx = get_netdev_rx_queue_index(phys_rxq);
|
||||
struct pp_memory_provider_params p = phys_rxq->mp_params;
|
||||
|
||||
if (!p->mp_ops)
|
||||
if (!p.mp_ops)
|
||||
return;
|
||||
|
||||
__netif_mp_uninstall_rxq(virt_rxq, p);
|
||||
__netif_mp_close_rxq(phys_rxq->dev, rxq_idx, p);
|
||||
__netif_mp_close_rxq(phys_rxq->dev, rxq_idx, &p);
|
||||
__netif_mp_uninstall_rxq(virt_rxq, &p);
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ int sk_msg_alloc(struct sock *sk, struct sk_msg *msg, int len,
|
||||
sge = &msg->sg.data[msg->sg.end];
|
||||
sg_unmark_end(sge);
|
||||
sg_set_page(sge, pfrag->page, use, orig_offset);
|
||||
__clear_bit(msg->sg.end, msg->sg.copy);
|
||||
get_page(pfrag->page);
|
||||
sk_msg_iter_next(msg, end);
|
||||
}
|
||||
@@ -185,6 +186,7 @@ static int sk_msg_free_elem(struct sock *sk, struct sk_msg *msg, u32 i,
|
||||
sk_mem_uncharge(sk, len);
|
||||
put_page(sg_page(sge));
|
||||
}
|
||||
__clear_bit(i, msg->sg.copy);
|
||||
memset(sge, 0, sizeof(*sge));
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ void *ife_decode(struct sk_buff *skb, u16 *metalen)
|
||||
if (unlikely(ifehdrln < 2))
|
||||
return NULL;
|
||||
|
||||
if (unlikely(!pskb_may_pull(skb, total_pull)))
|
||||
if (unlikely(!pskb_may_pull(skb, total_pull + ETH_HLEN)))
|
||||
return NULL;
|
||||
|
||||
ifehdr = (struct ifeheadr *)(skb->data + skb->dev->hard_header_len);
|
||||
|
||||
@@ -2166,10 +2166,14 @@ static int fib_leaf_notify(struct key_vector *l, struct fib_table *tb,
|
||||
if (fa->fa_slen == last_slen)
|
||||
continue;
|
||||
|
||||
if (!fib_info_hold_safe(fa->fa_info))
|
||||
continue;
|
||||
|
||||
last_slen = fa->fa_slen;
|
||||
err = call_fib_entry_notifier(nb, FIB_EVENT_ENTRY_REPLACE,
|
||||
l->key, KEYLENGTH - fa->fa_slen,
|
||||
fa, extack);
|
||||
fib_info_put(fa->fa_info);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1281,6 +1281,7 @@ void inet_csk_destroy_sock(struct sock *sk)
|
||||
void inet_csk_prepare_for_destroy_sock(struct sock *sk)
|
||||
{
|
||||
/* The below has to be done to allow calling inet_csk_destroy_sock */
|
||||
tcp_clear_sock_ops_cb_flags(sk);
|
||||
sock_set_flag(sk, SOCK_DEAD);
|
||||
tcp_orphan_count_inc();
|
||||
}
|
||||
|
||||
@@ -3277,11 +3277,11 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst)
|
||||
/*
|
||||
* Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and
|
||||
* corresponding MSS is IPV6_MAXPLEN - tcp_header_size.
|
||||
* IPV6_MAXPLEN is also valid and means: "any MSS,
|
||||
* rely only on pmtu discovery"
|
||||
* Limit the default MSS to GSO_BY_FRAGS - 1 to avoid
|
||||
* collision with the GSO_BY_FRAGS magic value (0xFFFF).
|
||||
*/
|
||||
if (mtu > IPV6_MAXPLEN - sizeof(struct tcphdr))
|
||||
mtu = IPV6_MAXPLEN;
|
||||
mtu = min_t(unsigned int, IPV6_MAXPLEN, GSO_BY_FRAGS - 1);
|
||||
return mtu;
|
||||
}
|
||||
|
||||
|
||||
@@ -1302,8 +1302,8 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
|
||||
psock->save_write_space = csk->sk_write_space;
|
||||
psock->save_state_change = csk->sk_state_change;
|
||||
csk->sk_user_data = psock;
|
||||
csk->sk_data_ready = psock_data_ready;
|
||||
csk->sk_write_space = psock_write_space;
|
||||
WRITE_ONCE(csk->sk_data_ready, psock_data_ready);
|
||||
WRITE_ONCE(csk->sk_write_space, psock_write_space);
|
||||
csk->sk_state_change = psock_state_change;
|
||||
|
||||
write_unlock_bh(&csk->sk_callback_lock);
|
||||
@@ -1379,8 +1379,8 @@ static void kcm_unattach(struct kcm_psock *psock)
|
||||
*/
|
||||
write_lock_bh(&csk->sk_callback_lock);
|
||||
csk->sk_user_data = NULL;
|
||||
csk->sk_data_ready = psock->save_data_ready;
|
||||
csk->sk_write_space = psock->save_write_space;
|
||||
WRITE_ONCE(csk->sk_data_ready, psock->save_data_ready);
|
||||
WRITE_ONCE(csk->sk_write_space, psock->save_write_space);
|
||||
csk->sk_state_change = psock->save_state_change;
|
||||
strp_stop(&psock->strp);
|
||||
|
||||
|
||||
@@ -496,7 +496,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
|
||||
if (cb->dst_port == QRTR_PORT_CTRL_LEGACY)
|
||||
cb->dst_port = QRTR_PORT_CTRL;
|
||||
|
||||
if (!size || len != ALIGN(size, 4) + hdrlen)
|
||||
if (!size || size > len || len != ALIGN(size, 4) + hdrlen)
|
||||
goto err;
|
||||
|
||||
if ((cb->type == QRTR_TYPE_NEW_SERVER ||
|
||||
|
||||
@@ -471,13 +471,26 @@ int rxrpc_kernel_charge_accept(struct socket *sock, rxrpc_notify_rx_t notify_rx,
|
||||
unsigned long user_call_ID, gfp_t gfp,
|
||||
unsigned int debug_id)
|
||||
{
|
||||
struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
|
||||
struct rxrpc_backlog *b = rx->backlog;
|
||||
struct rxrpc_backlog *b;
|
||||
struct rxrpc_sock *rx;
|
||||
struct sock *sk;
|
||||
int ret;
|
||||
|
||||
if (sock->sk->sk_state == RXRPC_CLOSE)
|
||||
return -ESHUTDOWN;
|
||||
sk = sock->sk;
|
||||
rx = rxrpc_sk(sk);
|
||||
|
||||
return rxrpc_service_prealloc_one(rx, b, notify_rx, user_call_ID,
|
||||
gfp, debug_id);
|
||||
lock_sock(sk);
|
||||
if (sk->sk_state != RXRPC_SERVER_LISTENING || !rx->backlog) {
|
||||
ret = -ESHUTDOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
b = rx->backlog;
|
||||
ret = rxrpc_service_prealloc_one(rx, b, notify_rx, user_call_ID,
|
||||
gfp, debug_id);
|
||||
|
||||
out:
|
||||
release_sock(sk);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(rxrpc_kernel_charge_accept);
|
||||
|
||||
@@ -161,7 +161,7 @@ static int rxrpc_verify_data(struct rxrpc_call *call, struct sk_buff *skb)
|
||||
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
|
||||
int ret;
|
||||
|
||||
if (sp->len > call->rx_dec_bsize) {
|
||||
if (sp->len > call->rx_dec_bsize || !call->rx_dec_buffer) {
|
||||
/* Make sure we can hold a 1412-byte jumbo subpacket and make
|
||||
* sure that the buffer size is aligned to a crypto blocksize.
|
||||
*/
|
||||
@@ -262,12 +262,13 @@ static int rxrpc_recvmsg_oob(struct socket *sock, struct msghdr *msg,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(flags & MSG_PEEK))
|
||||
if (!(flags & MSG_PEEK)) {
|
||||
skb_unlink(skb, &rx->recvmsg_oobq);
|
||||
if (need_response)
|
||||
rxrpc_add_pending_oob(rx, skb);
|
||||
else
|
||||
rxrpc_free_skb(skb, rxrpc_skb_put_oob);
|
||||
if (need_response)
|
||||
rxrpc_add_pending_oob(rx, skb);
|
||||
else
|
||||
rxrpc_free_skb(skb, rxrpc_skb_put_oob);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -687,16 +687,17 @@ static int rxgk_issue_challenge(struct rxrpc_connection *conn)
|
||||
ret = do_udp_sendmsg(conn->local->socket, &msg, len);
|
||||
if (ret > 0)
|
||||
rxrpc_peer_mark_tx(conn->peer);
|
||||
__free_page(page);
|
||||
|
||||
if (ret < 0) {
|
||||
trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
|
||||
rxrpc_tx_point_rxgk_challenge);
|
||||
__free_page(page);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
trace_rxrpc_tx_packet(conn->debug_id, whdr,
|
||||
rxrpc_tx_point_rxgk_challenge);
|
||||
__free_page(page);
|
||||
_leave(" = 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <net/inet_sock.h>
|
||||
|
||||
#include <net/pkt_cls.h>
|
||||
#include <linux/siphash.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/route.h>
|
||||
#include <net/flow_dissector.h>
|
||||
@@ -57,11 +58,15 @@ struct flow_filter {
|
||||
struct rcu_work rwork;
|
||||
};
|
||||
|
||||
static siphash_aligned_key_t flow_keys_secret __read_mostly;
|
||||
|
||||
static inline u32 addr_fold(void *addr)
|
||||
{
|
||||
unsigned long a = (unsigned long)addr;
|
||||
|
||||
return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0);
|
||||
#ifdef CONFIG_64BIT
|
||||
return (u32)siphash_1u64((u64)addr, &flow_keys_secret);
|
||||
#else
|
||||
return (u32)siphash_1u32((u32)addr, &flow_keys_secret);
|
||||
#endif
|
||||
}
|
||||
|
||||
static u32 flow_get_src(const struct sk_buff *skb, const struct flow_keys *flow)
|
||||
@@ -596,6 +601,7 @@ static int flow_init(struct tcf_proto *tp)
|
||||
return -ENOBUFS;
|
||||
INIT_LIST_HEAD(&head->filters);
|
||||
rcu_assign_pointer(tp->root, head);
|
||||
net_get_random_once(&flow_keys_secret, sizeof(flow_keys_secret));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ static void drop_func(struct sk_buff *skb, void *ctx)
|
||||
qdisc_qstats_drop(sch);
|
||||
}
|
||||
|
||||
static struct sk_buff *codel_qdisc_dequeue(struct Qdisc *sch)
|
||||
static struct sk_buff *__codel_qdisc_dequeue(struct Qdisc *sch)
|
||||
{
|
||||
struct codel_sched_data *q = qdisc_priv(sch);
|
||||
struct sk_buff *skb;
|
||||
@@ -65,13 +65,51 @@ static struct sk_buff *codel_qdisc_dequeue(struct Qdisc *sch)
|
||||
&q->stats, qdisc_pkt_len, codel_get_enqueue_time,
|
||||
drop_func, dequeue_func);
|
||||
|
||||
if (skb)
|
||||
qdisc_bstats_update(sch, skb);
|
||||
return skb;
|
||||
}
|
||||
|
||||
static void codel_dequeue_drop(struct Qdisc *sch)
|
||||
{
|
||||
struct codel_sched_data *q = qdisc_priv(sch);
|
||||
|
||||
if (q->stats.drop_count) {
|
||||
qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len);
|
||||
qdisc_tree_reduce_backlog(sch, q->stats.drop_count,
|
||||
q->stats.drop_len);
|
||||
q->stats.drop_count = 0;
|
||||
q->stats.drop_len = 0;
|
||||
}
|
||||
if (skb)
|
||||
qdisc_bstats_update(sch, skb);
|
||||
}
|
||||
|
||||
static struct sk_buff *codel_qdisc_dequeue(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = __codel_qdisc_dequeue(sch);
|
||||
|
||||
codel_dequeue_drop(sch);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *codel_peek(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb = skb_peek(&sch->gso_skb);
|
||||
|
||||
if (!skb) {
|
||||
skb = __codel_qdisc_dequeue(sch);
|
||||
|
||||
if (skb) {
|
||||
__skb_queue_head(&sch->gso_skb, skb);
|
||||
/* it's still part of the queue */
|
||||
qdisc_qstats_backlog_inc(sch, skb);
|
||||
sch->q.qlen++;
|
||||
}
|
||||
|
||||
codel_dequeue_drop(sch);
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
@@ -257,7 +295,7 @@ static struct Qdisc_ops codel_qdisc_ops __read_mostly = {
|
||||
|
||||
.enqueue = codel_qdisc_enqueue,
|
||||
.dequeue = codel_qdisc_dequeue,
|
||||
.peek = qdisc_peek_dequeued,
|
||||
.peek = codel_peek,
|
||||
.init = codel_init,
|
||||
.reset = codel_reset,
|
||||
.change = codel_change,
|
||||
|
||||
@@ -578,7 +578,7 @@ static void drop_and_retry(struct dualpi2_sched_data *q, struct sk_buff *skb,
|
||||
qdisc_qstats_drop(sch);
|
||||
}
|
||||
|
||||
static struct sk_buff *dualpi2_qdisc_dequeue(struct Qdisc *sch)
|
||||
static struct sk_buff *__dualpi2_qdisc_dequeue(struct Qdisc *sch)
|
||||
{
|
||||
struct dualpi2_sched_data *q = qdisc_priv(sch);
|
||||
struct sk_buff *skb;
|
||||
@@ -605,12 +605,49 @@ static struct sk_buff *dualpi2_qdisc_dequeue(struct Qdisc *sch)
|
||||
break;
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static void dualpi2_dequeue_drop(struct Qdisc *sch)
|
||||
{
|
||||
struct dualpi2_sched_data *q = qdisc_priv(sch);
|
||||
|
||||
if (q->deferred_drops_cnt) {
|
||||
qdisc_tree_reduce_backlog(sch, q->deferred_drops_cnt,
|
||||
q->deferred_drops_len);
|
||||
q->deferred_drops_cnt = 0;
|
||||
q->deferred_drops_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct sk_buff *dualpi2_qdisc_dequeue(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = __dualpi2_qdisc_dequeue(sch);
|
||||
|
||||
dualpi2_dequeue_drop(sch);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *dualpi2_peek(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb = skb_peek(&sch->gso_skb);
|
||||
|
||||
if (!skb) {
|
||||
skb = __dualpi2_qdisc_dequeue(sch);
|
||||
|
||||
if (skb) {
|
||||
__skb_queue_head(&sch->gso_skb, skb);
|
||||
/* it's still part of the queue */
|
||||
qdisc_qstats_backlog_inc(sch, skb);
|
||||
sch->q.qlen++;
|
||||
}
|
||||
|
||||
dualpi2_dequeue_drop(sch);
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
@@ -1165,7 +1202,7 @@ static struct Qdisc_ops dualpi2_qdisc_ops __read_mostly = {
|
||||
.priv_size = sizeof(struct dualpi2_sched_data),
|
||||
.enqueue = dualpi2_qdisc_enqueue,
|
||||
.dequeue = dualpi2_qdisc_dequeue,
|
||||
.peek = qdisc_peek_dequeued,
|
||||
.peek = dualpi2_peek,
|
||||
.init = dualpi2_init,
|
||||
.destroy = dualpi2_destroy,
|
||||
.reset = dualpi2_reset,
|
||||
@@ -1174,6 +1211,7 @@ static struct Qdisc_ops dualpi2_qdisc_ops __read_mostly = {
|
||||
.dump_stats = dualpi2_dump_stats,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
MODULE_ALIAS_NET_SCH("dualpi2");
|
||||
|
||||
static int __init dualpi2_module_init(void)
|
||||
{
|
||||
|
||||
@@ -281,7 +281,7 @@ static void drop_func(struct sk_buff *skb, void *ctx)
|
||||
qdisc_qstats_drop(sch);
|
||||
}
|
||||
|
||||
static struct sk_buff *fq_codel_dequeue(struct Qdisc *sch)
|
||||
static struct sk_buff *__fq_codel_dequeue(struct Qdisc *sch)
|
||||
{
|
||||
struct fq_codel_sched_data *q = qdisc_priv(sch);
|
||||
struct sk_buff *skb;
|
||||
@@ -318,12 +318,49 @@ static struct sk_buff *fq_codel_dequeue(struct Qdisc *sch)
|
||||
qdisc_bstats_update(sch, skb);
|
||||
WRITE_ONCE(flow->deficit, flow->deficit - qdisc_pkt_len(skb));
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static void fq_codel_dequeue_drop(struct Qdisc *sch)
|
||||
{
|
||||
struct fq_codel_sched_data *q = qdisc_priv(sch);
|
||||
|
||||
if (q->cstats.drop_count) {
|
||||
qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
|
||||
q->cstats.drop_len);
|
||||
q->cstats.drop_count = 0;
|
||||
q->cstats.drop_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct sk_buff *fq_codel_dequeue(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = __fq_codel_dequeue(sch);
|
||||
|
||||
fq_codel_dequeue_drop(sch);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *fq_codel_peek(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb = skb_peek(&sch->gso_skb);
|
||||
|
||||
if (!skb) {
|
||||
skb = __fq_codel_dequeue(sch);
|
||||
|
||||
if (skb) {
|
||||
__skb_queue_head(&sch->gso_skb, skb);
|
||||
/* it's still part of the queue */
|
||||
qdisc_qstats_backlog_inc(sch, skb);
|
||||
sch->q.qlen++;
|
||||
}
|
||||
|
||||
fq_codel_dequeue_drop(sch);
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
@@ -726,7 +763,7 @@ static struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = {
|
||||
.priv_size = sizeof(struct fq_codel_sched_data),
|
||||
.enqueue = fq_codel_enqueue,
|
||||
.dequeue = fq_codel_dequeue,
|
||||
.peek = qdisc_peek_dequeued,
|
||||
.peek = fq_codel_peek,
|
||||
.init = fq_codel_init,
|
||||
.reset = fq_codel_reset,
|
||||
.destroy = fq_codel_destroy,
|
||||
|
||||
@@ -568,16 +568,24 @@ static void dev_watchdog(struct timer_list *t)
|
||||
dev->netdev_ops->ndo_tx_timeout(dev, i);
|
||||
netif_unfreeze_queues(dev);
|
||||
}
|
||||
if (!mod_timer(&dev->watchdog_timer,
|
||||
round_jiffies(oldest_start +
|
||||
dev->watchdog_timeo)))
|
||||
release = false;
|
||||
spin_lock(&dev->watchdog_lock);
|
||||
mod_timer(&dev->watchdog_timer,
|
||||
round_jiffies(oldest_start +
|
||||
dev->watchdog_timeo));
|
||||
release = false;
|
||||
spin_unlock(&dev->watchdog_lock);
|
||||
}
|
||||
}
|
||||
spin_unlock(&dev->tx_global_lock);
|
||||
|
||||
if (release)
|
||||
spin_lock(&dev->watchdog_lock);
|
||||
if (timer_pending(&dev->watchdog_timer))
|
||||
release = false;
|
||||
if (release && dev->watchdog_ref_held) {
|
||||
netdev_put(dev, &dev->watchdog_dev_tracker);
|
||||
dev->watchdog_ref_held = false;
|
||||
}
|
||||
spin_unlock(&dev->watchdog_lock);
|
||||
}
|
||||
|
||||
void netdev_watchdog_up(struct net_device *dev)
|
||||
@@ -586,18 +594,34 @@ void netdev_watchdog_up(struct net_device *dev)
|
||||
return;
|
||||
if (dev->watchdog_timeo <= 0)
|
||||
dev->watchdog_timeo = 5*HZ;
|
||||
spin_lock_bh(&dev->tx_global_lock);
|
||||
|
||||
spin_lock(&dev->watchdog_lock);
|
||||
if (!mod_timer(&dev->watchdog_timer,
|
||||
round_jiffies(jiffies + dev->watchdog_timeo)))
|
||||
netdev_hold(dev, &dev->watchdog_dev_tracker,
|
||||
GFP_ATOMIC);
|
||||
round_jiffies(jiffies + dev->watchdog_timeo))) {
|
||||
if (!dev->watchdog_ref_held) {
|
||||
netdev_hold(dev, &dev->watchdog_dev_tracker,
|
||||
GFP_ATOMIC);
|
||||
dev->watchdog_ref_held = true;
|
||||
}
|
||||
}
|
||||
spin_unlock(&dev->watchdog_lock);
|
||||
|
||||
spin_unlock_bh(&dev->tx_global_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(netdev_watchdog_up);
|
||||
|
||||
static void netdev_watchdog_down(struct net_device *dev)
|
||||
{
|
||||
netif_tx_lock_bh(dev);
|
||||
if (timer_delete(&dev->watchdog_timer))
|
||||
|
||||
spin_lock(&dev->watchdog_lock);
|
||||
if (timer_delete(&dev->watchdog_timer)) {
|
||||
netdev_put(dev, &dev->watchdog_dev_tracker);
|
||||
dev->watchdog_ref_held = false;
|
||||
}
|
||||
spin_unlock(&dev->watchdog_lock);
|
||||
|
||||
netif_tx_unlock_bh(dev);
|
||||
}
|
||||
|
||||
@@ -617,8 +641,6 @@ void netif_carrier_on(struct net_device *dev)
|
||||
return;
|
||||
atomic_inc(&dev->carrier_up_count);
|
||||
linkwatch_fire_event(dev);
|
||||
if (netif_running(dev))
|
||||
netdev_watchdog_up(dev);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(netif_carrier_on);
|
||||
|
||||
@@ -753,7 +753,7 @@ update_vf(struct hfsc_class *cl, unsigned int len, u64 cur_time)
|
||||
u64 f; /* , myf_bound, delta; */
|
||||
int go_passive = 0;
|
||||
|
||||
if (cl->qdisc->q.qlen == 0 && cl->cl_flags & HFSC_FSC)
|
||||
if (cl->qdisc->q.qlen == 0 && cl->cl_flags & HFSC_FSC && cl->cl_nactive)
|
||||
go_passive = 1;
|
||||
|
||||
for (; cl->cl_parent != NULL; cl = cl->cl_parent) {
|
||||
|
||||
@@ -2641,6 +2641,9 @@ static int sctp_process_param(struct sctp_association *asoc,
|
||||
goto fall_through;
|
||||
|
||||
addr_param = param.v + sizeof(struct sctp_addip_param);
|
||||
if (ntohs(addr_param->p.length) >
|
||||
ntohs(param.p->length) - sizeof(struct sctp_addip_param))
|
||||
break;
|
||||
|
||||
af = sctp_get_af_specific(param_type2af(addr_param->p.type));
|
||||
if (!af)
|
||||
@@ -3039,13 +3042,16 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
|
||||
union sctp_addr addr;
|
||||
struct sctp_af *af;
|
||||
|
||||
addr_param = (void *)asconf_param + sizeof(*asconf_param);
|
||||
|
||||
if (asconf_param->param_hdr.type != SCTP_PARAM_ADD_IP &&
|
||||
asconf_param->param_hdr.type != SCTP_PARAM_DEL_IP &&
|
||||
asconf_param->param_hdr.type != SCTP_PARAM_SET_PRIMARY)
|
||||
return SCTP_ERROR_UNKNOWN_PARAM;
|
||||
|
||||
addr_param = (void *)asconf_param + sizeof(*asconf_param);
|
||||
if (ntohs(addr_param->p.length) >
|
||||
ntohs(asconf_param->param_hdr.length) - sizeof(*asconf_param))
|
||||
return SCTP_ERROR_PROTO_VIOLATION;
|
||||
|
||||
switch (addr_param->p.type) {
|
||||
case SCTP_PARAM_IPV6_ADDRESS:
|
||||
if (!asoc->peer.ipv6_address)
|
||||
|
||||
@@ -482,6 +482,7 @@ void tipc_disable_l2_media(struct tipc_bearer *b)
|
||||
dev = (struct net_device *)rtnl_dereference(b->media_ptr);
|
||||
dev_remove_pack(&b->pt);
|
||||
RCU_INIT_POINTER(dev->tipc_ptr, NULL);
|
||||
RCU_INIT_POINTER(b->media_ptr, NULL);
|
||||
synchronize_net();
|
||||
dev_put(dev);
|
||||
}
|
||||
|
||||
@@ -280,12 +280,21 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i,
|
||||
u32 node, u32 dtype)
|
||||
{
|
||||
struct publication *p = NULL;
|
||||
u32 lower = ntohl(i->lower);
|
||||
u32 upper = ntohl(i->upper);
|
||||
struct tipc_socket_addr sk;
|
||||
struct tipc_uaddr ua;
|
||||
u32 key = ntohl(i->key);
|
||||
struct tipc_uaddr ua;
|
||||
|
||||
/* A peer-advertised binding with lower > upper can never be matched
|
||||
* or withdrawn and would leak the publication; the local bind path
|
||||
* rejects such ranges, so reject ranges learned from the network too.
|
||||
*/
|
||||
if (lower > upper)
|
||||
return false;
|
||||
|
||||
tipc_uaddr(&ua, TIPC_SERVICE_RANGE, TIPC_CLUSTER_SCOPE,
|
||||
ntohl(i->type), ntohl(i->lower), ntohl(i->upper));
|
||||
ntohl(i->type), lower, upper);
|
||||
sk.ref = ntohl(i->port);
|
||||
sk.node = node;
|
||||
|
||||
|
||||
@@ -152,11 +152,13 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
|
||||
{
|
||||
.cmd = TIPC_NL_BEARER_DISABLE,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.doit = tipc_nl_bearer_disable,
|
||||
},
|
||||
{
|
||||
.cmd = TIPC_NL_BEARER_ENABLE,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.doit = tipc_nl_bearer_enable,
|
||||
},
|
||||
{
|
||||
@@ -168,11 +170,13 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
|
||||
{
|
||||
.cmd = TIPC_NL_BEARER_ADD,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.doit = tipc_nl_bearer_add,
|
||||
},
|
||||
{
|
||||
.cmd = TIPC_NL_BEARER_SET,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.doit = tipc_nl_bearer_set,
|
||||
},
|
||||
{
|
||||
@@ -197,11 +201,13 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
|
||||
{
|
||||
.cmd = TIPC_NL_LINK_SET,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.doit = tipc_nl_node_set_link,
|
||||
},
|
||||
{
|
||||
.cmd = TIPC_NL_LINK_RESET_STATS,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.doit = tipc_nl_node_reset_link_stats,
|
||||
},
|
||||
{
|
||||
@@ -213,6 +219,7 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
|
||||
{
|
||||
.cmd = TIPC_NL_MEDIA_SET,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.doit = tipc_nl_media_set,
|
||||
},
|
||||
{
|
||||
@@ -228,6 +235,7 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
|
||||
{
|
||||
.cmd = TIPC_NL_NET_SET,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.doit = tipc_nl_net_set,
|
||||
},
|
||||
{
|
||||
@@ -238,6 +246,7 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
|
||||
{
|
||||
.cmd = TIPC_NL_MON_SET,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.doit = tipc_nl_node_set_monitor,
|
||||
},
|
||||
{
|
||||
@@ -255,6 +264,7 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
|
||||
{
|
||||
.cmd = TIPC_NL_PEER_REMOVE,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.doit = tipc_nl_peer_rm,
|
||||
},
|
||||
#ifdef CONFIG_TIPC_MEDIA_UDP
|
||||
@@ -269,11 +279,13 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
|
||||
{
|
||||
.cmd = TIPC_NL_KEY_SET,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.doit = tipc_nl_node_set_key,
|
||||
},
|
||||
{
|
||||
.cmd = TIPC_NL_KEY_FLUSH,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
.flags = GENL_UNS_ADMIN_PERM,
|
||||
.doit = tipc_nl_node_flush_key,
|
||||
},
|
||||
#endif
|
||||
|
||||
@@ -1363,6 +1363,9 @@ static void tipc_sk_conn_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb,
|
||||
__skb_queue_tail(xmitq, skb);
|
||||
return;
|
||||
} else if (mtyp == CONN_ACK) {
|
||||
if (tsk->snt_unacked < msg_conn_ack(hdr))
|
||||
goto exit;
|
||||
|
||||
was_cong = tsk_conn_cong(tsk);
|
||||
tipc_sk_push_backlog(tsk, msg_nagle_ack(hdr));
|
||||
tsk->snt_unacked -= msg_conn_ack(hdr);
|
||||
@@ -2453,17 +2456,17 @@ static void tipc_sk_enqueue(struct sk_buff_head *inputq, struct sock *sk,
|
||||
atomic_set(dcnt, 0);
|
||||
lim = rcvbuf_limit(sk, skb) + atomic_read(dcnt);
|
||||
if (likely(!sk_add_backlog(sk, skb, lim))) {
|
||||
trace_tipc_sk_overlimit1(sk, skb, TIPC_DUMP_ALL,
|
||||
trace_tipc_sk_overlimit1(sk, skb, TIPC_DUMP_SK_BKLGQ,
|
||||
"bklg & rcvq >90% allocated!");
|
||||
continue;
|
||||
}
|
||||
|
||||
trace_tipc_sk_dump(sk, skb, TIPC_DUMP_ALL, "err_overload!");
|
||||
trace_tipc_sk_dump(sk, skb, TIPC_DUMP_SK_BKLGQ, "err_overload!");
|
||||
/* Overload => reject message back to sender */
|
||||
onode = tipc_own_addr(sock_net(sk));
|
||||
sk_drops_inc(sk);
|
||||
if (tipc_msg_reverse(onode, &skb, TIPC_ERR_OVERLOAD)) {
|
||||
trace_tipc_sk_rej_msg(sk, skb, TIPC_DUMP_ALL,
|
||||
trace_tipc_sk_rej_msg(sk, skb, TIPC_DUMP_SK_BKLGQ,
|
||||
"@sk_enqueue!");
|
||||
__skb_queue_tail(xmitq, skb);
|
||||
}
|
||||
|
||||
@@ -1378,5 +1378,60 @@
|
||||
"teardown": [
|
||||
"$TC actions flush action ife"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "4e6b",
|
||||
"name": "Decode IFE packet with truncated inner Ethernet header",
|
||||
"category": [
|
||||
"actions",
|
||||
"ife"
|
||||
],
|
||||
"plugins": {
|
||||
"requires": [
|
||||
"nsPlugin",
|
||||
"scapyPlugin"
|
||||
]
|
||||
},
|
||||
"setup": [
|
||||
[
|
||||
"$TC actions flush action ife",
|
||||
0,
|
||||
1,
|
||||
255
|
||||
],
|
||||
"$TC qdisc add dev $DEV1 clsact"
|
||||
],
|
||||
"scapy": [
|
||||
{
|
||||
"iface": "$DEV0",
|
||||
"count": 1,
|
||||
"packet": "Ether(type=0xED3E) / Raw(b'\\x00\\x02\\xaa')"
|
||||
}
|
||||
],
|
||||
"cmdUnderTest": "$TC filter add dev $DEV1 ingress protocol all matchall action ife decode pipe index 10",
|
||||
"expExitCode": "0",
|
||||
"verifyCmd": "$TC -s -j actions get action ife index 10",
|
||||
"matchJSON": [
|
||||
{
|
||||
"total acts": 0
|
||||
},
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"kind": "ife",
|
||||
"mode": "decode",
|
||||
"index": 10,
|
||||
"stats": {
|
||||
"bytes": 3,
|
||||
"packets": 1,
|
||||
"drops": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DEV1 clsact"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1356,5 +1356,189 @@
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY handle 1: root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "c797",
|
||||
"name": "Verify fq_codel won't mistakenly deactivate QFQ parent class during peek",
|
||||
"category": [
|
||||
"qdisc",
|
||||
"qfq",
|
||||
"fq_codel"
|
||||
],
|
||||
"plugins": {
|
||||
"requires": "nsPlugin"
|
||||
},
|
||||
"setup": [
|
||||
"$IP link set dev $DUMMY up || true",
|
||||
"$IP addr add 10.10.10.10/24 dev $DUMMY || true",
|
||||
"$TC qdisc add dev $DUMMY root handle 1: qfq",
|
||||
"$TC class add dev $DUMMY parent 1: classid 1:1 qfq weight 1 maxpkt 1000",
|
||||
"$TC class add dev $DUMMY parent 1: classid 1:2 qfq weight 1 maxpkt 1000",
|
||||
"$TC qdisc add dev $DUMMY parent 1:1 handle 2:0 plug limit 1024",
|
||||
"$IP l set dev $DUMMY mtu 1500",
|
||||
"$TC qdisc add dev $DUMMY parent 1:2 handle 10: fq_codel target 1 interval 1 flows 1",
|
||||
"$TC filter add dev $DUMMY parent 1: protocol ip prio 1 u32 match ip dst 10.10.10.1/32 flowid 1:1",
|
||||
"$TC filter add dev $DUMMY parent 1: protocol ip prio 2 u32 match ip dst 10.10.10.2/32 flowid 1:2",
|
||||
"$IP l set dev $DUMMY mtu 65336",
|
||||
"ping -c 1 -I $DUMMY 10.10.10.1 -W0.01 > /dev/null || true",
|
||||
"ping -c 3 -s 2000 -I $DUMMY 10.10.10.2 -W0.01 > /dev/null || true",
|
||||
"sleep 0.1"
|
||||
],
|
||||
"cmdUnderTest": "$TC qdisc change dev $DUMMY handle 2:0 plug release_indefinite",
|
||||
"expExitCode": "0",
|
||||
"verifyCmd": "$TC -s -j qdisc show dev $DUMMY",
|
||||
"matchJSON": [
|
||||
{
|
||||
"kind": "qfq",
|
||||
"handle": "1:",
|
||||
"packets": 3,
|
||||
"drops": 1,
|
||||
"backlog": 0,
|
||||
"qlen": 0
|
||||
},
|
||||
{
|
||||
"kind": "plug",
|
||||
"handle": "2:",
|
||||
"packets": 1,
|
||||
"drops": 0,
|
||||
"backlog": 0,
|
||||
"qlen": 0
|
||||
},
|
||||
{
|
||||
"kind": "fq_codel",
|
||||
"handle": "10:",
|
||||
"packets": 2,
|
||||
"drops": 1,
|
||||
"backlog": 0,
|
||||
"qlen": 0
|
||||
}
|
||||
],
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY root",
|
||||
"$IP addr del 10.10.10.10/24 dev $DUMMY || true"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "82d9",
|
||||
"name": "Verify codel won't mistakenly deactivate QFQ parent class during peek",
|
||||
"category": [
|
||||
"qdisc",
|
||||
"qfq",
|
||||
"codel"
|
||||
],
|
||||
"plugins": {
|
||||
"requires": "nsPlugin"
|
||||
},
|
||||
"setup": [
|
||||
"$IP link set dev $DUMMY up || true",
|
||||
"$IP addr add 10.10.10.10/24 dev $DUMMY || true",
|
||||
"$TC qdisc add dev $DUMMY root handle 1: qfq",
|
||||
"$TC class add dev $DUMMY parent 1: classid 1:1 qfq weight 1 maxpkt 1000",
|
||||
"$TC class add dev $DUMMY parent 1: classid 1:2 qfq weight 1 maxpkt 1000",
|
||||
"$TC qdisc add dev $DUMMY parent 1:1 handle 2:0 plug limit 1024",
|
||||
"$IP l set dev $DUMMY mtu 1500",
|
||||
"$TC qdisc add dev $DUMMY parent 1:2 handle 10: codel target 1ms interval 1ms",
|
||||
"$TC filter add dev $DUMMY parent 1: protocol ip prio 1 u32 match ip dst 10.10.10.1/32 flowid 1:1",
|
||||
"$TC filter add dev $DUMMY parent 1: protocol ip prio 2 u32 match ip dst 10.10.10.2/32 flowid 1:2",
|
||||
"$IP l set dev $DUMMY mtu 65336",
|
||||
"ping -c 1 -I $DUMMY 10.10.10.1 -W0.01 > /dev/null || true",
|
||||
"ping -c 3 -s 2000 -I $DUMMY 10.10.10.2 -W0.01 > /dev/null || true",
|
||||
"sleep 0.1"
|
||||
],
|
||||
"cmdUnderTest": "$TC qdisc change dev $DUMMY handle 2:0 plug release_indefinite",
|
||||
"expExitCode": "0",
|
||||
"verifyCmd": "$TC -s -j qdisc show dev $DUMMY",
|
||||
"matchJSON": [
|
||||
{
|
||||
"kind": "qfq",
|
||||
"handle": "1:",
|
||||
"packets": 3,
|
||||
"drops": 1,
|
||||
"backlog": 0,
|
||||
"qlen": 0
|
||||
},
|
||||
{
|
||||
"kind": "plug",
|
||||
"handle": "2:",
|
||||
"packets": 1,
|
||||
"drops": 0,
|
||||
"backlog": 0,
|
||||
"qlen": 0
|
||||
},
|
||||
{
|
||||
"kind": "codel",
|
||||
"handle": "10:",
|
||||
"packets": 2,
|
||||
"drops": 1,
|
||||
"backlog": 0,
|
||||
"qlen": 0
|
||||
}
|
||||
],
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY root",
|
||||
"$IP addr del 10.10.10.10/24 dev $DUMMY || true"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "d3da",
|
||||
"name": "Verify dualpi2 won't mistakenly deactivate QFQ parent class during peek",
|
||||
"category": [
|
||||
"qdisc",
|
||||
"qfq",
|
||||
"dualpi2"
|
||||
],
|
||||
"plugins": {
|
||||
"requires": "nsPlugin"
|
||||
},
|
||||
"setup": [
|
||||
"$IP link set dev $DUMMY up || true",
|
||||
"$IP addr add 10.10.10.10/24 dev $DUMMY || true" ,
|
||||
"$TC qdisc add dev $DUMMY root handle 1: qfq",
|
||||
"$TC class add dev $DUMMY parent 1: classid 1:1 qfq weight 1 maxpkt 1000",
|
||||
"$TC class add dev $DUMMY parent 1: classid 1:2 qfq weight 1 maxpkt 1000",
|
||||
"$TC qdisc add dev $DUMMY parent 1:1 handle 2:0 plug limit 1024",
|
||||
"$TC qdisc add dev $DUMMY parent 1:2 handle 10: dualpi2 step_thresh 500ms",
|
||||
"$TC filter add dev $DUMMY parent 10: protocol ip prio 1 matchall classid 10:1 action ok",
|
||||
"$TC filter add dev $DUMMY parent 1: protocol ip prio 1 u32 match ip dst 10.10.10.1/32 flowid 1:1",
|
||||
"$TC filter add dev $DUMMY parent 1: protocol ip prio 2 u32 match ip dst 10.10.10.2/32 flowid 1:2",
|
||||
"ping -c 1 -I $DUMMY 10.10.10.1 -W0.01 || true",
|
||||
"ping -c 3 -i 0.1 -I $DUMMY 10.10.10.2 -W0.01 || true",
|
||||
"sleep 0.7",
|
||||
"ping -c 1 -I $DUMMY 10.10.10.2 -W0.01 || true",
|
||||
"$TC qdisc change dev $DUMMY handle 2:0 plug release_indefinite"
|
||||
],
|
||||
"cmdUnderTest": "ping -c 1 -I $DUMMY 10.10.10.1 -W0.01",
|
||||
"expExitCode": "1",
|
||||
"verifyCmd": "$TC -s -j qdisc show dev $DUMMY",
|
||||
"matchJSON": [
|
||||
{
|
||||
"kind": "qfq",
|
||||
"handle": "1:",
|
||||
"packets": 4,
|
||||
"drops": 2,
|
||||
"backlog": 0,
|
||||
"qlen": 0
|
||||
},
|
||||
{
|
||||
"kind": "plug",
|
||||
"handle": "2:",
|
||||
"packets": 2,
|
||||
"drops": 0,
|
||||
"backlog": 0,
|
||||
"qlen": 0
|
||||
},
|
||||
{
|
||||
"kind": "dualpi2",
|
||||
"handle": "10:",
|
||||
"packets": 2,
|
||||
"drops": 2,
|
||||
"backlog": 0,
|
||||
"qlen": 0
|
||||
}
|
||||
],
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY root",
|
||||
"$IP addr del 10.10.10.10/24 dev $DUMMY || true"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user