Merge tag 'net-6.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Paolo Abeni:
"No fixes from any subtree.
Current release - regressions:
- net: fix the missing unlock for detached devices
Previous releases - regressions:
- sched: fix UAF vulnerability in HFSC qdisc
- lwtunnel: disable BHs when required
- mptcp: pm: defer freeing of MPTCP userspace path manager entries
- tipc: fix NULL pointer dereference in tipc_mon_reinit_self()
- eth: virtio-net: disable delayed refill when pausing rx
Previous releases - always broken:
- phylink: fix suspend/resume with WoL enabled and link down
- eth:
- mlx5: fix null-ptr-deref in mlx5_create_{inner_,}ttc_table()
- xen-netfront: handle NULL returned by xdp_convert_buff_to_frame()
- enetc: fix frame corruption on bpf_xdp_adjust_head/tail() and XDP_PASS
- stmmac: fix dwmac1000 ptp timestamp status offset
- pds_core: prevent possible adminq overflow/stuck condition
Misc:
- a bunch of MAINTAINERS updates"
* tag 'net-6.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (32 commits)
net: stmmac: fix multiplication overflow when reading timestamp
net: stmmac: fix dwmac1000 ptp timestamp status offset
net: dp83822: Fix OF_MDIO config check
pds_core: make wait_context part of q_info
pds_core: Remove unnecessary check in pds_client_adminq_cmd()
pds_core: handle unsupported PDS_CORE_CMD_FW_CONTROL result
pds_core: Prevent possible adminq overflow/stuck condition
net: dsa: mt7530: sync driver-specific behavior of MT7531 variants
selftests/tc-testing: Add test for HFSC queue emptying during peek operation
net_sched: hfsc: Fix a potential UAF in hfsc_dequeue() too
net_sched: hfsc: Fix a UAF vulnerability in class handling
selftests: mptcp: diag: use mptcp_lib_get_info_value
mptcp: pm: Defer freeing of MPTCP userspace path manager entries
net: ethernet: mtk_eth_soc: net: revise NETSYSv3 hardware configuration
tipc: fix NULL pointer dereference in tipc_mon_reinit_self()
virtio-net: disable delayed refill when pausing rx
net: phy: leds: fix memory leak
net: phylink: mac_link_(up|down)() clarifications
net: phylink: fix suspend/resume with WoL enabled and link down
net: lwtunnel: disable BHs when required
...
This commit is contained in:
@@ -3191,6 +3191,12 @@ M: Dinh Nguyen <dinguyen@kernel.org>
|
||||
S: Maintained
|
||||
F: drivers/clk/socfpga/
|
||||
|
||||
ARM/SOCFPGA DWMAC GLUE LAYER
|
||||
M: Maxime Chevallier <maxime.chevallier@bootlin.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/socfpga-dwmac.txt
|
||||
F: drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
|
||||
|
||||
ARM/SOCFPGA EDAC BINDINGS
|
||||
M: Matthew Gerlach <matthew.gerlach@altera.com>
|
||||
S: Maintained
|
||||
@@ -16812,6 +16818,7 @@ F: Documentation/networking/net_cachelines/net_device.rst
|
||||
F: drivers/connector/
|
||||
F: drivers/net/
|
||||
F: drivers/ptp/
|
||||
F: drivers/s390/net/
|
||||
F: include/dt-bindings/net/
|
||||
F: include/linux/cn_proc.h
|
||||
F: include/linux/etherdevice.h
|
||||
@@ -16821,6 +16828,7 @@ F: include/linux/fddidevice.h
|
||||
F: include/linux/hippidevice.h
|
||||
F: include/linux/if_*
|
||||
F: include/linux/inetdevice.h
|
||||
F: include/linux/ism.h
|
||||
F: include/linux/netdev*
|
||||
F: include/linux/platform_data/wiznet.h
|
||||
F: include/uapi/linux/cn_proc.h
|
||||
@@ -21312,6 +21320,7 @@ L: linux-s390@vger.kernel.org
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/s390/net/
|
||||
F: include/linux/ism.h
|
||||
|
||||
S390 PCI SUBSYSTEM
|
||||
M: Niklas Schnelle <schnelle@linux.ibm.com>
|
||||
|
||||
@@ -2419,6 +2419,9 @@ mt7531_setup_common(struct dsa_switch *ds)
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
int ret, i;
|
||||
|
||||
ds->assisted_learning_on_cpu_port = true;
|
||||
ds->mtu_enforcement_ingress = true;
|
||||
|
||||
mt753x_trap_frames(priv);
|
||||
|
||||
/* Enable and reset MIB counters */
|
||||
@@ -2571,9 +2574,6 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ds->assisted_learning_on_cpu_port = true;
|
||||
ds->mtu_enforcement_ingress = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,6 @@
|
||||
|
||||
#include "core.h"
|
||||
|
||||
struct pdsc_wait_context {
|
||||
struct pdsc_qcq *qcq;
|
||||
struct completion wait_completion;
|
||||
};
|
||||
|
||||
static int pdsc_process_notifyq(struct pdsc_qcq *qcq)
|
||||
{
|
||||
union pds_core_notifyq_comp *comp;
|
||||
@@ -109,10 +104,10 @@ void pdsc_process_adminq(struct pdsc_qcq *qcq)
|
||||
q_info = &q->info[q->tail_idx];
|
||||
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
|
||||
|
||||
/* Copy out the completion data */
|
||||
memcpy(q_info->dest, comp, sizeof(*comp));
|
||||
|
||||
complete_all(&q_info->wc->wait_completion);
|
||||
if (!completion_done(&q_info->completion)) {
|
||||
memcpy(q_info->dest, comp, sizeof(*comp));
|
||||
complete(&q_info->completion);
|
||||
}
|
||||
|
||||
if (cq->tail_idx == cq->num_descs - 1)
|
||||
cq->done_color = !cq->done_color;
|
||||
@@ -162,8 +157,7 @@ irqreturn_t pdsc_adminq_isr(int irq, void *data)
|
||||
static int __pdsc_adminq_post(struct pdsc *pdsc,
|
||||
struct pdsc_qcq *qcq,
|
||||
union pds_core_adminq_cmd *cmd,
|
||||
union pds_core_adminq_comp *comp,
|
||||
struct pdsc_wait_context *wc)
|
||||
union pds_core_adminq_comp *comp)
|
||||
{
|
||||
struct pdsc_queue *q = &qcq->q;
|
||||
struct pdsc_q_info *q_info;
|
||||
@@ -205,9 +199,9 @@ static int __pdsc_adminq_post(struct pdsc *pdsc,
|
||||
/* Post the request */
|
||||
index = q->head_idx;
|
||||
q_info = &q->info[index];
|
||||
q_info->wc = wc;
|
||||
q_info->dest = comp;
|
||||
memcpy(q_info->desc, cmd, sizeof(*cmd));
|
||||
reinit_completion(&q_info->completion);
|
||||
|
||||
dev_dbg(pdsc->dev, "head_idx %d tail_idx %d\n",
|
||||
q->head_idx, q->tail_idx);
|
||||
@@ -231,16 +225,13 @@ int pdsc_adminq_post(struct pdsc *pdsc,
|
||||
union pds_core_adminq_comp *comp,
|
||||
bool fast_poll)
|
||||
{
|
||||
struct pdsc_wait_context wc = {
|
||||
.wait_completion =
|
||||
COMPLETION_INITIALIZER_ONSTACK(wc.wait_completion),
|
||||
};
|
||||
unsigned long poll_interval = 1;
|
||||
unsigned long poll_jiffies;
|
||||
unsigned long time_limit;
|
||||
unsigned long time_start;
|
||||
unsigned long time_done;
|
||||
unsigned long remaining;
|
||||
struct completion *wc;
|
||||
int err = 0;
|
||||
int index;
|
||||
|
||||
@@ -250,20 +241,19 @@ int pdsc_adminq_post(struct pdsc *pdsc,
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
wc.qcq = &pdsc->adminqcq;
|
||||
index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp, &wc);
|
||||
index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp);
|
||||
if (index < 0) {
|
||||
err = index;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
wc = &pdsc->adminqcq.q.info[index].completion;
|
||||
time_start = jiffies;
|
||||
time_limit = time_start + HZ * pdsc->devcmd_timeout;
|
||||
do {
|
||||
/* Timeslice the actual wait to catch IO errors etc early */
|
||||
poll_jiffies = msecs_to_jiffies(poll_interval);
|
||||
remaining = wait_for_completion_timeout(&wc.wait_completion,
|
||||
poll_jiffies);
|
||||
remaining = wait_for_completion_timeout(wc, poll_jiffies);
|
||||
if (remaining)
|
||||
break;
|
||||
|
||||
@@ -292,9 +282,11 @@ int pdsc_adminq_post(struct pdsc *pdsc,
|
||||
dev_dbg(pdsc->dev, "%s: elapsed %d msecs\n",
|
||||
__func__, jiffies_to_msecs(time_done - time_start));
|
||||
|
||||
/* Check the results */
|
||||
if (time_after_eq(time_done, time_limit))
|
||||
/* Check the results and clear an un-completed timeout */
|
||||
if (time_after_eq(time_done, time_limit) && !completion_done(wc)) {
|
||||
err = -ETIMEDOUT;
|
||||
complete(wc);
|
||||
}
|
||||
|
||||
dev_dbg(pdsc->dev, "read admin queue completion idx %d:\n", index);
|
||||
dynamic_hex_dump("comp ", DUMP_PREFIX_OFFSET, 16, 1,
|
||||
|
||||
@@ -107,9 +107,6 @@ int pds_client_adminq_cmd(struct pds_auxiliary_dev *padev,
|
||||
dev_dbg(pf->dev, "%s: %s opcode %d\n",
|
||||
__func__, dev_name(&padev->aux_dev.dev), req->opcode);
|
||||
|
||||
if (pf->state)
|
||||
return -ENXIO;
|
||||
|
||||
/* Wrap the client's request */
|
||||
cmd.client_request.opcode = PDS_AQ_CMD_CLIENT_CMD;
|
||||
cmd.client_request.client_id = cpu_to_le16(padev->client_id);
|
||||
|
||||
@@ -167,8 +167,10 @@ static void pdsc_q_map(struct pdsc_queue *q, void *base, dma_addr_t base_pa)
|
||||
q->base = base;
|
||||
q->base_pa = base_pa;
|
||||
|
||||
for (i = 0, cur = q->info; i < q->num_descs; i++, cur++)
|
||||
for (i = 0, cur = q->info; i < q->num_descs; i++, cur++) {
|
||||
cur->desc = base + (i * q->desc_size);
|
||||
init_completion(&cur->completion);
|
||||
}
|
||||
}
|
||||
|
||||
static void pdsc_cq_map(struct pdsc_cq *cq, void *base, dma_addr_t base_pa)
|
||||
@@ -325,10 +327,7 @@ static int pdsc_core_init(struct pdsc *pdsc)
|
||||
size_t sz;
|
||||
int err;
|
||||
|
||||
/* Scale the descriptor ring length based on number of CPUs and VFs */
|
||||
numdescs = max_t(int, PDSC_ADMINQ_MIN_LENGTH, num_online_cpus());
|
||||
numdescs += 2 * pci_sriov_get_totalvfs(pdsc->pdev);
|
||||
numdescs = roundup_pow_of_two(numdescs);
|
||||
numdescs = PDSC_ADMINQ_MAX_LENGTH;
|
||||
err = pdsc_qcq_alloc(pdsc, PDS_CORE_QTYPE_ADMINQ, 0, "adminq",
|
||||
PDS_CORE_QCQ_F_CORE | PDS_CORE_QCQ_F_INTR,
|
||||
numdescs,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#define PDSC_WATCHDOG_SECS 5
|
||||
#define PDSC_QUEUE_NAME_MAX_SZ 16
|
||||
#define PDSC_ADMINQ_MIN_LENGTH 16 /* must be a power of two */
|
||||
#define PDSC_ADMINQ_MAX_LENGTH 16 /* must be a power of two */
|
||||
#define PDSC_NOTIFYQ_LENGTH 64 /* must be a power of two */
|
||||
#define PDSC_TEARDOWN_RECOVERY false
|
||||
#define PDSC_TEARDOWN_REMOVING true
|
||||
@@ -96,7 +96,7 @@ struct pdsc_q_info {
|
||||
unsigned int bytes;
|
||||
unsigned int nbufs;
|
||||
struct pdsc_buf_info bufs[PDS_CORE_MAX_FRAGS];
|
||||
struct pdsc_wait_context *wc;
|
||||
struct completion completion;
|
||||
void *dest;
|
||||
};
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
|
||||
.fw_control.opcode = PDS_CORE_CMD_FW_CONTROL,
|
||||
.fw_control.oper = PDS_CORE_FW_GET_LIST,
|
||||
};
|
||||
struct pds_core_fw_list_info fw_list;
|
||||
struct pds_core_fw_list_info fw_list = {};
|
||||
struct pdsc *pdsc = devlink_priv(dl);
|
||||
union pds_core_dev_comp comp;
|
||||
char buf[32];
|
||||
@@ -118,8 +118,6 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
|
||||
if (!err)
|
||||
memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list));
|
||||
mutex_unlock(&pdsc->devcmd_lock);
|
||||
if (err && err != -EIO)
|
||||
return err;
|
||||
|
||||
listlen = min(fw_list.num_fw_slots, ARRAY_SIZE(fw_list.fw_names));
|
||||
for (i = 0; i < listlen; i++) {
|
||||
|
||||
@@ -1850,6 +1850,16 @@ static void enetc_xdp_drop(struct enetc_bdr *rx_ring, int rx_ring_first,
|
||||
}
|
||||
}
|
||||
|
||||
static void enetc_bulk_flip_buff(struct enetc_bdr *rx_ring, int rx_ring_first,
|
||||
int rx_ring_last)
|
||||
{
|
||||
while (rx_ring_first != rx_ring_last) {
|
||||
enetc_flip_rx_buff(rx_ring,
|
||||
&rx_ring->rx_swbd[rx_ring_first]);
|
||||
enetc_bdr_idx_inc(rx_ring, &rx_ring_first);
|
||||
}
|
||||
}
|
||||
|
||||
static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
|
||||
struct napi_struct *napi, int work_limit,
|
||||
struct bpf_prog *prog)
|
||||
@@ -1868,11 +1878,10 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
|
||||
|
||||
while (likely(rx_frm_cnt < work_limit)) {
|
||||
union enetc_rx_bd *rxbd, *orig_rxbd;
|
||||
int orig_i, orig_cleaned_cnt;
|
||||
struct xdp_buff xdp_buff;
|
||||
struct sk_buff *skb;
|
||||
int orig_i, err;
|
||||
u32 bd_status;
|
||||
int err;
|
||||
|
||||
rxbd = enetc_rxbd(rx_ring, i);
|
||||
bd_status = le32_to_cpu(rxbd->r.lstatus);
|
||||
@@ -1887,7 +1896,6 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
|
||||
break;
|
||||
|
||||
orig_rxbd = rxbd;
|
||||
orig_cleaned_cnt = cleaned_cnt;
|
||||
orig_i = i;
|
||||
|
||||
enetc_build_xdp_buff(rx_ring, bd_status, &rxbd, &i,
|
||||
@@ -1915,15 +1923,21 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
|
||||
rx_ring->stats.xdp_drops++;
|
||||
break;
|
||||
case XDP_PASS:
|
||||
rxbd = orig_rxbd;
|
||||
cleaned_cnt = orig_cleaned_cnt;
|
||||
i = orig_i;
|
||||
|
||||
skb = enetc_build_skb(rx_ring, bd_status, &rxbd,
|
||||
&i, &cleaned_cnt,
|
||||
ENETC_RXB_DMA_SIZE_XDP);
|
||||
if (unlikely(!skb))
|
||||
skb = xdp_build_skb_from_buff(&xdp_buff);
|
||||
/* Probably under memory pressure, stop NAPI */
|
||||
if (unlikely(!skb)) {
|
||||
enetc_xdp_drop(rx_ring, orig_i, i);
|
||||
rx_ring->stats.xdp_drops++;
|
||||
goto out;
|
||||
}
|
||||
|
||||
enetc_get_offloads(rx_ring, orig_rxbd, skb);
|
||||
|
||||
/* These buffers are about to be owned by the stack.
|
||||
* Update our buffer cache (the rx_swbd array elements)
|
||||
* with their other page halves.
|
||||
*/
|
||||
enetc_bulk_flip_buff(rx_ring, orig_i, i);
|
||||
|
||||
napi_gro_receive(napi, skb);
|
||||
break;
|
||||
@@ -1965,11 +1979,7 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
|
||||
enetc_xdp_drop(rx_ring, orig_i, i);
|
||||
rx_ring->stats.xdp_redirect_failures++;
|
||||
} else {
|
||||
while (orig_i != i) {
|
||||
enetc_flip_rx_buff(rx_ring,
|
||||
&rx_ring->rx_swbd[orig_i]);
|
||||
enetc_bdr_idx_inc(rx_ring, &orig_i);
|
||||
}
|
||||
enetc_bulk_flip_buff(rx_ring, orig_i, i);
|
||||
xdp_redirect_frm_cnt++;
|
||||
rx_ring->stats.xdp_redirect++;
|
||||
}
|
||||
@@ -3362,7 +3372,8 @@ static int enetc_int_vector_init(struct enetc_ndev_priv *priv, int i,
|
||||
bdr->buffer_offset = ENETC_RXB_PAD;
|
||||
priv->rx_ring[i] = bdr;
|
||||
|
||||
err = xdp_rxq_info_reg(&bdr->xdp.rxq, priv->ndev, i, 0);
|
||||
err = __xdp_rxq_info_reg(&bdr->xdp.rxq, priv->ndev, i, 0,
|
||||
ENETC_RXB_DMA_SIZE_XDP);
|
||||
if (err)
|
||||
goto free_vector;
|
||||
|
||||
|
||||
@@ -4043,11 +4043,27 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
|
||||
mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
|
||||
|
||||
if (mtk_is_netsys_v3_or_greater(eth)) {
|
||||
/* PSE should not drop port1, port8 and port9 packets */
|
||||
mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
|
||||
/* PSE dummy page mechanism */
|
||||
mtk_w32(eth, PSE_DUMMY_WORK_GDM(1) | PSE_DUMMY_WORK_GDM(2) |
|
||||
PSE_DUMMY_WORK_GDM(3) | DUMMY_PAGE_THR, PSE_DUMY_REQ);
|
||||
|
||||
/* PSE free buffer drop threshold */
|
||||
mtk_w32(eth, 0x00600009, PSE_IQ_REV(8));
|
||||
|
||||
/* PSE should not drop port8, port9 and port13 packets from
|
||||
* WDMA Tx
|
||||
*/
|
||||
mtk_w32(eth, 0x00002300, PSE_DROP_CFG);
|
||||
|
||||
/* PSE should drop packets to port8, port9 and port13 on WDMA Rx
|
||||
* ring full
|
||||
*/
|
||||
mtk_w32(eth, 0x00002300, PSE_PPE_DROP(0));
|
||||
mtk_w32(eth, 0x00002300, PSE_PPE_DROP(1));
|
||||
mtk_w32(eth, 0x00002300, PSE_PPE_DROP(2));
|
||||
|
||||
/* GDM and CDM Threshold */
|
||||
mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
|
||||
mtk_w32(eth, 0x08000707, MTK_CDMW0_THRES);
|
||||
mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
|
||||
|
||||
/* Disable GDM1 RX CRC stripping */
|
||||
@@ -4064,7 +4080,7 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
|
||||
mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
|
||||
|
||||
/* PSE should drop packets to port 8/9 on WDMA Rx ring full */
|
||||
mtk_w32(eth, 0x00000300, PSE_PPE0_DROP);
|
||||
mtk_w32(eth, 0x00000300, PSE_PPE_DROP(0));
|
||||
|
||||
/* PSE Free Queue Flow Control */
|
||||
mtk_w32(eth, 0x01fa01f4, PSE_FQFC_CFG2);
|
||||
|
||||
@@ -151,7 +151,15 @@
|
||||
#define PSE_FQFC_CFG1 0x100
|
||||
#define PSE_FQFC_CFG2 0x104
|
||||
#define PSE_DROP_CFG 0x108
|
||||
#define PSE_PPE0_DROP 0x110
|
||||
#define PSE_PPE_DROP(x) (0x110 + ((x) * 0x4))
|
||||
|
||||
/* PSE Last FreeQ Page Request Control */
|
||||
#define PSE_DUMY_REQ 0x10C
|
||||
/* PSE_DUMY_REQ is not a typo but actually called like that also in
|
||||
* MediaTek's datasheet
|
||||
*/
|
||||
#define PSE_DUMMY_WORK_GDM(x) BIT(16 + (x))
|
||||
#define DUMMY_PAGE_THR 0x1
|
||||
|
||||
/* PSE Input Queue Reservation Register*/
|
||||
#define PSE_IQ_REV(x) (0x140 + (((x) - 1) << 2))
|
||||
|
||||
@@ -637,10 +637,6 @@ struct mlx5_ttc_table *mlx5_create_inner_ttc_table(struct mlx5_core_dev *dev,
|
||||
bool use_l4_type;
|
||||
int err;
|
||||
|
||||
ttc = kvzalloc(sizeof(*ttc), GFP_KERNEL);
|
||||
if (!ttc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
switch (params->ns_type) {
|
||||
case MLX5_FLOW_NAMESPACE_PORT_SEL:
|
||||
use_l4_type = MLX5_CAP_GEN_2(dev, pcc_ifa2) &&
|
||||
@@ -654,7 +650,16 @@ struct mlx5_ttc_table *mlx5_create_inner_ttc_table(struct mlx5_core_dev *dev,
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
ttc = kvzalloc(sizeof(*ttc), GFP_KERNEL);
|
||||
if (!ttc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ns = mlx5_get_flow_namespace(dev, params->ns_type);
|
||||
if (!ns) {
|
||||
kvfree(ttc);
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
groups = use_l4_type ? &inner_ttc_groups[TTC_GROUPS_USE_L4_TYPE] :
|
||||
&inner_ttc_groups[TTC_GROUPS_DEFAULT];
|
||||
|
||||
@@ -710,10 +715,6 @@ struct mlx5_ttc_table *mlx5_create_ttc_table(struct mlx5_core_dev *dev,
|
||||
bool use_l4_type;
|
||||
int err;
|
||||
|
||||
ttc = kvzalloc(sizeof(*ttc), GFP_KERNEL);
|
||||
if (!ttc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
switch (params->ns_type) {
|
||||
case MLX5_FLOW_NAMESPACE_PORT_SEL:
|
||||
use_l4_type = MLX5_CAP_GEN_2(dev, pcc_ifa2) &&
|
||||
@@ -727,7 +728,16 @@ struct mlx5_ttc_table *mlx5_create_ttc_table(struct mlx5_core_dev *dev,
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
ttc = kvzalloc(sizeof(*ttc), GFP_KERNEL);
|
||||
if (!ttc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ns = mlx5_get_flow_namespace(dev, params->ns_type);
|
||||
if (!ns) {
|
||||
kvfree(ttc);
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
groups = use_l4_type ? &ttc_groups[TTC_GROUPS_USE_L4_TYPE] :
|
||||
&ttc_groups[TTC_GROUPS_DEFAULT];
|
||||
|
||||
|
||||
@@ -320,8 +320,8 @@ enum rtc_control {
|
||||
|
||||
/* PTP and timestamping registers */
|
||||
|
||||
#define GMAC3_X_ATSNS GENMASK(19, 16)
|
||||
#define GMAC3_X_ATSNS_SHIFT 16
|
||||
#define GMAC3_X_ATSNS GENMASK(29, 25)
|
||||
#define GMAC3_X_ATSNS_SHIFT 25
|
||||
|
||||
#define GMAC_PTP_TCR_ATSFC BIT(24)
|
||||
#define GMAC_PTP_TCR_ATSEN0 BIT(25)
|
||||
|
||||
@@ -553,7 +553,7 @@ void dwmac1000_get_ptptime(void __iomem *ptpaddr, u64 *ptp_time)
|
||||
u64 ns;
|
||||
|
||||
ns = readl(ptpaddr + GMAC_PTP_ATNR);
|
||||
ns += readl(ptpaddr + GMAC_PTP_ATSR) * NSEC_PER_SEC;
|
||||
ns += (u64)readl(ptpaddr + GMAC_PTP_ATSR) * NSEC_PER_SEC;
|
||||
|
||||
*ptp_time = ns;
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ static void get_ptptime(void __iomem *ptpaddr, u64 *ptp_time)
|
||||
u64 ns;
|
||||
|
||||
ns = readl(ptpaddr + PTP_ATNR);
|
||||
ns += readl(ptpaddr + PTP_ATSR) * NSEC_PER_SEC;
|
||||
ns += (u64)readl(ptpaddr + PTP_ATSR) * NSEC_PER_SEC;
|
||||
|
||||
*ptp_time = ns;
|
||||
}
|
||||
|
||||
@@ -730,7 +730,7 @@ static int dp83822_phy_reset(struct phy_device *phydev)
|
||||
return phydev->drv->config_init(phydev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_MDIO
|
||||
#if IS_ENABLED(CONFIG_OF_MDIO)
|
||||
static const u32 tx_amplitude_100base_tx_gain[] = {
|
||||
80, 82, 83, 85, 87, 88, 90, 92,
|
||||
93, 95, 97, 98, 100, 102, 103, 105,
|
||||
|
||||
@@ -37,47 +37,6 @@ static int lan88xx_write_page(struct phy_device *phydev, int page)
|
||||
return __phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, page);
|
||||
}
|
||||
|
||||
static int lan88xx_phy_config_intr(struct phy_device *phydev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
|
||||
/* unmask all source and clear them before enable */
|
||||
rc = phy_write(phydev, LAN88XX_INT_MASK, 0x7FFF);
|
||||
rc = phy_read(phydev, LAN88XX_INT_STS);
|
||||
rc = phy_write(phydev, LAN88XX_INT_MASK,
|
||||
LAN88XX_INT_MASK_MDINTPIN_EN_ |
|
||||
LAN88XX_INT_MASK_LINK_CHANGE_);
|
||||
} else {
|
||||
rc = phy_write(phydev, LAN88XX_INT_MASK, 0);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Ack interrupts after they have been disabled */
|
||||
rc = phy_read(phydev, LAN88XX_INT_STS);
|
||||
}
|
||||
|
||||
return rc < 0 ? rc : 0;
|
||||
}
|
||||
|
||||
static irqreturn_t lan88xx_handle_interrupt(struct phy_device *phydev)
|
||||
{
|
||||
int irq_status;
|
||||
|
||||
irq_status = phy_read(phydev, LAN88XX_INT_STS);
|
||||
if (irq_status < 0) {
|
||||
phy_error(phydev);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
if (!(irq_status & LAN88XX_INT_STS_LINK_CHANGE_))
|
||||
return IRQ_NONE;
|
||||
|
||||
phy_trigger_machine(phydev);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int lan88xx_suspend(struct phy_device *phydev)
|
||||
{
|
||||
struct lan88xx_priv *priv = phydev->priv;
|
||||
@@ -528,8 +487,9 @@ static struct phy_driver microchip_phy_driver[] = {
|
||||
.config_aneg = lan88xx_config_aneg,
|
||||
.link_change_notify = lan88xx_link_change_notify,
|
||||
|
||||
.config_intr = lan88xx_phy_config_intr,
|
||||
.handle_interrupt = lan88xx_handle_interrupt,
|
||||
/* Interrupt handling is broken, do not define related
|
||||
* functions to force polling.
|
||||
*/
|
||||
|
||||
.suspend = lan88xx_suspend,
|
||||
.resume = genphy_resume,
|
||||
|
||||
@@ -93,9 +93,8 @@ int phy_led_triggers_register(struct phy_device *phy)
|
||||
if (!phy->phy_num_led_triggers)
|
||||
return 0;
|
||||
|
||||
phy->led_link_trigger = devm_kzalloc(&phy->mdio.dev,
|
||||
sizeof(*phy->led_link_trigger),
|
||||
GFP_KERNEL);
|
||||
phy->led_link_trigger = kzalloc(sizeof(*phy->led_link_trigger),
|
||||
GFP_KERNEL);
|
||||
if (!phy->led_link_trigger) {
|
||||
err = -ENOMEM;
|
||||
goto out_clear;
|
||||
@@ -105,10 +104,9 @@ int phy_led_triggers_register(struct phy_device *phy)
|
||||
if (err)
|
||||
goto out_free_link;
|
||||
|
||||
phy->phy_led_triggers = devm_kcalloc(&phy->mdio.dev,
|
||||
phy->phy_num_led_triggers,
|
||||
sizeof(struct phy_led_trigger),
|
||||
GFP_KERNEL);
|
||||
phy->phy_led_triggers = kcalloc(phy->phy_num_led_triggers,
|
||||
sizeof(struct phy_led_trigger),
|
||||
GFP_KERNEL);
|
||||
if (!phy->phy_led_triggers) {
|
||||
err = -ENOMEM;
|
||||
goto out_unreg_link;
|
||||
@@ -129,11 +127,11 @@ int phy_led_triggers_register(struct phy_device *phy)
|
||||
out_unreg:
|
||||
while (i--)
|
||||
phy_led_trigger_unregister(&phy->phy_led_triggers[i]);
|
||||
devm_kfree(&phy->mdio.dev, phy->phy_led_triggers);
|
||||
kfree(phy->phy_led_triggers);
|
||||
out_unreg_link:
|
||||
phy_led_trigger_unregister(phy->led_link_trigger);
|
||||
out_free_link:
|
||||
devm_kfree(&phy->mdio.dev, phy->led_link_trigger);
|
||||
kfree(phy->led_link_trigger);
|
||||
phy->led_link_trigger = NULL;
|
||||
out_clear:
|
||||
phy->phy_num_led_triggers = 0;
|
||||
@@ -147,8 +145,13 @@ void phy_led_triggers_unregister(struct phy_device *phy)
|
||||
|
||||
for (i = 0; i < phy->phy_num_led_triggers; i++)
|
||||
phy_led_trigger_unregister(&phy->phy_led_triggers[i]);
|
||||
kfree(phy->phy_led_triggers);
|
||||
phy->phy_led_triggers = NULL;
|
||||
|
||||
if (phy->led_link_trigger)
|
||||
if (phy->led_link_trigger) {
|
||||
phy_led_trigger_unregister(phy->led_link_trigger);
|
||||
kfree(phy->led_link_trigger);
|
||||
phy->led_link_trigger = NULL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(phy_led_triggers_unregister);
|
||||
|
||||
+22
-16
@@ -81,6 +81,7 @@ struct phylink {
|
||||
unsigned int pcs_state;
|
||||
|
||||
bool link_failed;
|
||||
bool suspend_link_up;
|
||||
bool major_config_failed;
|
||||
bool mac_supports_eee_ops;
|
||||
bool mac_supports_eee;
|
||||
@@ -2545,14 +2546,16 @@ void phylink_suspend(struct phylink *pl, bool mac_wol)
|
||||
/* Stop the resolver bringing the link up */
|
||||
__set_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state);
|
||||
|
||||
/* Disable the carrier, to prevent transmit timeouts,
|
||||
* but one would hope all packets have been sent. This
|
||||
* also means phylink_resolve() will do nothing.
|
||||
*/
|
||||
if (pl->netdev)
|
||||
netif_carrier_off(pl->netdev);
|
||||
else
|
||||
pl->suspend_link_up = phylink_link_is_up(pl);
|
||||
if (pl->suspend_link_up) {
|
||||
/* Disable the carrier, to prevent transmit timeouts,
|
||||
* but one would hope all packets have been sent. This
|
||||
* also means phylink_resolve() will do nothing.
|
||||
*/
|
||||
if (pl->netdev)
|
||||
netif_carrier_off(pl->netdev);
|
||||
pl->old_link_state = false;
|
||||
}
|
||||
|
||||
/* We do not call mac_link_down() here as we want the
|
||||
* link to remain up to receive the WoL packets.
|
||||
@@ -2603,15 +2606,18 @@ void phylink_resume(struct phylink *pl)
|
||||
if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) {
|
||||
/* Wake-on-Lan enabled, MAC handling */
|
||||
|
||||
/* Call mac_link_down() so we keep the overall state balanced.
|
||||
* Do this under the state_mutex lock for consistency. This
|
||||
* will cause a "Link Down" message to be printed during
|
||||
* resume, which is harmless - the true link state will be
|
||||
* printed when we run a resolve.
|
||||
*/
|
||||
mutex_lock(&pl->state_mutex);
|
||||
phylink_link_down(pl);
|
||||
mutex_unlock(&pl->state_mutex);
|
||||
if (pl->suspend_link_up) {
|
||||
/* Call mac_link_down() so we keep the overall state
|
||||
* balanced. Do this under the state_mutex lock for
|
||||
* consistency. This will cause a "Link Down" message
|
||||
* to be printed during resume, which is harmless -
|
||||
* the true link state will be printed when we run a
|
||||
* resolve.
|
||||
*/
|
||||
mutex_lock(&pl->state_mutex);
|
||||
phylink_link_down(pl);
|
||||
mutex_unlock(&pl->state_mutex);
|
||||
}
|
||||
|
||||
/* Re-apply the link parameters so that all the settings get
|
||||
* restored to the MAC.
|
||||
|
||||
+57
-12
@@ -3342,7 +3342,8 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static void virtnet_rx_pause(struct virtnet_info *vi, struct receive_queue *rq)
|
||||
static void __virtnet_rx_pause(struct virtnet_info *vi,
|
||||
struct receive_queue *rq)
|
||||
{
|
||||
bool running = netif_running(vi->dev);
|
||||
|
||||
@@ -3352,17 +3353,63 @@ static void virtnet_rx_pause(struct virtnet_info *vi, struct receive_queue *rq)
|
||||
}
|
||||
}
|
||||
|
||||
static void virtnet_rx_resume(struct virtnet_info *vi, struct receive_queue *rq)
|
||||
static void virtnet_rx_pause_all(struct virtnet_info *vi)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Make sure refill_work does not run concurrently to
|
||||
* avoid napi_disable race which leads to deadlock.
|
||||
*/
|
||||
disable_delayed_refill(vi);
|
||||
cancel_delayed_work_sync(&vi->refill);
|
||||
for (i = 0; i < vi->max_queue_pairs; i++)
|
||||
__virtnet_rx_pause(vi, &vi->rq[i]);
|
||||
}
|
||||
|
||||
static void virtnet_rx_pause(struct virtnet_info *vi, struct receive_queue *rq)
|
||||
{
|
||||
/*
|
||||
* Make sure refill_work does not run concurrently to
|
||||
* avoid napi_disable race which leads to deadlock.
|
||||
*/
|
||||
disable_delayed_refill(vi);
|
||||
cancel_delayed_work_sync(&vi->refill);
|
||||
__virtnet_rx_pause(vi, rq);
|
||||
}
|
||||
|
||||
static void __virtnet_rx_resume(struct virtnet_info *vi,
|
||||
struct receive_queue *rq,
|
||||
bool refill)
|
||||
{
|
||||
bool running = netif_running(vi->dev);
|
||||
|
||||
if (!try_fill_recv(vi, rq, GFP_KERNEL))
|
||||
if (refill && !try_fill_recv(vi, rq, GFP_KERNEL))
|
||||
schedule_delayed_work(&vi->refill, 0);
|
||||
|
||||
if (running)
|
||||
virtnet_napi_enable(rq);
|
||||
}
|
||||
|
||||
static void virtnet_rx_resume_all(struct virtnet_info *vi)
|
||||
{
|
||||
int i;
|
||||
|
||||
enable_delayed_refill(vi);
|
||||
for (i = 0; i < vi->max_queue_pairs; i++) {
|
||||
if (i < vi->curr_queue_pairs)
|
||||
__virtnet_rx_resume(vi, &vi->rq[i], true);
|
||||
else
|
||||
__virtnet_rx_resume(vi, &vi->rq[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
static void virtnet_rx_resume(struct virtnet_info *vi, struct receive_queue *rq)
|
||||
{
|
||||
enable_delayed_refill(vi);
|
||||
__virtnet_rx_resume(vi, rq, true);
|
||||
}
|
||||
|
||||
static int virtnet_rx_resize(struct virtnet_info *vi,
|
||||
struct receive_queue *rq, u32 ring_num)
|
||||
{
|
||||
@@ -5959,12 +6006,12 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
|
||||
if (prog)
|
||||
bpf_prog_add(prog, vi->max_queue_pairs - 1);
|
||||
|
||||
virtnet_rx_pause_all(vi);
|
||||
|
||||
/* Make sure NAPI is not using any XDP TX queues for RX. */
|
||||
if (netif_running(dev)) {
|
||||
for (i = 0; i < vi->max_queue_pairs; i++) {
|
||||
virtnet_napi_disable(&vi->rq[i]);
|
||||
for (i = 0; i < vi->max_queue_pairs; i++)
|
||||
virtnet_napi_tx_disable(&vi->sq[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!prog) {
|
||||
@@ -5996,13 +6043,12 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
|
||||
vi->xdp_enabled = false;
|
||||
}
|
||||
|
||||
virtnet_rx_resume_all(vi);
|
||||
for (i = 0; i < vi->max_queue_pairs; i++) {
|
||||
if (old_prog)
|
||||
bpf_prog_put(old_prog);
|
||||
if (netif_running(dev)) {
|
||||
virtnet_napi_enable(&vi->rq[i]);
|
||||
if (netif_running(dev))
|
||||
virtnet_napi_tx_enable(&vi->sq[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -6014,11 +6060,10 @@ err:
|
||||
rcu_assign_pointer(vi->rq[i].xdp_prog, old_prog);
|
||||
}
|
||||
|
||||
virtnet_rx_resume_all(vi);
|
||||
if (netif_running(dev)) {
|
||||
for (i = 0; i < vi->max_queue_pairs; i++) {
|
||||
virtnet_napi_enable(&vi->rq[i]);
|
||||
for (i = 0; i < vi->max_queue_pairs; i++)
|
||||
virtnet_napi_tx_enable(&vi->sq[i]);
|
||||
}
|
||||
}
|
||||
if (prog)
|
||||
bpf_prog_sub(prog, vi->max_queue_pairs - 1);
|
||||
|
||||
@@ -985,20 +985,27 @@ static u32 xennet_run_xdp(struct netfront_queue *queue, struct page *pdata,
|
||||
act = bpf_prog_run_xdp(prog, xdp);
|
||||
switch (act) {
|
||||
case XDP_TX:
|
||||
get_page(pdata);
|
||||
xdpf = xdp_convert_buff_to_frame(xdp);
|
||||
err = xennet_xdp_xmit(queue->info->netdev, 1, &xdpf, 0);
|
||||
if (unlikely(!err))
|
||||
xdp_return_frame_rx_napi(xdpf);
|
||||
else if (unlikely(err < 0))
|
||||
if (unlikely(!xdpf)) {
|
||||
trace_xdp_exception(queue->info->netdev, prog, act);
|
||||
break;
|
||||
}
|
||||
get_page(pdata);
|
||||
err = xennet_xdp_xmit(queue->info->netdev, 1, &xdpf, 0);
|
||||
if (unlikely(err <= 0)) {
|
||||
if (err < 0)
|
||||
trace_xdp_exception(queue->info->netdev, prog, act);
|
||||
xdp_return_frame_rx_napi(xdpf);
|
||||
}
|
||||
break;
|
||||
case XDP_REDIRECT:
|
||||
get_page(pdata);
|
||||
err = xdp_do_redirect(queue->info->netdev, xdp, prog);
|
||||
*need_xdp_flush = true;
|
||||
if (unlikely(err))
|
||||
if (unlikely(err)) {
|
||||
trace_xdp_exception(queue->info->netdev, prog, act);
|
||||
xdp_return_buff(xdp);
|
||||
}
|
||||
break;
|
||||
case XDP_PASS:
|
||||
case XDP_DROP:
|
||||
|
||||
+20
-11
@@ -361,23 +361,29 @@ int mac_finish(struct phylink_config *config, unsigned int mode,
|
||||
phy_interface_t iface);
|
||||
|
||||
/**
|
||||
* mac_link_down() - take the link down
|
||||
* mac_link_down() - notification that the link has gone down
|
||||
* @config: a pointer to a &struct phylink_config.
|
||||
* @mode: link autonegotiation mode
|
||||
* @interface: link &typedef phy_interface_t mode
|
||||
*
|
||||
* If @mode is not an in-band negotiation mode (as defined by
|
||||
* phylink_autoneg_inband()), force the link down and disable any
|
||||
* Energy Efficient Ethernet MAC configuration. Interface type
|
||||
* selection must be done in mac_config().
|
||||
* Notifies the MAC that the link has gone down. This will not be called
|
||||
* unless mac_link_up() has been previously called.
|
||||
*
|
||||
* The MAC should stop processing packets for transmission and reception.
|
||||
* phylink will have called netif_carrier_off() to notify the networking
|
||||
* stack that the link has gone down, so MAC drivers should not make this
|
||||
* call.
|
||||
*
|
||||
* If @mode is %MLO_AN_INBAND, then this function must not prevent the
|
||||
* link coming up.
|
||||
*/
|
||||
void mac_link_down(struct phylink_config *config, unsigned int mode,
|
||||
phy_interface_t interface);
|
||||
|
||||
/**
|
||||
* mac_link_up() - allow the link to come up
|
||||
* mac_link_up() - notification that the link has come up
|
||||
* @config: a pointer to a &struct phylink_config.
|
||||
* @phy: any attached phy
|
||||
* @phy: any attached phy (deprecated - please use LPI interfaces)
|
||||
* @mode: link autonegotiation mode
|
||||
* @interface: link &typedef phy_interface_t mode
|
||||
* @speed: link speed
|
||||
@@ -385,7 +391,10 @@ void mac_link_down(struct phylink_config *config, unsigned int mode,
|
||||
* @tx_pause: link transmit pause enablement status
|
||||
* @rx_pause: link receive pause enablement status
|
||||
*
|
||||
* Configure the MAC for an established link.
|
||||
* Notifies the MAC that the link has come up, and the parameters of the
|
||||
* link as seen from the MACs point of view. If mac_link_up() has been
|
||||
* called previously, there will be an intervening call to mac_link_down()
|
||||
* before this method will be subsequently called.
|
||||
*
|
||||
* @speed, @duplex, @tx_pause and @rx_pause indicate the finalised link
|
||||
* settings, and should be used to configure the MAC block appropriately
|
||||
@@ -397,9 +406,9 @@ void mac_link_down(struct phylink_config *config, unsigned int mode,
|
||||
* that the user wishes to override the pause settings, and this should
|
||||
* be allowed when considering the implementation of this method.
|
||||
*
|
||||
* If in-band negotiation mode is disabled, allow the link to come up. If
|
||||
* @phy is non-%NULL, configure Energy Efficient Ethernet by calling
|
||||
* phy_init_eee() and perform appropriate MAC configuration for EEE.
|
||||
* Once configured, the MAC may begin to process packets for transmission
|
||||
* and reception.
|
||||
*
|
||||
* Interface type selection must be done in mac_config().
|
||||
*/
|
||||
void mac_link_up(struct phylink_config *config, struct phy_device *phy,
|
||||
|
||||
+20
-6
@@ -333,6 +333,8 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
struct dst_entry *dst;
|
||||
int ret;
|
||||
|
||||
local_bh_disable();
|
||||
|
||||
if (dev_xmit_recursion()) {
|
||||
net_crit_ratelimited("%s(): recursion limit reached on datapath\n",
|
||||
__func__);
|
||||
@@ -348,8 +350,10 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
lwtstate = dst->lwtstate;
|
||||
|
||||
if (lwtstate->type == LWTUNNEL_ENCAP_NONE ||
|
||||
lwtstate->type > LWTUNNEL_ENCAP_MAX)
|
||||
return 0;
|
||||
lwtstate->type > LWTUNNEL_ENCAP_MAX) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = -EOPNOTSUPP;
|
||||
rcu_read_lock();
|
||||
@@ -364,11 +368,13 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
if (ret == -EOPNOTSUPP)
|
||||
goto drop;
|
||||
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
drop:
|
||||
kfree_skb(skb);
|
||||
|
||||
out:
|
||||
local_bh_enable();
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lwtunnel_output);
|
||||
@@ -380,6 +386,8 @@ int lwtunnel_xmit(struct sk_buff *skb)
|
||||
struct dst_entry *dst;
|
||||
int ret;
|
||||
|
||||
local_bh_disable();
|
||||
|
||||
if (dev_xmit_recursion()) {
|
||||
net_crit_ratelimited("%s(): recursion limit reached on datapath\n",
|
||||
__func__);
|
||||
@@ -396,8 +404,10 @@ int lwtunnel_xmit(struct sk_buff *skb)
|
||||
lwtstate = dst->lwtstate;
|
||||
|
||||
if (lwtstate->type == LWTUNNEL_ENCAP_NONE ||
|
||||
lwtstate->type > LWTUNNEL_ENCAP_MAX)
|
||||
return 0;
|
||||
lwtstate->type > LWTUNNEL_ENCAP_MAX) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = -EOPNOTSUPP;
|
||||
rcu_read_lock();
|
||||
@@ -412,11 +422,13 @@ int lwtunnel_xmit(struct sk_buff *skb)
|
||||
if (ret == -EOPNOTSUPP)
|
||||
goto drop;
|
||||
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
drop:
|
||||
kfree_skb(skb);
|
||||
|
||||
out:
|
||||
local_bh_enable();
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lwtunnel_xmit);
|
||||
@@ -428,6 +440,8 @@ int lwtunnel_input(struct sk_buff *skb)
|
||||
struct dst_entry *dst;
|
||||
int ret;
|
||||
|
||||
DEBUG_NET_WARN_ON_ONCE(!in_softirq());
|
||||
|
||||
if (dev_xmit_recursion()) {
|
||||
net_crit_ratelimited("%s(): recursion limit reached on datapath\n",
|
||||
__func__);
|
||||
|
||||
@@ -861,14 +861,17 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
err = 0;
|
||||
netdev = netdev_get_by_index_lock(genl_info_net(info), ifindex);
|
||||
if (!netdev || !netif_device_present(netdev)) {
|
||||
if (!netdev) {
|
||||
err = -ENODEV;
|
||||
goto err_unlock_sock;
|
||||
}
|
||||
|
||||
if (!netdev_need_ops_lock(netdev)) {
|
||||
if (!netif_device_present(netdev))
|
||||
err = -ENODEV;
|
||||
else if (!netdev_need_ops_lock(netdev))
|
||||
err = -EOPNOTSUPP;
|
||||
if (err) {
|
||||
NL_SET_BAD_ATTR(info->extack,
|
||||
info->attrs[NETDEV_A_DEV_IFINDEX]);
|
||||
goto err_unlock;
|
||||
|
||||
+13
-5
@@ -100,10 +100,10 @@ static struct sk_buff *net_test_get_skb(struct net_device *ndev,
|
||||
ehdr->h_proto = htons(ETH_P_IP);
|
||||
|
||||
if (attr->tcp) {
|
||||
memset(thdr, 0, sizeof(*thdr));
|
||||
thdr->source = htons(attr->sport);
|
||||
thdr->dest = htons(attr->dport);
|
||||
thdr->doff = sizeof(struct tcphdr) / 4;
|
||||
thdr->check = 0;
|
||||
} else {
|
||||
uhdr->source = htons(attr->sport);
|
||||
uhdr->dest = htons(attr->dport);
|
||||
@@ -144,10 +144,18 @@ static struct sk_buff *net_test_get_skb(struct net_device *ndev,
|
||||
attr->id = net_test_next_id;
|
||||
shdr->id = net_test_next_id++;
|
||||
|
||||
if (attr->size)
|
||||
skb_put(skb, attr->size);
|
||||
if (attr->max_size && attr->max_size > skb->len)
|
||||
skb_put(skb, attr->max_size - skb->len);
|
||||
if (attr->size) {
|
||||
void *payload = skb_put(skb, attr->size);
|
||||
|
||||
memset(payload, 0, attr->size);
|
||||
}
|
||||
|
||||
if (attr->max_size && attr->max_size > skb->len) {
|
||||
size_t pad_len = attr->max_size - skb->len;
|
||||
void *pad = skb_put(skb, pad_len);
|
||||
|
||||
memset(pad, 0, pad_len);
|
||||
}
|
||||
|
||||
skb->csum = 0;
|
||||
skb->ip_summed = CHECKSUM_PARTIAL;
|
||||
|
||||
@@ -337,7 +337,11 @@ int mptcp_pm_nl_remove_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
|
||||
release_sock(sk);
|
||||
|
||||
sock_kfree_s(sk, match, sizeof(*match));
|
||||
kfree_rcu_mightsleep(match);
|
||||
/* Adjust sk_omem_alloc like sock_kfree_s() does, to match
|
||||
* with allocation of this memory by sock_kmemdup()
|
||||
*/
|
||||
atomic_sub(sizeof(*match), &sk->sk_omem_alloc);
|
||||
|
||||
err = 0;
|
||||
out:
|
||||
|
||||
+17
-6
@@ -961,6 +961,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
||||
|
||||
if (cl != NULL) {
|
||||
int old_flags;
|
||||
int len = 0;
|
||||
|
||||
if (parentid) {
|
||||
if (cl->cl_parent &&
|
||||
@@ -991,9 +992,13 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
||||
if (usc != NULL)
|
||||
hfsc_change_usc(cl, usc, cur_time);
|
||||
|
||||
if (cl->qdisc->q.qlen != 0)
|
||||
len = qdisc_peek_len(cl->qdisc);
|
||||
/* Check queue length again since some qdisc implementations
|
||||
* (e.g., netem/codel) might empty the queue during the peek
|
||||
* operation.
|
||||
*/
|
||||
if (cl->qdisc->q.qlen != 0) {
|
||||
int len = qdisc_peek_len(cl->qdisc);
|
||||
|
||||
if (cl->cl_flags & HFSC_RSC) {
|
||||
if (old_flags & HFSC_RSC)
|
||||
update_ed(cl, len);
|
||||
@@ -1636,10 +1641,16 @@ hfsc_dequeue(struct Qdisc *sch)
|
||||
if (cl->qdisc->q.qlen != 0) {
|
||||
/* update ed */
|
||||
next_len = qdisc_peek_len(cl->qdisc);
|
||||
if (realtime)
|
||||
update_ed(cl, next_len);
|
||||
else
|
||||
update_d(cl, next_len);
|
||||
/* Check queue length again since some qdisc implementations
|
||||
* (e.g., netem/codel) might empty the queue during the peek
|
||||
* operation.
|
||||
*/
|
||||
if (cl->qdisc->q.qlen != 0) {
|
||||
if (realtime)
|
||||
update_ed(cl, next_len);
|
||||
else
|
||||
update_d(cl, next_len);
|
||||
}
|
||||
} else {
|
||||
/* the class becomes passive */
|
||||
eltree_remove(cl);
|
||||
|
||||
+2
-1
@@ -716,7 +716,8 @@ void tipc_mon_reinit_self(struct net *net)
|
||||
if (!mon)
|
||||
continue;
|
||||
write_lock_bh(&mon->lock);
|
||||
mon->self->addr = tipc_own_addr(net);
|
||||
if (mon->self)
|
||||
mon->self->addr = tipc_own_addr(net);
|
||||
write_unlock_bh(&mon->lock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,9 +206,8 @@ chk_dump_one()
|
||||
local token
|
||||
local msg
|
||||
|
||||
ss_token="$(ss -inmHMN $ns | grep 'token:' |\
|
||||
head -n 1 |\
|
||||
sed 's/.*token:\([0-9a-f]*\).*/\1/')"
|
||||
ss_token="$(ss -inmHMN $ns |
|
||||
mptcp_lib_get_info_value "token" "token")"
|
||||
|
||||
token="$(ip netns exec $ns ./mptcp_diag -t $ss_token |\
|
||||
awk -F':[ \t]+' '/^token/ {print $2}')"
|
||||
|
||||
@@ -313,5 +313,44 @@
|
||||
"$TC qdisc del dev $DUMMY handle 1: root",
|
||||
"$IP addr del 10.10.10.10/24 dev $DUMMY || true"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "a4c3",
|
||||
"name": "Test HFSC with netem/blackhole - queue emptying during peek operation",
|
||||
"category": [
|
||||
"qdisc",
|
||||
"hfsc",
|
||||
"netem",
|
||||
"blackhole"
|
||||
],
|
||||
"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 handle 1:0 root drr",
|
||||
"$TC class add dev $DUMMY parent 1:0 classid 1:1 drr",
|
||||
"$TC class add dev $DUMMY parent 1:0 classid 1:2 drr",
|
||||
"$TC qdisc add dev $DUMMY parent 1:1 handle 2:0 plug limit 1024",
|
||||
"$TC qdisc add dev $DUMMY parent 1:2 handle 3:0 hfsc default 1",
|
||||
"$TC class add dev $DUMMY parent 3:0 classid 3:1 hfsc rt m1 5Mbit d 10ms m2 10Mbit",
|
||||
"$TC qdisc add dev $DUMMY parent 3:1 handle 4:0 netem delay 1ms",
|
||||
"$TC qdisc add dev $DUMMY parent 4:1 handle 5:0 blackhole",
|
||||
"ping -c 3 -W 0.01 -i 0.001 -s 1 10.10.10.10 -I $DUMMY > /dev/null 2>&1 || true",
|
||||
"$TC class change dev $DUMMY parent 3:0 classid 3:1 hfsc sc m1 5Mbit d 10ms m2 10Mbit",
|
||||
"$TC class del dev $DUMMY parent 3:0 classid 3:1",
|
||||
"$TC class add dev $DUMMY parent 3:0 classid 3:1 hfsc rt m1 5Mbit d 10ms m2 10Mbit",
|
||||
"ping -c 3 -W 0.01 -i 0.001 -s 1 10.10.10.10 -I $DUMMY > /dev/null 2>&1 || true"
|
||||
],
|
||||
"cmdUnderTest": "$TC class change dev $DUMMY parent 3:0 classid 3:1 hfsc sc m1 5Mbit d 10ms m2 10Mbit",
|
||||
"expExitCode": "0",
|
||||
"verifyCmd": "$TC -s qdisc show dev $DUMMY",
|
||||
"matchPattern": "qdisc hfsc 3:.*parent 1:2.*default 1",
|
||||
"matchCount": "1",
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY handle 1:0 root",
|
||||
"$IP addr del 10.10.10.10/24 dev $DUMMY || true"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user