Pull networking fixes from Paolo Abeni: "Including fixes from netfilter. Current release - regressions: - revert "net: fix cpu_max_bits_warn() usage in netif_attrmask_next{,_and}" - revert "net: sched: fq_codel: remove redundant resource cleanup in fq_codel_init()" - dsa: uninitialized variable in dsa_slave_netdevice_event() - eth: sunhme: uninitialized variable in happy_meal_init() Current release - new code bugs: - eth: octeontx2: fix resource not freed after malloc Previous releases - regressions: - sched: fix return value of qdisc ingress handling on success - sched: fix race condition in qdisc_graft() - udp: update reuse->has_conns under reuseport_lock. - tls: strp: make sure the TCP skbs do not have overlapping data - hsr: avoid possible NULL deref in skb_clone() - tipc: fix an information leak in tipc_topsrv_kern_subscr - phylink: add mac_managed_pm in phylink_config structure - eth: i40e: fix DMA mappings leak - eth: hyperv: fix a RX-path warning - eth: mtk: fix memory leaks Previous releases - always broken: - sched: cake: fix null pointer access issue when cake_init() fails" * tag 'net-6.1-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (43 commits) net: phy: dp83822: disable MDI crossover status change interrupt net: sched: fix race condition in qdisc_graft() net: hns: fix possible memory leak in hnae_ae_register() wwan_hwsim: fix possible memory leak in wwan_hwsim_dev_new() sfc: include vport_id in filter spec hash and equal() genetlink: fix kdoc warnings selftests: add selftest for chaining of tc ingress handling to egress net: Fix return value of qdisc ingress handling on success net: sched: sfb: fix null pointer access issue when sfb_init() fails Revert "net: sched: fq_codel: remove redundant resource cleanup in fq_codel_init()" net: sched: cake: fix null pointer access issue when cake_init() fails ethernet: marvell: octeontx2 Fix resource not freed after malloc netfilter: nf_tables: relax NFTA_SET_ELEM_KEY_END set flags requirements netfilter: rpfilter/fib: Set ->flowic_uid correctly for user namespaces. ionic: catch NULL pointer issue on reconfig net: hsr: avoid possible NULL deref in skb_clone() bnxt_en: fix memory leak in bnxt_nvm_test() ip6mr: fix UAF issue in ip6mr_sk_done() when addrconf_init_net() failed udp: Update reuse->has_conns under reuseport_lock. net: ethernet: mediatek: ppe: Remove the unused function mtk_foe_entry_usable() ...
Unified · Split
| @@ -8,7 +8,6 @@ title: Samsung S3FWRN5 NCI NFC Controller · 7 unmodified lines | |||
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Krzysztof Kozlowski <krzk@kernel.org> | 10 | - Krzysztof Kozlowski <krzk@kernel.org> |
| 11 | - Krzysztof Opasiak <k.opasiak@samsung.com> | ||
| 12 | 11 | ||
| 13 | properties: | 12 | properties: |
| 14 | compatible: | 13 | compatible: |
| @@ -18215,7 +18215,6 @@ F: include/media/drv-intf/s3c_camif.h · 18214 unmodified lines | |||
| 18215 | 18215 | ||
| 18216 | SAMSUNG S3FWRN5 NFC DRIVER | 18216 | SAMSUNG S3FWRN5 NFC DRIVER |
| 18217 | M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | 18217 | M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> |
| 18218 | M: Krzysztof Opasiak <k.opasiak@samsung.com> | ||
| 18219 | L: linux-nfc@lists.01.org (subscribers-only) | 18218 | L: linux-nfc@lists.01.org (subscribers-only) |
| 18220 | S: Maintained | 18219 | S: Maintained |
| 18221 | F: Documentation/devicetree/bindings/net/nfc/samsung,s3fwrn5.yaml | 18220 | F: Documentation/devicetree/bindings/net/nfc/samsung,s3fwrn5.yaml |
| @@ -21297,7 +21296,7 @@ L: linux-usb@vger.kernel.org · 3075 unmodified lines | |||
| 21297 | L: netdev@vger.kernel.org | 21296 | L: netdev@vger.kernel.org |
| 21298 | S: Maintained | 21297 | S: Maintained |
| 21299 | W: https://github.com/petkan/pegasus | 21298 | W: https://github.com/petkan/pegasus |
| 21300 | T: git git://github.com/petkan/pegasus.git | 21299 | T: git https://github.com/petkan/pegasus.git |
| 21301 | F: drivers/net/usb/pegasus.* | 21300 | F: drivers/net/usb/pegasus.* |
| 21302 | 21301 | ||
| 21303 | USB PHY LAYER | 21302 | USB PHY LAYER |
| @@ -21334,7 +21333,7 @@ L: linux-usb@vger.kernel.org · 30 unmodified lines | |||
| 21334 | L: netdev@vger.kernel.org | 21333 | L: netdev@vger.kernel.org |
| 21335 | S: Maintained | 21334 | S: Maintained |
| 21336 | W: https://github.com/petkan/rtl8150 | 21335 | W: https://github.com/petkan/rtl8150 |
| 21337 | T: git git://github.com/petkan/rtl8150.git | 21336 | T: git https://github.com/petkan/rtl8150.git |
| 21338 | F: drivers/net/usb/rtl8150.c | 21337 | F: drivers/net/usb/rtl8150.c |
| 21339 | 21338 | ||
| 21340 | USB SERIAL SUBSYSTEM | 21339 | USB SERIAL SUBSYSTEM |
| @@ -137,27 +137,42 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) · 136 unmodified lines | |||
| 137 | struct qca8k_mgmt_eth_data *mgmt_eth_data; | 137 | struct qca8k_mgmt_eth_data *mgmt_eth_data; |
| 138 | struct qca8k_priv *priv = ds->priv; | 138 | struct qca8k_priv *priv = ds->priv; |
| 139 | struct qca_mgmt_ethhdr *mgmt_ethhdr; | 139 | struct qca_mgmt_ethhdr *mgmt_ethhdr; |
| 140 | u32 command; | ||
| 140 | u8 len, cmd; | 141 | u8 len, cmd; |
| 142 | int i; | ||
| 141 | 143 | ||
| 142 | mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); | 144 | mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); |
| 143 | mgmt_eth_data = &priv->mgmt_eth_data; | 145 | mgmt_eth_data = &priv->mgmt_eth_data; |
| 144 | 146 | ||
| 145 | cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); | 147 | command = get_unaligned_le32(&mgmt_ethhdr->command); |
| 146 | len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); | 148 | cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command); |
| 149 | len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command); | ||
| 147 | 150 | ||
| 148 | /* Make sure the seq match the requested packet */ | 151 | /* Make sure the seq match the requested packet */ |
| 149 | if (mgmt_ethhdr->seq == mgmt_eth_data->seq) | 152 | if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq) |
| 150 | mgmt_eth_data->ack = true; | 153 | mgmt_eth_data->ack = true; |
| 151 | 154 | ||
| 152 | if (cmd == MDIO_READ) { | 155 | if (cmd == MDIO_READ) { |
| 153 | mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; | 156 | u32 *val = mgmt_eth_data->data; |
| 157 | |||
| 158 | *val = get_unaligned_le32(&mgmt_ethhdr->mdio_data); | ||
| 154 | 159 | ||
| 155 | /* Get the rest of the 12 byte of data. | 160 | /* Get the rest of the 12 byte of data. |
| 156 | * The read/write function will extract the requested data. | 161 | * The read/write function will extract the requested data. |
| 157 | */ | 162 | */ |
| 158 | if (len > QCA_HDR_MGMT_DATA1_LEN) | 163 | if (len > QCA_HDR_MGMT_DATA1_LEN) { |
| 159 | memcpy(mgmt_eth_data->data + 1, skb->data, | 164 | __le32 *data2 = (__le32 *)skb->data; |
| 160 | QCA_HDR_MGMT_DATA2_LEN); | 165 | int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN, |
| 166 | len - QCA_HDR_MGMT_DATA1_LEN); | ||
| 167 | |||
| 168 | val++; | ||
| 169 | |||
| 170 | for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) { | ||
| 171 | *val = get_unaligned_le32(data2); | ||
| 172 | val++; | ||
| 173 | data2++; | ||
| 174 | } | ||
| 175 | } | ||
| 161 | } | 176 | } |
| 162 | 177 | ||
| 163 | complete(&mgmt_eth_data->rw_done); | 178 | complete(&mgmt_eth_data->rw_done); |
| @@ -169,8 +184,10 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 * · 5 unmodified lines | |||
| 169 | struct qca_mgmt_ethhdr *mgmt_ethhdr; | 184 | struct qca_mgmt_ethhdr *mgmt_ethhdr; |
| 170 | unsigned int real_len; | 185 | unsigned int real_len; |
| 171 | struct sk_buff *skb; | 186 | struct sk_buff *skb; |
| 172 | u32 *data2; | 187 | __le32 *data2; |
| 188 | u32 command; | ||
| 173 | u16 hdr; | 189 | u16 hdr; |
| 190 | int i; | ||
| 174 | 191 | ||
| 175 | skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); | 192 | skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); |
| 176 | if (!skb) | 193 | if (!skb) |
| @@ -199,20 +216,32 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 * · 22 unmodified lines | |||
| 199 | hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); | 216 | hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); |
| 200 | hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); | 217 | hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); |
| 201 | 218 | ||
| 202 | mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); | 219 | command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); |
| 203 | mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); | 220 | command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); |
| 204 | mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); | 221 | command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); |
| 205 | mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, | 222 | command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, |
| 206 | QCA_HDR_MGMT_CHECK_CODE_VAL); | 223 | QCA_HDR_MGMT_CHECK_CODE_VAL); |
| 207 | 224 | ||
| 225 | put_unaligned_le32(command, &mgmt_ethhdr->command); | ||
| 226 | |||
| 208 | if (cmd == MDIO_WRITE) | 227 | if (cmd == MDIO_WRITE) |
| 209 | mgmt_ethhdr->mdio_data = *val; | 228 | put_unaligned_le32(*val, &mgmt_ethhdr->mdio_data); |
| 210 | 229 | ||
| 211 | mgmt_ethhdr->hdr = htons(hdr); | 230 | mgmt_ethhdr->hdr = htons(hdr); |
| 212 | 231 | ||
| 213 | data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); | 232 | data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); |
| 214 | if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) | 233 | if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) { |
| 215 | memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); | 234 | int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN, |
| 235 | len - QCA_HDR_MGMT_DATA1_LEN); | ||
| 236 | |||
| 237 | val++; | ||
| 238 | |||
| 239 | for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) { | ||
| 240 | put_unaligned_le32(*val, data2); | ||
| 241 | data2++; | ||
| 242 | val++; | ||
| 243 | } | ||
| 244 | } | ||
| 216 | 245 | ||
| 217 | return skb; | 246 | return skb; |
| 218 | } | 247 | } |
| @@ -220,9 +249,11 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 * · 1 unmodified line | |||
| 220 | static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) | 249 | static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) |
| 221 | { | 250 | { |
| 222 | struct qca_mgmt_ethhdr *mgmt_ethhdr; | 251 | struct qca_mgmt_ethhdr *mgmt_ethhdr; |
| 252 | u32 seq; | ||
| 223 | 253 | ||
| 254 | seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); | ||
| 224 | mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; | 255 | mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; |
| 225 | mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); | 256 | put_unaligned_le32(seq, &mgmt_ethhdr->seq); |
| 226 | } | 257 | } |
| 227 | 258 | ||
| 228 | static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) | 259 | static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) |
| @@ -1487,9 +1518,9 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk · 1258 unmodified lines | |||
| 1487 | struct qca8k_priv *priv = ds->priv; | 1518 | struct qca8k_priv *priv = ds->priv; |
| 1488 | const struct qca8k_mib_desc *mib; | 1519 | const struct qca8k_mib_desc *mib; |
| 1489 | struct mib_ethhdr *mib_ethhdr; | 1520 | struct mib_ethhdr *mib_ethhdr; |
| 1490 | int i, mib_len, offset = 0; | 1521 | __le32 *data2; |
| 1491 | u64 *data; | ||
| 1492 | u8 port; | 1522 | u8 port; |
| 1523 | int i; | ||
| 1493 | 1524 | ||
| 1494 | mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); | 1525 | mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); |
| 1495 | mib_eth_data = &priv->mib_eth_data; | 1526 | mib_eth_data = &priv->mib_eth_data; |
| @@ -1501,28 +1532,24 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk · 5 unmodified lines | |||
| 1501 | if (port != mib_eth_data->req_port) | 1532 | if (port != mib_eth_data->req_port) |
| 1502 | goto exit; | 1533 | goto exit; |
| 1503 | 1534 | ||
| 1504 | data = mib_eth_data->data; | 1535 | data2 = (__le32 *)skb->data; |
| 1505 | 1536 | ||
| 1506 | for (i = 0; i < priv->info->mib_count; i++) { | 1537 | for (i = 0; i < priv->info->mib_count; i++) { |
| 1507 | mib = &ar8327_mib[i]; | 1538 | mib = &ar8327_mib[i]; |
| 1508 | 1539 | ||
| 1509 | /* First 3 mib are present in the skb head */ | 1540 | /* First 3 mib are present in the skb head */ |
| 1510 | if (i < 3) { | 1541 | if (i < 3) { |
| 1511 | data[i] = mib_ethhdr->data[i]; | 1542 | mib_eth_data->data[i] = get_unaligned_le32(mib_ethhdr->data + i); |
| 1512 | continue; | 1543 | continue; |
| 1513 | } | 1544 | } |
| 1514 | 1545 | ||
| 1515 | mib_len = sizeof(uint32_t); | ||
| 1516 | |||
| 1517 | /* Some mib are 64 bit wide */ | 1546 | /* Some mib are 64 bit wide */ |
| 1518 | if (mib->size == 2) | 1547 | if (mib->size == 2) |
| 1519 | mib_len = sizeof(uint64_t); | 1548 | mib_eth_data->data[i] = get_unaligned_le64((__le64 *)data2); |
| 1520 | 1549 | else | |
| 1521 | /* Copy the mib value from packet to the */ | 1550 | mib_eth_data->data[i] = get_unaligned_le32(data2); |
| 1522 | memcpy(data + i, skb->data + offset, mib_len); | ||
| 1523 | 1551 | ||
| 1524 | /* Set the offset for the next mib */ | 1552 | data2 += mib->size; |
| 1525 | offset += mib_len; | ||
| 1526 | } | 1553 | } |
| 1527 | 1554 | ||
| 1528 | exit: | 1555 | exit: |
| @@ -613,6 +613,7 @@ static int bnxt_dl_reload_up(struct devlink *dl, enum devlink_reload_action acti · 612 unmodified lines | |||
| 613 | 613 | ||
| 614 | static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack) | 614 | static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack) |
| 615 | { | 615 | { |
| 616 | bool rc = false; | ||
| 616 | u32 datalen; | 617 | u32 datalen; |
| 617 | u16 index; | 618 | u16 index; |
| 618 | u8 *buf; | 619 | u8 *buf; |
| @@ -632,20 +633,20 @@ static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack) · 13 unmodified lines | |||
| 632 | 633 | ||
| 633 | if (bnxt_get_nvram_item(bp->dev, index, 0, datalen, buf)) { | 634 | if (bnxt_get_nvram_item(bp->dev, index, 0, datalen, buf)) { |
| 634 | NL_SET_ERR_MSG_MOD(extack, "nvm test vpd read error"); | 635 | NL_SET_ERR_MSG_MOD(extack, "nvm test vpd read error"); |
| 635 | goto err; | 636 | goto done; |
| 636 | } | 637 | } |
| 637 | 638 | ||
| 638 | if (bnxt_flash_nvram(bp->dev, BNX_DIR_TYPE_VPD, BNX_DIR_ORDINAL_FIRST, | 639 | if (bnxt_flash_nvram(bp->dev, BNX_DIR_TYPE_VPD, BNX_DIR_ORDINAL_FIRST, |
| 639 | BNX_DIR_EXT_NONE, 0, 0, buf, datalen)) { | 640 | BNX_DIR_EXT_NONE, 0, 0, buf, datalen)) { |
| 640 | NL_SET_ERR_MSG_MOD(extack, "nvm test vpd write error"); | 641 | NL_SET_ERR_MSG_MOD(extack, "nvm test vpd write error"); |
| 641 | goto err; | 642 | goto done; |
| 642 | } | 643 | } |
| 643 | 644 | ||
| 644 | return true; | 645 | rc = true; |
| 645 | 646 | ||
| 646 | err: | 647 | done: |
| 647 | kfree(buf); | 648 | kfree(buf); |
| 648 | return false; | 649 | return rc; |
| 649 | } | 650 | } |
| 650 | 651 | ||
| 651 | static bool bnxt_dl_selftest_check(struct devlink *dl, unsigned int id, | 652 | static bool bnxt_dl_selftest_check(struct devlink *dl, unsigned int id, |
| @@ -419,8 +419,10 @@ int hnae_ae_register(struct hnae_ae_dev *hdev, struct module *owner) · 418 unmodified lines | |||
| 419 | hdev->cls_dev.release = hnae_release; | 419 | hdev->cls_dev.release = hnae_release; |
| 420 | (void)dev_set_name(&hdev->cls_dev, "hnae%d", hdev->id); | 420 | (void)dev_set_name(&hdev->cls_dev, "hnae%d", hdev->id); |
| 421 | ret = device_register(&hdev->cls_dev); | 421 | ret = device_register(&hdev->cls_dev); |
| 422 | if (ret) | 422 | if (ret) { |
| 423 | put_device(&hdev->cls_dev); | ||
| 423 | return ret; | 424 | return ret; |
| 425 | } | ||
| 424 | 426 | ||
| 425 | __module_get(THIS_MODULE); | 427 | __module_get(THIS_MODULE); |
| 426 | 428 | ||
| @@ -2181,9 +2181,6 @@ static int i40e_set_ringparam(struct net_device *netdev, · 2180 unmodified lines | |||
| 2181 | */ | 2181 | */ |
| 2182 | rx_rings[i].tail = hw->hw_addr + I40E_PRTGEN_STATUS; | 2182 | rx_rings[i].tail = hw->hw_addr + I40E_PRTGEN_STATUS; |
| 2183 | err = i40e_setup_rx_descriptors(&rx_rings[i]); | 2183 | err = i40e_setup_rx_descriptors(&rx_rings[i]); |
| 2184 | if (err) | ||
| 2185 | goto rx_unwind; | ||
| 2186 | err = i40e_alloc_rx_bi(&rx_rings[i]); | ||
| 2187 | if (err) | 2184 | if (err) |
| 2188 | goto rx_unwind; | 2185 | goto rx_unwind; |
| 2189 | 2186 | ||
| @@ -3566,12 +3566,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) · 3565 unmodified lines | |||
| 3566 | if (ring->vsi->type == I40E_VSI_MAIN) | 3566 | if (ring->vsi->type == I40E_VSI_MAIN) |
| 3567 | xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); | 3567 | xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); |
| 3568 | 3568 | ||
| 3569 | kfree(ring->rx_bi); | ||
| 3570 | ring->xsk_pool = i40e_xsk_pool(ring); | 3569 | ring->xsk_pool = i40e_xsk_pool(ring); |
| 3571 | if (ring->xsk_pool) { | 3570 | if (ring->xsk_pool) { |
| 3572 | ret = i40e_alloc_rx_bi_zc(ring); | ||
| 3573 | if (ret) | ||
| 3574 | return ret; | ||
| 3575 | ring->rx_buf_len = | 3571 | ring->rx_buf_len = |
| 3576 | xsk_pool_get_rx_frame_size(ring->xsk_pool); | 3572 | xsk_pool_get_rx_frame_size(ring->xsk_pool); |
| 3577 | /* For AF_XDP ZC, we disallow packets to span on | 3573 | /* For AF_XDP ZC, we disallow packets to span on |
| @@ -3589,9 +3585,6 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) · 11 unmodified lines | |||
| 3589 | ring->queue_index); | 3585 | ring->queue_index); |
| 3590 | 3586 | ||
| 3591 | } else { | 3587 | } else { |
| 3592 | ret = i40e_alloc_rx_bi(ring); | ||
| 3593 | if (ret) | ||
| 3594 | return ret; | ||
| 3595 | ring->rx_buf_len = vsi->rx_buf_len; | 3588 | ring->rx_buf_len = vsi->rx_buf_len; |
| 3596 | if (ring->vsi->type == I40E_VSI_MAIN) { | 3589 | if (ring->vsi->type == I40E_VSI_MAIN) { |
| 3597 | ret = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, | 3590 | ret = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, |
| @@ -13296,6 +13289,14 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog, · 9698 unmodified lines | |||
| 13296 | i40e_reset_and_rebuild(pf, true, true); | 13289 | i40e_reset_and_rebuild(pf, true, true); |
| 13297 | } | 13290 | } |
| 13298 | 13291 | ||
| 13292 | if (!i40e_enabled_xdp_vsi(vsi) && prog) { | ||
| 13293 | if (i40e_realloc_rx_bi_zc(vsi, true)) | ||
| 13294 | return -ENOMEM; | ||
| 13295 | } else if (i40e_enabled_xdp_vsi(vsi) && !prog) { | ||
| 13296 | if (i40e_realloc_rx_bi_zc(vsi, false)) | ||
| 13297 | return -ENOMEM; | ||
| 13298 | } | ||
| 13299 | |||
| 13299 | for (i = 0; i < vsi->num_queue_pairs; i++) | 13300 | for (i = 0; i < vsi->num_queue_pairs; i++) |
| 13300 | WRITE_ONCE(vsi->rx_rings[i]->xdp_prog, vsi->xdp_prog); | 13301 | WRITE_ONCE(vsi->rx_rings[i]->xdp_prog, vsi->xdp_prog); |
| 13301 | 13302 | ||
| @@ -13528,6 +13529,7 @@ int i40e_queue_pair_disable(struct i40e_vsi *vsi, int queue_pair) · 226 unmodified lines | |||
| 13528 | 13529 | ||
| 13529 | i40e_queue_pair_disable_irq(vsi, queue_pair); | 13530 | i40e_queue_pair_disable_irq(vsi, queue_pair); |
| 13530 | err = i40e_queue_pair_toggle_rings(vsi, queue_pair, false /* off */); | 13531 | err = i40e_queue_pair_toggle_rings(vsi, queue_pair, false /* off */); |
| 13532 | i40e_clean_rx_ring(vsi->rx_rings[queue_pair]); | ||
| 13531 | i40e_queue_pair_toggle_napi(vsi, queue_pair, false /* off */); | 13533 | i40e_queue_pair_toggle_napi(vsi, queue_pair, false /* off */); |
| 13532 | i40e_queue_pair_clean_rings(vsi, queue_pair); | 13534 | i40e_queue_pair_clean_rings(vsi, queue_pair); |
| 13533 | i40e_queue_pair_reset_stats(vsi, queue_pair); | 13535 | i40e_queue_pair_reset_stats(vsi, queue_pair); |
| @@ -1457,14 +1457,6 @@ err: · 1456 unmodified lines | |||
| 1457 | return -ENOMEM; | 1457 | return -ENOMEM; |
| 1458 | } | 1458 | } |
| 1459 | 1459 | ||
| 1460 | int i40e_alloc_rx_bi(struct i40e_ring *rx_ring) | ||
| 1461 | { | ||
| 1462 | unsigned long sz = sizeof(*rx_ring->rx_bi) * rx_ring->count; | ||
| 1463 | |||
| 1464 | rx_ring->rx_bi = kzalloc(sz, GFP_KERNEL); | ||
| 1465 | return rx_ring->rx_bi ? 0 : -ENOMEM; | ||
| 1466 | } | ||
| 1467 | |||
| 1468 | static void i40e_clear_rx_bi(struct i40e_ring *rx_ring) | 1460 | static void i40e_clear_rx_bi(struct i40e_ring *rx_ring) |
| 1469 | { | 1461 | { |
| 1470 | memset(rx_ring->rx_bi, 0, sizeof(*rx_ring->rx_bi) * rx_ring->count); | 1462 | memset(rx_ring->rx_bi, 0, sizeof(*rx_ring->rx_bi) * rx_ring->count); |
| @@ -1593,6 +1585,11 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring) · 122 unmodified lines | |||
| 1593 | 1585 | ||
| 1594 | rx_ring->xdp_prog = rx_ring->vsi->xdp_prog; | 1586 | rx_ring->xdp_prog = rx_ring->vsi->xdp_prog; |
| 1595 | 1587 | ||
| 1588 | rx_ring->rx_bi = | ||
| 1589 | kcalloc(rx_ring->count, sizeof(*rx_ring->rx_bi), GFP_KERNEL); | ||
| 1590 | if (!rx_ring->rx_bi) | ||
| 1591 | return -ENOMEM; | ||
| 1592 | |||
| 1596 | return 0; | 1593 | return 0; |
| 1597 | } | 1594 | } |
| 1598 | 1595 | ||
| @@ -469,7 +469,6 @@ int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size); · 468 unmodified lines | |||
| 469 | bool __i40e_chk_linearize(struct sk_buff *skb); | 469 | bool __i40e_chk_linearize(struct sk_buff *skb); |
| 470 | int i40e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames, | 470 | int i40e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames, |
| 471 | u32 flags); | 471 | u32 flags); |
| 472 | int i40e_alloc_rx_bi(struct i40e_ring *rx_ring); | ||
| 473 | 472 | ||
| 474 | /** | 473 | /** |
| 475 | * i40e_get_head - Retrieve head from head writeback | 474 | * i40e_get_head - Retrieve head from head writeback |
| @@ -10,14 +10,6 @@ · 9 unmodified lines | |||
| 10 | #include "i40e_txrx_common.h" | 10 | #include "i40e_txrx_common.h" |
| 11 | #include "i40e_xsk.h" | 11 | #include "i40e_xsk.h" |
| 12 | 12 | ||
| 13 | int i40e_alloc_rx_bi_zc(struct i40e_ring *rx_ring) | ||
| 14 | { | ||
| 15 | unsigned long sz = sizeof(*rx_ring->rx_bi_zc) * rx_ring->count; | ||
| 16 | |||
| 17 | rx_ring->rx_bi_zc = kzalloc(sz, GFP_KERNEL); | ||
| 18 | return rx_ring->rx_bi_zc ? 0 : -ENOMEM; | ||
| 19 | } | ||
| 20 | |||
| 21 | void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring) | 13 | void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring) |
| 22 | { | 14 | { |
| 23 | memset(rx_ring->rx_bi_zc, 0, | 15 | memset(rx_ring->rx_bi_zc, 0, |
| @@ -29,6 +21,58 @@ static struct xdp_buff **i40e_rx_bi(struct i40e_ring *rx_ring, u32 idx) · 5 unmodified lines | |||
| 29 | return &rx_ring->rx_bi_zc[idx]; | 21 | return &rx_ring->rx_bi_zc[idx]; |
| 30 | } | 22 | } |
| 31 | 23 | ||
| 24 | /** | ||
| 25 | * i40e_realloc_rx_xdp_bi - reallocate SW ring for either XSK or normal buffer | ||
| 26 | * @rx_ring: Current rx ring | ||
| 27 | * @pool_present: is pool for XSK present | ||
| 28 | * | ||
| 29 | * Try allocating memory and return ENOMEM, if failed to allocate. | ||
| 30 | * If allocation was successful, substitute buffer with allocated one. | ||
| 31 | * Returns 0 on success, negative on failure | ||
| 32 | */ | ||
| 33 | static int i40e_realloc_rx_xdp_bi(struct i40e_ring *rx_ring, bool pool_present) | ||
| 34 | { | ||
| 35 | size_t elem_size = pool_present ? sizeof(*rx_ring->rx_bi_zc) : | ||
| 36 | sizeof(*rx_ring->rx_bi); | ||
| 37 | void *sw_ring = kcalloc(rx_ring->count, elem_size, GFP_KERNEL); | ||
| 38 | |||
| 39 | if (!sw_ring) | ||
| 40 | return -ENOMEM; | ||
| 41 | |||
| 42 | if (pool_present) { | ||
| 43 | kfree(rx_ring->rx_bi); | ||
| 44 | rx_ring->rx_bi = NULL; | ||
| 45 | rx_ring->rx_bi_zc = sw_ring; | ||
| 46 | } else { | ||
| 47 | kfree(rx_ring->rx_bi_zc); | ||
| 48 | rx_ring->rx_bi_zc = NULL; | ||
| 49 | rx_ring->rx_bi = sw_ring; | ||
| 50 | } | ||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | |||
| 54 | /** | ||
| 55 | * i40e_realloc_rx_bi_zc - reallocate rx SW rings | ||
| 56 | * @vsi: Current VSI | ||
| 57 | * @zc: is zero copy set | ||
| 58 | * | ||
| 59 | * Reallocate buffer for rx_rings that might be used by XSK. | ||
| 60 | * XDP requires more memory, than rx_buf provides. | ||
| 61 | * Returns 0 on success, negative on failure | ||
| 62 | */ | ||
| 63 | int i40e_realloc_rx_bi_zc(struct i40e_vsi *vsi, bool zc) | ||
| 64 | { | ||
| 65 | struct i40e_ring *rx_ring; | ||
| 66 | unsigned long q; | ||
| 67 | |||
| 68 | for_each_set_bit(q, vsi->af_xdp_zc_qps, vsi->alloc_queue_pairs) { | ||
| 69 | rx_ring = vsi->rx_rings[q]; | ||
| 70 | if (i40e_realloc_rx_xdp_bi(rx_ring, zc)) | ||
| 71 | return -ENOMEM; | ||
| 72 | } | ||
| 73 | return 0; | ||
| 74 | } | ||
| 75 | |||
| 32 | /** | 76 | /** |
| 33 | * i40e_xsk_pool_enable - Enable/associate an AF_XDP buffer pool to a | 77 | * i40e_xsk_pool_enable - Enable/associate an AF_XDP buffer pool to a |
| 34 | * certain ring/qid | 78 | * certain ring/qid |
| @@ -69,6 +113,10 @@ static int i40e_xsk_pool_enable(struct i40e_vsi *vsi, · 34 unmodified lines | |||
| 69 | if (err) | 113 | if (err) |
| 70 | return err; | 114 | return err; |
| 71 | 115 | ||
| 116 | err = i40e_realloc_rx_xdp_bi(vsi->rx_rings[qid], true); | ||
| 117 | if (err) | ||
| 118 | return err; | ||
| 119 | |||
| 72 | err = i40e_queue_pair_enable(vsi, qid); | 120 | err = i40e_queue_pair_enable(vsi, qid); |
| 73 | if (err) | 121 | if (err) |
| 74 | return err; | 122 | return err; |
| @@ -113,6 +161,9 @@ static int i40e_xsk_pool_disable(struct i40e_vsi *vsi, u16 qid) · 38 unmodified lines | |||
| 113 | xsk_pool_dma_unmap(pool, I40E_RX_DMA_ATTR); | 161 | xsk_pool_dma_unmap(pool, I40E_RX_DMA_ATTR); |
| 114 | 162 | ||
| 115 | if (if_running) { | 163 | if (if_running) { |
| 164 | err = i40e_realloc_rx_xdp_bi(vsi->rx_rings[qid], false); | ||
| 165 | if (err) | ||
| 166 | return err; | ||
| 116 | err = i40e_queue_pair_enable(vsi, qid); | 167 | err = i40e_queue_pair_enable(vsi, qid); |
| 117 | if (err) | 168 | if (err) |
| 118 | return err; | 169 | return err; |
| @@ -32,7 +32,7 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget); · 31 unmodified lines | |||
| 32 | 32 | ||
| 33 | bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi, struct i40e_ring *tx_ring); | 33 | bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi, struct i40e_ring *tx_ring); |
| 34 | int i40e_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags); | 34 | int i40e_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags); |
| 35 | int i40e_alloc_rx_bi_zc(struct i40e_ring *rx_ring); | 35 | int i40e_realloc_rx_bi_zc(struct i40e_vsi *vsi, bool zc); |
| 36 | void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring); | 36 | void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring); |
| 37 | 37 | ||
| 38 | #endif /* _I40E_XSK_H_ */ | 38 | #endif /* _I40E_XSK_H_ */ |
| @@ -815,6 +815,7 @@ free_flowid: · 814 unmodified lines | |||
| 815 | cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_FLOWID, | 815 | cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_FLOWID, |
| 816 | txsc->hw_flow_id, false); | 816 | txsc->hw_flow_id, false); |
| 817 | fail: | 817 | fail: |
| 818 | kfree(txsc); | ||
| 818 | return ERR_PTR(ret); | 819 | return ERR_PTR(ret); |
| 819 | } | 820 | } |
| 820 | 821 | ||
| @@ -870,6 +871,7 @@ free_flowid: · 49 unmodified lines | |||
| 870 | cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_FLOWID, | 871 | cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_FLOWID, |
| 871 | rxsc->hw_flow_id, false); | 872 | rxsc->hw_flow_id, false); |
| 872 | fail: | 873 | fail: |
| 874 | kfree(rxsc); | ||
| 873 | return ERR_PTR(ret); | 875 | return ERR_PTR(ret); |
| 874 | } | 876 | } |
| 875 | 877 | ||
| @@ -4060,19 +4060,23 @@ static int mtk_probe(struct platform_device *pdev) · 4059 unmodified lines | |||
| 4060 | eth->irq[i] = platform_get_irq(pdev, i); | 4060 | eth->irq[i] = platform_get_irq(pdev, i); |
| 4061 | if (eth->irq[i] < 0) { | 4061 | if (eth->irq[i] < 0) { |
| 4062 | dev_err(&pdev->dev, "no IRQ%d resource found\n", i); | 4062 | dev_err(&pdev->dev, "no IRQ%d resource found\n", i); |
| 4063 | return -ENXIO; | 4063 | err = -ENXIO; |
| 4064 | goto err_wed_exit; | ||
| 4064 | } | 4065 | } |
| 4065 | } | 4066 | } |
| 4066 | for (i = 0; i < ARRAY_SIZE(eth->clks); i++) { | 4067 | for (i = 0; i < ARRAY_SIZE(eth->clks); i++) { |
| 4067 | eth->clks[i] = devm_clk_get(eth->dev, | 4068 | eth->clks[i] = devm_clk_get(eth->dev, |
| 4068 | mtk_clks_source_name[i]); | 4069 | mtk_clks_source_name[i]); |
| 4069 | if (IS_ERR(eth->clks[i])) { | 4070 | if (IS_ERR(eth->clks[i])) { |
| 4070 | if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER) | 4071 | if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER) { |
| 4071 | return -EPROBE_DEFER; | 4072 | err = -EPROBE_DEFER; |
| 4073 | goto err_wed_exit; | ||
| 4074 | } | ||
| 4072 | if (eth->soc->required_clks & BIT(i)) { | 4075 | if (eth->soc->required_clks & BIT(i)) { |
| 4073 | dev_err(&pdev->dev, "clock %s not found\n", | 4076 | dev_err(&pdev->dev, "clock %s not found\n", |
| 4074 | mtk_clks_source_name[i]); | 4077 | mtk_clks_source_name[i]); |
| 4075 | return -EINVAL; | 4078 | err = -EINVAL; |
| 4079 | goto err_wed_exit; | ||
| 4076 | } | 4080 | } |
| 4077 | eth->clks[i] = NULL; | 4081 | eth->clks[i] = NULL; |
| 4078 | } | 4082 | } |
| @@ -4083,7 +4087,7 @@ static int mtk_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 4083 | 4087 | ||
| 4084 | err = mtk_hw_init(eth); | 4088 | err = mtk_hw_init(eth); |
| 4085 | if (err) | 4089 | if (err) |
| 4086 | return err; | 4090 | goto err_wed_exit; |
| 4087 | 4091 | ||
| 4088 | eth->hwlro = MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO); | 4092 | eth->hwlro = MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO); |
| 4089 | 4093 | ||
| @@ -4179,6 +4183,8 @@ err_free_dev: · 89 unmodified lines | |||
| 4179 | mtk_free_dev(eth); | 4183 | mtk_free_dev(eth); |
| 4180 | err_deinit_hw: | 4184 | err_deinit_hw: |
| 4181 | mtk_hw_deinit(eth); | 4185 | mtk_hw_deinit(eth); |
| 4186 | err_wed_exit: | ||
| 4187 | mtk_wed_exit(); | ||
| 4182 | 4188 | ||
| 4183 | return err; | 4189 | return err; |
| 4184 | } | 4190 | } |
| @@ -4198,6 +4204,7 @@ static int mtk_remove(struct platform_device *pdev) · 13 unmodified lines | |||
| 4198 | phylink_disconnect_phy(mac->phylink); | 4204 | phylink_disconnect_phy(mac->phylink); |
| 4199 | } | 4205 | } |
| 4200 | 4206 | ||
| 4207 | mtk_wed_exit(); | ||
| 4201 | mtk_hw_deinit(eth); | 4208 | mtk_hw_deinit(eth); |
| 4202 | 4209 | ||
| 4203 | netif_napi_del(ð->tx_napi); | 4210 | netif_napi_del(ð->tx_napi); |
| @@ -397,12 +397,6 @@ int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, · 396 unmodified lines | |||
| 397 | return 0; | 397 | return 0; |
| 398 | } | 398 | } |
| 399 | 399 | ||
| 400 | static inline bool mtk_foe_entry_usable(struct mtk_foe_entry *entry) | ||
| 401 | { | ||
| 402 | return !(entry->ib1 & MTK_FOE_IB1_STATIC) && | ||
| 403 | FIELD_GET(MTK_FOE_IB1_STATE, entry->ib1) != MTK_FOE_STATE_BIND; | ||
| 404 | } | ||
| 405 | |||
| 406 | static bool | 400 | static bool |
| 407 | mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, | 401 | mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, |
| 408 | struct mtk_foe_entry *data) | 402 | struct mtk_foe_entry *data) |
| @@ -1072,16 +1072,16 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, · 1071 unmodified lines | |||
| 1072 | 1072 | ||
| 1073 | pdev = of_find_device_by_node(np); | 1073 | pdev = of_find_device_by_node(np); |
| 1074 | if (!pdev) | 1074 | if (!pdev) |
| 1075 | return; | 1075 | goto err_of_node_put; |
| 1076 | 1076 | ||
| 1077 | get_device(&pdev->dev); | 1077 | get_device(&pdev->dev); |
| 1078 | irq = platform_get_irq(pdev, 0); | 1078 | irq = platform_get_irq(pdev, 0); |
| 1079 | if (irq < 0) | 1079 | if (irq < 0) |
| 1080 | return; | 1080 | goto err_put_device; |
| 1081 | 1081 | ||
| 1082 | regs = syscon_regmap_lookup_by_phandle(np, NULL); | 1082 | regs = syscon_regmap_lookup_by_phandle(np, NULL); |
| 1083 | if (IS_ERR(regs)) | 1083 | if (IS_ERR(regs)) |
| 1084 | return; | 1084 | goto err_put_device; |
| 1085 | 1085 | ||
| 1086 | rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops); | 1086 | rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops); |
| 1087 | 1087 | ||
| @@ -1124,8 +1124,16 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, · 36 unmodified lines | |||
| 1124 | 1124 | ||
| 1125 | hw_list[index] = hw; | 1125 | hw_list[index] = hw; |
| 1126 | 1126 | ||
| 1127 | mutex_unlock(&hw_lock); | ||
| 1128 | |||
| 1129 | return; | ||
| 1130 | |||
| 1127 | unlock: | 1131 | unlock: |
| 1128 | mutex_unlock(&hw_lock); | 1132 | mutex_unlock(&hw_lock); |
| 1133 | err_put_device: | ||
| 1134 | put_device(&pdev->dev); | ||
| 1135 | err_of_node_put: | ||
| 1136 | of_node_put(np); | ||
| 1129 | } | 1137 | } |
| 1130 | 1138 | ||
| 1131 | void mtk_wed_exit(void) | 1139 | void mtk_wed_exit(void) |
| @@ -1146,6 +1154,7 @@ void mtk_wed_exit(void) · 14 unmodified lines | |||
| 1146 | hw_list[i] = NULL; | 1154 | hw_list[i] = NULL; |
| 1147 | debugfs_remove(hw->debugfs_dir); | 1155 | debugfs_remove(hw->debugfs_dir); |
| 1148 | put_device(hw->dev); | 1156 | put_device(hw->dev); |
| 1157 | of_node_put(hw->node); | ||
| 1149 | kfree(hw); | 1158 | kfree(hw); |
| 1150 | } | 1159 | } |
| 1151 | } | 1160 | } |
| @@ -2817,11 +2817,15 @@ err_out: · 2816 unmodified lines | |||
| 2817 | * than the full array, but leave the qcq shells in place | 2817 | * than the full array, but leave the qcq shells in place |
| 2818 | */ | 2818 | */ |
| 2819 | for (i = lif->nxqs; i < lif->ionic->ntxqs_per_lif; i++) { | 2819 | for (i = lif->nxqs; i < lif->ionic->ntxqs_per_lif; i++) { |
| 2820 | lif->txqcqs[i]->flags &= ~IONIC_QCQ_F_INTR; | 2820 | if (lif->txqcqs && lif->txqcqs[i]) { |
| 2821 | ionic_qcq_free(lif, lif->txqcqs[i]); | 2821 | lif->txqcqs[i]->flags &= ~IONIC_QCQ_F_INTR; |
| 2822 | ionic_qcq_free(lif, lif->txqcqs[i]); | ||
| 2823 | } | ||
| 2822 | 2824 | ||
| 2823 | lif->rxqcqs[i]->flags &= ~IONIC_QCQ_F_INTR; | 2825 | if (lif->rxqcqs && lif->rxqcqs[i]) { |
| 2824 | ionic_qcq_free(lif, lif->rxqcqs[i]); | 2826 | lif->rxqcqs[i]->flags &= ~IONIC_QCQ_F_INTR; |
| 2827 | ionic_qcq_free(lif, lif->rxqcqs[i]); | ||
| 2828 | } | ||
| 2825 | } | 2829 | } |
| 2826 | 2830 | ||
| 2827 | if (err) | 2831 | if (err) |
| @@ -3277,6 +3277,30 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx) · 3276 unmodified lines | |||
| 3277 | bool was_enabled = efx->port_enabled; | 3277 | bool was_enabled = efx->port_enabled; |
| 3278 | int rc; | 3278 | int rc; |
| 3279 | 3279 | ||
| 3280 | #ifdef CONFIG_SFC_SRIOV | ||
| 3281 | /* If this function is a VF and we have access to the parent PF, | ||
| 3282 | * then use the PF control path to attempt to change the VF MAC address. | ||
| 3283 | */ | ||
| 3284 | if (efx->pci_dev->is_virtfn && efx->pci_dev->physfn) { | ||
| 3285 | struct efx_nic *efx_pf = pci_get_drvdata(efx->pci_dev->physfn); | ||
| 3286 | struct efx_ef10_nic_data *nic_data = efx->nic_data; | ||
| 3287 | u8 mac[ETH_ALEN]; | ||
| 3288 | |||
| 3289 | /* net_dev->dev_addr can be zeroed by efx_net_stop in | ||
| 3290 | * efx_ef10_sriov_set_vf_mac, so pass in a copy. | ||
| 3291 | */ | ||
| 3292 | ether_addr_copy(mac, efx->net_dev->dev_addr); | ||
| 3293 | |||
| 3294 | rc = efx_ef10_sriov_set_vf_mac(efx_pf, nic_data->vf_index, mac); | ||
| 3295 | if (!rc) | ||
| 3296 | return 0; | ||
| 3297 | |||
| 3298 | netif_dbg(efx, drv, efx->net_dev, | ||
| 3299 | "Updating VF mac via PF failed (%d), setting directly\n", | ||
| 3300 | rc); | ||
| 3301 | } | ||
| 3302 | #endif | ||
| 3303 | |||
| 3280 | efx_device_detach_sync(efx); | 3304 | efx_device_detach_sync(efx); |
| 3281 | efx_net_stop(efx->net_dev); | 3305 | efx_net_stop(efx->net_dev); |
| 3282 | 3306 | ||
| @@ -3297,40 +3321,6 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx) · 14 unmodified lines | |||
| 3297 | efx_net_open(efx->net_dev); | 3321 | efx_net_open(efx->net_dev); |
| 3298 | efx_device_attach_if_not_resetting(efx); | 3322 | efx_device_attach_if_not_resetting(efx); |
| 3299 | 3323 | ||
| 3300 | #ifdef CONFIG_SFC_SRIOV | ||
| 3301 | if (efx->pci_dev->is_virtfn && efx->pci_dev->physfn) { | ||
| 3302 | struct efx_ef10_nic_data *nic_data = efx->nic_data; | ||
| 3303 | struct pci_dev *pci_dev_pf = efx->pci_dev->physfn; | ||
| 3304 | |||
| 3305 | if (rc == -EPERM) { | ||
| 3306 | struct efx_nic *efx_pf; | ||
| 3307 | |||
| 3308 | /* Switch to PF and change MAC address on vport */ | ||
| 3309 | efx_pf = pci_get_drvdata(pci_dev_pf); | ||
| 3310 | |||
| 3311 | rc = efx_ef10_sriov_set_vf_mac(efx_pf, | ||
| 3312 | nic_data->vf_index, | ||
| 3313 | efx->net_dev->dev_addr); | ||
| 3314 | } else if (!rc) { | ||
| 3315 | struct efx_nic *efx_pf = pci_get_drvdata(pci_dev_pf); | ||
| 3316 | struct efx_ef10_nic_data *nic_data = efx_pf->nic_data; | ||
| 3317 | unsigned int i; | ||
| 3318 | |||
| 3319 | /* MAC address successfully changed by VF (with MAC | ||
| 3320 | * spoofing) so update the parent PF if possible. | ||
| 3321 | */ | ||
| 3322 | for (i = 0; i < efx_pf->vf_count; ++i) { | ||
| 3323 | struct ef10_vf *vf = nic_data->vf + i; | ||
| 3324 | |||
| 3325 | if (vf->efx == efx) { | ||
| 3326 | ether_addr_copy(vf->mac, | ||
| 3327 | efx->net_dev->dev_addr); | ||
| 3328 | return 0; | ||
| 3329 | } | ||
| 3330 | } | ||
| 3331 | } | ||
| 3332 | } else | ||
| 3333 | #endif | ||
| 3334 | if (rc == -EPERM) { | 3324 | if (rc == -EPERM) { |
| 3335 | netif_err(efx, drv, efx->net_dev, | 3325 | netif_err(efx, drv, efx->net_dev, |
| 3336 | "Cannot change MAC address; use sfboot to enable" | 3326 | "Cannot change MAC address; use sfboot to enable" |
| @@ -162,9 +162,9 @@ struct efx_filter_spec { · 161 unmodified lines | |||
| 162 | u32 priority:2; | 162 | u32 priority:2; |
| 163 | u32 flags:6; | 163 | u32 flags:6; |
| 164 | u32 dmaq_id:12; | 164 | u32 dmaq_id:12; |
| 165 | u32 vport_id; | ||
| 166 | u32 rss_context; | 165 | u32 rss_context; |
| 167 | __be16 outer_vid __aligned(4); /* allow jhash2() of match values */ | 166 | u32 vport_id; |
| 167 | __be16 outer_vid; | ||
| 168 | __be16 inner_vid; | 168 | __be16 inner_vid; |
| 169 | u8 loc_mac[ETH_ALEN]; | 169 | u8 loc_mac[ETH_ALEN]; |
| 170 | u8 rem_mac[ETH_ALEN]; | 170 | u8 rem_mac[ETH_ALEN]; |
| @@ -660,17 +660,17 @@ bool efx_filter_spec_equal(const struct efx_filter_spec *left, · 659 unmodified lines | |||
| 660 | (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX))) | 660 | (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX))) |
| 661 | return false; | 661 | return false; |
| 662 | 662 | ||
| 663 | return memcmp(&left->outer_vid, &right->outer_vid, | 663 | return memcmp(&left->vport_id, &right->vport_id, |
| 664 | sizeof(struct efx_filter_spec) - | 664 | sizeof(struct efx_filter_spec) - |
| 665 | offsetof(struct efx_filter_spec, outer_vid)) == 0; | 665 | offsetof(struct efx_filter_spec, vport_id)) == 0; |
| 666 | } | 666 | } |
| 667 | 667 | ||
| 668 | u32 efx_filter_spec_hash(const struct efx_filter_spec *spec) | 668 | u32 efx_filter_spec_hash(const struct efx_filter_spec *spec) |
| 669 | { | 669 | { |
| 670 | BUILD_BUG_ON(offsetof(struct efx_filter_spec, outer_vid) & 3); | 670 | BUILD_BUG_ON(offsetof(struct efx_filter_spec, vport_id) & 3); |
| 671 | return jhash2((const u32 *)&spec->outer_vid, | 671 | return jhash2((const u32 *)&spec->vport_id, |
| 672 | (sizeof(struct efx_filter_spec) - | 672 | (sizeof(struct efx_filter_spec) - |
| 673 | offsetof(struct efx_filter_spec, outer_vid)) / 4, | 673 | offsetof(struct efx_filter_spec, vport_id)) / 4, |
| 674 | 0); | 674 | 0); |
| 675 | } | 675 | } |
| 676 | 676 | ||
| @@ -1214,6 +1214,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv) · 1213 unmodified lines | |||
| 1214 | if (priv->plat->tx_queues_to_use > 1) | 1214 | if (priv->plat->tx_queues_to_use > 1) |
| 1215 | priv->phylink_config.mac_capabilities &= | 1215 | priv->phylink_config.mac_capabilities &= |
| 1216 | ~(MAC_10HD | MAC_100HD | MAC_1000HD); | 1216 | ~(MAC_10HD | MAC_100HD | MAC_1000HD); |
| 1217 | priv->phylink_config.mac_managed_pm = true; | ||
| 1217 | 1218 | ||
| 1218 | phylink = phylink_create(&priv->phylink_config, fwnode, | 1219 | phylink = phylink_create(&priv->phylink_config, fwnode, |
| 1219 | mode, &stmmac_phylink_mac_ops); | 1220 | mode, &stmmac_phylink_mac_ops); |
| @@ -1328,7 +1328,7 @@ static int happy_meal_init(struct happy_meal *hp) · 1327 unmodified lines | |||
| 1328 | void __iomem *erxregs = hp->erxregs; | 1328 | void __iomem *erxregs = hp->erxregs; |
| 1329 | void __iomem *bregs = hp->bigmacregs; | 1329 | void __iomem *bregs = hp->bigmacregs; |
| 1330 | void __iomem *tregs = hp->tcvregs; | 1330 | void __iomem *tregs = hp->tcvregs; |
| 1331 | const char *bursts; | 1331 | const char *bursts = "64"; |
| 1332 | u32 regtmp, rxcfg; | 1332 | u32 regtmp, rxcfg; |
| 1333 | 1333 | ||
| 1334 | /* If auto-negotiation timer is running, kill it. */ | 1334 | /* If auto-negotiation timer is running, kill it. */ |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | #include <linux/vmalloc.h> | 20 | #include <linux/vmalloc.h> |
| 21 | #include <linux/rtnetlink.h> | 21 | #include <linux/rtnetlink.h> |
| 22 | #include <linux/ucs2_string.h> | 22 | #include <linux/ucs2_string.h> |
| 23 | #include <linux/string.h> | ||
| 23 | 24 | ||
| 24 | #include "hyperv_net.h" | 25 | #include "hyperv_net.h" |
| 25 | #include "netvsc_trace.h" | 26 | #include "netvsc_trace.h" |
| @@ -335,9 +336,10 @@ static void rndis_filter_receive_response(struct net_device *ndev, · 309 unmodified lines | |||
| 335 | if (resp->msg_len <= | 336 | if (resp->msg_len <= |
| 336 | sizeof(struct rndis_message) + RNDIS_EXT_LEN) { | 337 | sizeof(struct rndis_message) + RNDIS_EXT_LEN) { |
| 337 | memcpy(&request->response_msg, resp, RNDIS_HEADER_SIZE + sizeof(*req_id)); | 338 | memcpy(&request->response_msg, resp, RNDIS_HEADER_SIZE + sizeof(*req_id)); |
| 338 | memcpy((void *)&request->response_msg + RNDIS_HEADER_SIZE + sizeof(*req_id), | 339 | unsafe_memcpy((void *)&request->response_msg + RNDIS_HEADER_SIZE + sizeof(*req_id), |
| 339 | data + RNDIS_HEADER_SIZE + sizeof(*req_id), | 340 | data + RNDIS_HEADER_SIZE + sizeof(*req_id), |
| 340 | resp->msg_len - RNDIS_HEADER_SIZE - sizeof(*req_id)); | 341 | resp->msg_len - RNDIS_HEADER_SIZE - sizeof(*req_id), |
| 342 | "request->response_msg is followed by a padding of RNDIS_EXT_LEN inside rndis_request"); | ||
| 341 | if (request->request_msg.ndis_msg_type == | 343 | if (request->request_msg.ndis_msg_type == |
| 342 | RNDIS_MSG_QUERY && request->request_msg.msg. | 344 | RNDIS_MSG_QUERY && request->request_msg.msg. |
| 343 | query_req.oid == RNDIS_OID_GEN_MEDIA_CONNECT_STATUS) | 345 | query_req.oid == RNDIS_OID_GEN_MEDIA_CONNECT_STATUS) |
| @@ -361,7 +361,7 @@ static void macvlan_broadcast_enqueue(struct macvlan_port *port, · 360 unmodified lines | |||
| 361 | } | 361 | } |
| 362 | spin_unlock(&port->bc_queue.lock); | 362 | spin_unlock(&port->bc_queue.lock); |
| 363 | 363 | ||
| 364 | schedule_work(&port->bc_work); | 364 | queue_work(system_unbound_wq, &port->bc_work); |
| 365 | 365 | ||
| 366 | if (err) | 366 | if (err) |
| 367 | goto free_nskb; | 367 | goto free_nskb; |
| @@ -254,8 +254,7 @@ static int dp83822_config_intr(struct phy_device *phydev) · 253 unmodified lines | |||
| 254 | DP83822_EEE_ERROR_CHANGE_INT_EN); | 254 | DP83822_EEE_ERROR_CHANGE_INT_EN); |
| 255 | 255 | ||
| 256 | if (!dp83822->fx_enabled) | 256 | if (!dp83822->fx_enabled) |
| 257 | misr_status |= DP83822_MDI_XOVER_INT_EN | | 257 | misr_status |= DP83822_ANEG_ERR_INT_EN | |
| 258 | DP83822_ANEG_ERR_INT_EN | | ||
| 259 | DP83822_WOL_PKT_INT_EN; | 258 | DP83822_WOL_PKT_INT_EN; |
| 260 | 259 | ||
| 261 | err = phy_write(phydev, MII_DP83822_MISR2, misr_status); | 260 | err = phy_write(phydev, MII_DP83822_MISR2, misr_status); |
| @@ -853,6 +853,14 @@ static int dp83867_config_init(struct phy_device *phydev) · 852 unmodified lines | |||
| 853 | else | 853 | else |
| 854 | val &= ~DP83867_SGMII_TYPE; | 854 | val &= ~DP83867_SGMII_TYPE; |
| 855 | phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL, val); | 855 | phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL, val); |
| 856 | |||
| 857 | /* This is a SW workaround for link instability if RX_CTRL is | ||
| 858 | * not strapped to mode 3 or 4 in HW. This is required for SGMII | ||
| 859 | * in addition to clearing bit 7, handled above. | ||
| 860 | */ | ||
| 861 | if (dp83867->rxctrl_strap_quirk) | ||
| 862 | phy_set_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, | ||
| 863 | BIT(8)); | ||
| 856 | } | 864 | } |
| 857 | 865 | ||
| 858 | val = phy_read(phydev, DP83867_CFG3); | 866 | val = phy_read(phydev, DP83867_CFG3); |
| @@ -1661,6 +1661,9 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy, · 1660 unmodified lines | |||
| 1661 | if (phy_interrupt_is_valid(phy)) | 1661 | if (phy_interrupt_is_valid(phy)) |
| 1662 | phy_request_interrupt(phy); | 1662 | phy_request_interrupt(phy); |
| 1663 | 1663 | ||
| 1664 | if (pl->config->mac_managed_pm) | ||
| 1665 | phy->mac_managed_pm = true; | ||
| 1666 | |||
| 1664 | return 0; | 1667 | return 0; |
| 1665 | } | 1668 | } |
| 1666 | 1669 | ||
| @@ -311,7 +311,7 @@ err_unreg_dev: · 310 unmodified lines | |||
| 311 | return ERR_PTR(err); | 311 | return ERR_PTR(err); |
| 312 | 312 | ||
| 313 | err_free_dev: | 313 | err_free_dev: |
| 314 | kfree(dev); | 314 | put_device(&dev->dev); |
| 315 | 315 | ||
| 316 | return ERR_PTR(err); | 316 | return ERR_PTR(err); |
| 317 | } | 317 | } |
| @@ -61,9 +61,9 @@ struct sk_buff; · 60 unmodified lines | |||
| 61 | 61 | ||
| 62 | /* Special struct emulating a Ethernet header */ | 62 | /* Special struct emulating a Ethernet header */ |
| 63 | struct qca_mgmt_ethhdr { | 63 | struct qca_mgmt_ethhdr { |
| 64 | u32 command; /* command bit 31:0 */ | 64 | __le32 command; /* command bit 31:0 */ |
| 65 | u32 seq; /* seq 63:32 */ | 65 | __le32 seq; /* seq 63:32 */ |
| 66 | u32 mdio_data; /* first 4byte mdio */ | 66 | __le32 mdio_data; /* first 4byte mdio */ |
| 67 | __be16 hdr; /* qca hdr */ | 67 | __be16 hdr; /* qca hdr */ |
| 68 | } __packed; | 68 | } __packed; |
| 69 | 69 | ||
| @@ -73,7 +73,7 @@ enum mdio_cmd { · 3 unmodified lines | |||
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | struct mib_ethhdr { | 75 | struct mib_ethhdr { |
| 76 | u32 data[3]; /* first 3 mib counter */ | 76 | __le32 data[3]; /* first 3 mib counter */ |
| 77 | __be16 hdr; /* qca hdr */ | 77 | __be16 hdr; /* qca hdr */ |
| 78 | } __packed; | 78 | } __packed; |
| 79 | 79 | ||
| @@ -3663,8 +3663,9 @@ static inline bool netif_attr_test_online(unsigned long j, · 3662 unmodified lines | |||
| 3663 | static inline unsigned int netif_attrmask_next(int n, const unsigned long *srcp, | 3663 | static inline unsigned int netif_attrmask_next(int n, const unsigned long *srcp, |
| 3664 | unsigned int nr_bits) | 3664 | unsigned int nr_bits) |
| 3665 | { | 3665 | { |
| 3666 | /* n is a prior cpu */ | 3666 | /* -1 is a legal arg here. */ |
| 3667 | cpu_max_bits_warn(n + 1, nr_bits); | 3667 | if (n != -1) |
| 3668 | cpu_max_bits_warn(n, nr_bits); | ||
| 3668 | 3669 | ||
| 3669 | if (srcp) | 3670 | if (srcp) |
| 3670 | return find_next_bit(srcp, nr_bits, n + 1); | 3671 | return find_next_bit(srcp, nr_bits, n + 1); |
| @@ -3685,8 +3686,9 @@ static inline int netif_attrmask_next_and(int n, const unsigned long *src1p, · 14 unmodified lines | |||
| 3685 | const unsigned long *src2p, | 3686 | const unsigned long *src2p, |
| 3686 | unsigned int nr_bits) | 3687 | unsigned int nr_bits) |
| 3687 | { | 3688 | { |
| 3688 | /* n is a prior cpu */ | 3689 | /* -1 is a legal arg here. */ |
| 3689 | cpu_max_bits_warn(n + 1, nr_bits); | 3690 | if (n != -1) |
| 3691 | cpu_max_bits_warn(n, nr_bits); | ||
| 3690 | 3692 | ||
| 3691 | if (src1p && src2p) | 3693 | if (src1p && src2p) |
| 3692 | return find_next_and_bit(src1p, src2p, nr_bits, n + 1); | 3694 | return find_next_and_bit(src1p, src2p, nr_bits, n + 1); |
| @@ -122,6 +122,7 @@ enum phylink_op_type { · 121 unmodified lines | |||
| 122 | * (See commit 7cceb599d15d ("net: phylink: avoid mac_config calls") | 122 | * (See commit 7cceb599d15d ("net: phylink: avoid mac_config calls") |
| 123 | * @poll_fixed_state: if true, starts link_poll, | 123 | * @poll_fixed_state: if true, starts link_poll, |
| 124 | * if MAC link is at %MLO_AN_FIXED mode. | 124 | * if MAC link is at %MLO_AN_FIXED mode. |
| 125 | * @mac_managed_pm: if true, indicate the MAC driver is responsible for PHY PM. | ||
| 125 | * @ovr_an_inband: if true, override PCS to MLO_AN_INBAND | 126 | * @ovr_an_inband: if true, override PCS to MLO_AN_INBAND |
| 126 | * @get_fixed_state: callback to execute to determine the fixed link state, | 127 | * @get_fixed_state: callback to execute to determine the fixed link state, |
| 127 | * if MAC link is at %MLO_AN_FIXED mode. | 128 | * if MAC link is at %MLO_AN_FIXED mode. |
| @@ -134,6 +135,7 @@ struct phylink_config { · 6 unmodified lines | |||
| 134 | enum phylink_op_type type; | 135 | enum phylink_op_type type; |
| 135 | bool legacy_pre_march2020; | 136 | bool legacy_pre_march2020; |
| 136 | bool poll_fixed_state; | 137 | bool poll_fixed_state; |
| 138 | bool mac_managed_pm; | ||
| 137 | bool ovr_an_inband; | 139 | bool ovr_an_inband; |
| 138 | void (*get_fixed_state)(struct phylink_config *config, | 140 | void (*get_fixed_state)(struct phylink_config *config, |
| 139 | struct phylink_link_state *state); | 141 | struct phylink_link_state *state); |
| @@ -37,6 +37,7 @@ struct genl_info; · 36 unmodified lines | |||
| 37 | * do additional, common, filtering and return an error | 37 | * do additional, common, filtering and return an error |
| 38 | * @post_doit: called after an operation's doit callback, it may | 38 | * @post_doit: called after an operation's doit callback, it may |
| 39 | * undo operations done by pre_doit, for example release locks | 39 | * undo operations done by pre_doit, for example release locks |
| 40 | * @module: pointer to the owning module (set to THIS_MODULE) | ||
| 40 | * @mcgrps: multicast groups used by this family | 41 | * @mcgrps: multicast groups used by this family |
| 41 | * @n_mcgrps: number of multicast groups | 42 | * @n_mcgrps: number of multicast groups |
| 42 | * @resv_start_op: first operation for which reserved fields of the header | 43 | * @resv_start_op: first operation for which reserved fields of the header |
| @@ -173,9 +174,9 @@ struct genl_ops { · 130 unmodified lines | |||
| 173 | }; | 174 | }; |
| 174 | 175 | ||
| 175 | /** | 176 | /** |
| 176 | * struct genl_info - info that is available during dumpit op call | 177 | * struct genl_dumpit_info - info that is available during dumpit op call |
| 177 | * @family: generic netlink family - for internal genl code usage | 178 | * @family: generic netlink family - for internal genl code usage |
| 178 | * @ops: generic netlink ops - for internal genl code usage | 179 | * @op: generic netlink ops - for internal genl code usage |
| 179 | * @attrs: netlink attributes | 180 | * @attrs: netlink attributes |
| 180 | */ | 181 | */ |
| 181 | struct genl_dumpit_info { | 182 | struct genl_dumpit_info { |
| @@ -354,6 +355,7 @@ int genlmsg_multicast_allns(const struct genl_family *family, · 172 unmodified lines | |||
| 354 | 355 | ||
| 355 | /** | 356 | /** |
| 356 | * genlmsg_unicast - unicast a netlink message | 357 | * genlmsg_unicast - unicast a netlink message |
| 358 | * @net: network namespace to look up @portid in | ||
| 357 | * @skb: netlink message as socket buffer | 359 | * @skb: netlink message as socket buffer |
| 358 | * @portid: netlink portid of the destination socket | 360 | * @portid: netlink portid of the destination socket |
| 359 | */ | 361 | */ |
| @@ -373,7 +375,7 @@ static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info) · 13 unmodified lines | |||
| 373 | } | 375 | } |
| 374 | 376 | ||
| 375 | /** | 377 | /** |
| 376 | * gennlmsg_data - head of message payload | 378 | * genlmsg_data - head of message payload |
| 377 | * @gnlh: genetlink message header | 379 | * @gnlh: genetlink message header |
| 378 | */ | 380 | */ |
| 379 | static inline void *genlmsg_data(const struct genlmsghdr *gnlh) | 381 | static inline void *genlmsg_data(const struct genlmsghdr *gnlh) |
| @@ -43,21 +43,20 @@ struct sock *reuseport_migrate_sock(struct sock *sk, · 42 unmodified lines | |||
| 43 | extern int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog); | 43 | extern int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog); |
| 44 | extern int reuseport_detach_prog(struct sock *sk); | 44 | extern int reuseport_detach_prog(struct sock *sk); |
| 45 | 45 | ||
| 46 | static inline bool reuseport_has_conns(struct sock *sk, bool set) | 46 | static inline bool reuseport_has_conns(struct sock *sk) |
| 47 | { | 47 | { |
| 48 | struct sock_reuseport *reuse; | 48 | struct sock_reuseport *reuse; |
| 49 | bool ret = false; | 49 | bool ret = false; |
| 50 | 50 | ||
| 51 | rcu_read_lock(); | 51 | rcu_read_lock(); |
| 52 | reuse = rcu_dereference(sk->sk_reuseport_cb); | 52 | reuse = rcu_dereference(sk->sk_reuseport_cb); |
| 53 | if (reuse) { | 53 | if (reuse && reuse->has_conns) |
| 54 | if (set) | 54 | ret = true; |
| 55 | reuse->has_conns = 1; | ||
| 56 | ret = reuse->has_conns; | ||
| 57 | } | ||
| 58 | rcu_read_unlock(); | 55 | rcu_read_unlock(); |
| 59 | 56 | ||
| 60 | return ret; | 57 | return ret; |
| 61 | } | 58 | } |
| 62 | 59 | ||
| 60 | void reuseport_has_conns_set(struct sock *sk); | ||
| 61 | |||
| 63 | #endif /* _SOCK_REUSEPORT_H */ | 62 | #endif /* _SOCK_REUSEPORT_H */ |
| @@ -219,11 +219,12 @@ static ssize_t proc_mpc_write(struct file *file, const char __user *buff, · 218 unmodified lines | |||
| 219 | if (!page) | 219 | if (!page) |
| 220 | return -ENOMEM; | 220 | return -ENOMEM; |
| 221 | 221 | ||
| 222 | for (p = page, len = 0; len < nbytes; p++, len++) { | 222 | for (p = page, len = 0; len < nbytes; p++) { |
| 223 | if (get_user(*p, buff++)) { | 223 | if (get_user(*p, buff++)) { |
| 224 | free_page((unsigned long)page); | 224 | free_page((unsigned long)page); |
| 225 | return -EFAULT; | 225 | return -EFAULT; |
| 226 | } | 226 | } |
| 227 | len += 1; | ||
| 227 | if (*p == '\0' || *p == '\n') | 228 | if (*p == '\0' || *p == '\n') |
| 228 | break; | 229 | break; |
| 229 | } | 230 | } |
| @@ -5136,11 +5136,13 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret, · 5135 unmodified lines | |||
| 5136 | case TC_ACT_SHOT: | 5136 | case TC_ACT_SHOT: |
| 5137 | mini_qdisc_qstats_cpu_drop(miniq); | 5137 | mini_qdisc_qstats_cpu_drop(miniq); |
| 5138 | kfree_skb_reason(skb, SKB_DROP_REASON_TC_INGRESS); | 5138 | kfree_skb_reason(skb, SKB_DROP_REASON_TC_INGRESS); |
| 5139 | *ret = NET_RX_DROP; | ||
| 5139 | return NULL; | 5140 | return NULL; |
| 5140 | case TC_ACT_STOLEN: | 5141 | case TC_ACT_STOLEN: |
| 5141 | case TC_ACT_QUEUED: | 5142 | case TC_ACT_QUEUED: |
| 5142 | case TC_ACT_TRAP: | 5143 | case TC_ACT_TRAP: |
| 5143 | consume_skb(skb); | 5144 | consume_skb(skb); |
| 5145 | *ret = NET_RX_SUCCESS; | ||
| 5144 | return NULL; | 5146 | return NULL; |
| 5145 | case TC_ACT_REDIRECT: | 5147 | case TC_ACT_REDIRECT: |
| 5146 | /* skb_mac_header check was done by cls/act_bpf, so | 5148 | /* skb_mac_header check was done by cls/act_bpf, so |
| @@ -5153,8 +5155,10 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret, · 6 unmodified lines | |||
| 5153 | *another = true; | 5155 | *another = true; |
| 5154 | break; | 5156 | break; |
| 5155 | } | 5157 | } |
| 5158 | *ret = NET_RX_SUCCESS; | ||
| 5156 | return NULL; | 5159 | return NULL; |
| 5157 | case TC_ACT_CONSUMED: | 5160 | case TC_ACT_CONSUMED: |
| 5161 | *ret = NET_RX_SUCCESS; | ||
| 5158 | return NULL; | 5162 | return NULL; |
| 5159 | default: | 5163 | default: |
| 5160 | break; | 5164 | break; |
| @@ -500,11 +500,11 @@ bool sk_msg_is_readable(struct sock *sk) · 499 unmodified lines | |||
| 500 | } | 500 | } |
| 501 | EXPORT_SYMBOL_GPL(sk_msg_is_readable); | 501 | EXPORT_SYMBOL_GPL(sk_msg_is_readable); |
| 502 | 502 | ||
| 503 | static struct sk_msg *alloc_sk_msg(void) | 503 | static struct sk_msg *alloc_sk_msg(gfp_t gfp) |
| 504 | { | 504 | { |
| 505 | struct sk_msg *msg; | 505 | struct sk_msg *msg; |
| 506 | 506 | ||
| 507 | msg = kzalloc(sizeof(*msg), __GFP_NOWARN | GFP_KERNEL); | 507 | msg = kzalloc(sizeof(*msg), gfp | __GFP_NOWARN); |
| 508 | if (unlikely(!msg)) | 508 | if (unlikely(!msg)) |
| 509 | return NULL; | 509 | return NULL; |
| 510 | sg_init_marker(msg->sg.data, NR_MSG_FRAG_IDS); | 510 | sg_init_marker(msg->sg.data, NR_MSG_FRAG_IDS); |
| @@ -520,7 +520,7 @@ static struct sk_msg *sk_psock_create_ingress_msg(struct sock *sk, · 9 unmodified lines | |||
| 520 | if (!sk_rmem_schedule(sk, skb, skb->truesize)) | 520 | if (!sk_rmem_schedule(sk, skb, skb->truesize)) |
| 521 | return NULL; | 521 | return NULL; |
| 522 | 522 | ||
| 523 | return alloc_sk_msg(); | 523 | return alloc_sk_msg(GFP_KERNEL); |
| 524 | } | 524 | } |
| 525 | 525 | ||
| 526 | static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb, | 526 | static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb, |
| @@ -597,7 +597,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb, · 70 unmodified lines | |||
| 597 | static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb, | 597 | static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb, |
| 598 | u32 off, u32 len) | 598 | u32 off, u32 len) |
| 599 | { | 599 | { |
| 600 | struct sk_msg *msg = alloc_sk_msg(); | 600 | struct sk_msg *msg = alloc_sk_msg(GFP_ATOMIC); |
| 601 | struct sock *sk = psock->sk; | 601 | struct sock *sk = psock->sk; |
| 602 | int err; | 602 | int err; |
| 603 | 603 | ||
| @@ -21,6 +21,22 @@ static DEFINE_IDA(reuseport_ida); · 20 unmodified lines | |||
| 21 | static int reuseport_resurrect(struct sock *sk, struct sock_reuseport *old_reuse, | 21 | static int reuseport_resurrect(struct sock *sk, struct sock_reuseport *old_reuse, |
| 22 | struct sock_reuseport *reuse, bool bind_inany); | 22 | struct sock_reuseport *reuse, bool bind_inany); |
| 23 | 23 | ||
| 24 | void reuseport_has_conns_set(struct sock *sk) | ||
| 25 | { | ||
| 26 | struct sock_reuseport *reuse; | ||
| 27 | |||
| 28 | if (!rcu_access_pointer(sk->sk_reuseport_cb)) | ||
| 29 | return; | ||
| 30 | |||
| 31 | spin_lock_bh(&reuseport_lock); | ||
| 32 | reuse = rcu_dereference_protected(sk->sk_reuseport_cb, | ||
| 33 | lockdep_is_held(&reuseport_lock)); | ||
| 34 | if (likely(reuse)) | ||
| 35 | reuse->has_conns = 1; | ||
| 36 | spin_unlock_bh(&reuseport_lock); | ||
| 37 | } | ||
| 38 | EXPORT_SYMBOL(reuseport_has_conns_set); | ||
| 39 | |||
| 24 | static int reuseport_sock_index(struct sock *sk, | 40 | static int reuseport_sock_index(struct sock *sk, |
| 25 | const struct sock_reuseport *reuse, | 41 | const struct sock_reuseport *reuse, |
| 26 | bool closed) | 42 | bool closed) |
| @@ -3145,7 +3145,7 @@ static int dsa_slave_netdevice_event(struct notifier_block *nb, · 3144 unmodified lines | |||
| 3145 | case NETDEV_CHANGELOWERSTATE: { | 3145 | case NETDEV_CHANGELOWERSTATE: { |
| 3146 | struct netdev_notifier_changelowerstate_info *info = ptr; | 3146 | struct netdev_notifier_changelowerstate_info *info = ptr; |
| 3147 | struct dsa_port *dp; | 3147 | struct dsa_port *dp; |
| 3148 | int err; | 3148 | int err = 0; |
| 3149 | 3149 | ||
| 3150 | if (dsa_slave_dev_check(dev)) { | 3150 | if (dsa_slave_dev_check(dev)) { |
| 3151 | dp = dsa_slave_to_port(dev); | 3151 | dp = dsa_slave_to_port(dev); |
| @@ -150,15 +150,15 @@ struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame, · 149 unmodified lines | |||
| 150 | struct hsr_port *port) | 150 | struct hsr_port *port) |
| 151 | { | 151 | { |
| 152 | if (!frame->skb_std) { | 152 | if (!frame->skb_std) { |
| 153 | if (frame->skb_hsr) { | 153 | if (frame->skb_hsr) |
| 154 | frame->skb_std = | 154 | frame->skb_std = |
| 155 | create_stripped_skb_hsr(frame->skb_hsr, frame); | 155 | create_stripped_skb_hsr(frame->skb_hsr, frame); |
| 156 | } else { | 156 | else |
| 157 | /* Unexpected */ | 157 | netdev_warn_once(port->dev, |
| 158 | WARN_ONCE(1, "%s:%d: Unexpected frame received (port_src %s)\n", | 158 | "Unexpected frame received in hsr_get_untagged_frame()\n"); |
| 159 | __FILE__, __LINE__, port->dev->name); | 159 | |
| 160 | if (!frame->skb_std) | ||
| 160 | return NULL; | 161 | return NULL; |
| 161 | } | ||
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | return skb_clone(frame->skb_std, GFP_ATOMIC); | 164 | return skb_clone(frame->skb_std, GFP_ATOMIC); |
| @@ -70,7 +70,7 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len · 69 unmodified lines | |||
| 70 | } | 70 | } |
| 71 | inet->inet_daddr = fl4->daddr; | 71 | inet->inet_daddr = fl4->daddr; |
| 72 | inet->inet_dport = usin->sin_port; | 72 | inet->inet_dport = usin->sin_port; |
| 73 | reuseport_has_conns(sk, true); | 73 | reuseport_has_conns_set(sk); |
| 74 | sk->sk_state = TCP_ESTABLISHED; | 74 | sk->sk_state = TCP_ESTABLISHED; |
| 75 | sk_set_txhash(sk); | 75 | sk_set_txhash(sk); |
| 76 | inet->inet_id = get_random_u16(); | 76 | inet->inet_id = get_random_u16(); |
| @@ -78,6 +78,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) · 77 unmodified lines | |||
| 78 | flow.flowi4_tos = iph->tos & IPTOS_RT_MASK; | 78 | flow.flowi4_tos = iph->tos & IPTOS_RT_MASK; |
| 79 | flow.flowi4_scope = RT_SCOPE_UNIVERSE; | 79 | flow.flowi4_scope = RT_SCOPE_UNIVERSE; |
| 80 | flow.flowi4_l3mdev = l3mdev_master_ifindex_rcu(xt_in(par)); | 80 | flow.flowi4_l3mdev = l3mdev_master_ifindex_rcu(xt_in(par)); |
| 81 | flow.flowi4_uid = sock_net_uid(xt_net(par), NULL); | ||
| 81 | 82 | ||
| 82 | return rpfilter_lookup_reverse(xt_net(par), &flow, xt_in(par), info->flags) ^ invert; | 83 | return rpfilter_lookup_reverse(xt_net(par), &flow, xt_in(par), info->flags) ^ invert; |
| 83 | } | 84 | } |
| @@ -65,6 +65,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs, · 64 unmodified lines | |||
| 65 | struct flowi4 fl4 = { | 65 | struct flowi4 fl4 = { |
| 66 | .flowi4_scope = RT_SCOPE_UNIVERSE, | 66 | .flowi4_scope = RT_SCOPE_UNIVERSE, |
| 67 | .flowi4_iif = LOOPBACK_IFINDEX, | 67 | .flowi4_iif = LOOPBACK_IFINDEX, |
| 68 | .flowi4_uid = sock_net_uid(nft_net(pkt), NULL), | ||
| 68 | }; | 69 | }; |
| 69 | const struct net_device *oif; | 70 | const struct net_device *oif; |
| 70 | const struct net_device *found; | 71 | const struct net_device *found; |
| @@ -448,7 +448,7 @@ static struct sock *udp4_lib_lookup2(struct net *net, · 447 unmodified lines | |||
| 448 | result = lookup_reuseport(net, sk, skb, | 448 | result = lookup_reuseport(net, sk, skb, |
| 449 | saddr, sport, daddr, hnum); | 449 | saddr, sport, daddr, hnum); |
| 450 | /* Fall back to scoring if group has connections */ | 450 | /* Fall back to scoring if group has connections */ |
| 451 | if (result && !reuseport_has_conns(sk, false)) | 451 | if (result && !reuseport_has_conns(sk)) |
| 452 | return result; | 452 | return result; |
| 453 | 453 | ||
| 454 | result = result ? : sk; | 454 | result = result ? : sk; |
| @@ -7214,9 +7214,11 @@ err_reg_dflt: · 7213 unmodified lines | |||
| 7214 | __addrconf_sysctl_unregister(net, all, NETCONFA_IFINDEX_ALL); | 7214 | __addrconf_sysctl_unregister(net, all, NETCONFA_IFINDEX_ALL); |
| 7215 | err_reg_all: | 7215 | err_reg_all: |
| 7216 | kfree(dflt); | 7216 | kfree(dflt); |
| 7217 | net->ipv6.devconf_dflt = NULL; | ||
| 7217 | #endif | 7218 | #endif |
| 7218 | err_alloc_dflt: | 7219 | err_alloc_dflt: |
| 7219 | kfree(all); | 7220 | kfree(all); |
| 7221 | net->ipv6.devconf_all = NULL; | ||
| 7220 | err_alloc_all: | 7222 | err_alloc_all: |
| 7221 | kfree(net->ipv6.inet6_addr_lst); | 7223 | kfree(net->ipv6.inet6_addr_lst); |
| 7222 | err_alloc_addr: | 7224 | err_alloc_addr: |
| @@ -256,7 +256,7 @@ ipv4_connected: · 255 unmodified lines | |||
| 256 | goto out; | 256 | goto out; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | reuseport_has_conns(sk, true); | 259 | reuseport_has_conns_set(sk); |
| 260 | sk->sk_state = TCP_ESTABLISHED; | 260 | sk->sk_state = TCP_ESTABLISHED; |
| 261 | sk_set_txhash(sk); | 261 | sk_set_txhash(sk); |
| 262 | out: | 262 | out: |
| @@ -40,6 +40,7 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb, · 39 unmodified lines | |||
| 40 | .flowi6_l3mdev = l3mdev_master_ifindex_rcu(dev), | 40 | .flowi6_l3mdev = l3mdev_master_ifindex_rcu(dev), |
| 41 | .flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK, | 41 | .flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK, |
| 42 | .flowi6_proto = iph->nexthdr, | 42 | .flowi6_proto = iph->nexthdr, |
| 43 | .flowi6_uid = sock_net_uid(net, NULL), | ||
| 43 | .daddr = iph->saddr, | 44 | .daddr = iph->saddr, |
| 44 | }; | 45 | }; |
| 45 | int lookup_flags; | 46 | int lookup_flags; |
| @@ -66,6 +66,7 @@ static u32 __nft_fib6_eval_type(const struct nft_fib *priv, · 65 unmodified lines | |||
| 66 | struct flowi6 fl6 = { | 66 | struct flowi6 fl6 = { |
| 67 | .flowi6_iif = LOOPBACK_IFINDEX, | 67 | .flowi6_iif = LOOPBACK_IFINDEX, |
| 68 | .flowi6_proto = pkt->tprot, | 68 | .flowi6_proto = pkt->tprot, |
| 69 | .flowi6_uid = sock_net_uid(nft_net(pkt), NULL), | ||
| 69 | }; | 70 | }; |
| 70 | u32 ret = 0; | 71 | u32 ret = 0; |
| 71 | 72 | ||
| @@ -163,6 +164,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, · 91 unmodified lines | |||
| 163 | struct flowi6 fl6 = { | 164 | struct flowi6 fl6 = { |
| 164 | .flowi6_iif = LOOPBACK_IFINDEX, | 165 | .flowi6_iif = LOOPBACK_IFINDEX, |
| 165 | .flowi6_proto = pkt->tprot, | 166 | .flowi6_proto = pkt->tprot, |
| 167 | .flowi6_uid = sock_net_uid(nft_net(pkt), NULL), | ||
| 166 | }; | 168 | }; |
| 167 | struct rt6_info *rt; | 169 | struct rt6_info *rt; |
| 168 | int lookup_flags; | 170 | int lookup_flags; |
| @@ -195,7 +195,7 @@ static struct sock *udp6_lib_lookup2(struct net *net, · 194 unmodified lines | |||
| 195 | result = lookup_reuseport(net, sk, skb, | 195 | result = lookup_reuseport(net, sk, skb, |
| 196 | saddr, sport, daddr, hnum); | 196 | saddr, sport, daddr, hnum); |
| 197 | /* Fall back to scoring if group has connections */ | 197 | /* Fall back to scoring if group has connections */ |
| 198 | if (result && !reuseport_has_conns(sk, false)) | 198 | if (result && !reuseport_has_conns(sk)) |
| 199 | return result; | 199 | return result; |
| 200 | 200 | ||
| 201 | result = result ? : sk; | 201 | result = result ? : sk; |
| @@ -5865,8 +5865,9 @@ static bool nft_setelem_valid_key_end(const struct nft_set *set, · 5864 unmodified lines | |||
| 5865 | (NFT_SET_CONCAT | NFT_SET_INTERVAL)) { | 5865 | (NFT_SET_CONCAT | NFT_SET_INTERVAL)) { |
| 5866 | if (flags & NFT_SET_ELEM_INTERVAL_END) | 5866 | if (flags & NFT_SET_ELEM_INTERVAL_END) |
| 5867 | return false; | 5867 | return false; |
| 5868 | if (!nla[NFTA_SET_ELEM_KEY_END] && | 5868 | |
| 5869 | !(flags & NFT_SET_ELEM_CATCHALL)) | 5869 | if (nla[NFTA_SET_ELEM_KEY_END] && |
| 5870 | flags & NFT_SET_ELEM_CATCHALL) | ||
| 5870 | return false; | 5871 | return false; |
| 5871 | } else { | 5872 | } else { |
| 5872 | if (nla[NFTA_SET_ELEM_KEY_END]) | 5873 | if (nla[NFTA_SET_ELEM_KEY_END]) |
| @@ -1099,12 +1099,13 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, · 1098 unmodified lines | |||
| 1099 | 1099 | ||
| 1100 | skip: | 1100 | skip: |
| 1101 | if (!ingress) { | 1101 | if (!ingress) { |
| 1102 | notify_and_destroy(net, skb, n, classid, | 1102 | old = rtnl_dereference(dev->qdisc); |
| 1103 | rtnl_dereference(dev->qdisc), new); | ||
| 1104 | if (new && !new->ops->attach) | 1103 | if (new && !new->ops->attach) |
| 1105 | qdisc_refcount_inc(new); | 1104 | qdisc_refcount_inc(new); |
| 1106 | rcu_assign_pointer(dev->qdisc, new ? : &noop_qdisc); | 1105 | rcu_assign_pointer(dev->qdisc, new ? : &noop_qdisc); |
| 1107 | 1106 | ||
| 1107 | notify_and_destroy(net, skb, n, classid, old, new); | ||
| 1108 | |||
| 1108 | if (new && new->ops->attach) | 1109 | if (new && new->ops->attach) |
| 1109 | new->ops->attach(new); | 1110 | new->ops->attach(new); |
| 1110 | } else { | 1111 | } else { |
| @@ -2224,8 +2224,12 @@ retry: · 2223 unmodified lines | |||
| 2224 | 2224 | ||
| 2225 | static void cake_reset(struct Qdisc *sch) | 2225 | static void cake_reset(struct Qdisc *sch) |
| 2226 | { | 2226 | { |
| 2227 | struct cake_sched_data *q = qdisc_priv(sch); | ||
| 2227 | u32 c; | 2228 | u32 c; |
| 2228 | 2229 | ||
| 2230 | if (!q->tins) | ||
| 2231 | return; | ||
| 2232 | |||
| 2229 | for (c = 0; c < CAKE_MAX_TINS; c++) | 2233 | for (c = 0; c < CAKE_MAX_TINS; c++) |
| 2230 | cake_clear_tin(sch, c); | 2234 | cake_clear_tin(sch, c); |
| 2231 | } | 2235 | } |
| @@ -478,24 +478,26 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt, · 477 unmodified lines | |||
| 478 | if (opt) { | 478 | if (opt) { |
| 479 | err = fq_codel_change(sch, opt, extack); | 479 | err = fq_codel_change(sch, opt, extack); |
| 480 | if (err) | 480 | if (err) |
| 481 | return err; | 481 | goto init_failure; |
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | err = tcf_block_get(&q->block, &q->filter_list, sch, extack); | 484 | err = tcf_block_get(&q->block, &q->filter_list, sch, extack); |
| 485 | if (err) | 485 | if (err) |
| 486 | return err; | 486 | goto init_failure; |
| 487 | 487 | ||
| 488 | if (!q->flows) { | 488 | if (!q->flows) { |
| 489 | q->flows = kvcalloc(q->flows_cnt, | 489 | q->flows = kvcalloc(q->flows_cnt, |
| 490 | sizeof(struct fq_codel_flow), | 490 | sizeof(struct fq_codel_flow), |
| 491 | GFP_KERNEL); | 491 | GFP_KERNEL); |
| 492 | if (!q->flows) | 492 | if (!q->flows) { |
| 493 | return -ENOMEM; | 493 | err = -ENOMEM; |
| 494 | 494 | goto init_failure; | |
| 495 | } | ||
| 495 | q->backlogs = kvcalloc(q->flows_cnt, sizeof(u32), GFP_KERNEL); | 496 | q->backlogs = kvcalloc(q->flows_cnt, sizeof(u32), GFP_KERNEL); |
| 496 | if (!q->backlogs) | 497 | if (!q->backlogs) { |
| 497 | return -ENOMEM; | 498 | err = -ENOMEM; |
| 498 | 499 | goto alloc_failure; | |
| 500 | } | ||
| 499 | for (i = 0; i < q->flows_cnt; i++) { | 501 | for (i = 0; i < q->flows_cnt; i++) { |
| 500 | struct fq_codel_flow *flow = q->flows + i; | 502 | struct fq_codel_flow *flow = q->flows + i; |
| 501 | 503 | ||
| @@ -508,6 +510,13 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt, · 6 unmodified lines | |||
| 508 | else | 510 | else |
| 509 | sch->flags &= ~TCQ_F_CAN_BYPASS; | 511 | sch->flags &= ~TCQ_F_CAN_BYPASS; |
| 510 | return 0; | 512 | return 0; |
| 513 | |||
| 514 | alloc_failure: | ||
| 515 | kvfree(q->flows); | ||
| 516 | q->flows = NULL; | ||
| 517 | init_failure: | ||
| 518 | q->flows_cnt = 0; | ||
| 519 | return err; | ||
| 511 | } | 520 | } |
| 512 | 521 | ||
| 513 | static int fq_codel_dump(struct Qdisc *sch, struct sk_buff *skb) | 522 | static int fq_codel_dump(struct Qdisc *sch, struct sk_buff *skb) |
| @@ -455,7 +455,8 @@ static void sfb_reset(struct Qdisc *sch) · 454 unmodified lines | |||
| 455 | { | 455 | { |
| 456 | struct sfb_sched_data *q = qdisc_priv(sch); | 456 | struct sfb_sched_data *q = qdisc_priv(sch); |
| 457 | 457 | ||
| 458 | qdisc_reset(q->qdisc); | 458 | if (likely(q->qdisc)) |
| 459 | qdisc_reset(q->qdisc); | ||
| 459 | q->slot = 0; | 460 | q->slot = 0; |
| 460 | q->double_buffering = false; | 461 | q->double_buffering = false; |
| 461 | sfb_zero_all_buckets(q); | 462 | sfb_zero_all_buckets(q); |
| @@ -896,7 +896,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini) · 895 unmodified lines | |||
| 896 | } | 896 | } |
| 897 | memcpy(lgr->pnet_id, ibdev->pnetid[ibport - 1], | 897 | memcpy(lgr->pnet_id, ibdev->pnetid[ibport - 1], |
| 898 | SMC_MAX_PNETID_LEN); | 898 | SMC_MAX_PNETID_LEN); |
| 899 | if (smc_wr_alloc_lgr_mem(lgr)) | 899 | rc = smc_wr_alloc_lgr_mem(lgr); |
| 900 | if (rc) | ||
| 900 | goto free_wq; | 901 | goto free_wq; |
| 901 | smc_llc_lgr_init(lgr, smc); | 902 | smc_llc_lgr_init(lgr, smc); |
| 902 | 903 | ||
| @@ -148,8 +148,8 @@ static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d, · 147 unmodified lines | |||
| 148 | { | 148 | { |
| 149 | struct net *net = d->net; | 149 | struct net *net = d->net; |
| 150 | struct tipc_net *tn = tipc_net(net); | 150 | struct tipc_net *tn = tipc_net(net); |
| 151 | bool trial = time_before(jiffies, tn->addr_trial_end); | ||
| 152 | u32 self = tipc_own_addr(net); | 151 | u32 self = tipc_own_addr(net); |
| 152 | bool trial = time_before(jiffies, tn->addr_trial_end) && !self; | ||
| 153 | 153 | ||
| 154 | if (mtyp == DSC_TRIAL_FAIL_MSG) { | 154 | if (mtyp == DSC_TRIAL_FAIL_MSG) { |
| 155 | if (!trial) | 155 | if (!trial) |
| @@ -568,7 +568,7 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower, · 567 unmodified lines | |||
| 568 | sub.seq.upper = upper; | 568 | sub.seq.upper = upper; |
| 569 | sub.timeout = TIPC_WAIT_FOREVER; | 569 | sub.timeout = TIPC_WAIT_FOREVER; |
| 570 | sub.filter = filter; | 570 | sub.filter = filter; |
| 571 | *(u32 *)&sub.usr_handle = port; | 571 | *(u64 *)&sub.usr_handle = (u64)port; |
| 572 | 572 | ||
| 573 | con = tipc_conn_alloc(tipc_topsrv(net)); | 573 | con = tipc_conn_alloc(tipc_topsrv(net)); |
| 574 | if (IS_ERR(con)) | 574 | if (IS_ERR(con)) |
| @@ -273,7 +273,7 @@ static int tls_strp_read_copyin(struct tls_strparser *strp) · 272 unmodified lines | |||
| 273 | return desc.error; | 273 | return desc.error; |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | static int tls_strp_read_short(struct tls_strparser *strp) | 276 | static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort) |
| 277 | { | 277 | { |
| 278 | struct skb_shared_info *shinfo; | 278 | struct skb_shared_info *shinfo; |
| 279 | struct page *page; | 279 | struct page *page; |
| @@ -283,7 +283,7 @@ static int tls_strp_read_short(struct tls_strparser *strp) · 3 unmodified lines | |||
| 283 | * to read the data out. Otherwise the connection will stall. | 283 | * to read the data out. Otherwise the connection will stall. |
| 284 | * Without pressure threshold of INT_MAX will never be ready. | 284 | * Without pressure threshold of INT_MAX will never be ready. |
| 285 | */ | 285 | */ |
| 286 | if (likely(!tcp_epollin_ready(strp->sk, INT_MAX))) | 286 | if (likely(qshort && !tcp_epollin_ready(strp->sk, INT_MAX))) |
| 287 | return 0; | 287 | return 0; |
| 288 | 288 | ||
| 289 | shinfo = skb_shinfo(strp->anchor); | 289 | shinfo = skb_shinfo(strp->anchor); |
| @@ -315,6 +315,27 @@ static int tls_strp_read_short(struct tls_strparser *strp) · 25 unmodified lines | |||
| 315 | return 0; | 315 | return 0; |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | static bool tls_strp_check_no_dup(struct tls_strparser *strp) | ||
| 319 | { | ||
| 320 | unsigned int len = strp->stm.offset + strp->stm.full_len; | ||
| 321 | struct sk_buff *skb; | ||
| 322 | u32 seq; | ||
| 323 | |||
| 324 | skb = skb_shinfo(strp->anchor)->frag_list; | ||
| 325 | seq = TCP_SKB_CB(skb)->seq; | ||
| 326 | |||
| 327 | while (skb->len < len) { | ||
| 328 | seq += skb->len; | ||
| 329 | len -= skb->len; | ||
| 330 | skb = skb->next; | ||
| 331 | |||
| 332 | if (TCP_SKB_CB(skb)->seq != seq) | ||
| 333 | return false; | ||
| 334 | } | ||
| 335 | |||
| 336 | return true; | ||
| 337 | } | ||
| 338 | |||
| 318 | static void tls_strp_load_anchor_with_queue(struct tls_strparser *strp, int len) | 339 | static void tls_strp_load_anchor_with_queue(struct tls_strparser *strp, int len) |
| 319 | { | 340 | { |
| 320 | struct tcp_sock *tp = tcp_sk(strp->sk); | 341 | struct tcp_sock *tp = tcp_sk(strp->sk); |
| @@ -373,7 +394,7 @@ static int tls_strp_read_sock(struct tls_strparser *strp) · 52 unmodified lines | |||
| 373 | return tls_strp_read_copyin(strp); | 394 | return tls_strp_read_copyin(strp); |
| 374 | 395 | ||
| 375 | if (inq < strp->stm.full_len) | 396 | if (inq < strp->stm.full_len) |
| 376 | return tls_strp_read_short(strp); | 397 | return tls_strp_read_copy(strp, true); |
| 377 | 398 | ||
| 378 | if (!strp->stm.full_len) { | 399 | if (!strp->stm.full_len) { |
| 379 | tls_strp_load_anchor_with_queue(strp, inq); | 400 | tls_strp_load_anchor_with_queue(strp, inq); |
| @@ -387,9 +408,12 @@ static int tls_strp_read_sock(struct tls_strparser *strp) · 7 unmodified lines | |||
| 387 | strp->stm.full_len = sz; | 408 | strp->stm.full_len = sz; |
| 388 | 409 | ||
| 389 | if (!strp->stm.full_len || inq < strp->stm.full_len) | 410 | if (!strp->stm.full_len || inq < strp->stm.full_len) |
| 390 | return tls_strp_read_short(strp); | 411 | return tls_strp_read_copy(strp, true); |
| 391 | } | 412 | } |
| 392 | 413 | ||
| 414 | if (!tls_strp_check_no_dup(strp)) | ||
| 415 | return tls_strp_read_copy(strp, false); | ||
| 416 | |||
| 393 | strp->msg_ready = 1; | 417 | strp->msg_ready = 1; |
| 394 | tls_rx_msg_ready(strp); | 418 | tls_rx_msg_ready(strp); |
| 395 | 419 | ||
| @@ -70,6 +70,7 @@ TEST_PROGS += io_uring_zerocopy_tx.sh · 69 unmodified lines | |||
| 70 | TEST_GEN_FILES += bind_bhash | 70 | TEST_GEN_FILES += bind_bhash |
| 71 | TEST_GEN_PROGS += sk_bind_sendto_listen | 71 | TEST_GEN_PROGS += sk_bind_sendto_listen |
| 72 | TEST_GEN_PROGS += sk_connect_zero_addr | 72 | TEST_GEN_PROGS += sk_connect_zero_addr |
| 73 | TEST_PROGS += test_ingress_egress_chaining.sh | ||
| 73 | 74 | ||
| 74 | TEST_FILES := settings | 75 | TEST_FILES := settings |
| 75 | 76 | ||
| @@ -0,0 +1,79 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 3 | |||
| 4 | # This test runs a simple ingress tc setup between two veth pairs, | ||
| 5 | # and chains a single egress rule to test ingress chaining to egress. | ||
| 6 | # | ||
| 7 | # Kselftest framework requirement - SKIP code is 4. | ||
| 8 | ksft_skip=4 | ||
| 9 | |||
| 10 | if [ "$(id -u)" -ne 0 ];then | ||
| 11 | echo "SKIP: Need root privileges" | ||
| 12 | exit $ksft_skip | ||
| 13 | fi | ||
| 14 | |||
| 15 | needed_mods="act_mirred cls_flower sch_ingress" | ||
| 16 | for mod in $needed_mods; do | ||
| 17 | modinfo $mod &>/dev/null || { echo "SKIP: Need act_mirred module"; exit $ksft_skip; } | ||
| 18 | done | ||
| 19 | |||
| 20 | ns="ns$((RANDOM%899+100))" | ||
| 21 | veth1="veth1$((RANDOM%899+100))" | ||
| 22 | veth2="veth2$((RANDOM%899+100))" | ||
| 23 | peer1="peer1$((RANDOM%899+100))" | ||
| 24 | peer2="peer2$((RANDOM%899+100))" | ||
| 25 | ip_peer1=198.51.100.5 | ||
| 26 | ip_peer2=198.51.100.6 | ||
| 27 | |||
| 28 | function fail() { | ||
| 29 | echo "FAIL: $@" >> /dev/stderr | ||
| 30 | exit 1 | ||
| 31 | } | ||
| 32 | |||
| 33 | function cleanup() { | ||
| 34 | killall -q -9 udpgso_bench_rx | ||
| 35 | ip link del $veth1 &> /dev/null | ||
| 36 | ip link del $veth2 &> /dev/null | ||
| 37 | ip netns del $ns &> /dev/null | ||
| 38 | } | ||
| 39 | trap cleanup EXIT | ||
| 40 | |||
| 41 | function config() { | ||
| 42 | echo "Setup veth pairs [$veth1, $peer1], and veth pair [$veth2, $peer2]" | ||
| 43 | ip link add $veth1 type veth peer name $peer1 | ||
| 44 | ip link add $veth2 type veth peer name $peer2 | ||
| 45 | ip addr add $ip_peer1/24 dev $peer1 | ||
| 46 | ip link set $peer1 up | ||
| 47 | ip netns add $ns | ||
| 48 | ip link set dev $peer2 netns $ns | ||
| 49 | ip netns exec $ns ip addr add $ip_peer2/24 dev $peer2 | ||
| 50 | ip netns exec $ns ip link set $peer2 up | ||
| 51 | ip link set $veth1 up | ||
| 52 | ip link set $veth2 up | ||
| 53 | |||
| 54 | echo "Add tc filter ingress->egress forwarding $veth1 <-> $veth2" | ||
| 55 | tc qdisc add dev $veth2 ingress | ||
| 56 | tc qdisc add dev $veth1 ingress | ||
| 57 | tc filter add dev $veth2 ingress prio 1 proto all flower \ | ||
| 58 | action mirred egress redirect dev $veth1 | ||
| 59 | tc filter add dev $veth1 ingress prio 1 proto all flower \ | ||
| 60 | action mirred egress redirect dev $veth2 | ||
| 61 | |||
| 62 | echo "Add tc filter egress->ingress forwarding $peer1 -> $veth1, bypassing the veth pipe" | ||
| 63 | tc qdisc add dev $peer1 clsact | ||
| 64 | tc filter add dev $peer1 egress prio 20 proto ip flower \ | ||
| 65 | action mirred ingress redirect dev $veth1 | ||
| 66 | } | ||
| 67 | |||
| 68 | function test_run() { | ||
| 69 | echo "Run tcp traffic" | ||
| 70 | ./udpgso_bench_rx -t & | ||
| 71 | sleep 1 | ||
| 72 | ip netns exec $ns timeout -k 2 10 ./udpgso_bench_tx -t -l 2 -4 -D $ip_peer1 || fail "traffic failed" | ||
| 73 | echo "Test passed" | ||
| 74 | } | ||
| 75 | |||
| 76 | config | ||
| 77 | test_run | ||
| 78 | trap - EXIT | ||
| 79 | cleanup | ||