Pull networking fixes from Jakub Kicinski: "Including fixes from xfrm, bpf, netfilter, and wireless. Current release - regressions: - xfrm: fix XFRM_MSG_MAPPING ABI breakage caused by inserting a new value in the middle of an enum - unix: fix an issue in unix_shutdown causing the other end read/write failures - phy: mdio: fix memory leak Current release - new code bugs: - mlx5e: improve MQPRIO resiliency against bad configs Previous releases - regressions: - bpf: fix integer overflow leading to OOB access in map element pre-allocation - stmmac: dwmac-rk: fix ethernet on rk3399 based devices - netfilter: conntrack: fix boot failure with nf_conntrack.enable_hooks=1 - brcmfmac: revert using ISO3166 country code and 0 rev as fallback - i40e: fix freeing of uninitialized misc IRQ vector - iavf: fix double unlock of crit_lock Previous releases - always broken: - bpf, arm: fix register clobbering in div/mod implementation - netfilter: nf_tables: correct issues in netlink rule change event notifications - dsa: tag_dsa: fix mask for trunked packets - usb: r8152: don't resubmit rx immediately to avoid soft lockup on device unplug - i40e: fix endless loop under rtnl if FW fails to correctly respond to capability query - mlx5e: fix rx checksum offload coexistence with ipsec offload - mlx5: force round second at 1PPS out start time and allow it only in supported clock modes - phy: pcs: xpcs: fix incorrect CL37 AN sequence, EEE disable sequence Misc: - xfrm: slightly rejig the new policy uAPI to make it less cryptic" * tag 'net-5.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (66 commits) net: prefer socket bound to interface when not in VRF iavf: fix double unlock of crit_lock i40e: Fix freeing of uninitialized misc IRQ vector i40e: fix endless loop under rtnl dt-bindings: net: dsa: marvell: fix compatible in example ionic: move filter sync_needed bit set gve: report 64bit tx_bytes counter from gve_handle_report_stats() gve: fix gve_get_stats() rtnetlink: fix if_nlmsg_stats_size() under estimation gve: Properly handle errors in gve_assign_qpl gve: Avoid freeing NULL pointer gve: Correct available tx qpl check unix: Fix an issue in unix_shutdown causing the other end read/write failures net: stmmac: trigger PCS EEE to turn off on link down net: pcs: xpcs: fix incorrect steps on disable EEE netlink: annotate data races around nlk->bound net: pcs: xpcs: fix incorrect CL37 AN sequence net: sfp: Fix typo in state machine debug string net/sched: sch_taprio: properly cancel timer from taprio_destroy() net: bridge: fix under estimation in br_get_linkxstats_size() ...
Unified · Split
| @@ -971,6 +971,7 @@ D: PowerPC · 970 unmodified lines | |||
| 971 | N: Daniel Drake | 971 | N: Daniel Drake |
| 972 | E: dsd@gentoo.org | 972 | E: dsd@gentoo.org |
| 973 | D: USBAT02 CompactFlash support in usb-storage | 973 | D: USBAT02 CompactFlash support in usb-storage |
| 974 | D: ZD1211RW wireless driver | ||
| 974 | S: UK | 975 | S: UK |
| 975 | 976 | ||
| 976 | N: Oleg Drokin | 977 | N: Oleg Drokin |
| @@ -83,7 +83,7 @@ Example: · 82 unmodified lines | |||
| 83 | #interrupt-cells = <2>; | 83 | #interrupt-cells = <2>; |
| 84 | 84 | ||
| 85 | switch0: switch@0 { | 85 | switch0: switch@0 { |
| 86 | compatible = "marvell,mv88e6390"; | 86 | compatible = "marvell,mv88e6190"; |
| 87 | reg = <0>; | 87 | reg = <0>; |
| 88 | reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; | 88 | reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; |
| 89 | 89 | ||
| @@ -8609,9 +8609,8 @@ F: Documentation/devicetree/bindings/iio/humidity/st,hts221.yaml · 8608 unmodified lines | |||
| 8609 | F: drivers/iio/humidity/hts221* | 8609 | F: drivers/iio/humidity/hts221* |
| 8610 | 8610 | ||
| 8611 | HUAWEI ETHERNET DRIVER | 8611 | HUAWEI ETHERNET DRIVER |
| 8612 | M: Bin Luo <luobin9@huawei.com> | ||
| 8613 | L: netdev@vger.kernel.org | 8612 | L: netdev@vger.kernel.org |
| 8614 | S: Supported | 8613 | S: Orphan |
| 8615 | F: Documentation/networking/device_drivers/ethernet/huawei/hinic.rst | 8614 | F: Documentation/networking/device_drivers/ethernet/huawei/hinic.rst |
| 8616 | F: drivers/net/ethernet/huawei/hinic/ | 8615 | F: drivers/net/ethernet/huawei/hinic/ |
| 8617 | 8616 | ||
| @@ -17794,7 +17793,6 @@ F: drivers/staging/nvec/ · 9176 unmodified lines | |||
| 17794 | 17793 | ||
| 17795 | STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON) | 17794 | STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON) |
| 17796 | M: Jens Frederich <jfrederich@gmail.com> | 17795 | M: Jens Frederich <jfrederich@gmail.com> |
| 17797 | M: Daniel Drake <dsd@laptop.org> | ||
| 17798 | M: Jon Nettleton <jon.nettleton@gmail.com> | 17796 | M: Jon Nettleton <jon.nettleton@gmail.com> |
| 17799 | S: Maintained | 17797 | S: Maintained |
| 17800 | W: http://wiki.laptop.org/go/DCON | 17798 | W: http://wiki.laptop.org/go/DCON |
| @@ -20700,7 +20698,6 @@ S: Maintained · 2899 unmodified lines | |||
| 20700 | F: mm/zbud.c | 20698 | F: mm/zbud.c |
| 20701 | 20699 | ||
| 20702 | ZD1211RW WIRELESS DRIVER | 20700 | ZD1211RW WIRELESS DRIVER |
| 20703 | M: Daniel Drake <dsd@gentoo.org> | ||
| 20704 | M: Ulrich Kunitz <kune@deine-taler.de> | 20701 | M: Ulrich Kunitz <kune@deine-taler.de> |
| 20705 | L: linux-wireless@vger.kernel.org | 20702 | L: linux-wireless@vger.kernel.org |
| 20706 | L: zd1211-devs@lists.sourceforge.net (subscribers-only) | 20703 | L: zd1211-devs@lists.sourceforge.net (subscribers-only) |
| @@ -36,6 +36,10 @@ · 35 unmodified lines | |||
| 36 | * +-----+ | 36 | * +-----+ |
| 37 | * |RSVD | JIT scratchpad | 37 | * |RSVD | JIT scratchpad |
| 38 | * current ARM_SP => +-----+ <= (BPF_FP - STACK_SIZE + SCRATCH_SIZE) | 38 | * current ARM_SP => +-----+ <= (BPF_FP - STACK_SIZE + SCRATCH_SIZE) |
| 39 | * | ... | caller-saved registers | ||
| 40 | * +-----+ | ||
| 41 | * | ... | arguments passed on stack | ||
| 42 | * ARM_SP during call => +-----| | ||
| 39 | * | | | 43 | * | | |
| 40 | * | ... | Function call stack | 44 | * | ... | Function call stack |
| 41 | * | | | 45 | * | | |
| @@ -63,6 +67,12 @@ · 21 unmodified lines | |||
| 63 | * | 67 | * |
| 64 | * When popping registers off the stack at the end of a BPF function, we | 68 | * When popping registers off the stack at the end of a BPF function, we |
| 65 | * reference them via the current ARM_FP register. | 69 | * reference them via the current ARM_FP register. |
| 70 | * | ||
| 71 | * Some eBPF operations are implemented via a call to a helper function. | ||
| 72 | * Such calls are "invisible" in the eBPF code, so it is up to the calling | ||
| 73 | * program to preserve any caller-saved ARM registers during the call. The | ||
| 74 | * JIT emits code to push and pop those registers onto the stack, immediately | ||
| 75 | * above the callee stack frame. | ||
| 66 | */ | 76 | */ |
| 67 | #define CALLEE_MASK (1 << ARM_R4 | 1 << ARM_R5 | 1 << ARM_R6 | \ | 77 | #define CALLEE_MASK (1 << ARM_R4 | 1 << ARM_R5 | 1 << ARM_R6 | \ |
| 68 | 1 << ARM_R7 | 1 << ARM_R8 | 1 << ARM_R9 | \ | 78 | 1 << ARM_R7 | 1 << ARM_R8 | 1 << ARM_R9 | \ |
| @@ -70,6 +80,8 @@ · 1 unmodified line | |||
| 70 | #define CALLEE_PUSH_MASK (CALLEE_MASK | 1 << ARM_LR) | 80 | #define CALLEE_PUSH_MASK (CALLEE_MASK | 1 << ARM_LR) |
| 71 | #define CALLEE_POP_MASK (CALLEE_MASK | 1 << ARM_PC) | 81 | #define CALLEE_POP_MASK (CALLEE_MASK | 1 << ARM_PC) |
| 72 | 82 | ||
| 83 | #define CALLER_MASK (1 << ARM_R0 | 1 << ARM_R1 | 1 << ARM_R2 | 1 << ARM_R3) | ||
| 84 | |||
| 73 | enum { | 85 | enum { |
| 74 | /* Stack layout - these are offsets from (top of stack - 4) */ | 86 | /* Stack layout - these are offsets from (top of stack - 4) */ |
| 75 | BPF_R2_HI, | 87 | BPF_R2_HI, |
| @@ -464,6 +476,7 @@ static inline int epilogue_offset(const struct jit_ctx *ctx) · 388 unmodified lines | |||
| 464 | 476 | ||
| 465 | static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) | 477 | static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) |
| 466 | { | 478 | { |
| 479 | const int exclude_mask = BIT(ARM_R0) | BIT(ARM_R1); | ||
| 467 | const s8 *tmp = bpf2a32[TMP_REG_1]; | 480 | const s8 *tmp = bpf2a32[TMP_REG_1]; |
| 468 | 481 | ||
| 469 | #if __LINUX_ARM_ARCH__ == 7 | 482 | #if __LINUX_ARM_ARCH__ == 7 |
| @@ -495,11 +508,17 @@ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) · 25 unmodified lines | |||
| 495 | emit(ARM_MOV_R(ARM_R0, rm), ctx); | 508 | emit(ARM_MOV_R(ARM_R0, rm), ctx); |
| 496 | } | 509 | } |
| 497 | 510 | ||
| 511 | /* Push caller-saved registers on stack */ | ||
| 512 | emit(ARM_PUSH(CALLER_MASK & ~exclude_mask), ctx); | ||
| 513 | |||
| 498 | /* Call appropriate function */ | 514 | /* Call appropriate function */ |
| 499 | emit_mov_i(ARM_IP, op == BPF_DIV ? | 515 | emit_mov_i(ARM_IP, op == BPF_DIV ? |
| 500 | (u32)jit_udiv32 : (u32)jit_mod32, ctx); | 516 | (u32)jit_udiv32 : (u32)jit_mod32, ctx); |
| 501 | emit_blx_r(ARM_IP, ctx); | 517 | emit_blx_r(ARM_IP, ctx); |
| 502 | 518 | ||
| 519 | /* Restore caller-saved registers from stack */ | ||
| 520 | emit(ARM_POP(CALLER_MASK & ~exclude_mask), ctx); | ||
| 521 | |||
| 503 | /* Save return value */ | 522 | /* Save return value */ |
| 504 | if (rd != ARM_R0) | 523 | if (rd != ARM_R0) |
| 505 | emit(ARM_MOV_R(rd, ARM_R0), ctx); | 524 | emit(ARM_MOV_R(rd, ARM_R0), ctx); |
| @@ -154,7 +154,7 @@ · 153 unmodified lines | |||
| 154 | 154 | ||
| 155 | fm1mac3: ethernet@e4000 { | 155 | fm1mac3: ethernet@e4000 { |
| 156 | phy-handle = <&sgmii_aqr_phy3>; | 156 | phy-handle = <&sgmii_aqr_phy3>; |
| 157 | phy-connection-type = "sgmii-2500"; | 157 | phy-connection-type = "2500base-x"; |
| 158 | sleep = <&rcpm 0x20000000>; | 158 | sleep = <&rcpm 0x20000000>; |
| 159 | }; | 159 | }; |
| 160 | 160 | ||
| @@ -780,7 +780,7 @@ struct gve_queue_page_list *gve_assign_rx_qpl(struct gve_priv *priv) · 779 unmodified lines | |||
| 780 | gve_num_tx_qpls(priv)); | 780 | gve_num_tx_qpls(priv)); |
| 781 | 781 | ||
| 782 | /* we are out of rx qpls */ | 782 | /* we are out of rx qpls */ |
| 783 | if (id == priv->qpl_cfg.qpl_map_size) | 783 | if (id == gve_num_tx_qpls(priv) + gve_num_rx_qpls(priv)) |
| 784 | return NULL; | 784 | return NULL; |
| 785 | 785 | ||
| 786 | set_bit(id, priv->qpl_cfg.qpl_id_map); | 786 | set_bit(id, priv->qpl_cfg.qpl_id_map); |
| @@ -41,6 +41,7 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) · 40 unmodified lines | |||
| 41 | { | 41 | { |
| 42 | struct gve_priv *priv = netdev_priv(dev); | 42 | struct gve_priv *priv = netdev_priv(dev); |
| 43 | unsigned int start; | 43 | unsigned int start; |
| 44 | u64 packets, bytes; | ||
| 44 | int ring; | 45 | int ring; |
| 45 | 46 | ||
| 46 | if (priv->rx) { | 47 | if (priv->rx) { |
| @@ -48,10 +49,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) · 1 unmodified line | |||
| 48 | do { | 49 | do { |
| 49 | start = | 50 | start = |
| 50 | u64_stats_fetch_begin(&priv->rx[ring].statss); | 51 | u64_stats_fetch_begin(&priv->rx[ring].statss); |
| 51 | s->rx_packets += priv->rx[ring].rpackets; | 52 | packets = priv->rx[ring].rpackets; |
| 52 | s->rx_bytes += priv->rx[ring].rbytes; | 53 | bytes = priv->rx[ring].rbytes; |
| 53 | } while (u64_stats_fetch_retry(&priv->rx[ring].statss, | 54 | } while (u64_stats_fetch_retry(&priv->rx[ring].statss, |
| 54 | start)); | 55 | start)); |
| 56 | s->rx_packets += packets; | ||
| 57 | s->rx_bytes += bytes; | ||
| 55 | } | 58 | } |
| 56 | } | 59 | } |
| 57 | if (priv->tx) { | 60 | if (priv->tx) { |
| @@ -59,10 +62,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) · 1 unmodified line | |||
| 59 | do { | 62 | do { |
| 60 | start = | 63 | start = |
| 61 | u64_stats_fetch_begin(&priv->tx[ring].statss); | 64 | u64_stats_fetch_begin(&priv->tx[ring].statss); |
| 62 | s->tx_packets += priv->tx[ring].pkt_done; | 65 | packets = priv->tx[ring].pkt_done; |
| 63 | s->tx_bytes += priv->tx[ring].bytes_done; | 66 | bytes = priv->tx[ring].bytes_done; |
| 64 | } while (u64_stats_fetch_retry(&priv->tx[ring].statss, | 67 | } while (u64_stats_fetch_retry(&priv->tx[ring].statss, |
| 65 | start)); | 68 | start)); |
| 69 | s->tx_packets += packets; | ||
| 70 | s->tx_bytes += bytes; | ||
| 66 | } | 71 | } |
| 67 | } | 72 | } |
| 68 | } | 73 | } |
| @@ -82,6 +87,9 @@ static int gve_alloc_counter_array(struct gve_priv *priv) · 13 unmodified lines | |||
| 82 | 87 | ||
| 83 | static void gve_free_counter_array(struct gve_priv *priv) | 88 | static void gve_free_counter_array(struct gve_priv *priv) |
| 84 | { | 89 | { |
| 90 | if (!priv->counter_array) | ||
| 91 | return; | ||
| 92 | |||
| 85 | dma_free_coherent(&priv->pdev->dev, | 93 | dma_free_coherent(&priv->pdev->dev, |
| 86 | priv->num_event_counters * | 94 | priv->num_event_counters * |
| 87 | sizeof(*priv->counter_array), | 95 | sizeof(*priv->counter_array), |
| @@ -142,6 +150,9 @@ static int gve_alloc_stats_report(struct gve_priv *priv) · 54 unmodified lines | |||
| 142 | 150 | ||
| 143 | static void gve_free_stats_report(struct gve_priv *priv) | 151 | static void gve_free_stats_report(struct gve_priv *priv) |
| 144 | { | 152 | { |
| 153 | if (!priv->stats_report) | ||
| 154 | return; | ||
| 155 | |||
| 145 | del_timer_sync(&priv->stats_report_timer); | 156 | del_timer_sync(&priv->stats_report_timer); |
| 146 | dma_free_coherent(&priv->pdev->dev, priv->stats_report_len, | 157 | dma_free_coherent(&priv->pdev->dev, priv->stats_report_len, |
| 147 | priv->stats_report, priv->stats_report_bus); | 158 | priv->stats_report, priv->stats_report_bus); |
| @@ -370,18 +381,19 @@ static void gve_free_notify_blocks(struct gve_priv *priv) · 222 unmodified lines | |||
| 370 | { | 381 | { |
| 371 | int i; | 382 | int i; |
| 372 | 383 | ||
| 373 | if (priv->msix_vectors) { | 384 | if (!priv->msix_vectors) |
| 374 | /* Free the irqs */ | 385 | return; |
| 375 | for (i = 0; i < priv->num_ntfy_blks; i++) { | ||
| 376 | struct gve_notify_block *block = &priv->ntfy_blocks[i]; | ||
| 377 | int msix_idx = i; | ||
| 378 | 386 | ||
| 379 | irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector, | 387 | /* Free the irqs */ |
| 380 | NULL); | 388 | for (i = 0; i < priv->num_ntfy_blks; i++) { |
| 381 | free_irq(priv->msix_vectors[msix_idx].vector, block); | 389 | struct gve_notify_block *block = &priv->ntfy_blocks[i]; |
| 382 | } | 390 | int msix_idx = i; |
| 383 | free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv); | 391 | |
| 392 | irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector, | ||
| 393 | NULL); | ||
| 394 | free_irq(priv->msix_vectors[msix_idx].vector, block); | ||
| 384 | } | 395 | } |
| 396 | free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv); | ||
| 385 | dma_free_coherent(&priv->pdev->dev, | 397 | dma_free_coherent(&priv->pdev->dev, |
| 386 | priv->num_ntfy_blks * sizeof(*priv->ntfy_blocks), | 398 | priv->num_ntfy_blks * sizeof(*priv->ntfy_blocks), |
| 387 | priv->ntfy_blocks, priv->ntfy_block_bus); | 399 | priv->ntfy_blocks, priv->ntfy_block_bus); |
| @@ -1185,9 +1197,10 @@ static void gve_handle_reset(struct gve_priv *priv) · 797 unmodified lines | |||
| 1185 | 1197 | ||
| 1186 | void gve_handle_report_stats(struct gve_priv *priv) | 1198 | void gve_handle_report_stats(struct gve_priv *priv) |
| 1187 | { | 1199 | { |
| 1188 | int idx, stats_idx = 0, tx_bytes; | ||
| 1189 | unsigned int start = 0; | ||
| 1190 | struct stats *stats = priv->stats_report->stats; | 1200 | struct stats *stats = priv->stats_report->stats; |
| 1201 | int idx, stats_idx = 0; | ||
| 1202 | unsigned int start = 0; | ||
| 1203 | u64 tx_bytes; | ||
| 1191 | 1204 | ||
| 1192 | if (!gve_get_report_stats(priv)) | 1205 | if (!gve_get_report_stats(priv)) |
| 1193 | return; | 1206 | return; |
| @@ -104,8 +104,14 @@ static int gve_prefill_rx_pages(struct gve_rx_ring *rx) · 103 unmodified lines | |||
| 104 | if (!rx->data.page_info) | 104 | if (!rx->data.page_info) |
| 105 | return -ENOMEM; | 105 | return -ENOMEM; |
| 106 | 106 | ||
| 107 | if (!rx->data.raw_addressing) | 107 | if (!rx->data.raw_addressing) { |
| 108 | rx->data.qpl = gve_assign_rx_qpl(priv); | 108 | rx->data.qpl = gve_assign_rx_qpl(priv); |
| 109 | if (!rx->data.qpl) { | ||
| 110 | kvfree(rx->data.page_info); | ||
| 111 | rx->data.page_info = NULL; | ||
| 112 | return -ENOMEM; | ||
| 113 | } | ||
| 114 | } | ||
| 109 | for (i = 0; i < slots; i++) { | 115 | for (i = 0; i < slots; i++) { |
| 110 | if (!rx->data.raw_addressing) { | 116 | if (!rx->data.raw_addressing) { |
| 111 | struct page *page = rx->data.qpl->pages[i]; | 117 | struct page *page = rx->data.qpl->pages[i]; |
| @@ -4871,7 +4871,8 @@ static void i40e_clear_interrupt_scheme(struct i40e_pf *pf) · 4870 unmodified lines | |||
| 4871 | { | 4871 | { |
| 4872 | int i; | 4872 | int i; |
| 4873 | 4873 | ||
| 4874 | i40e_free_misc_vector(pf); | 4874 | if (test_bit(__I40E_MISC_IRQ_REQUESTED, pf->state)) |
| 4875 | i40e_free_misc_vector(pf); | ||
| 4875 | 4876 | ||
| 4876 | i40e_put_lump(pf->irq_pile, pf->iwarp_base_vector, | 4877 | i40e_put_lump(pf->irq_pile, pf->iwarp_base_vector, |
| 4877 | I40E_IWARP_IRQ_PILE_ID); | 4878 | I40E_IWARP_IRQ_PILE_ID); |
| @@ -10113,7 +10114,7 @@ static int i40e_get_capabilities(struct i40e_pf *pf, · 5235 unmodified lines | |||
| 10113 | if (pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOMEM) { | 10114 | if (pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOMEM) { |
| 10114 | /* retry with a larger buffer */ | 10115 | /* retry with a larger buffer */ |
| 10115 | buf_len = data_size; | 10116 | buf_len = data_size; |
| 10116 | } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK) { | 10117 | } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK || err) { |
| 10117 | dev_info(&pf->pdev->dev, | 10118 | dev_info(&pf->pdev->dev, |
| 10118 | "capability discovery failed, err %s aq_err %s\n", | 10119 | "capability discovery failed, err %s aq_err %s\n", |
| 10119 | i40e_stat_str(&pf->hw, err), | 10120 | i40e_stat_str(&pf->hw, err), |
| @@ -1965,7 +1965,6 @@ static void iavf_watchdog_task(struct work_struct *work) · 1964 unmodified lines | |||
| 1965 | } | 1965 | } |
| 1966 | adapter->aq_required = 0; | 1966 | adapter->aq_required = 0; |
| 1967 | adapter->current_op = VIRTCHNL_OP_UNKNOWN; | 1967 | adapter->current_op = VIRTCHNL_OP_UNKNOWN; |
| 1968 | mutex_unlock(&adapter->crit_lock); | ||
| 1969 | queue_delayed_work(iavf_wq, | 1968 | queue_delayed_work(iavf_wq, |
| 1970 | &adapter->watchdog_task, | 1969 | &adapter->watchdog_task, |
| 1971 | msecs_to_jiffies(10)); | 1970 | msecs_to_jiffies(10)); |
| @@ -252,6 +252,7 @@ struct mlx5e_params { · 251 unmodified lines | |||
| 252 | struct { | 252 | struct { |
| 253 | u16 mode; | 253 | u16 mode; |
| 254 | u8 num_tc; | 254 | u8 num_tc; |
| 255 | struct netdev_tc_txq tc_to_txq[TC_MAX_QUEUE]; | ||
| 255 | } mqprio; | 256 | } mqprio; |
| 256 | bool rx_cqe_compress_def; | 257 | bool rx_cqe_compress_def; |
| 257 | bool tunneled_offload_en; | 258 | bool tunneled_offload_en; |
| @@ -845,6 +846,7 @@ struct mlx5e_priv { · 587 unmodified lines | |||
| 845 | struct mlx5e_channel_stats channel_stats[MLX5E_MAX_NUM_CHANNELS]; | 846 | struct mlx5e_channel_stats channel_stats[MLX5E_MAX_NUM_CHANNELS]; |
| 846 | struct mlx5e_channel_stats trap_stats; | 847 | struct mlx5e_channel_stats trap_stats; |
| 847 | struct mlx5e_ptp_stats ptp_stats; | 848 | struct mlx5e_ptp_stats ptp_stats; |
| 849 | u16 stats_nch; | ||
| 848 | u16 max_nch; | 850 | u16 max_nch; |
| 849 | u8 max_opened_tc; | 851 | u8 max_opened_tc; |
| 850 | bool tx_ptp_opened; | 852 | bool tx_ptp_opened; |
| @@ -1100,12 +1102,6 @@ int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv, · 249 unmodified lines | |||
| 1100 | struct ethtool_pauseparam *pauseparam); | 1102 | struct ethtool_pauseparam *pauseparam); |
| 1101 | 1103 | ||
| 1102 | /* mlx5e generic netdev management API */ | 1104 | /* mlx5e generic netdev management API */ |
| 1103 | static inline unsigned int | ||
| 1104 | mlx5e_calc_max_nch(struct mlx5e_priv *priv, const struct mlx5e_profile *profile) | ||
| 1105 | { | ||
| 1106 | return priv->netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1); | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | static inline bool | 1105 | static inline bool |
| 1110 | mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev) | 1106 | mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev) |
| 1111 | { | 1107 | { |
| @@ -1114,11 +1110,13 @@ mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev) · 2 unmodified lines | |||
| 1114 | } | 1110 | } |
| 1115 | 1111 | ||
| 1116 | int mlx5e_priv_init(struct mlx5e_priv *priv, | 1112 | int mlx5e_priv_init(struct mlx5e_priv *priv, |
| 1113 | const struct mlx5e_profile *profile, | ||
| 1117 | struct net_device *netdev, | 1114 | struct net_device *netdev, |
| 1118 | struct mlx5_core_dev *mdev); | 1115 | struct mlx5_core_dev *mdev); |
| 1119 | void mlx5e_priv_cleanup(struct mlx5e_priv *priv); | 1116 | void mlx5e_priv_cleanup(struct mlx5e_priv *priv); |
| 1120 | struct net_device * | 1117 | struct net_device * |
| 1121 | mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs); | 1118 | mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile, |
| 1119 | unsigned int txqs, unsigned int rxqs); | ||
| 1122 | int mlx5e_attach_netdev(struct mlx5e_priv *priv); | 1120 | int mlx5e_attach_netdev(struct mlx5e_priv *priv); |
| 1123 | void mlx5e_detach_netdev(struct mlx5e_priv *priv); | 1121 | void mlx5e_detach_netdev(struct mlx5e_priv *priv); |
| 1124 | void mlx5e_destroy_netdev(struct mlx5e_priv *priv); | 1122 | void mlx5e_destroy_netdev(struct mlx5e_priv *priv); |
| @@ -35,7 +35,7 @@ static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data, · 34 unmodified lines | |||
| 35 | { | 35 | { |
| 36 | int ch, i = 0; | 36 | int ch, i = 0; |
| 37 | 37 | ||
| 38 | for (ch = 0; ch < priv->max_nch; ch++) { | 38 | for (ch = 0; ch < priv->stats_nch; ch++) { |
| 39 | void *buf = data + i; | 39 | void *buf = data + i; |
| 40 | 40 | ||
| 41 | if (WARN_ON_ONCE(buf + | 41 | if (WARN_ON_ONCE(buf + |
| @@ -51,7 +51,7 @@ static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data, · 9 unmodified lines | |||
| 51 | static int mlx5e_hv_vhca_stats_buf_size(struct mlx5e_priv *priv) | 51 | static int mlx5e_hv_vhca_stats_buf_size(struct mlx5e_priv *priv) |
| 52 | { | 52 | { |
| 53 | return (sizeof(struct mlx5e_hv_vhca_per_ring_stats) * | 53 | return (sizeof(struct mlx5e_hv_vhca_per_ring_stats) * |
| 54 | priv->max_nch); | 54 | priv->stats_nch); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | static void mlx5e_hv_vhca_stats_work(struct work_struct *work) | 57 | static void mlx5e_hv_vhca_stats_work(struct work_struct *work) |
| @@ -100,7 +100,7 @@ static void mlx5e_hv_vhca_stats_control(struct mlx5_hv_vhca_agent *agent, · 42 unmodified lines | |||
| 100 | sagent = &priv->stats_agent; | 100 | sagent = &priv->stats_agent; |
| 101 | 101 | ||
| 102 | block->version = MLX5_HV_VHCA_STATS_VERSION; | 102 | block->version = MLX5_HV_VHCA_STATS_VERSION; |
| 103 | block->rings = priv->max_nch; | 103 | block->rings = priv->stats_nch; |
| 104 | 104 | ||
| 105 | if (!block->command) { | 105 | if (!block->command) { |
| 106 | cancel_delayed_work_sync(&priv->stats_agent.work); | 106 | cancel_delayed_work_sync(&priv->stats_agent.work); |
| @@ -13,8 +13,6 @@ struct mlx5e_ptp_fs { · 12 unmodified lines | |||
| 13 | bool valid; | 13 | bool valid; |
| 14 | }; | 14 | }; |
| 15 | 15 | ||
| 16 | #define MLX5E_PTP_CHANNEL_IX 0 | ||
| 17 | |||
| 18 | struct mlx5e_ptp_params { | 16 | struct mlx5e_ptp_params { |
| 19 | struct mlx5e_params params; | 17 | struct mlx5e_params params; |
| 20 | struct mlx5e_sq_param txq_sq_param; | 18 | struct mlx5e_sq_param txq_sq_param; |
| @@ -509,6 +507,7 @@ static int mlx5e_init_ptp_rq(struct mlx5e_ptp *c, struct mlx5e_params *params, · 488 unmodified lines | |||
| 509 | rq->mdev = mdev; | 507 | rq->mdev = mdev; |
| 510 | rq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); | 508 | rq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); |
| 511 | rq->stats = &c->priv->ptp_stats.rq; | 509 | rq->stats = &c->priv->ptp_stats.rq; |
| 510 | rq->ix = MLX5E_PTP_CHANNEL_IX; | ||
| 512 | rq->ptp_cyc2time = mlx5_rq_ts_translator(mdev); | 511 | rq->ptp_cyc2time = mlx5_rq_ts_translator(mdev); |
| 513 | err = mlx5e_rq_set_handlers(rq, params, false); | 512 | err = mlx5e_rq_set_handlers(rq, params, false); |
| 514 | if (err) | 513 | if (err) |
| @@ -8,6 +8,8 @@ · 7 unmodified lines | |||
| 8 | #include "en_stats.h" | 8 | #include "en_stats.h" |
| 9 | #include <linux/ptp_classify.h> | 9 | #include <linux/ptp_classify.h> |
| 10 | 10 | ||
| 11 | #define MLX5E_PTP_CHANNEL_IX 0 | ||
| 12 | |||
| 11 | struct mlx5e_ptpsq { | 13 | struct mlx5e_ptpsq { |
| 12 | struct mlx5e_txqsq txqsq; | 14 | struct mlx5e_txqsq txqsq; |
| 13 | struct mlx5e_cq ts_cq; | 15 | struct mlx5e_cq ts_cq; |
| @@ -2036,6 +2036,17 @@ static int set_pflag_tx_port_ts(struct net_device *netdev, bool enable) · 2035 unmodified lines | |||
| 2036 | } | 2036 | } |
| 2037 | 2037 | ||
| 2038 | new_params = priv->channels.params; | 2038 | new_params = priv->channels.params; |
| 2039 | /* Don't allow enabling TX-port-TS if MQPRIO mode channel offload is | ||
| 2040 | * active, since it defines explicitly which TC accepts the packet. | ||
| 2041 | * This conflicts with TX-port-TS hijacking the PTP traffic to a specific | ||
| 2042 | * HW TX-queue. | ||
| 2043 | */ | ||
| 2044 | if (enable && new_params.mqprio.mode == TC_MQPRIO_MODE_CHANNEL) { | ||
| 2045 | netdev_err(priv->netdev, | ||
| 2046 | "%s: MQPRIO mode channel offload is active, cannot set the TX-port-TS\n", | ||
| 2047 | __func__); | ||
| 2048 | return -EINVAL; | ||
| 2049 | } | ||
| 2039 | MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_TX_PORT_TS, enable); | 2050 | MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_TX_PORT_TS, enable); |
| 2040 | /* No need to verify SQ stop room as | 2051 | /* No need to verify SQ stop room as |
| 2041 | * ptpsq.txqsq.stop_room <= generic_sq->stop_room, and both | 2052 | * ptpsq.txqsq.stop_room <= generic_sq->stop_room, and both |
| @@ -2264,7 +2264,7 @@ void mlx5e_set_netdev_mtu_boundaries(struct mlx5e_priv *priv) · 2263 unmodified lines | |||
| 2264 | } | 2264 | } |
| 2265 | 2265 | ||
| 2266 | static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc, | 2266 | static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc, |
| 2267 | struct tc_mqprio_qopt_offload *mqprio) | 2267 | struct netdev_tc_txq *tc_to_txq) |
| 2268 | { | 2268 | { |
| 2269 | int tc, err; | 2269 | int tc, err; |
| 2270 | 2270 | ||
| @@ -2282,11 +2282,8 @@ static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc, · 11 unmodified lines | |||
| 2282 | for (tc = 0; tc < ntc; tc++) { | 2282 | for (tc = 0; tc < ntc; tc++) { |
| 2283 | u16 count, offset; | 2283 | u16 count, offset; |
| 2284 | 2284 | ||
| 2285 | /* For DCB mode, map netdev TCs to offset 0 | 2285 | count = tc_to_txq[tc].count; |
| 2286 | * We have our own UP to TXQ mapping for QoS | 2286 | offset = tc_to_txq[tc].offset; |
| 2287 | */ | ||
| 2288 | count = mqprio ? mqprio->qopt.count[tc] : nch; | ||
| 2289 | offset = mqprio ? mqprio->qopt.offset[tc] : 0; | ||
| 2290 | netdev_set_tc_queue(netdev, tc, count, offset); | 2287 | netdev_set_tc_queue(netdev, tc, count, offset); |
| 2291 | } | 2288 | } |
| 2292 | 2289 | ||
| @@ -2315,19 +2312,24 @@ int mlx5e_update_tx_netdev_queues(struct mlx5e_priv *priv) · 22 unmodified lines | |||
| 2315 | 2312 | ||
| 2316 | static int mlx5e_update_netdev_queues(struct mlx5e_priv *priv) | 2313 | static int mlx5e_update_netdev_queues(struct mlx5e_priv *priv) |
| 2317 | { | 2314 | { |
| 2315 | struct netdev_tc_txq old_tc_to_txq[TC_MAX_QUEUE], *tc_to_txq; | ||
| 2318 | struct net_device *netdev = priv->netdev; | 2316 | struct net_device *netdev = priv->netdev; |
| 2319 | int old_num_txqs, old_ntc; | 2317 | int old_num_txqs, old_ntc; |
| 2320 | int num_rxqs, nch, ntc; | 2318 | int num_rxqs, nch, ntc; |
| 2321 | int err; | 2319 | int err; |
| 2320 | int i; | ||
| 2322 | 2321 | ||
| 2323 | old_num_txqs = netdev->real_num_tx_queues; | 2322 | old_num_txqs = netdev->real_num_tx_queues; |
| 2324 | old_ntc = netdev->num_tc ? : 1; | 2323 | old_ntc = netdev->num_tc ? : 1; |
| 2324 | for (i = 0; i < ARRAY_SIZE(old_tc_to_txq); i++) | ||
| 2325 | old_tc_to_txq[i] = netdev->tc_to_txq[i]; | ||
| 2325 | 2326 | ||
| 2326 | nch = priv->channels.params.num_channels; | 2327 | nch = priv->channels.params.num_channels; |
| 2327 | ntc = mlx5e_get_dcb_num_tc(&priv->channels.params); | 2328 | ntc = priv->channels.params.mqprio.num_tc; |
| 2328 | num_rxqs = nch * priv->profile->rq_groups; | 2329 | num_rxqs = nch * priv->profile->rq_groups; |
| 2330 | tc_to_txq = priv->channels.params.mqprio.tc_to_txq; | ||
| 2329 | 2331 | ||
| 2330 | err = mlx5e_netdev_set_tcs(netdev, nch, ntc, NULL); | 2332 | err = mlx5e_netdev_set_tcs(netdev, nch, ntc, tc_to_txq); |
| 2331 | if (err) | 2333 | if (err) |
| 2332 | goto err_out; | 2334 | goto err_out; |
| 2333 | err = mlx5e_update_tx_netdev_queues(priv); | 2335 | err = mlx5e_update_tx_netdev_queues(priv); |
| @@ -2350,11 +2352,14 @@ err_txqs: · 16 unmodified lines | |||
| 2350 | WARN_ON_ONCE(netif_set_real_num_tx_queues(netdev, old_num_txqs)); | 2352 | WARN_ON_ONCE(netif_set_real_num_tx_queues(netdev, old_num_txqs)); |
| 2351 | 2353 | ||
| 2352 | err_tcs: | 2354 | err_tcs: |
| 2353 | mlx5e_netdev_set_tcs(netdev, old_num_txqs / old_ntc, old_ntc, NULL); | 2355 | WARN_ON_ONCE(mlx5e_netdev_set_tcs(netdev, old_num_txqs / old_ntc, old_ntc, |
| 2356 | old_tc_to_txq)); | ||
| 2354 | err_out: | 2357 | err_out: |
| 2355 | return err; | 2358 | return err; |
| 2356 | } | 2359 | } |
| 2357 | 2360 | ||
| 2361 | static MLX5E_DEFINE_PREACTIVATE_WRAPPER_CTX(mlx5e_update_netdev_queues); | ||
| 2362 | |||
| 2358 | static void mlx5e_set_default_xps_cpumasks(struct mlx5e_priv *priv, | 2363 | static void mlx5e_set_default_xps_cpumasks(struct mlx5e_priv *priv, |
| 2359 | struct mlx5e_params *params) | 2364 | struct mlx5e_params *params) |
| 2360 | { | 2365 | { |
| @@ -2861,6 +2866,58 @@ static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd) · 500 unmodified lines | |||
| 2861 | return 0; | 2866 | return 0; |
| 2862 | } | 2867 | } |
| 2863 | 2868 | ||
| 2869 | static void mlx5e_mqprio_build_default_tc_to_txq(struct netdev_tc_txq *tc_to_txq, | ||
| 2870 | int ntc, int nch) | ||
| 2871 | { | ||
| 2872 | int tc; | ||
| 2873 | |||
| 2874 | memset(tc_to_txq, 0, sizeof(*tc_to_txq) * TC_MAX_QUEUE); | ||
| 2875 | |||
| 2876 | /* Map netdev TCs to offset 0. | ||
| 2877 | * We have our own UP to TXQ mapping for DCB mode of QoS | ||
| 2878 | */ | ||
| 2879 | for (tc = 0; tc < ntc; tc++) { | ||
| 2880 | tc_to_txq[tc] = (struct netdev_tc_txq) { | ||
| 2881 | .count = nch, | ||
| 2882 | .offset = 0, | ||
| 2883 | }; | ||
| 2884 | } | ||
| 2885 | } | ||
| 2886 | |||
| 2887 | static void mlx5e_mqprio_build_tc_to_txq(struct netdev_tc_txq *tc_to_txq, | ||
| 2888 | struct tc_mqprio_qopt *qopt) | ||
| 2889 | { | ||
| 2890 | int tc; | ||
| 2891 | |||
| 2892 | for (tc = 0; tc < TC_MAX_QUEUE; tc++) { | ||
| 2893 | tc_to_txq[tc] = (struct netdev_tc_txq) { | ||
| 2894 | .count = qopt->count[tc], | ||
| 2895 | .offset = qopt->offset[tc], | ||
| 2896 | }; | ||
| 2897 | } | ||
| 2898 | } | ||
| 2899 | |||
| 2900 | static void mlx5e_params_mqprio_dcb_set(struct mlx5e_params *params, u8 num_tc) | ||
| 2901 | { | ||
| 2902 | params->mqprio.mode = TC_MQPRIO_MODE_DCB; | ||
| 2903 | params->mqprio.num_tc = num_tc; | ||
| 2904 | mlx5e_mqprio_build_default_tc_to_txq(params->mqprio.tc_to_txq, num_tc, | ||
| 2905 | params->num_channels); | ||
| 2906 | } | ||
| 2907 | |||
| 2908 | static void mlx5e_params_mqprio_channel_set(struct mlx5e_params *params, | ||
| 2909 | struct tc_mqprio_qopt *qopt) | ||
| 2910 | { | ||
| 2911 | params->mqprio.mode = TC_MQPRIO_MODE_CHANNEL; | ||
| 2912 | params->mqprio.num_tc = qopt->num_tc; | ||
| 2913 | mlx5e_mqprio_build_tc_to_txq(params->mqprio.tc_to_txq, qopt); | ||
| 2914 | } | ||
| 2915 | |||
| 2916 | static void mlx5e_params_mqprio_reset(struct mlx5e_params *params) | ||
| 2917 | { | ||
| 2918 | mlx5e_params_mqprio_dcb_set(params, 1); | ||
| 2919 | } | ||
| 2920 | |||
| 2864 | static int mlx5e_setup_tc_mqprio_dcb(struct mlx5e_priv *priv, | 2921 | static int mlx5e_setup_tc_mqprio_dcb(struct mlx5e_priv *priv, |
| 2865 | struct tc_mqprio_qopt *mqprio) | 2922 | struct tc_mqprio_qopt *mqprio) |
| 2866 | { | 2923 | { |
| @@ -2874,8 +2931,7 @@ static int mlx5e_setup_tc_mqprio_dcb(struct mlx5e_priv *priv, · 7 unmodified lines | |||
| 2874 | return -EINVAL; | 2931 | return -EINVAL; |
| 2875 | 2932 | ||
| 2876 | new_params = priv->channels.params; | 2933 | new_params = priv->channels.params; |
| 2877 | new_params.mqprio.mode = TC_MQPRIO_MODE_DCB; | 2934 | mlx5e_params_mqprio_dcb_set(&new_params, tc ? tc : 1); |
| 2878 | new_params.mqprio.num_tc = tc ? tc : 1; | ||
| 2879 | 2935 | ||
| 2880 | err = mlx5e_safe_switch_params(priv, &new_params, | 2936 | err = mlx5e_safe_switch_params(priv, &new_params, |
| 2881 | mlx5e_num_channels_changed_ctx, NULL, true); | 2937 | mlx5e_num_channels_changed_ctx, NULL, true); |
| @@ -2889,9 +2945,17 @@ static int mlx5e_mqprio_channel_validate(struct mlx5e_priv *priv, · 7 unmodified lines | |||
| 2889 | struct tc_mqprio_qopt_offload *mqprio) | 2945 | struct tc_mqprio_qopt_offload *mqprio) |
| 2890 | { | 2946 | { |
| 2891 | struct net_device *netdev = priv->netdev; | 2947 | struct net_device *netdev = priv->netdev; |
| 2948 | struct mlx5e_ptp *ptp_channel; | ||
| 2892 | int agg_count = 0; | 2949 | int agg_count = 0; |
| 2893 | int i; | 2950 | int i; |
| 2894 | 2951 | ||
| 2952 | ptp_channel = priv->channels.ptp; | ||
| 2953 | if (ptp_channel && test_bit(MLX5E_PTP_STATE_TX, ptp_channel->state)) { | ||
| 2954 | netdev_err(netdev, | ||
| 2955 | "Cannot activate MQPRIO mode channel since it conflicts with TX port TS\n"); | ||
| 2956 | return -EINVAL; | ||
| 2957 | } | ||
| 2958 | |||
| 2895 | if (mqprio->qopt.offset[0] != 0 || mqprio->qopt.num_tc < 1 || | 2959 | if (mqprio->qopt.offset[0] != 0 || mqprio->qopt.num_tc < 1 || |
| 2896 | mqprio->qopt.num_tc > MLX5E_MAX_NUM_MQPRIO_CH_TC) | 2960 | mqprio->qopt.num_tc > MLX5E_MAX_NUM_MQPRIO_CH_TC) |
| 2897 | return -EINVAL; | 2961 | return -EINVAL; |
| @@ -2926,25 +2990,12 @@ static int mlx5e_mqprio_channel_validate(struct mlx5e_priv *priv, · 28 unmodified lines | |||
| 2926 | return 0; | 2990 | return 0; |
| 2927 | } | 2991 | } |
| 2928 | 2992 | ||
| 2929 | static int mlx5e_mqprio_channel_set_tcs_ctx(struct mlx5e_priv *priv, void *ctx) | ||
| 2930 | { | ||
| 2931 | struct tc_mqprio_qopt_offload *mqprio = (struct tc_mqprio_qopt_offload *)ctx; | ||
| 2932 | struct net_device *netdev = priv->netdev; | ||
| 2933 | u8 num_tc; | ||
| 2934 | |||
| 2935 | if (priv->channels.params.mqprio.mode != TC_MQPRIO_MODE_CHANNEL) | ||
| 2936 | return -EINVAL; | ||
| 2937 | |||
| 2938 | num_tc = priv->channels.params.mqprio.num_tc; | ||
| 2939 | mlx5e_netdev_set_tcs(netdev, 0, num_tc, mqprio); | ||
| 2940 | |||
| 2941 | return 0; | ||
| 2942 | } | ||
| 2943 | |||
| 2944 | static int mlx5e_setup_tc_mqprio_channel(struct mlx5e_priv *priv, | 2993 | static int mlx5e_setup_tc_mqprio_channel(struct mlx5e_priv *priv, |
| 2945 | struct tc_mqprio_qopt_offload *mqprio) | 2994 | struct tc_mqprio_qopt_offload *mqprio) |
| 2946 | { | 2995 | { |
| 2996 | mlx5e_fp_preactivate preactivate; | ||
| 2947 | struct mlx5e_params new_params; | 2997 | struct mlx5e_params new_params; |
| 2998 | bool nch_changed; | ||
| 2948 | int err; | 2999 | int err; |
| 2949 | 3000 | ||
| 2950 | err = mlx5e_mqprio_channel_validate(priv, mqprio); | 3001 | err = mlx5e_mqprio_channel_validate(priv, mqprio); |
| @@ -2952,12 +3003,12 @@ static int mlx5e_setup_tc_mqprio_channel(struct mlx5e_priv *priv, · 1 unmodified line | |||
| 2952 | return err; | 3003 | return err; |
| 2953 | 3004 | ||
| 2954 | new_params = priv->channels.params; | 3005 | new_params = priv->channels.params; |
| 2955 | new_params.mqprio.mode = TC_MQPRIO_MODE_CHANNEL; | 3006 | mlx5e_params_mqprio_channel_set(&new_params, &mqprio->qopt); |
| 2956 | new_params.mqprio.num_tc = mqprio->qopt.num_tc; | ||
| 2957 | err = mlx5e_safe_switch_params(priv, &new_params, | ||
| 2958 | mlx5e_mqprio_channel_set_tcs_ctx, mqprio, true); | ||
| 2959 | 3007 | ||
| 2960 | return err; | 3008 | nch_changed = mlx5e_get_dcb_num_tc(&priv->channels.params) > 1; |
| 3009 | preactivate = nch_changed ? mlx5e_num_channels_changed_ctx : | ||
| 3010 | mlx5e_update_netdev_queues_ctx; | ||
| 3011 | return mlx5e_safe_switch_params(priv, &new_params, preactivate, NULL, true); | ||
| 2961 | } | 3012 | } |
| 2962 | 3013 | ||
| 2963 | static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv, | 3014 | static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv, |
| @@ -3065,7 +3116,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s) · 101 unmodified lines | |||
| 3065 | { | 3116 | { |
| 3066 | int i; | 3117 | int i; |
| 3067 | 3118 | ||
| 3068 | for (i = 0; i < priv->max_nch; i++) { | 3119 | for (i = 0; i < priv->stats_nch; i++) { |
| 3069 | struct mlx5e_channel_stats *channel_stats = &priv->channel_stats[i]; | 3120 | struct mlx5e_channel_stats *channel_stats = &priv->channel_stats[i]; |
| 3070 | struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq; | 3121 | struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq; |
| 3071 | struct mlx5e_rq_stats *rq_stats = &channel_stats->rq; | 3122 | struct mlx5e_rq_stats *rq_stats = &channel_stats->rq; |
| @@ -4186,13 +4237,11 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16 · 1114 unmodified lines | |||
| 4186 | struct mlx5_core_dev *mdev = priv->mdev; | 4237 | struct mlx5_core_dev *mdev = priv->mdev; |
| 4187 | u8 rx_cq_period_mode; | 4238 | u8 rx_cq_period_mode; |
| 4188 | 4239 | ||
| 4189 | priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile); | ||
| 4190 | |||
| 4191 | params->sw_mtu = mtu; | 4240 | params->sw_mtu = mtu; |
| 4192 | params->hard_mtu = MLX5E_ETH_HARD_MTU; | 4241 | params->hard_mtu = MLX5E_ETH_HARD_MTU; |
| 4193 | params->num_channels = min_t(unsigned int, MLX5E_MAX_NUM_CHANNELS / 2, | 4242 | params->num_channels = min_t(unsigned int, MLX5E_MAX_NUM_CHANNELS / 2, |
| 4194 | priv->max_nch); | 4243 | priv->max_nch); |
| 4195 | params->mqprio.num_tc = 1; | 4244 | mlx5e_params_mqprio_reset(params); |
| 4196 | 4245 | ||
| 4197 | /* Set an initial non-zero value, so that mlx5e_select_queue won't | 4246 | /* Set an initial non-zero value, so that mlx5e_select_queue won't |
| 4198 | * divide by zero if called before first activating channels. | 4247 | * divide by zero if called before first activating channels. |
| @@ -4682,8 +4731,35 @@ static const struct mlx5e_profile mlx5e_nic_profile = { · 483 unmodified lines | |||
| 4682 | .rx_ptp_support = true, | 4731 | .rx_ptp_support = true, |
| 4683 | }; | 4732 | }; |
| 4684 | 4733 | ||
| 4734 | static unsigned int | ||
| 4735 | mlx5e_calc_max_nch(struct mlx5_core_dev *mdev, struct net_device *netdev, | ||
| 4736 | const struct mlx5e_profile *profile) | ||
| 4737 | |||
| 4738 | { | ||
| 4739 | unsigned int max_nch, tmp; | ||
| 4740 | |||
| 4741 | /* core resources */ | ||
| 4742 | max_nch = mlx5e_get_max_num_channels(mdev); | ||
| 4743 | |||
| 4744 | /* netdev rx queues */ | ||
| 4745 | tmp = netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1); | ||
| 4746 | max_nch = min_t(unsigned int, max_nch, tmp); | ||
| 4747 | |||
| 4748 | /* netdev tx queues */ | ||
| 4749 | tmp = netdev->num_tx_queues; | ||
| 4750 | if (mlx5_qos_is_supported(mdev)) | ||
| 4751 | tmp -= mlx5e_qos_max_leaf_nodes(mdev); | ||
| 4752 | if (MLX5_CAP_GEN(mdev, ts_cqe_to_dest_cqn)) | ||
| 4753 | tmp -= profile->max_tc; | ||
| 4754 | tmp = tmp / profile->max_tc; | ||
| 4755 | max_nch = min_t(unsigned int, max_nch, tmp); | ||
| 4756 | |||
| 4757 | return max_nch; | ||
| 4758 | } | ||
| 4759 | |||
| 4685 | /* mlx5e generic netdev management API (move to en_common.c) */ | 4760 | /* mlx5e generic netdev management API (move to en_common.c) */ |
| 4686 | int mlx5e_priv_init(struct mlx5e_priv *priv, | 4761 | int mlx5e_priv_init(struct mlx5e_priv *priv, |
| 4762 | const struct mlx5e_profile *profile, | ||
| 4687 | struct net_device *netdev, | 4763 | struct net_device *netdev, |
| 4688 | struct mlx5_core_dev *mdev) | 4764 | struct mlx5_core_dev *mdev) |
| 4689 | { | 4765 | { |
| @@ -4691,6 +4767,8 @@ int mlx5e_priv_init(struct mlx5e_priv *priv, · 1 unmodified line | |||
| 4691 | priv->mdev = mdev; | 4767 | priv->mdev = mdev; |
| 4692 | priv->netdev = netdev; | 4768 | priv->netdev = netdev; |
| 4693 | priv->msglevel = MLX5E_MSG_LEVEL; | 4769 | priv->msglevel = MLX5E_MSG_LEVEL; |
| 4770 | priv->max_nch = mlx5e_calc_max_nch(mdev, netdev, profile); | ||
| 4771 | priv->stats_nch = priv->max_nch; | ||
| 4694 | priv->max_opened_tc = 1; | 4772 | priv->max_opened_tc = 1; |
| 4695 | 4773 | ||
| 4696 | if (!alloc_cpumask_var(&priv->scratchpad.cpumask, GFP_KERNEL)) | 4774 | if (!alloc_cpumask_var(&priv->scratchpad.cpumask, GFP_KERNEL)) |
| @@ -4734,7 +4812,8 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv) · 37 unmodified lines | |||
| 4734 | } | 4812 | } |
| 4735 | 4813 | ||
| 4736 | struct net_device * | 4814 | struct net_device * |
| 4737 | mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs) | 4815 | mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile, |
| 4816 | unsigned int txqs, unsigned int rxqs) | ||
| 4738 | { | 4817 | { |
| 4739 | struct net_device *netdev; | 4818 | struct net_device *netdev; |
| 4740 | int err; | 4819 | int err; |
| @@ -4745,7 +4824,7 @@ mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int · 4 unmodified lines | |||
| 4745 | return NULL; | 4824 | return NULL; |
| 4746 | } | 4825 | } |
| 4747 | 4826 | ||
| 4748 | err = mlx5e_priv_init(netdev_priv(netdev), netdev, mdev); | 4827 | err = mlx5e_priv_init(netdev_priv(netdev), profile, netdev, mdev); |
| 4749 | if (err) { | 4828 | if (err) { |
| 4750 | mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err); | 4829 | mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err); |
| 4751 | goto err_free_netdev; | 4830 | goto err_free_netdev; |
| @@ -4787,7 +4866,7 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv) · 35 unmodified lines | |||
| 4787 | clear_bit(MLX5E_STATE_DESTROYING, &priv->state); | 4866 | clear_bit(MLX5E_STATE_DESTROYING, &priv->state); |
| 4788 | 4867 | ||
| 4789 | /* max number of channels may have changed */ | 4868 | /* max number of channels may have changed */ |
| 4790 | max_nch = mlx5e_get_max_num_channels(priv->mdev); | 4869 | max_nch = mlx5e_calc_max_nch(priv->mdev, priv->netdev, profile); |
| 4791 | if (priv->channels.params.num_channels > max_nch) { | 4870 | if (priv->channels.params.num_channels > max_nch) { |
| 4792 | mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch); | 4871 | mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch); |
| 4793 | /* Reducing the number of channels - RXFH has to be reset, and | 4872 | /* Reducing the number of channels - RXFH has to be reset, and |
| @@ -4795,7 +4874,18 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv) · 1 unmodified line | |||
| 4795 | */ | 4874 | */ |
| 4796 | priv->netdev->priv_flags &= ~IFF_RXFH_CONFIGURED; | 4875 | priv->netdev->priv_flags &= ~IFF_RXFH_CONFIGURED; |
| 4797 | priv->channels.params.num_channels = max_nch; | 4876 | priv->channels.params.num_channels = max_nch; |
| 4877 | if (priv->channels.params.mqprio.mode == TC_MQPRIO_MODE_CHANNEL) { | ||
| 4878 | mlx5_core_warn(priv->mdev, "MLX5E: Disabling MQPRIO channel mode\n"); | ||
| 4879 | mlx5e_params_mqprio_reset(&priv->channels.params); | ||
| 4880 | } | ||
| 4798 | } | 4881 | } |
| 4882 | if (max_nch != priv->max_nch) { | ||
| 4883 | mlx5_core_warn(priv->mdev, | ||
| 4884 | "MLX5E: Updating max number of channels from %u to %u\n", | ||
| 4885 | priv->max_nch, max_nch); | ||
| 4886 | priv->max_nch = max_nch; | ||
| 4887 | } | ||
| 4888 | |||
| 4799 | /* 1. Set the real number of queues in the kernel the first time. | 4889 | /* 1. Set the real number of queues in the kernel the first time. |
| 4800 | * 2. Set our default XPS cpumask. | 4890 | * 2. Set our default XPS cpumask. |
| 4801 | * 3. Build the RQT. | 4891 | * 3. Build the RQT. |
| @@ -4860,7 +4950,7 @@ mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mde · 58 unmodified lines | |||
| 4860 | struct mlx5e_priv *priv = netdev_priv(netdev); | 4950 | struct mlx5e_priv *priv = netdev_priv(netdev); |
| 4861 | int err; | 4951 | int err; |
| 4862 | 4952 | ||
| 4863 | err = mlx5e_priv_init(priv, netdev, mdev); | 4953 | err = mlx5e_priv_init(priv, new_profile, netdev, mdev); |
| 4864 | if (err) { | 4954 | if (err) { |
| 4865 | mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err); | 4955 | mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err); |
| 4866 | return err; | 4956 | return err; |
| @@ -4886,20 +4976,12 @@ priv_cleanup: · 19 unmodified lines | |||
| 4886 | int mlx5e_netdev_change_profile(struct mlx5e_priv *priv, | 4976 | int mlx5e_netdev_change_profile(struct mlx5e_priv *priv, |
| 4887 | const struct mlx5e_profile *new_profile, void *new_ppriv) | 4977 | const struct mlx5e_profile *new_profile, void *new_ppriv) |
| 4888 | { | 4978 | { |
| 4889 | unsigned int new_max_nch = mlx5e_calc_max_nch(priv, new_profile); | ||
| 4890 | const struct mlx5e_profile *orig_profile = priv->profile; | 4979 | const struct mlx5e_profile *orig_profile = priv->profile; |
| 4891 | struct net_device *netdev = priv->netdev; | 4980 | struct net_device *netdev = priv->netdev; |
| 4892 | struct mlx5_core_dev *mdev = priv->mdev; | 4981 | struct mlx5_core_dev *mdev = priv->mdev; |
| 4893 | void *orig_ppriv = priv->ppriv; | 4982 | void *orig_ppriv = priv->ppriv; |
| 4894 | int err, rollback_err; | 4983 | int err, rollback_err; |
| 4895 | 4984 | ||
| 4896 | /* sanity */ | ||
| 4897 | if (new_max_nch != priv->max_nch) { | ||
| 4898 | netdev_warn(netdev, "%s: Replacing profile with different max channels\n", | ||
| 4899 | __func__); | ||
| 4900 | return -EINVAL; | ||
| 4901 | } | ||
| 4902 | |||
| 4903 | /* cleanup old profile */ | 4985 | /* cleanup old profile */ |
| 4904 | mlx5e_detach_netdev(priv); | 4986 | mlx5e_detach_netdev(priv); |
| 4905 | priv->profile->cleanup(priv); | 4987 | priv->profile->cleanup(priv); |
| @@ -4995,7 +5077,7 @@ static int mlx5e_probe(struct auxiliary_device *adev, · 89 unmodified lines | |||
| 4995 | nch = mlx5e_get_max_num_channels(mdev); | 5077 | nch = mlx5e_get_max_num_channels(mdev); |
| 4996 | txqs = nch * profile->max_tc + ptp_txqs + qos_sqs; | 5078 | txqs = nch * profile->max_tc + ptp_txqs + qos_sqs; |
| 4997 | rxqs = nch * profile->rq_groups; | 5079 | rxqs = nch * profile->rq_groups; |
| 4998 | netdev = mlx5e_create_netdev(mdev, txqs, rxqs); | 5080 | netdev = mlx5e_create_netdev(mdev, profile, txqs, rxqs); |
| 4999 | if (!netdev) { | 5081 | if (!netdev) { |
| 5000 | mlx5_core_err(mdev, "mlx5e_create_netdev failed\n"); | 5082 | mlx5_core_err(mdev, "mlx5e_create_netdev failed\n"); |
| 5001 | return -ENOMEM; | 5083 | return -ENOMEM; |
| @@ -596,7 +596,6 @@ static void mlx5e_build_rep_params(struct net_device *netdev) · 595 unmodified lines | |||
| 596 | MLX5_CQ_PERIOD_MODE_START_FROM_CQE : | 596 | MLX5_CQ_PERIOD_MODE_START_FROM_CQE : |
| 597 | MLX5_CQ_PERIOD_MODE_START_FROM_EQE; | 597 | MLX5_CQ_PERIOD_MODE_START_FROM_EQE; |
| 598 | 598 | ||
| 599 | priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile); | ||
| 600 | params = &priv->channels.params; | 599 | params = &priv->channels.params; |
| 601 | 600 | ||
| 602 | params->num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS; | 601 | params->num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS; |
| @@ -1169,7 +1168,7 @@ mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) · 566 unmodified lines | |||
| 1169 | nch = mlx5e_get_max_num_channels(dev); | 1168 | nch = mlx5e_get_max_num_channels(dev); |
| 1170 | txqs = nch * profile->max_tc; | 1169 | txqs = nch * profile->max_tc; |
| 1171 | rxqs = nch * profile->rq_groups; | 1170 | rxqs = nch * profile->rq_groups; |
| 1172 | netdev = mlx5e_create_netdev(dev, txqs, rxqs); | 1171 | netdev = mlx5e_create_netdev(dev, profile, txqs, rxqs); |
| 1173 | if (!netdev) { | 1172 | if (!netdev) { |
| 1174 | mlx5_core_warn(dev, | 1173 | mlx5_core_warn(dev, |
| 1175 | "Failed to create representor netdev for vport %d\n", | 1174 | "Failed to create representor netdev for vport %d\n", |
| @@ -1001,14 +1001,9 @@ static inline void mlx5e_handle_csum(struct net_device *netdev, · 1000 unmodified lines | |||
| 1001 | goto csum_unnecessary; | 1001 | goto csum_unnecessary; |
| 1002 | 1002 | ||
| 1003 | if (likely(is_last_ethertype_ip(skb, &network_depth, &proto))) { | 1003 | if (likely(is_last_ethertype_ip(skb, &network_depth, &proto))) { |
| 1004 | u8 ipproto = get_ip_proto(skb, network_depth, proto); | 1004 | if (unlikely(get_ip_proto(skb, network_depth, proto) == IPPROTO_SCTP)) |
| 1005 | |||
| 1006 | if (unlikely(ipproto == IPPROTO_SCTP)) | ||
| 1007 | goto csum_unnecessary; | 1005 | goto csum_unnecessary; |
| 1008 | 1006 | ||
| 1009 | if (unlikely(mlx5_ipsec_is_rx_flow(cqe))) | ||
| 1010 | goto csum_none; | ||
| 1011 | |||
| 1012 | stats->csum_complete++; | 1007 | stats->csum_complete++; |
| 1013 | skb->ip_summed = CHECKSUM_COMPLETE; | 1008 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 1014 | skb->csum = csum_unfold((__force __sum16)cqe->check_sum); | 1009 | skb->csum = csum_unfold((__force __sum16)cqe->check_sum); |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | |||
| 34 | #include "en.h" | 34 | #include "en.h" |
| 35 | #include "en_accel/tls.h" | 35 | #include "en_accel/tls.h" |
| 36 | #include "en_accel/en_accel.h" | 36 | #include "en_accel/en_accel.h" |
| 37 | #include "en/ptp.h" | ||
| 37 | 38 | ||
| 38 | static unsigned int stats_grps_num(struct mlx5e_priv *priv) | 39 | static unsigned int stats_grps_num(struct mlx5e_priv *priv) |
| 39 | { | 40 | { |
| @@ -450,7 +451,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw) · 410 unmodified lines | |||
| 450 | 451 | ||
| 451 | memset(s, 0, sizeof(*s)); | 452 | memset(s, 0, sizeof(*s)); |
| 452 | 453 | ||
| 453 | for (i = 0; i < priv->max_nch; i++) { | 454 | for (i = 0; i < priv->stats_nch; i++) { |
| 454 | struct mlx5e_channel_stats *channel_stats = | 455 | struct mlx5e_channel_stats *channel_stats = |
| 455 | &priv->channel_stats[i]; | 456 | &priv->channel_stats[i]; |
| 456 | int j; | 457 | int j; |
| @@ -2076,7 +2077,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(ptp) · 1619 unmodified lines | |||
| 2076 | if (priv->rx_ptp_opened) { | 2077 | if (priv->rx_ptp_opened) { |
| 2077 | for (i = 0; i < NUM_PTP_RQ_STATS; i++) | 2078 | for (i = 0; i < NUM_PTP_RQ_STATS; i++) |
| 2078 | sprintf(data + (idx++) * ETH_GSTRING_LEN, | 2079 | sprintf(data + (idx++) * ETH_GSTRING_LEN, |
| 2079 | ptp_rq_stats_desc[i].format); | 2080 | ptp_rq_stats_desc[i].format, MLX5E_PTP_CHANNEL_IX); |
| 2080 | } | 2081 | } |
| 2081 | return idx; | 2082 | return idx; |
| 2082 | } | 2083 | } |
| @@ -2119,7 +2120,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(ptp) { return; } · 36 unmodified lines | |||
| 2119 | 2120 | ||
| 2120 | static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels) | 2121 | static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels) |
| 2121 | { | 2122 | { |
| 2122 | int max_nch = priv->max_nch; | 2123 | int max_nch = priv->stats_nch; |
| 2123 | 2124 | ||
| 2124 | return (NUM_RQ_STATS * max_nch) + | 2125 | return (NUM_RQ_STATS * max_nch) + |
| 2125 | (NUM_CH_STATS * max_nch) + | 2126 | (NUM_CH_STATS * max_nch) + |
| @@ -2133,7 +2134,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels) · 7 unmodified lines | |||
| 2133 | static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels) | 2134 | static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels) |
| 2134 | { | 2135 | { |
| 2135 | bool is_xsk = priv->xsk.ever_used; | 2136 | bool is_xsk = priv->xsk.ever_used; |
| 2136 | int max_nch = priv->max_nch; | 2137 | int max_nch = priv->stats_nch; |
| 2137 | int i, j, tc; | 2138 | int i, j, tc; |
| 2138 | 2139 | ||
| 2139 | for (i = 0; i < max_nch; i++) | 2140 | for (i = 0; i < max_nch; i++) |
| @@ -2175,7 +2176,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels) · 35 unmodified lines | |||
| 2175 | static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(channels) | 2176 | static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(channels) |
| 2176 | { | 2177 | { |
| 2177 | bool is_xsk = priv->xsk.ever_used; | 2178 | bool is_xsk = priv->xsk.ever_used; |
| 2178 | int max_nch = priv->max_nch; | 2179 | int max_nch = priv->stats_nch; |
| 2179 | int i, j, tc; | 2180 | int i, j, tc; |
| 2180 | 2181 | ||
| 2181 | for (i = 0; i < max_nch; i++) | 2182 | for (i = 0; i < max_nch; i++) |
| @@ -79,12 +79,16 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw, · 78 unmodified lines | |||
| 79 | int dest_num = 0; | 79 | int dest_num = 0; |
| 80 | int err = 0; | 80 | int err = 0; |
| 81 | 81 | ||
| 82 | if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) { | 82 | if (vport->egress.legacy.drop_counter) { |
| 83 | drop_counter = vport->egress.legacy.drop_counter; | ||
| 84 | } else if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) { | ||
| 83 | drop_counter = mlx5_fc_create(esw->dev, false); | 85 | drop_counter = mlx5_fc_create(esw->dev, false); |
| 84 | if (IS_ERR(drop_counter)) | 86 | if (IS_ERR(drop_counter)) { |
| 85 | esw_warn(esw->dev, | 87 | esw_warn(esw->dev, |
| 86 | "vport[%d] configure egress drop rule counter err(%ld)\n", | 88 | "vport[%d] configure egress drop rule counter err(%ld)\n", |
| 87 | vport->vport, PTR_ERR(drop_counter)); | 89 | vport->vport, PTR_ERR(drop_counter)); |
| 90 | drop_counter = NULL; | ||
| 91 | } | ||
| 88 | vport->egress.legacy.drop_counter = drop_counter; | 92 | vport->egress.legacy.drop_counter = drop_counter; |
| 89 | } | 93 | } |
| 90 | 94 | ||
| @@ -123,7 +127,7 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw, · 32 unmodified lines | |||
| 123 | flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP; | 127 | flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP; |
| 124 | 128 | ||
| 125 | /* Attach egress drop flow counter */ | 129 | /* Attach egress drop flow counter */ |
| 126 | if (!IS_ERR_OR_NULL(drop_counter)) { | 130 | if (drop_counter) { |
| 127 | flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT; | 131 | flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT; |
| 128 | drop_ctr_dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER; | 132 | drop_ctr_dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER; |
| 129 | drop_ctr_dst.counter_id = mlx5_fc_id(drop_counter); | 133 | drop_ctr_dst.counter_id = mlx5_fc_id(drop_counter); |
| @@ -162,7 +166,7 @@ void esw_acl_egress_lgcy_cleanup(struct mlx5_eswitch *esw, · 32 unmodified lines | |||
| 162 | esw_acl_egress_table_destroy(vport); | 166 | esw_acl_egress_table_destroy(vport); |
| 163 | 167 | ||
| 164 | clean_drop_counter: | 168 | clean_drop_counter: |
| 165 | if (!IS_ERR_OR_NULL(vport->egress.legacy.drop_counter)) { | 169 | if (vport->egress.legacy.drop_counter) { |
| 166 | mlx5_fc_destroy(esw->dev, vport->egress.legacy.drop_counter); | 170 | mlx5_fc_destroy(esw->dev, vport->egress.legacy.drop_counter); |
| 167 | vport->egress.legacy.drop_counter = NULL; | 171 | vport->egress.legacy.drop_counter = NULL; |
| 168 | } | 172 | } |
| @@ -160,7 +160,9 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw, · 159 unmodified lines | |||
| 160 | 160 | ||
| 161 | esw_acl_ingress_lgcy_rules_destroy(vport); | 161 | esw_acl_ingress_lgcy_rules_destroy(vport); |
| 162 | 162 | ||
| 163 | if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) { | 163 | if (vport->ingress.legacy.drop_counter) { |
| 164 | counter = vport->ingress.legacy.drop_counter; | ||
| 165 | } else if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) { | ||
| 164 | counter = mlx5_fc_create(esw->dev, false); | 166 | counter = mlx5_fc_create(esw->dev, false); |
| 165 | if (IS_ERR(counter)) { | 167 | if (IS_ERR(counter)) { |
| 166 | esw_warn(esw->dev, | 168 | esw_warn(esw->dev, |
| @@ -113,7 +113,7 @@ static void mlx5i_grp_sw_update_stats(struct mlx5e_priv *priv) · 112 unmodified lines | |||
| 113 | struct mlx5e_sw_stats s = { 0 }; | 113 | struct mlx5e_sw_stats s = { 0 }; |
| 114 | int i, j; | 114 | int i, j; |
| 115 | 115 | ||
| 116 | for (i = 0; i < priv->max_nch; i++) { | 116 | for (i = 0; i < priv->stats_nch; i++) { |
| 117 | struct mlx5e_channel_stats *channel_stats; | 117 | struct mlx5e_channel_stats *channel_stats; |
| 118 | struct mlx5e_rq_stats *rq_stats; | 118 | struct mlx5e_rq_stats *rq_stats; |
| 119 | 119 | ||
| @@ -711,7 +711,7 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u32 port_num, · 591 unmodified lines | |||
| 711 | goto destroy_ht; | 711 | goto destroy_ht; |
| 712 | } | 712 | } |
| 713 | 713 | ||
| 714 | err = mlx5e_priv_init(epriv, netdev, mdev); | 714 | err = mlx5e_priv_init(epriv, prof, netdev, mdev); |
| 715 | if (err) | 715 | if (err) |
| 716 | goto destroy_mdev_resources; | 716 | goto destroy_mdev_resources; |
| 717 | 717 | ||
| @@ -448,22 +448,20 @@ static u64 find_target_cycles(struct mlx5_core_dev *mdev, s64 target_ns) · 447 unmodified lines | |||
| 448 | return cycles_now + cycles_delta; | 448 | return cycles_now + cycles_delta; |
| 449 | } | 449 | } |
| 450 | 450 | ||
| 451 | static u64 perout_conf_internal_timer(struct mlx5_core_dev *mdev, | 451 | static u64 perout_conf_internal_timer(struct mlx5_core_dev *mdev, s64 sec) |
| 452 | s64 sec, u32 nsec) | ||
| 453 | { | 452 | { |
| 454 | struct timespec64 ts; | 453 | struct timespec64 ts = {}; |
| 455 | s64 target_ns; | 454 | s64 target_ns; |
| 456 | 455 | ||
| 457 | ts.tv_sec = sec; | 456 | ts.tv_sec = sec; |
| 458 | ts.tv_nsec = nsec; | ||
| 459 | target_ns = timespec64_to_ns(&ts); | 457 | target_ns = timespec64_to_ns(&ts); |
| 460 | 458 | ||
| 461 | return find_target_cycles(mdev, target_ns); | 459 | return find_target_cycles(mdev, target_ns); |
| 462 | } | 460 | } |
| 463 | 461 | ||
| 464 | static u64 perout_conf_real_time(s64 sec, u32 nsec) | 462 | static u64 perout_conf_real_time(s64 sec) |
| 465 | { | 463 | { |
| 466 | return (u64)nsec | (u64)sec << 32; | 464 | return (u64)sec << 32; |
| 467 | } | 465 | } |
| 468 | 466 | ||
| 469 | static int mlx5_perout_configure(struct ptp_clock_info *ptp, | 467 | static int mlx5_perout_configure(struct ptp_clock_info *ptp, |
| @@ -474,6 +472,7 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, · 4 unmodified lines | |||
| 474 | container_of(ptp, struct mlx5_clock, ptp_info); | 472 | container_of(ptp, struct mlx5_clock, ptp_info); |
| 475 | struct mlx5_core_dev *mdev = | 473 | struct mlx5_core_dev *mdev = |
| 476 | container_of(clock, struct mlx5_core_dev, clock); | 474 | container_of(clock, struct mlx5_core_dev, clock); |
| 475 | bool rt_mode = mlx5_real_time_mode(mdev); | ||
| 477 | u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0}; | 476 | u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0}; |
| 478 | struct timespec64 ts; | 477 | struct timespec64 ts; |
| 479 | u32 field_select = 0; | 478 | u32 field_select = 0; |
| @@ -501,8 +500,10 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, · 21 unmodified lines | |||
| 501 | 500 | ||
| 502 | if (on) { | 501 | if (on) { |
| 503 | bool rt_mode = mlx5_real_time_mode(mdev); | 502 | bool rt_mode = mlx5_real_time_mode(mdev); |
| 504 | u32 nsec; | 503 | s64 sec = rq->perout.start.sec; |
| 505 | s64 sec; | 504 | |
| 505 | if (rq->perout.start.nsec) | ||
| 506 | return -EINVAL; | ||
| 506 | 507 | ||
| 507 | pin_mode = MLX5_PIN_MODE_OUT; | 508 | pin_mode = MLX5_PIN_MODE_OUT; |
| 508 | pattern = MLX5_OUT_PATTERN_PERIODIC; | 509 | pattern = MLX5_OUT_PATTERN_PERIODIC; |
| @@ -513,14 +514,11 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, · 4 unmodified lines | |||
| 513 | if ((ns >> 1) != 500000000LL) | 514 | if ((ns >> 1) != 500000000LL) |
| 514 | return -EINVAL; | 515 | return -EINVAL; |
| 515 | 516 | ||
| 516 | nsec = rq->perout.start.nsec; | ||
| 517 | sec = rq->perout.start.sec; | ||
| 518 | |||
| 519 | if (rt_mode && sec > U32_MAX) | 517 | if (rt_mode && sec > U32_MAX) |
| 520 | return -EINVAL; | 518 | return -EINVAL; |
| 521 | 519 | ||
| 522 | time_stamp = rt_mode ? perout_conf_real_time(sec, nsec) : | 520 | time_stamp = rt_mode ? perout_conf_real_time(sec) : |
| 523 | perout_conf_internal_timer(mdev, sec, nsec); | 521 | perout_conf_internal_timer(mdev, sec); |
| 524 | 522 | ||
| 525 | field_select |= MLX5_MTPPS_FS_PIN_MODE | | 523 | field_select |= MLX5_MTPPS_FS_PIN_MODE | |
| 526 | MLX5_MTPPS_FS_PATTERN | | 524 | MLX5_MTPPS_FS_PATTERN | |
| @@ -538,6 +536,9 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, · 11 unmodified lines | |||
| 538 | if (err) | 536 | if (err) |
| 539 | return err; | 537 | return err; |
| 540 | 538 | ||
| 539 | if (rt_mode) | ||
| 540 | return 0; | ||
| 541 | |||
| 541 | return mlx5_set_mtppse(mdev, pin, 0, | 542 | return mlx5_set_mtppse(mdev, pin, 0, |
| 542 | MLX5_EVENT_MODE_REPETETIVE & on); | 543 | MLX5_EVENT_MODE_REPETETIVE & on); |
| 543 | } | 544 | } |
| @@ -705,20 +706,14 @@ static void ts_next_sec(struct timespec64 *ts) · 161 unmodified lines | |||
| 705 | static u64 perout_conf_next_event_timer(struct mlx5_core_dev *mdev, | 706 | static u64 perout_conf_next_event_timer(struct mlx5_core_dev *mdev, |
| 706 | struct mlx5_clock *clock) | 707 | struct mlx5_clock *clock) |
| 707 | { | 708 | { |
| 708 | bool rt_mode = mlx5_real_time_mode(mdev); | ||
| 709 | struct timespec64 ts; | 709 | struct timespec64 ts; |
| 710 | s64 target_ns; | 710 | s64 target_ns; |
| 711 | 711 | ||
| 712 | if (rt_mode) | 712 | mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL); |
| 713 | ts = mlx5_ptp_gettimex_real_time(mdev, NULL); | ||
| 714 | else | ||
| 715 | mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL); | ||
| 716 | |||
| 717 | ts_next_sec(&ts); | 713 | ts_next_sec(&ts); |
| 718 | target_ns = timespec64_to_ns(&ts); | 714 | target_ns = timespec64_to_ns(&ts); |
| 719 | 715 | ||
| 720 | return rt_mode ? perout_conf_real_time(ts.tv_sec, ts.tv_nsec) : | 716 | return find_target_cycles(mdev, target_ns); |
| 721 | find_target_cycles(mdev, target_ns); | ||
| 722 | } | 717 | } |
| 723 | 718 | ||
| 724 | static int mlx5_pps_event(struct notifier_block *nb, | 719 | static int mlx5_pps_event(struct notifier_block *nb, |
| @@ -13,8 +13,8 @@ · 12 unmodified lines | |||
| 13 | #endif | 13 | #endif |
| 14 | 14 | ||
| 15 | #define MLX5_MAX_IRQ_NAME (32) | 15 | #define MLX5_MAX_IRQ_NAME (32) |
| 16 | /* max irq_index is 255. three chars */ | 16 | /* max irq_index is 2047, so four chars */ |
| 17 | #define MLX5_MAX_IRQ_IDX_CHARS (3) | 17 | #define MLX5_MAX_IRQ_IDX_CHARS (4) |
| 18 | 18 | ||
| 19 | #define MLX5_SFS_PER_CTRL_IRQ 64 | 19 | #define MLX5_SFS_PER_CTRL_IRQ 64 |
| 20 | #define MLX5_IRQ_CTRL_SF_MAX 8 | 20 | #define MLX5_IRQ_CTRL_SF_MAX 8 |
| @@ -633,8 +633,9 @@ void mlx5_irq_table_destroy(struct mlx5_core_dev *dev) · 612 unmodified lines | |||
| 633 | int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table) | 633 | int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table) |
| 634 | { | 634 | { |
| 635 | if (table->sf_comp_pool) | 635 | if (table->sf_comp_pool) |
| 636 | return table->sf_comp_pool->xa_num_irqs.max - | 636 | return min_t(int, num_online_cpus(), |
| 637 | table->sf_comp_pool->xa_num_irqs.min + 1; | 637 | table->sf_comp_pool->xa_num_irqs.max - |
| 638 | table->sf_comp_pool->xa_num_irqs.min + 1); | ||
| 638 | else | 639 | else |
| 639 | return mlx5_irq_table_get_num_comp(table); | 640 | return mlx5_irq_table_get_num_comp(table); |
| 640 | } | 641 | } |
| @@ -998,8 +998,8 @@ ocelot_vcap_block_find_filter_by_index(struct ocelot_vcap_block *block, · 997 unmodified lines | |||
| 998 | } | 998 | } |
| 999 | 999 | ||
| 1000 | struct ocelot_vcap_filter * | 1000 | struct ocelot_vcap_filter * |
| 1001 | ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int cookie, | 1001 | ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, |
| 1002 | bool tc_offload) | 1002 | unsigned long cookie, bool tc_offload) |
| 1003 | { | 1003 | { |
| 1004 | struct ocelot_vcap_filter *filter; | 1004 | struct ocelot_vcap_filter *filter; |
| 1005 | 1005 | ||
| @@ -1292,8 +1292,10 @@ int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr) · 1291 unmodified lines | |||
| 1292 | if (err && err != -EEXIST) { | 1292 | if (err && err != -EEXIST) { |
| 1293 | /* set the state back to NEW so we can try again later */ | 1293 | /* set the state back to NEW so we can try again later */ |
| 1294 | f = ionic_rx_filter_by_addr(lif, addr); | 1294 | f = ionic_rx_filter_by_addr(lif, addr); |
| 1295 | if (f && f->state == IONIC_FILTER_STATE_SYNCED) | 1295 | if (f && f->state == IONIC_FILTER_STATE_SYNCED) { |
| 1296 | f->state = IONIC_FILTER_STATE_NEW; | 1296 | f->state = IONIC_FILTER_STATE_NEW; |
| 1297 | set_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state); | ||
| 1298 | } | ||
| 1297 | 1299 | ||
| 1298 | spin_unlock_bh(&lif->rx_filters.lock); | 1300 | spin_unlock_bh(&lif->rx_filters.lock); |
| 1299 | 1301 | ||
| @@ -349,9 +349,6 @@ loop_out: · 348 unmodified lines | |||
| 349 | list_for_each_entry_safe(sync_item, spos, &sync_add_list, list) { | 349 | list_for_each_entry_safe(sync_item, spos, &sync_add_list, list) { |
| 350 | (void)ionic_lif_addr_add(lif, sync_item->f.cmd.mac.addr); | 350 | (void)ionic_lif_addr_add(lif, sync_item->f.cmd.mac.addr); |
| 351 | 351 | ||
| 352 | if (sync_item->f.state != IONIC_FILTER_STATE_SYNCED) | ||
| 353 | set_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state); | ||
| 354 | |||
| 355 | list_del(&sync_item->list); | 352 | list_del(&sync_item->list); |
| 356 | devm_kfree(dev, sync_item); | 353 | devm_kfree(dev, sync_item); |
| 357 | } | 354 | } |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | |||
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 22 | #include <linux/mfd/syscon.h> | 22 | #include <linux/mfd/syscon.h> |
| 23 | #include <linux/regmap.h> | 23 | #include <linux/regmap.h> |
| 24 | #include <linux/pm_runtime.h> | ||
| 24 | 25 | ||
| 25 | #include "stmmac_platform.h" | 26 | #include "stmmac_platform.h" |
| 26 | 27 | ||
| @@ -1528,6 +1529,8 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) · 1501 unmodified lines | |||
| 1528 | return ret; | 1529 | return ret; |
| 1529 | } | 1530 | } |
| 1530 | 1531 | ||
| 1532 | pm_runtime_get_sync(dev); | ||
| 1533 | |||
| 1531 | if (bsp_priv->integrated_phy) | 1534 | if (bsp_priv->integrated_phy) |
| 1532 | rk_gmac_integrated_phy_powerup(bsp_priv); | 1535 | rk_gmac_integrated_phy_powerup(bsp_priv); |
| 1533 | 1536 | ||
| @@ -1539,6 +1542,8 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac) · 5 unmodified lines | |||
| 1539 | if (gmac->integrated_phy) | 1542 | if (gmac->integrated_phy) |
| 1540 | rk_gmac_integrated_phy_powerdown(gmac); | 1543 | rk_gmac_integrated_phy_powerdown(gmac); |
| 1541 | 1544 | ||
| 1545 | pm_runtime_put_sync(&gmac->pdev->dev); | ||
| 1546 | |||
| 1542 | phy_power_on(gmac, false); | 1547 | phy_power_on(gmac, false); |
| 1543 | gmac_clk_enable(gmac, false); | 1548 | gmac_clk_enable(gmac, false); |
| 1544 | } | 1549 | } |
| @@ -477,6 +477,10 @@ bool stmmac_eee_init(struct stmmac_priv *priv) · 476 unmodified lines | |||
| 477 | stmmac_lpi_entry_timer_config(priv, 0); | 477 | stmmac_lpi_entry_timer_config(priv, 0); |
| 478 | del_timer_sync(&priv->eee_ctrl_timer); | 478 | del_timer_sync(&priv->eee_ctrl_timer); |
| 479 | stmmac_set_eee_timer(priv, priv->hw, 0, eee_tw_timer); | 479 | stmmac_set_eee_timer(priv, priv->hw, 0, eee_tw_timer); |
| 480 | if (priv->hw->xpcs) | ||
| 481 | xpcs_config_eee(priv->hw->xpcs, | ||
| 482 | priv->plat->mult_fact_100ns, | ||
| 483 | false); | ||
| 480 | } | 484 | } |
| 481 | mutex_unlock(&priv->lock); | 485 | mutex_unlock(&priv->lock); |
| 482 | return false; | 486 | return false; |
| @@ -1038,7 +1042,7 @@ static void stmmac_mac_link_down(struct phylink_config *config, · 555 unmodified lines | |||
| 1038 | stmmac_mac_set(priv, priv->ioaddr, false); | 1042 | stmmac_mac_set(priv, priv->ioaddr, false); |
| 1039 | priv->eee_active = false; | 1043 | priv->eee_active = false; |
| 1040 | priv->tx_lpi_enabled = false; | 1044 | priv->tx_lpi_enabled = false; |
| 1041 | stmmac_eee_init(priv); | 1045 | priv->eee_enabled = stmmac_eee_init(priv); |
| 1042 | stmmac_set_eee_pls(priv, priv->hw, false); | 1046 | stmmac_set_eee_pls(priv, priv->hw, false); |
| 1043 | 1047 | ||
| 1044 | if (priv->dma_cap.fpesel) | 1048 | if (priv->dma_cap.fpesel) |
| @@ -666,6 +666,10 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) · 665 unmodified lines | |||
| 666 | { | 666 | { |
| 667 | int ret; | 667 | int ret; |
| 668 | 668 | ||
| 669 | ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0); | ||
| 670 | if (ret < 0) | ||
| 671 | return ret; | ||
| 672 | |||
| 669 | if (enable) { | 673 | if (enable) { |
| 670 | /* Enable EEE */ | 674 | /* Enable EEE */ |
| 671 | ret = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | | 675 | ret = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | |
| @@ -673,9 +677,6 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) · 1 unmodified line | |||
| 673 | DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | | 677 | DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | |
| 674 | mult_fact_100ns << DW_VR_MII_EEE_MULT_FACT_100NS_SHIFT; | 678 | mult_fact_100ns << DW_VR_MII_EEE_MULT_FACT_100NS_SHIFT; |
| 675 | } else { | 679 | } else { |
| 676 | ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0); | ||
| 677 | if (ret < 0) | ||
| 678 | return ret; | ||
| 679 | ret &= ~(DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | | 680 | ret &= ~(DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | |
| 680 | DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN | | 681 | DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN | |
| 681 | DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | | 682 | DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | |
| @@ -690,21 +691,28 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) · 8 unmodified lines | |||
| 690 | if (ret < 0) | 691 | if (ret < 0) |
| 691 | return ret; | 692 | return ret; |
| 692 | 693 | ||
| 693 | ret |= DW_VR_MII_EEE_TRN_LPI; | 694 | if (enable) |
| 695 | ret |= DW_VR_MII_EEE_TRN_LPI; | ||
| 696 | else | ||
| 697 | ret &= ~DW_VR_MII_EEE_TRN_LPI; | ||
| 698 | |||
| 694 | return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, ret); | 699 | return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, ret); |
| 695 | } | 700 | } |
| 696 | EXPORT_SYMBOL_GPL(xpcs_config_eee); | 701 | EXPORT_SYMBOL_GPL(xpcs_config_eee); |
| 697 | 702 | ||
| 698 | static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) | 703 | static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) |
| 699 | { | 704 | { |
| 700 | int ret; | 705 | int ret, mdio_ctrl; |
| 701 | 706 | ||
| 702 | /* For AN for C37 SGMII mode, the settings are :- | 707 | /* For AN for C37 SGMII mode, the settings are :- |
| 703 | * 1) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN) | 708 | * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case |
| 704 | * 2) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII) | 709 | it is already enabled) |
| 710 | * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN) | ||
| 711 | * 3) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII) | ||
| 705 | * DW xPCS used with DW EQoS MAC is always MAC side SGMII. | 712 | * DW xPCS used with DW EQoS MAC is always MAC side SGMII. |
| 706 | * 3) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic | 713 | * 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic |
| 707 | * speed/duplex mode change by HW after SGMII AN complete) | 714 | * speed/duplex mode change by HW after SGMII AN complete) |
| 715 | * 5) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable SGMII AN) | ||
| 708 | * | 716 | * |
| 709 | * Note: Since it is MAC side SGMII, there is no need to set | 717 | * Note: Since it is MAC side SGMII, there is no need to set |
| 710 | * SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from | 718 | * SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from |
| @@ -712,6 +720,17 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) · 1 unmodified line | |||
| 712 | * between PHY and Link Partner. There is also no need to | 720 | * between PHY and Link Partner. There is also no need to |
| 713 | * trigger AN restart for MAC-side SGMII. | 721 | * trigger AN restart for MAC-side SGMII. |
| 714 | */ | 722 | */ |
| 723 | mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL); | ||
| 724 | if (mdio_ctrl < 0) | ||
| 725 | return mdio_ctrl; | ||
| 726 | |||
| 727 | if (mdio_ctrl & AN_CL37_EN) { | ||
| 728 | ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, | ||
| 729 | mdio_ctrl & ~AN_CL37_EN); | ||
| 730 | if (ret < 0) | ||
| 731 | return ret; | ||
| 732 | } | ||
| 733 | |||
| 715 | ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL); | 734 | ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL); |
| 716 | if (ret < 0) | 735 | if (ret < 0) |
| 717 | return ret; | 736 | return ret; |
| @@ -736,7 +755,15 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) · 18 unmodified lines | |||
| 736 | else | 755 | else |
| 737 | ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; | 756 | ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; |
| 738 | 757 | ||
| 739 | return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); | 758 | ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); |
| 759 | if (ret < 0) | ||
| 760 | return ret; | ||
| 761 | |||
| 762 | if (phylink_autoneg_inband(mode)) | ||
| 763 | ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, | ||
| 764 | mdio_ctrl | AN_CL37_EN); | ||
| 765 | |||
| 766 | return ret; | ||
| 740 | } | 767 | } |
| 741 | 768 | ||
| 742 | static int xpcs_config_2500basex(struct dw_xpcs *xpcs) | 769 | static int xpcs_config_2500basex(struct dw_xpcs *xpcs) |
| @@ -538,10 +538,16 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner) · 537 unmodified lines | |||
| 538 | bus->dev.groups = NULL; | 538 | bus->dev.groups = NULL; |
| 539 | dev_set_name(&bus->dev, "%s", bus->id); | 539 | dev_set_name(&bus->dev, "%s", bus->id); |
| 540 | 540 | ||
| 541 | /* We need to set state to MDIOBUS_UNREGISTERED to correctly release | ||
| 542 | * the device in mdiobus_free() | ||
| 543 | * | ||
| 544 | * State will be updated later in this function in case of success | ||
| 545 | */ | ||
| 546 | bus->state = MDIOBUS_UNREGISTERED; | ||
| 547 | |||
| 541 | err = device_register(&bus->dev); | 548 | err = device_register(&bus->dev); |
| 542 | if (err) { | 549 | if (err) { |
| 543 | pr_err("mii_bus %s failed to register\n", bus->id); | 550 | pr_err("mii_bus %s failed to register\n", bus->id); |
| 544 | put_device(&bus->dev); | ||
| 545 | return -EINVAL; | 551 | return -EINVAL; |
| 546 | } | 552 | } |
| 547 | 553 | ||
| @@ -134,7 +134,7 @@ static const char * const sm_state_strings[] = { · 133 unmodified lines | |||
| 134 | [SFP_S_LINK_UP] = "link_up", | 134 | [SFP_S_LINK_UP] = "link_up", |
| 135 | [SFP_S_TX_FAULT] = "tx_fault", | 135 | [SFP_S_TX_FAULT] = "tx_fault", |
| 136 | [SFP_S_REINIT] = "reinit", | 136 | [SFP_S_REINIT] = "reinit", |
| 137 | [SFP_S_TX_DISABLE] = "rx_disable", | 137 | [SFP_S_TX_DISABLE] = "tx_disable", |
| 138 | }; | 138 | }; |
| 139 | 139 | ||
| 140 | static const char *sm_state_to_str(unsigned short sm_state) | 140 | static const char *sm_state_to_str(unsigned short sm_state) |
| @@ -767,6 +767,7 @@ enum rtl8152_flags { · 766 unmodified lines | |||
| 767 | PHY_RESET, | 767 | PHY_RESET, |
| 768 | SCHEDULE_TASKLET, | 768 | SCHEDULE_TASKLET, |
| 769 | GREEN_ETHERNET, | 769 | GREEN_ETHERNET, |
| 770 | RX_EPROTO, | ||
| 770 | }; | 771 | }; |
| 771 | 772 | ||
| 772 | #define DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2 0x3082 | 773 | #define DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2 0x3082 |
| @@ -1770,6 +1771,14 @@ static void read_bulk_callback(struct urb *urb) · 997 unmodified lines | |||
| 1770 | rtl_set_unplug(tp); | 1771 | rtl_set_unplug(tp); |
| 1771 | netif_device_detach(tp->netdev); | 1772 | netif_device_detach(tp->netdev); |
| 1772 | return; | 1773 | return; |
| 1774 | case -EPROTO: | ||
| 1775 | urb->actual_length = 0; | ||
| 1776 | spin_lock_irqsave(&tp->rx_lock, flags); | ||
| 1777 | list_add_tail(&agg->list, &tp->rx_done); | ||
| 1778 | spin_unlock_irqrestore(&tp->rx_lock, flags); | ||
| 1779 | set_bit(RX_EPROTO, &tp->flags); | ||
| 1780 | schedule_delayed_work(&tp->schedule, 1); | ||
| 1781 | return; | ||
| 1773 | case -ENOENT: | 1782 | case -ENOENT: |
| 1774 | return; /* the urb is in unlink state */ | 1783 | return; /* the urb is in unlink state */ |
| 1775 | case -ETIME: | 1784 | case -ETIME: |
| @@ -2425,6 +2434,7 @@ static int rx_bottom(struct r8152 *tp, int budget) · 649 unmodified lines | |||
| 2425 | if (list_empty(&tp->rx_done)) | 2434 | if (list_empty(&tp->rx_done)) |
| 2426 | goto out1; | 2435 | goto out1; |
| 2427 | 2436 | ||
| 2437 | clear_bit(RX_EPROTO, &tp->flags); | ||
| 2428 | INIT_LIST_HEAD(&rx_queue); | 2438 | INIT_LIST_HEAD(&rx_queue); |
| 2429 | spin_lock_irqsave(&tp->rx_lock, flags); | 2439 | spin_lock_irqsave(&tp->rx_lock, flags); |
| 2430 | list_splice_init(&tp->rx_done, &rx_queue); | 2440 | list_splice_init(&tp->rx_done, &rx_queue); |
| @@ -2441,7 +2451,7 @@ static int rx_bottom(struct r8152 *tp, int budget) · 10 unmodified lines | |||
| 2441 | 2451 | ||
| 2442 | agg = list_entry(cursor, struct rx_agg, list); | 2452 | agg = list_entry(cursor, struct rx_agg, list); |
| 2443 | urb = agg->urb; | 2453 | urb = agg->urb; |
| 2444 | if (urb->actual_length < ETH_ZLEN) | 2454 | if (urb->status != 0 || urb->actual_length < ETH_ZLEN) |
| 2445 | goto submit; | 2455 | goto submit; |
| 2446 | 2456 | ||
| 2447 | agg_free = rtl_get_free_rx(tp, GFP_ATOMIC); | 2457 | agg_free = rtl_get_free_rx(tp, GFP_ATOMIC); |
| @@ -6643,6 +6653,10 @@ static void rtl_work_func_t(struct work_struct *work) · 4195 unmodified lines | |||
| 6643 | netif_carrier_ok(tp->netdev)) | 6653 | netif_carrier_ok(tp->netdev)) |
| 6644 | tasklet_schedule(&tp->tx_tl); | 6654 | tasklet_schedule(&tp->tx_tl); |
| 6645 | 6655 | ||
| 6656 | if (test_and_clear_bit(RX_EPROTO, &tp->flags) && | ||
| 6657 | !list_empty(&tp->rx_done)) | ||
| 6658 | napi_schedule(&tp->napi); | ||
| 6659 | |||
| 6646 | mutex_unlock(&tp->control); | 6660 | mutex_unlock(&tp->control); |
| 6647 | 6661 | ||
| 6648 | out1: | 6662 | out1: |
| @@ -3,9 +3,7 @@ config ATH5K · 2 unmodified lines | |||
| 3 | tristate "Atheros 5xxx wireless cards support" | 3 | tristate "Atheros 5xxx wireless cards support" |
| 4 | depends on (PCI || ATH25) && MAC80211 | 4 | depends on (PCI || ATH25) && MAC80211 |
| 5 | select ATH_COMMON | 5 | select ATH_COMMON |
| 6 | select MAC80211_LEDS | 6 | select MAC80211_LEDS if LEDS_CLASS=y || LEDS_CLASS=MAC80211 |
| 7 | select LEDS_CLASS | ||
| 8 | select NEW_LEDS | ||
| 9 | select ATH5K_AHB if ATH25 | 7 | select ATH5K_AHB if ATH25 |
| 10 | select ATH5K_PCI if !ATH25 | 8 | select ATH5K_PCI if !ATH25 |
| 11 | help | 9 | help |
| @@ -89,7 +89,8 @@ static const struct pci_device_id ath5k_led_devices[] = { · 88 unmodified lines | |||
| 89 | 89 | ||
| 90 | void ath5k_led_enable(struct ath5k_hw *ah) | 90 | void ath5k_led_enable(struct ath5k_hw *ah) |
| 91 | { | 91 | { |
| 92 | if (test_bit(ATH_STAT_LEDSOFT, ah->status)) { | 92 | if (IS_ENABLED(CONFIG_MAC80211_LEDS) && |
| 93 | test_bit(ATH_STAT_LEDSOFT, ah->status)) { | ||
| 93 | ath5k_hw_set_gpio_output(ah, ah->led_pin); | 94 | ath5k_hw_set_gpio_output(ah, ah->led_pin); |
| 94 | ath5k_led_off(ah); | 95 | ath5k_led_off(ah); |
| 95 | } | 96 | } |
| @@ -104,7 +105,8 @@ static void ath5k_led_on(struct ath5k_hw *ah) · 8 unmodified lines | |||
| 104 | 105 | ||
| 105 | void ath5k_led_off(struct ath5k_hw *ah) | 106 | void ath5k_led_off(struct ath5k_hw *ah) |
| 106 | { | 107 | { |
| 107 | if (!test_bit(ATH_STAT_LEDSOFT, ah->status)) | 108 | if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || |
| 109 | !test_bit(ATH_STAT_LEDSOFT, ah->status)) | ||
| 108 | return; | 110 | return; |
| 109 | ath5k_hw_set_gpio(ah, ah->led_pin, !ah->led_on); | 111 | ath5k_hw_set_gpio(ah, ah->led_pin, !ah->led_on); |
| 110 | } | 112 | } |
| @@ -146,7 +148,7 @@ ath5k_register_led(struct ath5k_hw *ah, struct ath5k_led *led, · 35 unmodified lines | |||
| 146 | static void | 148 | static void |
| 147 | ath5k_unregister_led(struct ath5k_led *led) | 149 | ath5k_unregister_led(struct ath5k_led *led) |
| 148 | { | 150 | { |
| 149 | if (!led->ah) | 151 | if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || !led->ah) |
| 150 | return; | 152 | return; |
| 151 | led_classdev_unregister(&led->led_dev); | 153 | led_classdev_unregister(&led->led_dev); |
| 152 | ath5k_led_off(led->ah); | 154 | ath5k_led_off(led->ah); |
| @@ -169,7 +171,7 @@ int ath5k_init_leds(struct ath5k_hw *ah) · 16 unmodified lines | |||
| 169 | char name[ATH5K_LED_MAX_NAME_LEN + 1]; | 171 | char name[ATH5K_LED_MAX_NAME_LEN + 1]; |
| 170 | const struct pci_device_id *match; | 172 | const struct pci_device_id *match; |
| 171 | 173 | ||
| 172 | if (!ah->pdev) | 174 | if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || !ah->pdev) |
| 173 | return 0; | 175 | return 0; |
| 174 | 176 | ||
| 175 | #ifdef CONFIG_ATH5K_AHB | 177 | #ifdef CONFIG_ATH5K_AHB |
| @@ -7463,23 +7463,18 @@ static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2], · 7462 unmodified lines | |||
| 7463 | s32 found_index; | 7463 | s32 found_index; |
| 7464 | int i; | 7464 | int i; |
| 7465 | 7465 | ||
| 7466 | country_codes = drvr->settings->country_codes; | ||
| 7467 | if (!country_codes) { | ||
| 7468 | brcmf_dbg(TRACE, "No country codes configured for device\n"); | ||
| 7469 | return -EINVAL; | ||
| 7470 | } | ||
| 7471 | |||
| 7466 | if ((alpha2[0] == ccreq->country_abbrev[0]) && | 7472 | if ((alpha2[0] == ccreq->country_abbrev[0]) && |
| 7467 | (alpha2[1] == ccreq->country_abbrev[1])) { | 7473 | (alpha2[1] == ccreq->country_abbrev[1])) { |
| 7468 | brcmf_dbg(TRACE, "Country code already set\n"); | 7474 | brcmf_dbg(TRACE, "Country code already set\n"); |
| 7469 | return -EAGAIN; | 7475 | return -EAGAIN; |
| 7470 | } | 7476 | } |
| 7471 | 7477 | ||
| 7472 | country_codes = drvr->settings->country_codes; | ||
| 7473 | if (!country_codes) { | ||
| 7474 | brcmf_dbg(TRACE, "No country codes configured for device, using ISO3166 code and 0 rev\n"); | ||
| 7475 | memset(ccreq, 0, sizeof(*ccreq)); | ||
| 7476 | ccreq->country_abbrev[0] = alpha2[0]; | ||
| 7477 | ccreq->country_abbrev[1] = alpha2[1]; | ||
| 7478 | ccreq->ccode[0] = alpha2[0]; | ||
| 7479 | ccreq->ccode[1] = alpha2[1]; | ||
| 7480 | return 0; | ||
| 7481 | } | ||
| 7482 | |||
| 7483 | found_index = -1; | 7478 | found_index = -1; |
| 7484 | for (i = 0; i < country_codes->table_size; i++) { | 7479 | for (i = 0; i < country_codes->table_size; i++) { |
| 7485 | cc = &country_codes->table[i]; | 7480 | cc = &country_codes->table[i]; |
| @@ -160,6 +160,7 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, · 159 unmodified lines | |||
| 160 | mvm->ptk_icvlen = key->icv_len; | 160 | mvm->ptk_icvlen = key->icv_len; |
| 161 | mvm->gtk_ivlen = key->iv_len; | 161 | mvm->gtk_ivlen = key->iv_len; |
| 162 | mvm->gtk_icvlen = key->icv_len; | 162 | mvm->gtk_icvlen = key->icv_len; |
| 163 | mutex_unlock(&mvm->mutex); | ||
| 163 | 164 | ||
| 164 | /* don't upload key again */ | 165 | /* don't upload key again */ |
| 165 | return; | 166 | return; |
| @@ -360,11 +361,11 @@ static void iwl_mvm_wowlan_get_rsc_v5_data(struct ieee80211_hw *hw, · 194 unmodified lines | |||
| 360 | if (sta) { | 361 | if (sta) { |
| 361 | rsc = data->rsc->ucast_rsc; | 362 | rsc = data->rsc->ucast_rsc; |
| 362 | } else { | 363 | } else { |
| 363 | if (WARN_ON(data->gtks > ARRAY_SIZE(data->gtk_ids))) | 364 | if (WARN_ON(data->gtks >= ARRAY_SIZE(data->gtk_ids))) |
| 364 | return; | 365 | return; |
| 365 | data->gtk_ids[data->gtks] = key->keyidx; | 366 | data->gtk_ids[data->gtks] = key->keyidx; |
| 366 | rsc = data->rsc->mcast_rsc[data->gtks % 2]; | 367 | rsc = data->rsc->mcast_rsc[data->gtks % 2]; |
| 367 | if (WARN_ON(key->keyidx > | 368 | if (WARN_ON(key->keyidx >= |
| 368 | ARRAY_SIZE(data->rsc->mcast_key_id_map))) | 369 | ARRAY_SIZE(data->rsc->mcast_key_id_map))) |
| 369 | return; | 370 | return; |
| 370 | data->rsc->mcast_key_id_map[key->keyidx] = data->gtks % 2; | 371 | data->rsc->mcast_key_id_map[key->keyidx] = data->gtks % 2; |
| @@ -662,12 +662,13 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm, · 661 unmodified lines | |||
| 662 | u32 *uid) | 662 | u32 *uid) |
| 663 | { | 663 | { |
| 664 | u32 id; | 664 | u32 id; |
| 665 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); | 665 | struct iwl_mvm_vif *mvmvif; |
| 666 | enum nl80211_iftype iftype; | 666 | enum nl80211_iftype iftype; |
| 667 | 667 | ||
| 668 | if (!te_data->vif) | 668 | if (!te_data->vif) |
| 669 | return false; | 669 | return false; |
| 670 | 670 | ||
| 671 | mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); | ||
| 671 | iftype = te_data->vif->type; | 672 | iftype = te_data->vif->type; |
| 672 | 673 | ||
| 673 | /* | 674 | /* |
| @@ -547,6 +547,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { · 546 unmodified lines | |||
| 547 | IWL_DEV_INFO(0x43F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), | 547 | IWL_DEV_INFO(0x43F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), |
| 548 | IWL_DEV_INFO(0x43F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), | 548 | IWL_DEV_INFO(0x43F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), |
| 549 | IWL_DEV_INFO(0x43F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), | 549 | IWL_DEV_INFO(0x43F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), |
| 550 | IWL_DEV_INFO(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650s_name), | ||
| 551 | IWL_DEV_INFO(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650i_name), | ||
| 550 | IWL_DEV_INFO(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), | 552 | IWL_DEV_INFO(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), |
| 551 | IWL_DEV_INFO(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), | 553 | IWL_DEV_INFO(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), |
| 552 | IWL_DEV_INFO(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), | 554 | IWL_DEV_INFO(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), |
| @@ -62,8 +62,8 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, · 61 unmodified lines | |||
| 62 | 62 | ||
| 63 | pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0; | 63 | pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0; |
| 64 | 64 | ||
| 65 | pad = ((void *)skb->data - (sizeof(*local_tx_pd) + hroom)- | 65 | pad = ((uintptr_t)skb->data - (sizeof(*local_tx_pd) + hroom)) & |
| 66 | NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1); | 66 | (MWIFIEX_DMA_ALIGN_SZ - 1); |
| 67 | skb_push(skb, sizeof(*local_tx_pd) + pad); | 67 | skb_push(skb, sizeof(*local_tx_pd) + pad); |
| 68 | 68 | ||
| 69 | local_tx_pd = (struct txpd *) skb->data; | 69 | local_tx_pd = (struct txpd *) skb->data; |
| @@ -475,8 +475,8 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv, · 474 unmodified lines | |||
| 475 | 475 | ||
| 476 | pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0; | 476 | pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0; |
| 477 | 477 | ||
| 478 | pad = ((void *)skb->data - (sizeof(*txpd) + hroom) - NULL) & | 478 | pad = ((uintptr_t)skb->data - (sizeof(*txpd) + hroom)) & |
| 479 | (MWIFIEX_DMA_ALIGN_SZ - 1); | 479 | (MWIFIEX_DMA_ALIGN_SZ - 1); |
| 480 | 480 | ||
| 481 | skb_push(skb, sizeof(*txpd) + pad); | 481 | skb_push(skb, sizeof(*txpd) + pad); |
| 482 | 482 | ||
| @@ -644,6 +644,7 @@ static const struct pci_device_id pch_ieee1588_pcidev_id[] = { · 643 unmodified lines | |||
| 644 | }, | 644 | }, |
| 645 | {0} | 645 | {0} |
| 646 | }; | 646 | }; |
| 647 | MODULE_DEVICE_TABLE(pci, pch_ieee1588_pcidev_id); | ||
| 647 | 648 | ||
| 648 | static SIMPLE_DEV_PM_OPS(pch_pm_ops, pch_suspend, pch_resume); | 649 | static SIMPLE_DEV_PM_OPS(pch_pm_ops, pch_suspend, pch_resume); |
| 649 | 650 | ||
| @@ -308,7 +308,7 @@ static inline void ether_addr_copy(u8 *dst, const u8 *src) · 307 unmodified lines | |||
| 308 | */ | 308 | */ |
| 309 | static inline void eth_hw_addr_set(struct net_device *dev, const u8 *addr) | 309 | static inline void eth_hw_addr_set(struct net_device *dev, const u8 *addr) |
| 310 | { | 310 | { |
| 311 | ether_addr_copy(dev->dev_addr, addr); | 311 | __dev_addr_set(dev, addr, ETH_ALEN); |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | /** | 314 | /** |
| @@ -17,7 +17,6 @@ struct inet_frags_ctl; · 16 unmodified lines | |||
| 17 | struct nft_ct_frag6_pernet { | 17 | struct nft_ct_frag6_pernet { |
| 18 | struct ctl_table_header *nf_frag_frags_hdr; | 18 | struct ctl_table_header *nf_frag_frags_hdr; |
| 19 | struct fqdir *fqdir; | 19 | struct fqdir *fqdir; |
| 20 | unsigned int users; | ||
| 21 | }; | 20 | }; |
| 22 | 21 | ||
| 23 | #endif /* _NF_DEFRAG_IPV6_H */ | 22 | #endif /* _NF_DEFRAG_IPV6_H */ |
| @@ -1202,7 +1202,7 @@ struct nft_object *nft_obj_lookup(const struct net *net, · 1201 unmodified lines | |||
| 1202 | 1202 | ||
| 1203 | void nft_obj_notify(struct net *net, const struct nft_table *table, | 1203 | void nft_obj_notify(struct net *net, const struct nft_table *table, |
| 1204 | struct nft_object *obj, u32 portid, u32 seq, | 1204 | struct nft_object *obj, u32 portid, u32 seq, |
| 1205 | int event, int family, int report, gfp_t gfp); | 1205 | int event, u16 flags, int family, int report, gfp_t gfp); |
| 1206 | 1206 | ||
| 1207 | /** | 1207 | /** |
| 1208 | * struct nft_object_type - stateful object type | 1208 | * struct nft_object_type - stateful object type |
| @@ -27,5 +27,11 @@ struct netns_nf { · 26 unmodified lines | |||
| 27 | #if IS_ENABLED(CONFIG_DECNET) | 27 | #if IS_ENABLED(CONFIG_DECNET) |
| 28 | struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS]; | 28 | struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS]; |
| 29 | #endif | 29 | #endif |
| 30 | #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) | ||
| 31 | unsigned int defrag_ipv4_users; | ||
| 32 | #endif | ||
| 33 | #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) | ||
| 34 | unsigned int defrag_ipv6_users; | ||
| 35 | #endif | ||
| 30 | }; | 36 | }; |
| 31 | #endif | 37 | #endif |
| @@ -307,6 +307,7 @@ struct bpf_local_storage; · 306 unmodified lines | |||
| 307 | * @sk_priority: %SO_PRIORITY setting | 307 | * @sk_priority: %SO_PRIORITY setting |
| 308 | * @sk_type: socket type (%SOCK_STREAM, etc) | 308 | * @sk_type: socket type (%SOCK_STREAM, etc) |
| 309 | * @sk_protocol: which protocol this socket belongs in this network family | 309 | * @sk_protocol: which protocol this socket belongs in this network family |
| 310 | * @sk_peer_lock: lock protecting @sk_peer_pid and @sk_peer_cred | ||
| 310 | * @sk_peer_pid: &struct pid for this socket's peer | 311 | * @sk_peer_pid: &struct pid for this socket's peer |
| 311 | * @sk_peer_cred: %SO_PEERCRED setting | 312 | * @sk_peer_cred: %SO_PEERCRED setting |
| 312 | * @sk_rcvlowat: %SO_RCVLOWAT setting | 313 | * @sk_rcvlowat: %SO_RCVLOWAT setting |
| @@ -694,7 +694,7 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot, · 693 unmodified lines | |||
| 694 | int ocelot_vcap_filter_del(struct ocelot *ocelot, | 694 | int ocelot_vcap_filter_del(struct ocelot *ocelot, |
| 695 | struct ocelot_vcap_filter *rule); | 695 | struct ocelot_vcap_filter *rule); |
| 696 | struct ocelot_vcap_filter * | 696 | struct ocelot_vcap_filter * |
| 697 | ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int id, | 697 | ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, |
| 698 | bool tc_offload); | 698 | unsigned long cookie, bool tc_offload); |
| 699 | 699 | ||
| 700 | #endif /* _OCELOT_VCAP_H_ */ | 700 | #endif /* _OCELOT_VCAP_H_ */ |
| @@ -213,13 +213,13 @@ enum { · 212 unmodified lines | |||
| 213 | XFRM_MSG_GETSPDINFO, | 213 | XFRM_MSG_GETSPDINFO, |
| 214 | #define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO | 214 | #define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO |
| 215 | 215 | ||
| 216 | XFRM_MSG_MAPPING, | ||
| 217 | #define XFRM_MSG_MAPPING XFRM_MSG_MAPPING | ||
| 218 | |||
| 216 | XFRM_MSG_SETDEFAULT, | 219 | XFRM_MSG_SETDEFAULT, |
| 217 | #define XFRM_MSG_SETDEFAULT XFRM_MSG_SETDEFAULT | 220 | #define XFRM_MSG_SETDEFAULT XFRM_MSG_SETDEFAULT |
| 218 | XFRM_MSG_GETDEFAULT, | 221 | XFRM_MSG_GETDEFAULT, |
| 219 | #define XFRM_MSG_GETDEFAULT XFRM_MSG_GETDEFAULT | 222 | #define XFRM_MSG_GETDEFAULT XFRM_MSG_GETDEFAULT |
| 220 | |||
| 221 | XFRM_MSG_MAPPING, | ||
| 222 | #define XFRM_MSG_MAPPING XFRM_MSG_MAPPING | ||
| 223 | __XFRM_MSG_MAX | 223 | __XFRM_MSG_MAX |
| 224 | }; | 224 | }; |
| 225 | #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) | 225 | #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) |
| @@ -514,9 +514,12 @@ struct xfrm_user_offload { · 288 unmodified lines | |||
| 514 | #define XFRM_OFFLOAD_INBOUND 2 | 514 | #define XFRM_OFFLOAD_INBOUND 2 |
| 515 | 515 | ||
| 516 | struct xfrm_userpolicy_default { | 516 | struct xfrm_userpolicy_default { |
| 517 | #define XFRM_USERPOLICY_DIRMASK_MAX (sizeof(__u8) * 8) | 517 | #define XFRM_USERPOLICY_UNSPEC 0 |
| 518 | __u8 dirmask; | 518 | #define XFRM_USERPOLICY_BLOCK 1 |
| 519 | __u8 action; | 519 | #define XFRM_USERPOLICY_ACCEPT 2 |
| 520 | __u8 in; | ||
| 521 | __u8 fwd; | ||
| 522 | __u8 out; | ||
| 520 | }; | 523 | }; |
| 521 | 524 | ||
| 522 | #ifndef __KERNEL__ | 525 | #ifndef __KERNEL__ |
| @@ -63,7 +63,8 @@ static inline int stack_map_data_size(struct bpf_map *map) · 62 unmodified lines | |||
| 63 | 63 | ||
| 64 | static int prealloc_elems_and_freelist(struct bpf_stack_map *smap) | 64 | static int prealloc_elems_and_freelist(struct bpf_stack_map *smap) |
| 65 | { | 65 | { |
| 66 | u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size; | 66 | u64 elem_size = sizeof(struct stack_map_bucket) + |
| 67 | (u64)smap->map.value_size; | ||
| 67 | int err; | 68 | int err; |
| 68 | 69 | ||
| 69 | smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries, | 70 | smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries, |
| @@ -1666,7 +1666,8 @@ static size_t br_get_linkxstats_size(const struct net_device *dev, int attr) · 1665 unmodified lines | |||
| 1666 | } | 1666 | } |
| 1667 | 1667 | ||
| 1668 | return numvls * nla_total_size(sizeof(struct bridge_vlan_xstats)) + | 1668 | return numvls * nla_total_size(sizeof(struct bridge_vlan_xstats)) + |
| 1669 | nla_total_size(sizeof(struct br_mcast_stats)) + | 1669 | nla_total_size_64bit(sizeof(struct br_mcast_stats)) + |
| 1670 | (p ? nla_total_size_64bit(sizeof(p->stp_xstats)) : 0) + | ||
| 1670 | nla_total_size(0); | 1671 | nla_total_size(0); |
| 1671 | } | 1672 | } |
| 1672 | 1673 | ||
| @@ -5262,7 +5262,7 @@ nla_put_failure: · 5261 unmodified lines | |||
| 5262 | static size_t if_nlmsg_stats_size(const struct net_device *dev, | 5262 | static size_t if_nlmsg_stats_size(const struct net_device *dev, |
| 5263 | u32 filter_mask) | 5263 | u32 filter_mask) |
| 5264 | { | 5264 | { |
| 5265 | size_t size = 0; | 5265 | size_t size = NLMSG_ALIGN(sizeof(struct if_stats_msg)); |
| 5266 | 5266 | ||
| 5267 | if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, 0)) | 5267 | if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, 0)) |
| 5268 | size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64)); | 5268 | size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64)); |
| @@ -210,7 +210,7 @@ static struct sk_buff *dsa_rcv_ll(struct sk_buff *skb, struct net_device *dev, · 209 unmodified lines | |||
| 210 | cmd = dsa_header[0] >> 6; | 210 | cmd = dsa_header[0] >> 6; |
| 211 | switch (cmd) { | 211 | switch (cmd) { |
| 212 | case DSA_CMD_FORWARD: | 212 | case DSA_CMD_FORWARD: |
| 213 | trunk = !!(dsa_header[1] & 7); | 213 | trunk = !!(dsa_header[1] & 4); |
| 214 | break; | 214 | break; |
| 215 | 215 | ||
| 216 | case DSA_CMD_TO_CPU: | 216 | case DSA_CMD_TO_CPU: |
| @@ -242,8 +242,10 @@ static inline int compute_score(struct sock *sk, struct net *net, · 241 unmodified lines | |||
| 242 | 242 | ||
| 243 | if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif)) | 243 | if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif)) |
| 244 | return -1; | 244 | return -1; |
| 245 | score = sk->sk_bound_dev_if ? 2 : 1; | ||
| 245 | 246 | ||
| 246 | score = sk->sk_family == PF_INET ? 2 : 1; | 247 | if (sk->sk_family == PF_INET) |
| 248 | score++; | ||
| 247 | if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) | 249 | if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) |
| 248 | score++; | 250 | score++; |
| 249 | } | 251 | } |
| @@ -20,13 +20,8 @@ · 19 unmodified lines | |||
| 20 | #endif | 20 | #endif |
| 21 | #include <net/netfilter/nf_conntrack_zones.h> | 21 | #include <net/netfilter/nf_conntrack_zones.h> |
| 22 | 22 | ||
| 23 | static unsigned int defrag4_pernet_id __read_mostly; | ||
| 24 | static DEFINE_MUTEX(defrag4_mutex); | 23 | static DEFINE_MUTEX(defrag4_mutex); |
| 25 | 24 | ||
| 26 | struct defrag4_pernet { | ||
| 27 | unsigned int users; | ||
| 28 | }; | ||
| 29 | |||
| 30 | static int nf_ct_ipv4_gather_frags(struct net *net, struct sk_buff *skb, | 25 | static int nf_ct_ipv4_gather_frags(struct net *net, struct sk_buff *skb, |
| 31 | u_int32_t user) | 26 | u_int32_t user) |
| 32 | { | 27 | { |
| @@ -111,19 +106,15 @@ static const struct nf_hook_ops ipv4_defrag_ops[] = { · 78 unmodified lines | |||
| 111 | 106 | ||
| 112 | static void __net_exit defrag4_net_exit(struct net *net) | 107 | static void __net_exit defrag4_net_exit(struct net *net) |
| 113 | { | 108 | { |
| 114 | struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id); | 109 | if (net->nf.defrag_ipv4_users) { |
| 115 | |||
| 116 | if (nf_defrag->users) { | ||
| 117 | nf_unregister_net_hooks(net, ipv4_defrag_ops, | 110 | nf_unregister_net_hooks(net, ipv4_defrag_ops, |
| 118 | ARRAY_SIZE(ipv4_defrag_ops)); | 111 | ARRAY_SIZE(ipv4_defrag_ops)); |
| 119 | nf_defrag->users = 0; | 112 | net->nf.defrag_ipv4_users = 0; |
| 120 | } | 113 | } |
| 121 | } | 114 | } |
| 122 | 115 | ||
| 123 | static struct pernet_operations defrag4_net_ops = { | 116 | static struct pernet_operations defrag4_net_ops = { |
| 124 | .exit = defrag4_net_exit, | 117 | .exit = defrag4_net_exit, |
| 125 | .id = &defrag4_pernet_id, | ||
| 126 | .size = sizeof(struct defrag4_pernet), | ||
| 127 | }; | 118 | }; |
| 128 | 119 | ||
| 129 | static int __init nf_defrag_init(void) | 120 | static int __init nf_defrag_init(void) |
| @@ -138,24 +129,23 @@ static void __exit nf_defrag_fini(void) · 8 unmodified lines | |||
| 138 | 129 | ||
| 139 | int nf_defrag_ipv4_enable(struct net *net) | 130 | int nf_defrag_ipv4_enable(struct net *net) |
| 140 | { | 131 | { |
| 141 | struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id); | ||
| 142 | int err = 0; | 132 | int err = 0; |
| 143 | 133 | ||
| 144 | mutex_lock(&defrag4_mutex); | 134 | mutex_lock(&defrag4_mutex); |
| 145 | if (nf_defrag->users == UINT_MAX) { | 135 | if (net->nf.defrag_ipv4_users == UINT_MAX) { |
| 146 | err = -EOVERFLOW; | 136 | err = -EOVERFLOW; |
| 147 | goto out_unlock; | 137 | goto out_unlock; |
| 148 | } | 138 | } |
| 149 | 139 | ||
| 150 | if (nf_defrag->users) { | 140 | if (net->nf.defrag_ipv4_users) { |
| 151 | nf_defrag->users++; | 141 | net->nf.defrag_ipv4_users++; |
| 152 | goto out_unlock; | 142 | goto out_unlock; |
| 153 | } | 143 | } |
| 154 | 144 | ||
| 155 | err = nf_register_net_hooks(net, ipv4_defrag_ops, | 145 | err = nf_register_net_hooks(net, ipv4_defrag_ops, |
| 156 | ARRAY_SIZE(ipv4_defrag_ops)); | 146 | ARRAY_SIZE(ipv4_defrag_ops)); |
| 157 | if (err == 0) | 147 | if (err == 0) |
| 158 | nf_defrag->users = 1; | 148 | net->nf.defrag_ipv4_users = 1; |
| 159 | 149 | ||
| 160 | out_unlock: | 150 | out_unlock: |
| 161 | mutex_unlock(&defrag4_mutex); | 151 | mutex_unlock(&defrag4_mutex); |
| @@ -165,12 +155,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable); · 3 unmodified lines | |||
| 165 | 155 | ||
| 166 | void nf_defrag_ipv4_disable(struct net *net) | 156 | void nf_defrag_ipv4_disable(struct net *net) |
| 167 | { | 157 | { |
| 168 | struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id); | ||
| 169 | |||
| 170 | mutex_lock(&defrag4_mutex); | 158 | mutex_lock(&defrag4_mutex); |
| 171 | if (nf_defrag->users) { | 159 | if (net->nf.defrag_ipv4_users) { |
| 172 | nf_defrag->users--; | 160 | net->nf.defrag_ipv4_users--; |
| 173 | if (nf_defrag->users == 0) | 161 | if (net->nf.defrag_ipv4_users == 0) |
| 174 | nf_unregister_net_hooks(net, ipv4_defrag_ops, | 162 | nf_unregister_net_hooks(net, ipv4_defrag_ops, |
| 175 | ARRAY_SIZE(ipv4_defrag_ops)); | 163 | ARRAY_SIZE(ipv4_defrag_ops)); |
| 176 | } | 164 | } |
| @@ -390,7 +390,8 @@ static int compute_score(struct sock *sk, struct net *net, · 389 unmodified lines | |||
| 390 | dif, sdif); | 390 | dif, sdif); |
| 391 | if (!dev_match) | 391 | if (!dev_match) |
| 392 | return -1; | 392 | return -1; |
| 393 | score += 4; | 393 | if (sk->sk_bound_dev_if) |
| 394 | score += 4; | ||
| 394 | 395 | ||
| 395 | if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) | 396 | if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) |
| 396 | score++; | 397 | score++; |
| @@ -106,7 +106,7 @@ static inline int compute_score(struct sock *sk, struct net *net, · 105 unmodified lines | |||
| 106 | if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif)) | 106 | if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif)) |
| 107 | return -1; | 107 | return -1; |
| 108 | 108 | ||
| 109 | score = 1; | 109 | score = sk->sk_bound_dev_if ? 2 : 1; |
| 110 | if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) | 110 | if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) |
| 111 | score++; | 111 | score++; |
| 112 | } | 112 | } |
| @@ -33,7 +33,7 @@ · 32 unmodified lines | |||
| 33 | 33 | ||
| 34 | static const char nf_frags_cache_name[] = "nf-frags"; | 34 | static const char nf_frags_cache_name[] = "nf-frags"; |
| 35 | 35 | ||
| 36 | unsigned int nf_frag_pernet_id __read_mostly; | 36 | static unsigned int nf_frag_pernet_id __read_mostly; |
| 37 | static struct inet_frags nf_frags; | 37 | static struct inet_frags nf_frags; |
| 38 | 38 | ||
| 39 | static struct nft_ct_frag6_pernet *nf_frag_pernet(struct net *net) | 39 | static struct nft_ct_frag6_pernet *nf_frag_pernet(struct net *net) |
| @@ -25,8 +25,6 @@ · 24 unmodified lines | |||
| 25 | #include <net/netfilter/nf_conntrack_zones.h> | 25 | #include <net/netfilter/nf_conntrack_zones.h> |
| 26 | #include <net/netfilter/ipv6/nf_defrag_ipv6.h> | 26 | #include <net/netfilter/ipv6/nf_defrag_ipv6.h> |
| 27 | 27 | ||
| 28 | extern unsigned int nf_frag_pernet_id; | ||
| 29 | |||
| 30 | static DEFINE_MUTEX(defrag6_mutex); | 28 | static DEFINE_MUTEX(defrag6_mutex); |
| 31 | 29 | ||
| 32 | static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, | 30 | static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, |
| @@ -91,12 +89,10 @@ static const struct nf_hook_ops ipv6_defrag_ops[] = { · 58 unmodified lines | |||
| 91 | 89 | ||
| 92 | static void __net_exit defrag6_net_exit(struct net *net) | 90 | static void __net_exit defrag6_net_exit(struct net *net) |
| 93 | { | 91 | { |
| 94 | struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id); | 92 | if (net->nf.defrag_ipv6_users) { |
| 95 | |||
| 96 | if (nf_frag->users) { | ||
| 97 | nf_unregister_net_hooks(net, ipv6_defrag_ops, | 93 | nf_unregister_net_hooks(net, ipv6_defrag_ops, |
| 98 | ARRAY_SIZE(ipv6_defrag_ops)); | 94 | ARRAY_SIZE(ipv6_defrag_ops)); |
| 99 | nf_frag->users = 0; | 95 | net->nf.defrag_ipv6_users = 0; |
| 100 | } | 96 | } |
| 101 | } | 97 | } |
| 102 | 98 | ||
| @@ -134,24 +130,23 @@ static void __exit nf_defrag_fini(void) · 31 unmodified lines | |||
| 134 | 130 | ||
| 135 | int nf_defrag_ipv6_enable(struct net *net) | 131 | int nf_defrag_ipv6_enable(struct net *net) |
| 136 | { | 132 | { |
| 137 | struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id); | ||
| 138 | int err = 0; | 133 | int err = 0; |
| 139 | 134 | ||
| 140 | mutex_lock(&defrag6_mutex); | 135 | mutex_lock(&defrag6_mutex); |
| 141 | if (nf_frag->users == UINT_MAX) { | 136 | if (net->nf.defrag_ipv6_users == UINT_MAX) { |
| 142 | err = -EOVERFLOW; | 137 | err = -EOVERFLOW; |
| 143 | goto out_unlock; | 138 | goto out_unlock; |
| 144 | } | 139 | } |
| 145 | 140 | ||
| 146 | if (nf_frag->users) { | 141 | if (net->nf.defrag_ipv6_users) { |
| 147 | nf_frag->users++; | 142 | net->nf.defrag_ipv6_users++; |
| 148 | goto out_unlock; | 143 | goto out_unlock; |
| 149 | } | 144 | } |
| 150 | 145 | ||
| 151 | err = nf_register_net_hooks(net, ipv6_defrag_ops, | 146 | err = nf_register_net_hooks(net, ipv6_defrag_ops, |
| 152 | ARRAY_SIZE(ipv6_defrag_ops)); | 147 | ARRAY_SIZE(ipv6_defrag_ops)); |
| 153 | if (err == 0) | 148 | if (err == 0) |
| 154 | nf_frag->users = 1; | 149 | net->nf.defrag_ipv6_users = 1; |
| 155 | 150 | ||
| 156 | out_unlock: | 151 | out_unlock: |
| 157 | mutex_unlock(&defrag6_mutex); | 152 | mutex_unlock(&defrag6_mutex); |
| @@ -161,12 +156,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable); · 3 unmodified lines | |||
| 161 | 156 | ||
| 162 | void nf_defrag_ipv6_disable(struct net *net) | 157 | void nf_defrag_ipv6_disable(struct net *net) |
| 163 | { | 158 | { |
| 164 | struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id); | ||
| 165 | |||
| 166 | mutex_lock(&defrag6_mutex); | 159 | mutex_lock(&defrag6_mutex); |
| 167 | if (nf_frag->users) { | 160 | if (net->nf.defrag_ipv6_users) { |
| 168 | nf_frag->users--; | 161 | net->nf.defrag_ipv6_users--; |
| 169 | if (nf_frag->users == 0) | 162 | if (net->nf.defrag_ipv6_users == 0) |
| 170 | nf_unregister_net_hooks(net, ipv6_defrag_ops, | 163 | nf_unregister_net_hooks(net, ipv6_defrag_ops, |
| 171 | ARRAY_SIZE(ipv6_defrag_ops)); | 164 | ARRAY_SIZE(ipv6_defrag_ops)); |
| 172 | } | 165 | } |
| @@ -133,7 +133,8 @@ static int compute_score(struct sock *sk, struct net *net, · 132 unmodified lines | |||
| 133 | dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif); | 133 | dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif); |
| 134 | if (!dev_match) | 134 | if (!dev_match) |
| 135 | return -1; | 135 | return -1; |
| 136 | score++; | 136 | if (sk->sk_bound_dev_if) |
| 137 | score++; | ||
| 137 | 138 | ||
| 138 | if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) | 139 | if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) |
| 139 | score++; | 140 | score++; |
| @@ -780,6 +780,7 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event) · 779 unmodified lines | |||
| 780 | { | 780 | { |
| 781 | struct nftables_pernet *nft_net; | 781 | struct nftables_pernet *nft_net; |
| 782 | struct sk_buff *skb; | 782 | struct sk_buff *skb; |
| 783 | u16 flags = 0; | ||
| 783 | int err; | 784 | int err; |
| 784 | 785 | ||
| 785 | if (!ctx->report && | 786 | if (!ctx->report && |
| @@ -790,8 +791,11 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event) · 4 unmodified lines | |||
| 790 | if (skb == NULL) | 791 | if (skb == NULL) |
| 791 | goto err; | 792 | goto err; |
| 792 | 793 | ||
| 794 | if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) | ||
| 795 | flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); | ||
| 796 | |||
| 793 | err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq, | 797 | err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq, |
| 794 | event, 0, ctx->family, ctx->table); | 798 | event, flags, ctx->family, ctx->table); |
| 795 | if (err < 0) { | 799 | if (err < 0) { |
| 796 | kfree_skb(skb); | 800 | kfree_skb(skb); |
| 797 | goto err; | 801 | goto err; |
| @@ -1563,6 +1567,7 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event) · 765 unmodified lines | |||
| 1563 | { | 1567 | { |
| 1564 | struct nftables_pernet *nft_net; | 1568 | struct nftables_pernet *nft_net; |
| 1565 | struct sk_buff *skb; | 1569 | struct sk_buff *skb; |
| 1570 | u16 flags = 0; | ||
| 1566 | int err; | 1571 | int err; |
| 1567 | 1572 | ||
| 1568 | if (!ctx->report && | 1573 | if (!ctx->report && |
| @@ -1573,8 +1578,11 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event) · 4 unmodified lines | |||
| 1573 | if (skb == NULL) | 1578 | if (skb == NULL) |
| 1574 | goto err; | 1579 | goto err; |
| 1575 | 1580 | ||
| 1581 | if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) | ||
| 1582 | flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); | ||
| 1583 | |||
| 1576 | err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq, | 1584 | err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq, |
| 1577 | event, 0, ctx->family, ctx->table, | 1585 | event, flags, ctx->family, ctx->table, |
| 1578 | ctx->chain); | 1586 | ctx->chain); |
| 1579 | if (err < 0) { | 1587 | if (err < 0) { |
| 1580 | kfree_skb(skb); | 1588 | kfree_skb(skb); |
| @@ -2866,8 +2874,7 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, · 1285 unmodified lines | |||
| 2866 | u32 flags, int family, | 2874 | u32 flags, int family, |
| 2867 | const struct nft_table *table, | 2875 | const struct nft_table *table, |
| 2868 | const struct nft_chain *chain, | 2876 | const struct nft_chain *chain, |
| 2869 | const struct nft_rule *rule, | 2877 | const struct nft_rule *rule, u64 handle) |
| 2870 | const struct nft_rule *prule) | ||
| 2871 | { | 2878 | { |
| 2872 | struct nlmsghdr *nlh; | 2879 | struct nlmsghdr *nlh; |
| 2873 | const struct nft_expr *expr, *next; | 2880 | const struct nft_expr *expr, *next; |
| @@ -2887,9 +2894,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, · 13 unmodified lines | |||
| 2887 | NFTA_RULE_PAD)) | 2894 | NFTA_RULE_PAD)) |
| 2888 | goto nla_put_failure; | 2895 | goto nla_put_failure; |
| 2889 | 2896 | ||
| 2890 | if (event != NFT_MSG_DELRULE && prule) { | 2897 | if (event != NFT_MSG_DELRULE && handle) { |
| 2891 | if (nla_put_be64(skb, NFTA_RULE_POSITION, | 2898 | if (nla_put_be64(skb, NFTA_RULE_POSITION, cpu_to_be64(handle), |
| 2892 | cpu_to_be64(prule->handle), | ||
| 2893 | NFTA_RULE_PAD)) | 2899 | NFTA_RULE_PAD)) |
| 2894 | goto nla_put_failure; | 2900 | goto nla_put_failure; |
| 2895 | } | 2901 | } |
| @@ -2925,7 +2931,10 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx, · 29 unmodified lines | |||
| 2925 | const struct nft_rule *rule, int event) | 2931 | const struct nft_rule *rule, int event) |
| 2926 | { | 2932 | { |
| 2927 | struct nftables_pernet *nft_net = nft_pernet(ctx->net); | 2933 | struct nftables_pernet *nft_net = nft_pernet(ctx->net); |
| 2934 | const struct nft_rule *prule; | ||
| 2928 | struct sk_buff *skb; | 2935 | struct sk_buff *skb; |
| 2936 | u64 handle = 0; | ||
| 2937 | u16 flags = 0; | ||
| 2929 | int err; | 2938 | int err; |
| 2930 | 2939 | ||
| 2931 | if (!ctx->report && | 2940 | if (!ctx->report && |
| @@ -2936,9 +2945,20 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx, · 4 unmodified lines | |||
| 2936 | if (skb == NULL) | 2945 | if (skb == NULL) |
| 2937 | goto err; | 2946 | goto err; |
| 2938 | 2947 | ||
| 2948 | if (event == NFT_MSG_NEWRULE && | ||
| 2949 | !list_is_first(&rule->list, &ctx->chain->rules) && | ||
| 2950 | !list_is_last(&rule->list, &ctx->chain->rules)) { | ||
| 2951 | prule = list_prev_entry(rule, list); | ||
| 2952 | handle = prule->handle; | ||
| 2953 | } | ||
| 2954 | if (ctx->flags & (NLM_F_APPEND | NLM_F_REPLACE)) | ||
| 2955 | flags |= NLM_F_APPEND; | ||
| 2956 | if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) | ||
| 2957 | flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); | ||
| 2958 | |||
| 2939 | err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq, | 2959 | err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq, |
| 2940 | event, 0, ctx->family, ctx->table, | 2960 | event, flags, ctx->family, ctx->table, |
| 2941 | ctx->chain, rule, NULL); | 2961 | ctx->chain, rule, handle); |
| 2942 | if (err < 0) { | 2962 | if (err < 0) { |
| 2943 | kfree_skb(skb); | 2963 | kfree_skb(skb); |
| 2944 | goto err; | 2964 | goto err; |
| @@ -2964,6 +2984,7 @@ static int __nf_tables_dump_rules(struct sk_buff *skb, · 19 unmodified lines | |||
| 2964 | struct net *net = sock_net(skb->sk); | 2984 | struct net *net = sock_net(skb->sk); |
| 2965 | const struct nft_rule *rule, *prule; | 2985 | const struct nft_rule *rule, *prule; |
| 2966 | unsigned int s_idx = cb->args[0]; | 2986 | unsigned int s_idx = cb->args[0]; |
| 2987 | u64 handle; | ||
| 2967 | 2988 | ||
| 2968 | prule = NULL; | 2989 | prule = NULL; |
| 2969 | list_for_each_entry_rcu(rule, &chain->rules, list) { | 2990 | list_for_each_entry_rcu(rule, &chain->rules, list) { |
| @@ -2975,12 +2996,17 @@ static int __nf_tables_dump_rules(struct sk_buff *skb, · 5 unmodified lines | |||
| 2975 | memset(&cb->args[1], 0, | 2996 | memset(&cb->args[1], 0, |
| 2976 | sizeof(cb->args) - sizeof(cb->args[0])); | 2997 | sizeof(cb->args) - sizeof(cb->args[0])); |
| 2977 | } | 2998 | } |
| 2999 | if (prule) | ||
| 3000 | handle = prule->handle; | ||
| 3001 | else | ||
| 3002 | handle = 0; | ||
| 3003 | |||
| 2978 | if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid, | 3004 | if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid, |
| 2979 | cb->nlh->nlmsg_seq, | 3005 | cb->nlh->nlmsg_seq, |
| 2980 | NFT_MSG_NEWRULE, | 3006 | NFT_MSG_NEWRULE, |
| 2981 | NLM_F_MULTI | NLM_F_APPEND, | 3007 | NLM_F_MULTI | NLM_F_APPEND, |
| 2982 | table->family, | 3008 | table->family, |
| 2983 | table, chain, rule, prule) < 0) | 3009 | table, chain, rule, handle) < 0) |
| 2984 | return 1; | 3010 | return 1; |
| 2985 | 3011 | ||
| 2986 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | 3012 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); |
| @@ -3143,7 +3169,7 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info, · 156 unmodified lines | |||
| 3143 | 3169 | ||
| 3144 | err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid, | 3170 | err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid, |
| 3145 | info->nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0, | 3171 | info->nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0, |
| 3146 | family, table, chain, rule, NULL); | 3172 | family, table, chain, rule, 0); |
| 3147 | if (err < 0) | 3173 | if (err < 0) |
| 3148 | goto err_fill_rule_info; | 3174 | goto err_fill_rule_info; |
| 3149 | 3175 | ||
| @@ -3403,17 +3429,15 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, · 253 unmodified lines | |||
| 3403 | } | 3429 | } |
| 3404 | 3430 | ||
| 3405 | if (info->nlh->nlmsg_flags & NLM_F_REPLACE) { | 3431 | if (info->nlh->nlmsg_flags & NLM_F_REPLACE) { |
| 3432 | err = nft_delrule(&ctx, old_rule); | ||
| 3433 | if (err < 0) | ||
| 3434 | goto err_destroy_flow_rule; | ||
| 3435 | |||
| 3406 | trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule); | 3436 | trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule); |
| 3407 | if (trans == NULL) { | 3437 | if (trans == NULL) { |
| 3408 | err = -ENOMEM; | 3438 | err = -ENOMEM; |
| 3409 | goto err_destroy_flow_rule; | 3439 | goto err_destroy_flow_rule; |
| 3410 | } | 3440 | } |
| 3411 | err = nft_delrule(&ctx, old_rule); | ||
| 3412 | if (err < 0) { | ||
| 3413 | nft_trans_destroy(trans); | ||
| 3414 | goto err_destroy_flow_rule; | ||
| 3415 | } | ||
| 3416 | |||
| 3417 | list_add_tail_rcu(&rule->list, &old_rule->list); | 3441 | list_add_tail_rcu(&rule->list, &old_rule->list); |
| 3418 | } else { | 3442 | } else { |
| 3419 | trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule); | 3443 | trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule); |
| @@ -3943,8 +3967,9 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx, · 523 unmodified lines | |||
| 3943 | gfp_t gfp_flags) | 3967 | gfp_t gfp_flags) |
| 3944 | { | 3968 | { |
| 3945 | struct nftables_pernet *nft_net = nft_pernet(ctx->net); | 3969 | struct nftables_pernet *nft_net = nft_pernet(ctx->net); |
| 3946 | struct sk_buff *skb; | ||
| 3947 | u32 portid = ctx->portid; | 3970 | u32 portid = ctx->portid; |
| 3971 | struct sk_buff *skb; | ||
| 3972 | u16 flags = 0; | ||
| 3948 | int err; | 3973 | int err; |
| 3949 | 3974 | ||
| 3950 | if (!ctx->report && | 3975 | if (!ctx->report && |
| @@ -3955,7 +3980,10 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx, · 4 unmodified lines | |||
| 3955 | if (skb == NULL) | 3980 | if (skb == NULL) |
| 3956 | goto err; | 3981 | goto err; |
| 3957 | 3982 | ||
| 3958 | err = nf_tables_fill_set(skb, ctx, set, event, 0); | 3983 | if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) |
| 3984 | flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); | ||
| 3985 | |||
| 3986 | err = nf_tables_fill_set(skb, ctx, set, event, flags); | ||
| 3959 | if (err < 0) { | 3987 | if (err < 0) { |
| 3960 | kfree_skb(skb); | 3988 | kfree_skb(skb); |
| 3961 | goto err; | 3989 | goto err; |
| @@ -5231,12 +5259,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb, · 1269 unmodified lines | |||
| 5231 | static void nf_tables_setelem_notify(const struct nft_ctx *ctx, | 5259 | static void nf_tables_setelem_notify(const struct nft_ctx *ctx, |
| 5232 | const struct nft_set *set, | 5260 | const struct nft_set *set, |
| 5233 | const struct nft_set_elem *elem, | 5261 | const struct nft_set_elem *elem, |
| 5234 | int event, u16 flags) | 5262 | int event) |
| 5235 | { | 5263 | { |
| 5236 | struct nftables_pernet *nft_net; | 5264 | struct nftables_pernet *nft_net; |
| 5237 | struct net *net = ctx->net; | 5265 | struct net *net = ctx->net; |
| 5238 | u32 portid = ctx->portid; | 5266 | u32 portid = ctx->portid; |
| 5239 | struct sk_buff *skb; | 5267 | struct sk_buff *skb; |
| 5268 | u16 flags = 0; | ||
| 5240 | int err; | 5269 | int err; |
| 5241 | 5270 | ||
| 5242 | if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES)) | 5271 | if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES)) |
| @@ -5246,6 +5275,9 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx, · 3 unmodified lines | |||
| 5246 | if (skb == NULL) | 5275 | if (skb == NULL) |
| 5247 | goto err; | 5276 | goto err; |
| 5248 | 5277 | ||
| 5278 | if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) | ||
| 5279 | flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); | ||
| 5280 | |||
| 5249 | err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags, | 5281 | err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags, |
| 5250 | set, elem); | 5282 | set, elem); |
| 5251 | if (err < 0) { | 5283 | if (err < 0) { |
| @@ -6921,7 +6953,7 @@ static int nf_tables_delobj(struct sk_buff *skb, const struct nfnl_info *info, · 1669 unmodified lines | |||
| 6921 | 6953 | ||
| 6922 | void nft_obj_notify(struct net *net, const struct nft_table *table, | 6954 | void nft_obj_notify(struct net *net, const struct nft_table *table, |
| 6923 | struct nft_object *obj, u32 portid, u32 seq, int event, | 6955 | struct nft_object *obj, u32 portid, u32 seq, int event, |
| 6924 | int family, int report, gfp_t gfp) | 6956 | u16 flags, int family, int report, gfp_t gfp) |
| 6925 | { | 6957 | { |
| 6926 | struct nftables_pernet *nft_net = nft_pernet(net); | 6958 | struct nftables_pernet *nft_net = nft_pernet(net); |
| 6927 | struct sk_buff *skb; | 6959 | struct sk_buff *skb; |
| @@ -6946,8 +6978,9 @@ void nft_obj_notify(struct net *net, const struct nft_table *table, · 18 unmodified lines | |||
| 6946 | if (skb == NULL) | 6978 | if (skb == NULL) |
| 6947 | goto err; | 6979 | goto err; |
| 6948 | 6980 | ||
| 6949 | err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family, | 6981 | err = nf_tables_fill_obj_info(skb, net, portid, seq, event, |
| 6950 | table, obj, false); | 6982 | flags & (NLM_F_CREATE | NLM_F_EXCL), |
| 6983 | family, table, obj, false); | ||
| 6951 | if (err < 0) { | 6984 | if (err < 0) { |
| 6952 | kfree_skb(skb); | 6985 | kfree_skb(skb); |
| 6953 | goto err; | 6986 | goto err; |
| @@ -6964,7 +6997,7 @@ static void nf_tables_obj_notify(const struct nft_ctx *ctx, · 10 unmodified lines | |||
| 6964 | struct nft_object *obj, int event) | 6997 | struct nft_object *obj, int event) |
| 6965 | { | 6998 | { |
| 6966 | nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event, | 6999 | nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event, |
| 6967 | ctx->family, ctx->report, GFP_KERNEL); | 7000 | ctx->flags, ctx->family, ctx->report, GFP_KERNEL); |
| 6968 | } | 7001 | } |
| 6969 | 7002 | ||
| 6970 | /* | 7003 | /* |
| @@ -7745,6 +7778,7 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx, · 774 unmodified lines | |||
| 7745 | { | 7778 | { |
| 7746 | struct nftables_pernet *nft_net = nft_pernet(ctx->net); | 7779 | struct nftables_pernet *nft_net = nft_pernet(ctx->net); |
| 7747 | struct sk_buff *skb; | 7780 | struct sk_buff *skb; |
| 7781 | u16 flags = 0; | ||
| 7748 | int err; | 7782 | int err; |
| 7749 | 7783 | ||
| 7750 | if (!ctx->report && | 7784 | if (!ctx->report && |
| @@ -7755,8 +7789,11 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx, · 4 unmodified lines | |||
| 7755 | if (skb == NULL) | 7789 | if (skb == NULL) |
| 7756 | goto err; | 7790 | goto err; |
| 7757 | 7791 | ||
| 7792 | if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) | ||
| 7793 | flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); | ||
| 7794 | |||
| 7758 | err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid, | 7795 | err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid, |
| 7759 | ctx->seq, event, 0, | 7796 | ctx->seq, event, flags, |
| 7760 | ctx->family, flowtable, hook_list); | 7797 | ctx->family, flowtable, hook_list); |
| 7761 | if (err < 0) { | 7798 | if (err < 0) { |
| 7762 | kfree_skb(skb); | 7799 | kfree_skb(skb); |
| @@ -8634,7 +8671,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) · 871 unmodified lines | |||
| 8634 | nft_setelem_activate(net, te->set, &te->elem); | 8671 | nft_setelem_activate(net, te->set, &te->elem); |
| 8635 | nf_tables_setelem_notify(&trans->ctx, te->set, | 8672 | nf_tables_setelem_notify(&trans->ctx, te->set, |
| 8636 | &te->elem, | 8673 | &te->elem, |
| 8637 | NFT_MSG_NEWSETELEM, 0); | 8674 | NFT_MSG_NEWSETELEM); |
| 8638 | nft_trans_destroy(trans); | 8675 | nft_trans_destroy(trans); |
| 8639 | break; | 8676 | break; |
| 8640 | case NFT_MSG_DELSETELEM: | 8677 | case NFT_MSG_DELSETELEM: |
| @@ -8642,7 +8679,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) · 1 unmodified line | |||
| 8642 | 8679 | ||
| 8643 | nf_tables_setelem_notify(&trans->ctx, te->set, | 8680 | nf_tables_setelem_notify(&trans->ctx, te->set, |
| 8644 | &te->elem, | 8681 | &te->elem, |
| 8645 | NFT_MSG_DELSETELEM, 0); | 8682 | NFT_MSG_DELSETELEM); |
| 8646 | nft_setelem_remove(net, te->set, &te->elem); | 8683 | nft_setelem_remove(net, te->set, &te->elem); |
| 8647 | if (!nft_setelem_is_catchall(te->set, &te->elem)) { | 8684 | if (!nft_setelem_is_catchall(te->set, &te->elem)) { |
| 8648 | atomic_dec(&te->set->nelems); | 8685 | atomic_dec(&te->set->nelems); |
| @@ -60,7 +60,7 @@ static void nft_quota_obj_eval(struct nft_object *obj, · 59 unmodified lines | |||
| 60 | if (overquota && | 60 | if (overquota && |
| 61 | !test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags)) | 61 | !test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags)) |
| 62 | nft_obj_notify(nft_net(pkt), obj->key.table, obj, 0, 0, | 62 | nft_obj_notify(nft_net(pkt), obj->key.table, obj, 0, 0, |
| 63 | NFT_MSG_NEWOBJ, nft_pf(pkt), 0, GFP_ATOMIC); | 63 | NFT_MSG_NEWOBJ, 0, nft_pf(pkt), 0, GFP_ATOMIC); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | static int nft_quota_do_init(const struct nlattr * const tb[], | 66 | static int nft_quota_do_init(const struct nlattr * const tb[], |
| @@ -594,7 +594,10 @@ static int netlink_insert(struct sock *sk, u32 portid) · 593 unmodified lines | |||
| 594 | 594 | ||
| 595 | /* We need to ensure that the socket is hashed and visible. */ | 595 | /* We need to ensure that the socket is hashed and visible. */ |
| 596 | smp_wmb(); | 596 | smp_wmb(); |
| 597 | nlk_sk(sk)->bound = portid; | 597 | /* Paired with lockless reads from netlink_bind(), |
| 598 | * netlink_connect() and netlink_sendmsg(). | ||
| 599 | */ | ||
| 600 | WRITE_ONCE(nlk_sk(sk)->bound, portid); | ||
| 598 | 601 | ||
| 599 | err: | 602 | err: |
| 600 | release_sock(sk); | 603 | release_sock(sk); |
| @@ -1012,7 +1015,8 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, · 411 unmodified lines | |||
| 1012 | if (nlk->ngroups < BITS_PER_LONG) | 1015 | if (nlk->ngroups < BITS_PER_LONG) |
| 1013 | groups &= (1UL << nlk->ngroups) - 1; | 1016 | groups &= (1UL << nlk->ngroups) - 1; |
| 1014 | 1017 | ||
| 1015 | bound = nlk->bound; | 1018 | /* Paired with WRITE_ONCE() in netlink_insert() */ |
| 1019 | bound = READ_ONCE(nlk->bound); | ||
| 1016 | if (bound) { | 1020 | if (bound) { |
| 1017 | /* Ensure nlk->portid is up-to-date. */ | 1021 | /* Ensure nlk->portid is up-to-date. */ |
| 1018 | smp_rmb(); | 1022 | smp_rmb(); |
| @@ -1098,8 +1102,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, · 79 unmodified lines | |||
| 1098 | 1102 | ||
| 1099 | /* No need for barriers here as we return to user-space without | 1103 | /* No need for barriers here as we return to user-space without |
| 1100 | * using any of the bound attributes. | 1104 | * using any of the bound attributes. |
| 1105 | * Paired with WRITE_ONCE() in netlink_insert(). | ||
| 1101 | */ | 1106 | */ |
| 1102 | if (!nlk->bound) | 1107 | if (!READ_ONCE(nlk->bound)) |
| 1103 | err = netlink_autobind(sock); | 1108 | err = netlink_autobind(sock); |
| 1104 | 1109 | ||
| 1105 | if (err == 0) { | 1110 | if (err == 0) { |
| @@ -1888,7 +1893,8 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) · 782 unmodified lines | |||
| 1888 | dst_group = nlk->dst_group; | 1893 | dst_group = nlk->dst_group; |
| 1889 | } | 1894 | } |
| 1890 | 1895 | ||
| 1891 | if (!nlk->bound) { | 1896 | /* Paired with WRITE_ONCE() in netlink_insert() */ |
| 1897 | if (!READ_ONCE(nlk->bound)) { | ||
| 1892 | err = netlink_autobind(sock); | 1898 | err = netlink_autobind(sock); |
| 1893 | if (err) | 1899 | if (err) |
| 1894 | goto out; | 1900 | goto out; |
| @@ -233,6 +233,9 @@ int fifo_set_limit(struct Qdisc *q, unsigned int limit) · 232 unmodified lines | |||
| 233 | if (strncmp(q->ops->id + 1, "fifo", 4) != 0) | 233 | if (strncmp(q->ops->id + 1, "fifo", 4) != 0) |
| 234 | return 0; | 234 | return 0; |
| 235 | 235 | ||
| 236 | if (!q->ops->change) | ||
| 237 | return 0; | ||
| 238 | |||
| 236 | nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)), GFP_KERNEL); | 239 | nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)), GFP_KERNEL); |
| 237 | if (nla) { | 240 | if (nla) { |
| 238 | nla->nla_type = RTM_NEWQDISC; | 241 | nla->nla_type = RTM_NEWQDISC; |
| @@ -1641,6 +1641,10 @@ static void taprio_destroy(struct Qdisc *sch) · 1640 unmodified lines | |||
| 1641 | list_del(&q->taprio_list); | 1641 | list_del(&q->taprio_list); |
| 1642 | spin_unlock(&taprio_list_lock); | 1642 | spin_unlock(&taprio_list_lock); |
| 1643 | 1643 | ||
| 1644 | /* Note that taprio_reset() might not be called if an error | ||
| 1645 | * happens in qdisc_create(), after taprio_init() has been called. | ||
| 1646 | */ | ||
| 1647 | hrtimer_cancel(&q->advance_timer); | ||
| 1644 | 1648 | ||
| 1645 | taprio_disable_offload(dev, q, NULL); | 1649 | taprio_disable_offload(dev, q, NULL); |
| 1646 | 1650 | ||
| @@ -2882,6 +2882,9 @@ static int unix_shutdown(struct socket *sock, int mode) · 2881 unmodified lines | |||
| 2882 | 2882 | ||
| 2883 | unix_state_lock(sk); | 2883 | unix_state_lock(sk); |
| 2884 | sk->sk_shutdown |= mode; | 2884 | sk->sk_shutdown |= mode; |
| 2885 | if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) && | ||
| 2886 | mode == SHUTDOWN_MASK) | ||
| 2887 | sk->sk_state = TCP_CLOSE; | ||
| 2885 | other = unix_peer(sk); | 2888 | other = unix_peer(sk); |
| 2886 | if (other) | 2889 | if (other) |
| 2887 | sock_hold(other); | 2890 | sock_hold(other); |
| @@ -2904,12 +2907,10 @@ static int unix_shutdown(struct socket *sock, int mode) · 16 unmodified lines | |||
| 2904 | other->sk_shutdown |= peer_mode; | 2907 | other->sk_shutdown |= peer_mode; |
| 2905 | unix_state_unlock(other); | 2908 | unix_state_unlock(other); |
| 2906 | other->sk_state_change(other); | 2909 | other->sk_state_change(other); |
| 2907 | if (peer_mode == SHUTDOWN_MASK) { | 2910 | if (peer_mode == SHUTDOWN_MASK) |
| 2908 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); | 2911 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); |
| 2909 | other->sk_state = TCP_CLOSE; | 2912 | else if (peer_mode & RCV_SHUTDOWN) |
| 2910 | } else if (peer_mode & RCV_SHUTDOWN) { | ||
| 2911 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); | 2913 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); |
| 2912 | } | ||
| 2913 | } | 2914 | } |
| 2914 | if (other) | 2915 | if (other) |
| 2915 | sock_put(other); | 2916 | sock_put(other); |
| @@ -1961,24 +1961,65 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb, · 1960 unmodified lines | |||
| 1961 | return skb; | 1961 | return skb; |
| 1962 | } | 1962 | } |
| 1963 | 1963 | ||
| 1964 | static int xfrm_notify_userpolicy(struct net *net) | ||
| 1965 | { | ||
| 1966 | struct xfrm_userpolicy_default *up; | ||
| 1967 | int len = NLMSG_ALIGN(sizeof(*up)); | ||
| 1968 | struct nlmsghdr *nlh; | ||
| 1969 | struct sk_buff *skb; | ||
| 1970 | int err; | ||
| 1971 | |||
| 1972 | skb = nlmsg_new(len, GFP_ATOMIC); | ||
| 1973 | if (skb == NULL) | ||
| 1974 | return -ENOMEM; | ||
| 1975 | |||
| 1976 | nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_GETDEFAULT, sizeof(*up), 0); | ||
| 1977 | if (nlh == NULL) { | ||
| 1978 | kfree_skb(skb); | ||
| 1979 | return -EMSGSIZE; | ||
| 1980 | } | ||
| 1981 | |||
| 1982 | up = nlmsg_data(nlh); | ||
| 1983 | up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ? | ||
| 1984 | XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; | ||
| 1985 | up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ? | ||
| 1986 | XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; | ||
| 1987 | up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ? | ||
| 1988 | XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; | ||
| 1989 | |||
| 1990 | nlmsg_end(skb, nlh); | ||
| 1991 | |||
| 1992 | rcu_read_lock(); | ||
| 1993 | err = xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_POLICY); | ||
| 1994 | rcu_read_unlock(); | ||
| 1995 | |||
| 1996 | return err; | ||
| 1997 | } | ||
| 1998 | |||
| 1964 | static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh, | 1999 | static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh, |
| 1965 | struct nlattr **attrs) | 2000 | struct nlattr **attrs) |
| 1966 | { | 2001 | { |
| 1967 | struct net *net = sock_net(skb->sk); | 2002 | struct net *net = sock_net(skb->sk); |
| 1968 | struct xfrm_userpolicy_default *up = nlmsg_data(nlh); | 2003 | struct xfrm_userpolicy_default *up = nlmsg_data(nlh); |
| 1969 | u8 dirmask; | ||
| 1970 | u8 old_default = net->xfrm.policy_default; | ||
| 1971 | 2004 | ||
| 1972 | if (up->dirmask >= XFRM_USERPOLICY_DIRMASK_MAX) | 2005 | if (up->in == XFRM_USERPOLICY_BLOCK) |
| 1973 | return -EINVAL; | 2006 | net->xfrm.policy_default |= XFRM_POL_DEFAULT_IN; |
| 2007 | else if (up->in == XFRM_USERPOLICY_ACCEPT) | ||
| 2008 | net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_IN; | ||
| 1974 | 2009 | ||
| 1975 | dirmask = (1 << up->dirmask) & XFRM_POL_DEFAULT_MASK; | 2010 | if (up->fwd == XFRM_USERPOLICY_BLOCK) |
| 2011 | net->xfrm.policy_default |= XFRM_POL_DEFAULT_FWD; | ||
| 2012 | else if (up->fwd == XFRM_USERPOLICY_ACCEPT) | ||
| 2013 | net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_FWD; | ||
| 1976 | 2014 | ||
| 1977 | net->xfrm.policy_default = (old_default & (0xff ^ dirmask)) | 2015 | if (up->out == XFRM_USERPOLICY_BLOCK) |
| 1978 | | (up->action << up->dirmask); | 2016 | net->xfrm.policy_default |= XFRM_POL_DEFAULT_OUT; |
| 2017 | else if (up->out == XFRM_USERPOLICY_ACCEPT) | ||
| 2018 | net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_OUT; | ||
| 1979 | 2019 | ||
| 1980 | rt_genid_bump_all(net); | 2020 | rt_genid_bump_all(net); |
| 1981 | 2021 | ||
| 2022 | xfrm_notify_userpolicy(net); | ||
| 1982 | return 0; | 2023 | return 0; |
| 1983 | } | 2024 | } |
| 1984 | 2025 | ||
| @@ -1988,13 +2029,11 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh, · 3 unmodified lines | |||
| 1988 | struct sk_buff *r_skb; | 2029 | struct sk_buff *r_skb; |
| 1989 | struct nlmsghdr *r_nlh; | 2030 | struct nlmsghdr *r_nlh; |
| 1990 | struct net *net = sock_net(skb->sk); | 2031 | struct net *net = sock_net(skb->sk); |
| 1991 | struct xfrm_userpolicy_default *r_up, *up; | 2032 | struct xfrm_userpolicy_default *r_up; |
| 1992 | int len = NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_default)); | 2033 | int len = NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_default)); |
| 1993 | u32 portid = NETLINK_CB(skb).portid; | 2034 | u32 portid = NETLINK_CB(skb).portid; |
| 1994 | u32 seq = nlh->nlmsg_seq; | 2035 | u32 seq = nlh->nlmsg_seq; |
| 1995 | 2036 | ||
| 1996 | up = nlmsg_data(nlh); | ||
| 1997 | |||
| 1998 | r_skb = nlmsg_new(len, GFP_ATOMIC); | 2037 | r_skb = nlmsg_new(len, GFP_ATOMIC); |
| 1999 | if (!r_skb) | 2038 | if (!r_skb) |
| 2000 | return -ENOMEM; | 2039 | return -ENOMEM; |
| @@ -2007,8 +2046,12 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh, · 6 unmodified lines | |||
| 2007 | 2046 | ||
| 2008 | r_up = nlmsg_data(r_nlh); | 2047 | r_up = nlmsg_data(r_nlh); |
| 2009 | 2048 | ||
| 2010 | r_up->action = ((net->xfrm.policy_default & (1 << up->dirmask)) >> up->dirmask); | 2049 | r_up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ? |
| 2011 | r_up->dirmask = up->dirmask; | 2050 | XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; |
| 2051 | r_up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ? | ||
| 2052 | XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; | ||
| 2053 | r_up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ? | ||
| 2054 | XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; | ||
| 2012 | nlmsg_end(r_skb, r_nlh); | 2055 | nlmsg_end(r_skb, r_nlh); |
| 2013 | 2056 | ||
| 2014 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid); | 2057 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid); |
| @@ -322,17 +322,11 @@ $(obj)/hbm_edt_kern.o: $(src)/hbm.h $(src)/hbm_kern.h · 321 unmodified lines | |||
| 322 | 322 | ||
| 323 | -include $(BPF_SAMPLES_PATH)/Makefile.target | 323 | -include $(BPF_SAMPLES_PATH)/Makefile.target |
| 324 | 324 | ||
| 325 | VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux) \ | 325 | VMLINUX_BTF_PATHS ?= $(abspath $(if $(O),$(O)/vmlinux)) \ |
| 326 | $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \ | 326 | $(abspath $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux)) \ |
| 327 | ../../../../vmlinux \ | 327 | $(abspath ./vmlinux) |
| 328 | /sys/kernel/btf/vmlinux \ | ||
| 329 | /boot/vmlinux-$(shell uname -r) | ||
| 330 | VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS)))) | 328 | VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS)))) |
| 331 | 329 | ||
| 332 | ifeq ($(VMLINUX_BTF),) | ||
| 333 | $(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)") | ||
| 334 | endif | ||
| 335 | |||
| 336 | $(obj)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | 330 | $(obj)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) |
| 337 | ifeq ($(VMLINUX_H),) | 331 | ifeq ($(VMLINUX_H),) |
| 338 | $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@ | 332 | $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@ |
| @@ -340,6 +334,11 @@ else · 1 unmodified line | |||
| 340 | $(Q)cp "$(VMLINUX_H)" $@ | 334 | $(Q)cp "$(VMLINUX_H)" $@ |
| 341 | endif | 335 | endif |
| 342 | 336 | ||
| 337 | ifeq ($(VMLINUX_BTF),) | ||
| 338 | $(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)",\ | ||
| 339 | build the kernel or set VMLINUX_BTF variable) | ||
| 340 | endif | ||
| 341 | |||
| 343 | clean-files += vmlinux.h | 342 | clean-files += vmlinux.h |
| 344 | 343 | ||
| 345 | # Get Clang's default includes on this system, as opposed to those seen by | 344 | # Get Clang's default includes on this system, as opposed to those seen by |
| @@ -1,4 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ |
| 2 | /* eBPF instruction mini library */ | 2 | /* eBPF instruction mini library */ |
| 3 | #ifndef __BPF_INSN_H | 3 | #ifndef __BPF_INSN_H |
| 4 | #define __BPF_INSN_H | 4 | #define __BPF_INSN_H |
| @@ -5,11 +5,6 @@ · 4 unmodified lines | |||
| 5 | #include "xdp_sample.bpf.h" | 5 | #include "xdp_sample.bpf.h" |
| 6 | #include "xdp_sample_shared.h" | 6 | #include "xdp_sample_shared.h" |
| 7 | 7 | ||
| 8 | enum { | ||
| 9 | BPF_F_BROADCAST = (1ULL << 3), | ||
| 10 | BPF_F_EXCLUDE_INGRESS = (1ULL << 4), | ||
| 11 | }; | ||
| 12 | |||
| 13 | struct { | 8 | struct { |
| 14 | __uint(type, BPF_MAP_TYPE_DEVMAP_HASH); | 9 | __uint(type, BPF_MAP_TYPE_DEVMAP_HASH); |
| 15 | __uint(key_size, sizeof(int)); | 10 | __uint(key_size, sizeof(int)); |
| @@ -126,6 +126,8 @@ static const struct nlmsg_perm nlmsg_xfrm_perms[] = · 125 unmodified lines | |||
| 126 | { XFRM_MSG_NEWSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, | 126 | { XFRM_MSG_NEWSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, |
| 127 | { XFRM_MSG_GETSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_READ }, | 127 | { XFRM_MSG_GETSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_READ }, |
| 128 | { XFRM_MSG_MAPPING, NETLINK_XFRM_SOCKET__NLMSG_READ }, | 128 | { XFRM_MSG_MAPPING, NETLINK_XFRM_SOCKET__NLMSG_READ }, |
| 129 | { XFRM_MSG_SETDEFAULT, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, | ||
| 130 | { XFRM_MSG_GETDEFAULT, NETLINK_XFRM_SOCKET__NLMSG_READ }, | ||
| 129 | }; | 131 | }; |
| 130 | 132 | ||
| 131 | static const struct nlmsg_perm nlmsg_audit_perms[] = | 133 | static const struct nlmsg_perm nlmsg_audit_perms[] = |
| @@ -189,7 +191,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) · 57 unmodified lines | |||
| 189 | * structures at the top of this file with the new mappings | 191 | * structures at the top of this file with the new mappings |
| 190 | * before updating the BUILD_BUG_ON() macro! | 192 | * before updating the BUILD_BUG_ON() macro! |
| 191 | */ | 193 | */ |
| 192 | BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_MAPPING); | 194 | BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_GETDEFAULT); |
| 193 | err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms, | 195 | err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms, |
| 194 | sizeof(nlmsg_xfrm_perms)); | 196 | sizeof(nlmsg_xfrm_perms)); |
| 195 | break; | 197 | break; |
| @@ -6894,7 +6894,8 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr) · 6893 unmodified lines | |||
| 6894 | 6894 | ||
| 6895 | if (obj->gen_loader) { | 6895 | if (obj->gen_loader) { |
| 6896 | /* reset FDs */ | 6896 | /* reset FDs */ |
| 6897 | btf__set_fd(obj->btf, -1); | 6897 | if (obj->btf) |
| 6898 | btf__set_fd(obj->btf, -1); | ||
| 6898 | for (i = 0; i < obj->nr_maps; i++) | 6899 | for (i = 0; i < obj->nr_maps; i++) |
| 6899 | obj->maps[i].fd = -1; | 6900 | obj->maps[i].fd = -1; |
| 6900 | if (!err) | 6901 | if (!err) |
| @@ -88,6 +88,7 @@ void strset__free(struct strset *set) · 87 unmodified lines | |||
| 88 | 88 | ||
| 89 | hashmap__free(set->strs_hash); | 89 | hashmap__free(set->strs_hash); |
| 90 | free(set->strs_data); | 90 | free(set->strs_data); |
| 91 | free(set); | ||
| 91 | } | 92 | } |
| 92 | 93 | ||
| 93 | size_t strset__data_size(const struct strset *set) | 94 | size_t strset__data_size(const struct strset *set) |