mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller"
"What's a holiday weekend without some networking bug fixes? [1]
1) Fix some eBPF JIT bugs wrt. SKB pointers across helper function
calls, from Daniel Borkmann.
2) Fix regression from errata limiting change to marvell PHY driver,
from Zhao Qiang.
3) Fix u16 overflow in SCTP, from Xin Long.
4) Fix potential memory leak during bridge newlink, from Nikolay
Aleksandrov.
5) Fix BPF selftest build on s390, from Hendrik Brueckner.
6) Don't append to cfg80211 automatically generated certs file,
always write new ones from scratch. From Thierry Reding.
7) Fix sleep in atomic in mac80211 hwsim, from Jia-Ju Bai.
8) Fix hang on tg3 MTU change with certain chips, from Brian King.
9) Add stall detection to arc emac driver and reset chip when this
happens, from Alexander Kochetkov.
10) Fix MTU limitng in GRE tunnel drivers, from Xin Long.
11) Fix stmmac timestamping bug due to mis-shifting of field. From
Fredrik Hallenberg.
12) Fix metrics match when deleting an ipv4 route. The kernel sets
some internal metrics bits which the user isn't going to set when
it makes the delete request. From Phil Sutter.
13) mvneta driver loop over RX queues limits on "txq_number" :-) Fix
from Yelena Krivosheev.
14) Fix double free and memory corruption in get_net_ns_by_id, from
Eric W. Biederman.
15) Flush ipv4 FIB tables in the reverse order. Some tables can share
their actual backing data, in particular this happens for the MAIN
and LOCAL tables. We have to kill the LOCAL table first, because
it uses MAIN's backing memory. Fix from Ido Schimmel.
16) Several eBPF verifier value tracking fixes, from Edward Cree, Jann
Horn, and Alexei Starovoitov.
17) Make changes to ipv6 autoflowlabel sysctl really propagate to
sockets, unless the socket has set the per-socket value
explicitly. From Shaohua Li.
18) Fix leaks and double callback invocations of zerocopy SKBs, from
Willem de Bruijn"
[1] Is this a trick question? "Relaxing"? "Quiet"? "Fine"? - Linus.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (77 commits)
skbuff: skb_copy_ubufs must release uarg even without user frags
skbuff: orphan frags before zerocopy clone
net: reevalulate autoflowlabel setting after sysctl setting
openvswitch: Fix pop_vlan action for double tagged frames
ipv6: Honor specified parameters in fibmatch lookup
bpf: do not allow root to mangle valid pointers
selftests/bpf: add tests for recent bugfixes
bpf: fix integer overflows
bpf: don't prune branches when a scalar is replaced with a pointer
bpf: force strict alignment checks for stack pointers
bpf: fix missing error return in check_stack_boundary()
bpf: fix 32-bit ALU op verification
bpf: fix incorrect tracking of register size truncation
bpf: fix incorrect sign extension in check_alu_op()
bpf/verifier: fix bounds calculation on BPF_RSH
ipv4: Fix use-after-free when flushing FIB tables
s390/qeth: fix error handling in checksum cmd callback
tipc: remove joining group member from congested list
selftests: net: Adding config fragment CONFIG_NUMA=y
nfp: bpf: keep track of the offloaded program
...
This commit is contained in:
commit
ead68f2161
73 files changed
+1549
-493
No files matched your search
@@ -763,7 +763,8 @@ emit_clear:
|
||||
func = (u8 *) __bpf_call_base + imm;
|
||||
|
||||
/* Save skb pointer if we need to re-cache skb data */
|
||||
if (bpf_helper_changes_pkt_data(func))
|
||||
if ((ctx->seen & SEEN_SKB) &&
|
||||
bpf_helper_changes_pkt_data(func))
|
||||
PPC_BPF_STL(3, 1, bpf_jit_stack_local(ctx));
|
||||
|
||||
bpf_jit_emit_func_call(image, ctx, (u64)func);
|
||||
@@ -772,7 +773,8 @@ emit_clear:
|
||||
PPC_MR(b2p[BPF_REG_0], 3);
|
||||
|
||||
/* refresh skb cache */
|
||||
if (bpf_helper_changes_pkt_data(func)) {
|
||||
if ((ctx->seen & SEEN_SKB) &&
|
||||
bpf_helper_changes_pkt_data(func)) {
|
||||
/* reload skb pointer to r3 */
|
||||
PPC_BPF_LL(3, 1, bpf_jit_stack_local(ctx));
|
||||
bpf_jit_emit_skb_loads(image, ctx);
|
||||
|
||||
@@ -55,8 +55,7 @@ struct bpf_jit {
|
||||
#define SEEN_LITERAL 8 /* code uses literals */
|
||||
#define SEEN_FUNC 16 /* calls C functions */
|
||||
#define SEEN_TAIL_CALL 32 /* code uses tail calls */
|
||||
#define SEEN_SKB_CHANGE 64 /* code changes skb data */
|
||||
#define SEEN_REG_AX 128 /* code uses constant blinding */
|
||||
#define SEEN_REG_AX 64 /* code uses constant blinding */
|
||||
#define SEEN_STACK (SEEN_FUNC | SEEN_MEM | SEEN_SKB)
|
||||
|
||||
/*
|
||||
@@ -448,12 +447,12 @@ static void bpf_jit_prologue(struct bpf_jit *jit, u32 stack_depth)
|
||||
EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0,
|
||||
REG_15, 152);
|
||||
}
|
||||
if (jit->seen & SEEN_SKB)
|
||||
if (jit->seen & SEEN_SKB) {
|
||||
emit_load_skb_data_hlen(jit);
|
||||
if (jit->seen & SEEN_SKB_CHANGE)
|
||||
/* stg %b1,ST_OFF_SKBP(%r0,%r15) */
|
||||
EMIT6_DISP_LH(0xe3000000, 0x0024, BPF_REG_1, REG_0, REG_15,
|
||||
STK_OFF_SKBP);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -983,8 +982,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
|
||||
EMIT2(0x0d00, REG_14, REG_W1);
|
||||
/* lgr %b0,%r2: load return value into %b0 */
|
||||
EMIT4(0xb9040000, BPF_REG_0, REG_2);
|
||||
if (bpf_helper_changes_pkt_data((void *)func)) {
|
||||
jit->seen |= SEEN_SKB_CHANGE;
|
||||
if ((jit->seen & SEEN_SKB) &&
|
||||
bpf_helper_changes_pkt_data((void *)func)) {
|
||||
/* lg %b1,ST_OFF_SKBP(%r15) */
|
||||
EMIT6_DISP_LH(0xe3000000, 0x0004, BPF_REG_1, REG_0,
|
||||
REG_15, STK_OFF_SKBP);
|
||||
|
||||
@@ -1245,14 +1245,16 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
||||
u8 *func = ((u8 *)__bpf_call_base) + imm;
|
||||
|
||||
ctx->saw_call = true;
|
||||
if (ctx->saw_ld_abs_ind && bpf_helper_changes_pkt_data(func))
|
||||
emit_reg_move(bpf2sparc[BPF_REG_1], L7, ctx);
|
||||
|
||||
emit_call((u32 *)func, ctx);
|
||||
emit_nop(ctx);
|
||||
|
||||
emit_reg_move(O0, bpf2sparc[BPF_REG_0], ctx);
|
||||
|
||||
if (bpf_helper_changes_pkt_data(func) && ctx->saw_ld_abs_ind)
|
||||
load_skb_regs(ctx, bpf2sparc[BPF_REG_6]);
|
||||
if (ctx->saw_ld_abs_ind && bpf_helper_changes_pkt_data(func))
|
||||
load_skb_regs(ctx, L7);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -159,6 +159,8 @@ struct arc_emac_priv {
|
||||
unsigned int link;
|
||||
unsigned int duplex;
|
||||
unsigned int speed;
|
||||
|
||||
unsigned int rx_missed_errors;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
#include "emac.h"
|
||||
|
||||
static void arc_emac_restart(struct net_device *ndev);
|
||||
|
||||
/**
|
||||
* arc_emac_tx_avail - Return the number of available slots in the tx ring.
|
||||
* @priv: Pointer to ARC EMAC private data structure.
|
||||
@@ -210,39 +212,48 @@ static int arc_emac_rx(struct net_device *ndev, int budget)
|
||||
continue;
|
||||
}
|
||||
|
||||
pktlen = info & LEN_MASK;
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += pktlen;
|
||||
skb = rx_buff->skb;
|
||||
skb_put(skb, pktlen);
|
||||
skb->dev = ndev;
|
||||
skb->protocol = eth_type_trans(skb, ndev);
|
||||
|
||||
dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr),
|
||||
dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE);
|
||||
|
||||
/* Prepare the BD for next cycle */
|
||||
rx_buff->skb = netdev_alloc_skb_ip_align(ndev,
|
||||
EMAC_BUFFER_SIZE);
|
||||
if (unlikely(!rx_buff->skb)) {
|
||||
/* Prepare the BD for next cycle. netif_receive_skb()
|
||||
* only if new skb was allocated and mapped to avoid holes
|
||||
* in the RX fifo.
|
||||
*/
|
||||
skb = netdev_alloc_skb_ip_align(ndev, EMAC_BUFFER_SIZE);
|
||||
if (unlikely(!skb)) {
|
||||
if (net_ratelimit())
|
||||
netdev_err(ndev, "cannot allocate skb\n");
|
||||
/* Return ownership to EMAC */
|
||||
rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
|
||||
stats->rx_errors++;
|
||||
/* Because receive_skb is below, increment rx_dropped */
|
||||
stats->rx_dropped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* receive_skb only if new skb was allocated to avoid holes */
|
||||
netif_receive_skb(skb);
|
||||
|
||||
addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data,
|
||||
addr = dma_map_single(&ndev->dev, (void *)skb->data,
|
||||
EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(&ndev->dev, addr)) {
|
||||
if (net_ratelimit())
|
||||
netdev_err(ndev, "cannot dma map\n");
|
||||
dev_kfree_skb(rx_buff->skb);
|
||||
netdev_err(ndev, "cannot map dma buffer\n");
|
||||
dev_kfree_skb(skb);
|
||||
/* Return ownership to EMAC */
|
||||
rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
|
||||
stats->rx_errors++;
|
||||
stats->rx_dropped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* unmap previosly mapped skb */
|
||||
dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr),
|
||||
dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE);
|
||||
|
||||
pktlen = info & LEN_MASK;
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += pktlen;
|
||||
skb_put(rx_buff->skb, pktlen);
|
||||
rx_buff->skb->dev = ndev;
|
||||
rx_buff->skb->protocol = eth_type_trans(rx_buff->skb, ndev);
|
||||
|
||||
netif_receive_skb(rx_buff->skb);
|
||||
|
||||
rx_buff->skb = skb;
|
||||
dma_unmap_addr_set(rx_buff, addr, addr);
|
||||
dma_unmap_len_set(rx_buff, len, EMAC_BUFFER_SIZE);
|
||||
|
||||
@@ -258,6 +269,53 @@ static int arc_emac_rx(struct net_device *ndev, int budget)
|
||||
return work_done;
|
||||
}
|
||||
|
||||
/**
|
||||
* arc_emac_rx_miss_handle - handle R_MISS register
|
||||
* @ndev: Pointer to the net_device structure.
|
||||
*/
|
||||
static void arc_emac_rx_miss_handle(struct net_device *ndev)
|
||||
{
|
||||
struct arc_emac_priv *priv = netdev_priv(ndev);
|
||||
struct net_device_stats *stats = &ndev->stats;
|
||||
unsigned int miss;
|
||||
|
||||
miss = arc_reg_get(priv, R_MISS);
|
||||
if (miss) {
|
||||
stats->rx_errors += miss;
|
||||
stats->rx_missed_errors += miss;
|
||||
priv->rx_missed_errors += miss;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* arc_emac_rx_stall_check - check RX stall
|
||||
* @ndev: Pointer to the net_device structure.
|
||||
* @budget: How many BDs requested to process on 1 call.
|
||||
* @work_done: How many BDs processed
|
||||
*
|
||||
* Under certain conditions EMAC stop reception of incoming packets and
|
||||
* continuously increment R_MISS register instead of saving data into
|
||||
* provided buffer. This function detect that condition and restart
|
||||
* EMAC.
|
||||
*/
|
||||
static void arc_emac_rx_stall_check(struct net_device *ndev,
|
||||
int budget, unsigned int work_done)
|
||||
{
|
||||
struct arc_emac_priv *priv = netdev_priv(ndev);
|
||||
struct arc_emac_bd *rxbd;
|
||||
|
||||
if (work_done)
|
||||
priv->rx_missed_errors = 0;
|
||||
|
||||
if (priv->rx_missed_errors && budget) {
|
||||
rxbd = &priv->rxbd[priv->last_rx_bd];
|
||||
if (le32_to_cpu(rxbd->info) & FOR_EMAC) {
|
||||
arc_emac_restart(ndev);
|
||||
priv->rx_missed_errors = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* arc_emac_poll - NAPI poll handler.
|
||||
* @napi: Pointer to napi_struct structure.
|
||||
@@ -272,6 +330,7 @@ static int arc_emac_poll(struct napi_struct *napi, int budget)
|
||||
unsigned int work_done;
|
||||
|
||||
arc_emac_tx_clean(ndev);
|
||||
arc_emac_rx_miss_handle(ndev);
|
||||
|
||||
work_done = arc_emac_rx(ndev, budget);
|
||||
if (work_done < budget) {
|
||||
@@ -279,6 +338,8 @@ static int arc_emac_poll(struct napi_struct *napi, int budget)
|
||||
arc_reg_or(priv, R_ENABLE, RXINT_MASK | TXINT_MASK);
|
||||
}
|
||||
|
||||
arc_emac_rx_stall_check(ndev, budget, work_done);
|
||||
|
||||
return work_done;
|
||||
}
|
||||
|
||||
@@ -320,6 +381,8 @@ static irqreturn_t arc_emac_intr(int irq, void *dev_instance)
|
||||
if (status & MSER_MASK) {
|
||||
stats->rx_missed_errors += 0x100;
|
||||
stats->rx_errors += 0x100;
|
||||
priv->rx_missed_errors += 0x100;
|
||||
napi_schedule(&priv->napi);
|
||||
}
|
||||
|
||||
if (status & RXCR_MASK) {
|
||||
@@ -732,6 +795,63 @@ static int arc_emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* arc_emac_restart - Restart EMAC
|
||||
* @ndev: Pointer to net_device structure.
|
||||
*
|
||||
* This function do hardware reset of EMAC in order to restore
|
||||
* network packets reception.
|
||||
*/
|
||||
static void arc_emac_restart(struct net_device *ndev)
|
||||
{
|
||||
struct arc_emac_priv *priv = netdev_priv(ndev);
|
||||
struct net_device_stats *stats = &ndev->stats;
|
||||
int i;
|
||||
|
||||
if (net_ratelimit())
|
||||
netdev_warn(ndev, "restarting stalled EMAC\n");
|
||||
|
||||
netif_stop_queue(ndev);
|
||||
|
||||
/* Disable interrupts */
|
||||
arc_reg_clr(priv, R_ENABLE, RXINT_MASK | TXINT_MASK | ERR_MASK);
|
||||
|
||||
/* Disable EMAC */
|
||||
arc_reg_clr(priv, R_CTRL, EN_MASK);
|
||||
|
||||
/* Return the sk_buff to system */
|
||||
arc_free_tx_queue(ndev);
|
||||
|
||||
/* Clean Tx BD's */
|
||||
priv->txbd_curr = 0;
|
||||
priv->txbd_dirty = 0;
|
||||
memset(priv->txbd, 0, TX_RING_SZ);
|
||||
|
||||
for (i = 0; i < RX_BD_NUM; i++) {
|
||||
struct arc_emac_bd *rxbd = &priv->rxbd[i];
|
||||
unsigned int info = le32_to_cpu(rxbd->info);
|
||||
|
||||
if (!(info & FOR_EMAC)) {
|
||||
stats->rx_errors++;
|
||||
stats->rx_dropped++;
|
||||
}
|
||||
/* Return ownership to EMAC */
|
||||
rxbd->info = cpu_to_le32(FOR_EMAC | EMAC_BUFFER_SIZE);
|
||||
}
|
||||
priv->last_rx_bd = 0;
|
||||
|
||||
/* Make sure info is visible to EMAC before enable */
|
||||
wmb();
|
||||
|
||||
/* Enable interrupts */
|
||||
arc_reg_set(priv, R_ENABLE, RXINT_MASK | TXINT_MASK | ERR_MASK);
|
||||
|
||||
/* Enable EMAC */
|
||||
arc_reg_or(priv, R_CTRL, EN_MASK);
|
||||
|
||||
netif_start_queue(ndev);
|
||||
}
|
||||
|
||||
static const struct net_device_ops arc_emac_netdev_ops = {
|
||||
.ndo_open = arc_emac_open,
|
||||
.ndo_stop = arc_emac_stop,
|
||||
|
||||
@@ -14225,7 +14225,9 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
|
||||
/* Reset PHY, otherwise the read DMA engine will be in a mode that
|
||||
* breaks all requests to 256 bytes.
|
||||
*/
|
||||
if (tg3_asic_rev(tp) == ASIC_REV_57766)
|
||||
if (tg3_asic_rev(tp) == ASIC_REV_57766 ||
|
||||
tg3_asic_rev(tp) == ASIC_REV_5717 ||
|
||||
tg3_asic_rev(tp) == ASIC_REV_5719)
|
||||
reset_phy = true;
|
||||
|
||||
err = tg3_restart_hw(tp, reset_phy);
|
||||
|
||||
@@ -1214,6 +1214,10 @@ static void mvneta_port_disable(struct mvneta_port *pp)
|
||||
val &= ~MVNETA_GMAC0_PORT_ENABLE;
|
||||
mvreg_write(pp, MVNETA_GMAC_CTRL_0, val);
|
||||
|
||||
pp->link = 0;
|
||||
pp->duplex = -1;
|
||||
pp->speed = 0;
|
||||
|
||||
udelay(200);
|
||||
}
|
||||
|
||||
@@ -1958,9 +1962,9 @@ static int mvneta_rx_swbm(struct mvneta_port *pp, int rx_todo,
|
||||
|
||||
if (!mvneta_rxq_desc_is_first_last(rx_status) ||
|
||||
(rx_status & MVNETA_RXD_ERR_SUMMARY)) {
|
||||
mvneta_rx_error(pp, rx_desc);
|
||||
err_drop_frame:
|
||||
dev->stats.rx_errors++;
|
||||
mvneta_rx_error(pp, rx_desc);
|
||||
/* leave the descriptor untouched */
|
||||
continue;
|
||||
}
|
||||
@@ -3011,7 +3015,7 @@ static void mvneta_cleanup_rxqs(struct mvneta_port *pp)
|
||||
{
|
||||
int queue;
|
||||
|
||||
for (queue = 0; queue < txq_number; queue++)
|
||||
for (queue = 0; queue < rxq_number; queue++)
|
||||
mvneta_rxq_deinit(pp, &pp->rxqs[queue]);
|
||||
}
|
||||
|
||||
|
||||
@@ -1961,11 +1961,12 @@ static int mtk_hw_init(struct mtk_eth *eth)
|
||||
/* set GE2 TUNE */
|
||||
regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0);
|
||||
|
||||
/* GE1, Force 1000M/FD, FC ON */
|
||||
mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(0));
|
||||
|
||||
/* GE2, Force 1000M/FD, FC ON */
|
||||
mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(1));
|
||||
/* Set linkdown as the default for each GMAC. Its own MCR would be set
|
||||
* up with the more appropriate value when mtk_phy_link_adjust call is
|
||||
* being invoked.
|
||||
*/
|
||||
for (i = 0; i < MTK_MAC_COUNT; i++)
|
||||
mtk_w32(eth, 0, MTK_MAC_MCR(i));
|
||||
|
||||
/* Indicates CDM to parse the MTK special tag from CPU
|
||||
* which also is working out for untag packets.
|
||||
|
||||
@@ -362,7 +362,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
|
||||
case MLX5_CMD_OP_QUERY_VPORT_COUNTER:
|
||||
case MLX5_CMD_OP_ALLOC_Q_COUNTER:
|
||||
case MLX5_CMD_OP_QUERY_Q_COUNTER:
|
||||
case MLX5_CMD_OP_SET_RATE_LIMIT:
|
||||
case MLX5_CMD_OP_SET_PP_RATE_LIMIT:
|
||||
case MLX5_CMD_OP_QUERY_RATE_LIMIT:
|
||||
case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT:
|
||||
case MLX5_CMD_OP_QUERY_SCHEDULING_ELEMENT:
|
||||
@@ -505,7 +505,7 @@ const char *mlx5_command_str(int command)
|
||||
MLX5_COMMAND_STR_CASE(ALLOC_Q_COUNTER);
|
||||
MLX5_COMMAND_STR_CASE(DEALLOC_Q_COUNTER);
|
||||
MLX5_COMMAND_STR_CASE(QUERY_Q_COUNTER);
|
||||
MLX5_COMMAND_STR_CASE(SET_RATE_LIMIT);
|
||||
MLX5_COMMAND_STR_CASE(SET_PP_RATE_LIMIT);
|
||||
MLX5_COMMAND_STR_CASE(QUERY_RATE_LIMIT);
|
||||
MLX5_COMMAND_STR_CASE(CREATE_SCHEDULING_ELEMENT);
|
||||
MLX5_COMMAND_STR_CASE(DESTROY_SCHEDULING_ELEMENT);
|
||||
|
||||
@@ -82,6 +82,9 @@
|
||||
max_t(u32, MLX5_MPWRQ_MIN_LOG_STRIDE_SZ(mdev), req)
|
||||
#define MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev) MLX5_MPWRQ_LOG_STRIDE_SZ(mdev, 6)
|
||||
#define MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) MLX5_MPWRQ_LOG_STRIDE_SZ(mdev, 8)
|
||||
#define MLX5E_MPWQE_STRIDE_SZ(mdev, cqe_cmprs) \
|
||||
(cqe_cmprs ? MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) : \
|
||||
MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev))
|
||||
|
||||
#define MLX5_MPWRQ_LOG_WQE_SZ 18
|
||||
#define MLX5_MPWRQ_WQE_PAGE_ORDER (MLX5_MPWRQ_LOG_WQE_SZ - PAGE_SHIFT > 0 ? \
|
||||
@@ -590,6 +593,7 @@ struct mlx5e_channel {
|
||||
struct mlx5_core_dev *mdev;
|
||||
struct hwtstamp_config *tstamp;
|
||||
int ix;
|
||||
int cpu;
|
||||
};
|
||||
|
||||
struct mlx5e_channels {
|
||||
@@ -935,8 +939,9 @@ void mlx5e_set_tx_cq_mode_params(struct mlx5e_params *params,
|
||||
u8 cq_period_mode);
|
||||
void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params,
|
||||
u8 cq_period_mode);
|
||||
void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev,
|
||||
struct mlx5e_params *params, u8 rq_type);
|
||||
void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev,
|
||||
struct mlx5e_params *params,
|
||||
u8 rq_type);
|
||||
|
||||
static inline bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev)
|
||||
{
|
||||
|
||||
@@ -274,6 +274,7 @@ int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets)
|
||||
static int mlx5e_dbcnl_validate_ets(struct net_device *netdev,
|
||||
struct ieee_ets *ets)
|
||||
{
|
||||
bool have_ets_tc = false;
|
||||
int bw_sum = 0;
|
||||
int i;
|
||||
|
||||
@@ -288,11 +289,14 @@ static int mlx5e_dbcnl_validate_ets(struct net_device *netdev,
|
||||
}
|
||||
|
||||
/* Validate Bandwidth Sum */
|
||||
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
|
||||
if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS)
|
||||
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
|
||||
if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) {
|
||||
have_ets_tc = true;
|
||||
bw_sum += ets->tc_tx_bw[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (bw_sum != 0 && bw_sum != 100) {
|
||||
if (have_ets_tc && bw_sum != 100) {
|
||||
netdev_err(netdev,
|
||||
"Failed to validate ETS: BW sum is illegal\n");
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1523,8 +1523,10 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val
|
||||
new_channels.params = priv->channels.params;
|
||||
MLX5E_SET_PFLAG(&new_channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS, new_val);
|
||||
|
||||
mlx5e_set_rq_type_params(priv->mdev, &new_channels.params,
|
||||
new_channels.params.rq_wq_type);
|
||||
new_channels.params.mpwqe_log_stride_sz =
|
||||
MLX5E_MPWQE_STRIDE_SZ(priv->mdev, new_val);
|
||||
new_channels.params.mpwqe_log_num_strides =
|
||||
MLX5_MPWRQ_LOG_WQE_SZ - new_channels.params.mpwqe_log_stride_sz;
|
||||
|
||||
if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
|
||||
priv->channels.params = new_channels.params;
|
||||
@@ -1536,6 +1538,10 @@ int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool new_val
|
||||
return err;
|
||||
|
||||
mlx5e_switch_priv_channels(priv, &new_channels, NULL);
|
||||
mlx5e_dbg(DRV, priv, "MLX5E: RxCqeCmprss was turned %s\n",
|
||||
MLX5E_GET_PFLAG(&priv->channels.params,
|
||||
MLX5E_PFLAG_RX_CQE_COMPRESS) ? "ON" : "OFF");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,11 +71,6 @@ struct mlx5e_channel_param {
|
||||
struct mlx5e_cq_param icosq_cq;
|
||||
};
|
||||
|
||||
static int mlx5e_get_node(struct mlx5e_priv *priv, int ix)
|
||||
{
|
||||
return pci_irq_get_node(priv->mdev->pdev, MLX5_EQ_VEC_COMP_BASE + ix);
|
||||
}
|
||||
|
||||
static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
|
||||
{
|
||||
return MLX5_CAP_GEN(mdev, striding_rq) &&
|
||||
@@ -83,8 +78,8 @@ static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
|
||||
MLX5_CAP_ETH(mdev, reg_umr_sq);
|
||||
}
|
||||
|
||||
void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev,
|
||||
struct mlx5e_params *params, u8 rq_type)
|
||||
void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev,
|
||||
struct mlx5e_params *params, u8 rq_type)
|
||||
{
|
||||
params->rq_wq_type = rq_type;
|
||||
params->lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
|
||||
@@ -93,10 +88,8 @@ void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev,
|
||||
params->log_rq_size = is_kdump_kernel() ?
|
||||
MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW :
|
||||
MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE_MPW;
|
||||
params->mpwqe_log_stride_sz =
|
||||
MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS) ?
|
||||
MLX5_MPWRQ_CQE_CMPRS_LOG_STRIDE_SZ(mdev) :
|
||||
MLX5_MPWRQ_DEF_LOG_STRIDE_SZ(mdev);
|
||||
params->mpwqe_log_stride_sz = MLX5E_MPWQE_STRIDE_SZ(mdev,
|
||||
MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS));
|
||||
params->mpwqe_log_num_strides = MLX5_MPWRQ_LOG_WQE_SZ -
|
||||
params->mpwqe_log_stride_sz;
|
||||
break;
|
||||
@@ -120,13 +113,14 @@ void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev,
|
||||
MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS));
|
||||
}
|
||||
|
||||
static void mlx5e_set_rq_params(struct mlx5_core_dev *mdev, struct mlx5e_params *params)
|
||||
static void mlx5e_set_rq_params(struct mlx5_core_dev *mdev,
|
||||
struct mlx5e_params *params)
|
||||
{
|
||||
u8 rq_type = mlx5e_check_fragmented_striding_rq_cap(mdev) &&
|
||||
!params->xdp_prog && !MLX5_IPSEC_DEV(mdev) ?
|
||||
MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ :
|
||||
MLX5_WQ_TYPE_LINKED_LIST;
|
||||
mlx5e_set_rq_type_params(mdev, params, rq_type);
|
||||
mlx5e_init_rq_type_params(mdev, params, rq_type);
|
||||
}
|
||||
|
||||
static void mlx5e_update_carrier(struct mlx5e_priv *priv)
|
||||
@@ -444,17 +438,16 @@ static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq,
|
||||
int wq_sz = mlx5_wq_ll_get_size(&rq->wq);
|
||||
int mtt_sz = mlx5e_get_wqe_mtt_sz();
|
||||
int mtt_alloc = mtt_sz + MLX5_UMR_ALIGN - 1;
|
||||
int node = mlx5e_get_node(c->priv, c->ix);
|
||||
int i;
|
||||
|
||||
rq->mpwqe.info = kzalloc_node(wq_sz * sizeof(*rq->mpwqe.info),
|
||||
GFP_KERNEL, node);
|
||||
GFP_KERNEL, cpu_to_node(c->cpu));
|
||||
if (!rq->mpwqe.info)
|
||||
goto err_out;
|
||||
|
||||
/* We allocate more than mtt_sz as we will align the pointer */
|
||||
rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz,
|
||||
GFP_KERNEL, node);
|
||||
rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz, GFP_KERNEL,
|
||||
cpu_to_node(c->cpu));
|
||||
if (unlikely(!rq->mpwqe.mtt_no_align))
|
||||
goto err_free_wqe_info;
|
||||
|
||||
@@ -562,7 +555,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
|
||||
int err;
|
||||
int i;
|
||||
|
||||
rqp->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
|
||||
rqp->wq.db_numa_node = cpu_to_node(c->cpu);
|
||||
|
||||
err = mlx5_wq_ll_create(mdev, &rqp->wq, rqc_wq, &rq->wq,
|
||||
&rq->wq_ctrl);
|
||||
@@ -629,8 +622,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
|
||||
default: /* MLX5_WQ_TYPE_LINKED_LIST */
|
||||
rq->wqe.frag_info =
|
||||
kzalloc_node(wq_sz * sizeof(*rq->wqe.frag_info),
|
||||
GFP_KERNEL,
|
||||
mlx5e_get_node(c->priv, c->ix));
|
||||
GFP_KERNEL, cpu_to_node(c->cpu));
|
||||
if (!rq->wqe.frag_info) {
|
||||
err = -ENOMEM;
|
||||
goto err_rq_wq_destroy;
|
||||
@@ -1000,13 +992,13 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c,
|
||||
sq->uar_map = mdev->mlx5e_res.bfreg.map;
|
||||
sq->min_inline_mode = params->tx_min_inline_mode;
|
||||
|
||||
param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
|
||||
param->wq.db_numa_node = cpu_to_node(c->cpu);
|
||||
err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
|
||||
|
||||
err = mlx5e_alloc_xdpsq_db(sq, mlx5e_get_node(c->priv, c->ix));
|
||||
err = mlx5e_alloc_xdpsq_db(sq, cpu_to_node(c->cpu));
|
||||
if (err)
|
||||
goto err_sq_wq_destroy;
|
||||
|
||||
@@ -1053,13 +1045,13 @@ static int mlx5e_alloc_icosq(struct mlx5e_channel *c,
|
||||
sq->channel = c;
|
||||
sq->uar_map = mdev->mlx5e_res.bfreg.map;
|
||||
|
||||
param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
|
||||
param->wq.db_numa_node = cpu_to_node(c->cpu);
|
||||
err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
|
||||
|
||||
err = mlx5e_alloc_icosq_db(sq, mlx5e_get_node(c->priv, c->ix));
|
||||
err = mlx5e_alloc_icosq_db(sq, cpu_to_node(c->cpu));
|
||||
if (err)
|
||||
goto err_sq_wq_destroy;
|
||||
|
||||
@@ -1126,13 +1118,13 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
|
||||
if (MLX5_IPSEC_DEV(c->priv->mdev))
|
||||
set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state);
|
||||
|
||||
param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
|
||||
param->wq.db_numa_node = cpu_to_node(c->cpu);
|
||||
err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
|
||||
|
||||
err = mlx5e_alloc_txqsq_db(sq, mlx5e_get_node(c->priv, c->ix));
|
||||
err = mlx5e_alloc_txqsq_db(sq, cpu_to_node(c->cpu));
|
||||
if (err)
|
||||
goto err_sq_wq_destroy;
|
||||
|
||||
@@ -1504,8 +1496,8 @@ static int mlx5e_alloc_cq(struct mlx5e_channel *c,
|
||||
struct mlx5_core_dev *mdev = c->priv->mdev;
|
||||
int err;
|
||||
|
||||
param->wq.buf_numa_node = mlx5e_get_node(c->priv, c->ix);
|
||||
param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
|
||||
param->wq.buf_numa_node = cpu_to_node(c->cpu);
|
||||
param->wq.db_numa_node = cpu_to_node(c->cpu);
|
||||
param->eq_ix = c->ix;
|
||||
|
||||
err = mlx5e_alloc_cq_common(mdev, param, cq);
|
||||
@@ -1604,6 +1596,11 @@ static void mlx5e_close_cq(struct mlx5e_cq *cq)
|
||||
mlx5e_free_cq(cq);
|
||||
}
|
||||
|
||||
static int mlx5e_get_cpu(struct mlx5e_priv *priv, int ix)
|
||||
{
|
||||
return cpumask_first(priv->mdev->priv.irq_info[ix].mask);
|
||||
}
|
||||
|
||||
static int mlx5e_open_tx_cqs(struct mlx5e_channel *c,
|
||||
struct mlx5e_params *params,
|
||||
struct mlx5e_channel_param *cparam)
|
||||
@@ -1752,12 +1749,13 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
|
||||
{
|
||||
struct mlx5e_cq_moder icocq_moder = {0, 0};
|
||||
struct net_device *netdev = priv->netdev;
|
||||
int cpu = mlx5e_get_cpu(priv, ix);
|
||||
struct mlx5e_channel *c;
|
||||
unsigned int irq;
|
||||
int err;
|
||||
int eqn;
|
||||
|
||||
c = kzalloc_node(sizeof(*c), GFP_KERNEL, mlx5e_get_node(priv, ix));
|
||||
c = kzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu));
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1765,6 +1763,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
|
||||
c->mdev = priv->mdev;
|
||||
c->tstamp = &priv->tstamp;
|
||||
c->ix = ix;
|
||||
c->cpu = cpu;
|
||||
c->pdev = &priv->mdev->pdev->dev;
|
||||
c->netdev = priv->netdev;
|
||||
c->mkey_be = cpu_to_be32(priv->mdev->mlx5e_res.mkey.key);
|
||||
@@ -1853,8 +1852,7 @@ static void mlx5e_activate_channel(struct mlx5e_channel *c)
|
||||
for (tc = 0; tc < c->num_tc; tc++)
|
||||
mlx5e_activate_txqsq(&c->sq[tc]);
|
||||
mlx5e_activate_rq(&c->rq);
|
||||
netif_set_xps_queue(c->netdev,
|
||||
mlx5_get_vector_affinity(c->priv->mdev, c->ix), c->ix);
|
||||
netif_set_xps_queue(c->netdev, get_cpu_mask(c->cpu), c->ix);
|
||||
}
|
||||
|
||||
static void mlx5e_deactivate_channel(struct mlx5e_channel *c)
|
||||
@@ -3679,6 +3677,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
|
||||
struct sk_buff *skb,
|
||||
netdev_features_t features)
|
||||
{
|
||||
unsigned int offset = 0;
|
||||
struct udphdr *udph;
|
||||
u8 proto;
|
||||
u16 port;
|
||||
@@ -3688,7 +3687,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
|
||||
proto = ip_hdr(skb)->protocol;
|
||||
break;
|
||||
case htons(ETH_P_IPV6):
|
||||
proto = ipv6_hdr(skb)->nexthdr;
|
||||
proto = ipv6_find_hdr(skb, &offset, -1, NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
goto out;
|
||||
|
||||
@@ -466,7 +466,7 @@ static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr)
|
||||
break;
|
||||
case MLX5_EVENT_TYPE_CQ_ERROR:
|
||||
cqn = be32_to_cpu(eqe->data.cq_err.cqn) & 0xffffff;
|
||||
mlx5_core_warn(dev, "CQ error on CQN 0x%x, syndrom 0x%x\n",
|
||||
mlx5_core_warn(dev, "CQ error on CQN 0x%x, syndrome 0x%x\n",
|
||||
cqn, eqe->data.cq_err.syndrome);
|
||||
mlx5_cq_event(dev, cqn, eqe->type);
|
||||
break;
|
||||
@@ -775,7 +775,7 @@ err1:
|
||||
return err;
|
||||
}
|
||||
|
||||
int mlx5_stop_eqs(struct mlx5_core_dev *dev)
|
||||
void mlx5_stop_eqs(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_eq_table *table = &dev->priv.eq_table;
|
||||
int err;
|
||||
@@ -784,22 +784,26 @@ int mlx5_stop_eqs(struct mlx5_core_dev *dev)
|
||||
if (MLX5_CAP_GEN(dev, pg)) {
|
||||
err = mlx5_destroy_unmap_eq(dev, &table->pfault_eq);
|
||||
if (err)
|
||||
return err;
|
||||
mlx5_core_err(dev, "failed to destroy page fault eq, err(%d)\n",
|
||||
err);
|
||||
}
|
||||
#endif
|
||||
|
||||
err = mlx5_destroy_unmap_eq(dev, &table->pages_eq);
|
||||
if (err)
|
||||
return err;
|
||||
mlx5_core_err(dev, "failed to destroy pages eq, err(%d)\n",
|
||||
err);
|
||||
|
||||
mlx5_destroy_unmap_eq(dev, &table->async_eq);
|
||||
err = mlx5_destroy_unmap_eq(dev, &table->async_eq);
|
||||
if (err)
|
||||
mlx5_core_err(dev, "failed to destroy async eq, err(%d)\n",
|
||||
err);
|
||||
mlx5_cmd_use_polling(dev);
|
||||
|
||||
err = mlx5_destroy_unmap_eq(dev, &table->cmd_eq);
|
||||
if (err)
|
||||
mlx5_cmd_use_events(dev);
|
||||
|
||||
return err;
|
||||
mlx5_core_err(dev, "failed to destroy command eq, err(%d)\n",
|
||||
err);
|
||||
}
|
||||
|
||||
int mlx5_core_eq_query(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
|
||||
|
||||
@@ -66,6 +66,9 @@ static int mlx5_fpga_mem_read_i2c(struct mlx5_fpga_device *fdev, size_t size,
|
||||
u8 actual_size;
|
||||
int err;
|
||||
|
||||
if (!size)
|
||||
return -EINVAL;
|
||||
|
||||
if (!fdev->mdev)
|
||||
return -ENOTCONN;
|
||||
|
||||
@@ -95,6 +98,9 @@ static int mlx5_fpga_mem_write_i2c(struct mlx5_fpga_device *fdev, size_t size,
|
||||
u8 actual_size;
|
||||
int err;
|
||||
|
||||
if (!size)
|
||||
return -EINVAL;
|
||||
|
||||
if (!fdev->mdev)
|
||||
return -ENOTCONN;
|
||||
|
||||
|
||||
@@ -174,6 +174,8 @@ static void del_hw_fte(struct fs_node *node);
|
||||
static void del_sw_flow_table(struct fs_node *node);
|
||||
static void del_sw_flow_group(struct fs_node *node);
|
||||
static void del_sw_fte(struct fs_node *node);
|
||||
static void del_sw_prio(struct fs_node *node);
|
||||
static void del_sw_ns(struct fs_node *node);
|
||||
/* Delete rule (destination) is special case that
|
||||
* requires to lock the FTE for all the deletion process.
|
||||
*/
|
||||
@@ -408,6 +410,16 @@ static inline struct mlx5_core_dev *get_dev(struct fs_node *node)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void del_sw_ns(struct fs_node *node)
|
||||
{
|
||||
kfree(node);
|
||||
}
|
||||
|
||||
static void del_sw_prio(struct fs_node *node)
|
||||
{
|
||||
kfree(node);
|
||||
}
|
||||
|
||||
static void del_hw_flow_table(struct fs_node *node)
|
||||
{
|
||||
struct mlx5_flow_table *ft;
|
||||
@@ -2064,7 +2076,7 @@ static struct fs_prio *fs_create_prio(struct mlx5_flow_namespace *ns,
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
fs_prio->node.type = FS_TYPE_PRIO;
|
||||
tree_init_node(&fs_prio->node, NULL, NULL);
|
||||
tree_init_node(&fs_prio->node, NULL, del_sw_prio);
|
||||
tree_add_node(&fs_prio->node, &ns->node);
|
||||
fs_prio->num_levels = num_levels;
|
||||
fs_prio->prio = prio;
|
||||
@@ -2090,7 +2102,7 @@ static struct mlx5_flow_namespace *fs_create_namespace(struct fs_prio *prio)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
fs_init_namespace(ns);
|
||||
tree_init_node(&ns->node, NULL, NULL);
|
||||
tree_init_node(&ns->node, NULL, del_sw_ns);
|
||||
tree_add_node(&ns->node, &prio->node);
|
||||
list_add_tail(&ns->node.list, &prio->node.children);
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ static void print_health_info(struct mlx5_core_dev *dev)
|
||||
u32 fw;
|
||||
int i;
|
||||
|
||||
/* If the syndrom is 0, the device is OK and no need to print buffer */
|
||||
/* If the syndrome is 0, the device is OK and no need to print buffer */
|
||||
if (!ioread8(&h->synd))
|
||||
return;
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
|
||||
struct mlx5e_params *params)
|
||||
{
|
||||
/* Override RQ params as IPoIB supports only LINKED LIST RQ for now */
|
||||
mlx5e_set_rq_type_params(mdev, params, MLX5_WQ_TYPE_LINKED_LIST);
|
||||
mlx5e_init_rq_type_params(mdev, params, MLX5_WQ_TYPE_LINKED_LIST);
|
||||
|
||||
/* RQ size in ipoib by default is 512 */
|
||||
params->log_rq_size = is_kdump_kernel() ?
|
||||
|
||||
@@ -317,9 +317,6 @@ static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev)
|
||||
{
|
||||
struct mlx5_priv *priv = &dev->priv;
|
||||
struct mlx5_eq_table *table = &priv->eq_table;
|
||||
struct irq_affinity irqdesc = {
|
||||
.pre_vectors = MLX5_EQ_VEC_COMP_BASE,
|
||||
};
|
||||
int num_eqs = 1 << MLX5_CAP_GEN(dev, log_max_eq);
|
||||
int nvec;
|
||||
|
||||
@@ -333,10 +330,9 @@ static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev)
|
||||
if (!priv->irq_info)
|
||||
goto err_free_msix;
|
||||
|
||||
nvec = pci_alloc_irq_vectors_affinity(dev->pdev,
|
||||
nvec = pci_alloc_irq_vectors(dev->pdev,
|
||||
MLX5_EQ_VEC_COMP_BASE + 1, nvec,
|
||||
PCI_IRQ_MSIX | PCI_IRQ_AFFINITY,
|
||||
&irqdesc);
|
||||
PCI_IRQ_MSIX);
|
||||
if (nvec < 0)
|
||||
return nvec;
|
||||
|
||||
@@ -622,6 +618,63 @@ u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev)
|
||||
return (u64)timer_l | (u64)timer_h1 << 32;
|
||||
}
|
||||
|
||||
static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
|
||||
{
|
||||
struct mlx5_priv *priv = &mdev->priv;
|
||||
int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i);
|
||||
|
||||
if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) {
|
||||
mlx5_core_warn(mdev, "zalloc_cpumask_var failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node),
|
||||
priv->irq_info[i].mask);
|
||||
|
||||
if (IS_ENABLED(CONFIG_SMP) &&
|
||||
irq_set_affinity_hint(irq, priv->irq_info[i].mask))
|
||||
mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i)
|
||||
{
|
||||
struct mlx5_priv *priv = &mdev->priv;
|
||||
int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i);
|
||||
|
||||
irq_set_affinity_hint(irq, NULL);
|
||||
free_cpumask_var(priv->irq_info[i].mask);
|
||||
}
|
||||
|
||||
static int mlx5_irq_set_affinity_hints(struct mlx5_core_dev *mdev)
|
||||
{
|
||||
int err;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++) {
|
||||
err = mlx5_irq_set_affinity_hint(mdev, i);
|
||||
if (err)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
for (i--; i >= 0; i--)
|
||||
mlx5_irq_clear_affinity_hint(mdev, i);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mlx5_irq_clear_affinity_hints(struct mlx5_core_dev *mdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++)
|
||||
mlx5_irq_clear_affinity_hint(mdev, i);
|
||||
}
|
||||
|
||||
int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
|
||||
unsigned int *irqn)
|
||||
{
|
||||
@@ -1097,6 +1150,12 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
|
||||
goto err_stop_eqs;
|
||||
}
|
||||
|
||||
err = mlx5_irq_set_affinity_hints(dev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to alloc affinity hint cpumask\n");
|
||||
goto err_affinity_hints;
|
||||
}
|
||||
|
||||
err = mlx5_init_fs(dev);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "Failed to init flow steering\n");
|
||||
@@ -1154,6 +1213,9 @@ err_sriov:
|
||||
mlx5_cleanup_fs(dev);
|
||||
|
||||
err_fs:
|
||||
mlx5_irq_clear_affinity_hints(dev);
|
||||
|
||||
err_affinity_hints:
|
||||
free_comp_eqs(dev);
|
||||
|
||||
err_stop_eqs:
|
||||
@@ -1222,6 +1284,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
|
||||
|
||||
mlx5_sriov_detach(dev);
|
||||
mlx5_cleanup_fs(dev);
|
||||
mlx5_irq_clear_affinity_hints(dev);
|
||||
free_comp_eqs(dev);
|
||||
mlx5_stop_eqs(dev);
|
||||
mlx5_put_uars_page(dev, priv->uar);
|
||||
|
||||
@@ -213,8 +213,8 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
|
||||
err_cmd:
|
||||
memset(din, 0, sizeof(din));
|
||||
memset(dout, 0, sizeof(dout));
|
||||
MLX5_SET(destroy_qp_in, in, opcode, MLX5_CMD_OP_DESTROY_QP);
|
||||
MLX5_SET(destroy_qp_in, in, qpn, qp->qpn);
|
||||
MLX5_SET(destroy_qp_in, din, opcode, MLX5_CMD_OP_DESTROY_QP);
|
||||
MLX5_SET(destroy_qp_in, din, qpn, qp->qpn);
|
||||
mlx5_cmd_exec(dev, din, sizeof(din), dout, sizeof(dout));
|
||||
return err;
|
||||
}
|
||||
|
||||
Loaded 20 of 73 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user