Skip to content

Commit ae76715

Browse files
hadarhenziondavem330
authored andcommitted
net/mlx5e: Check the minimum inline header mode before xmit
Each send queue (SQ) has inline mode that defines the minimal required inline headers in the SQ WQE. Before sending each packet check that the minimum required headers on the WQE are copied. Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 5fc382d commit ae76715

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ struct mlx5e_sq {
398398
u32 sqn;
399399
u16 bf_buf_size;
400400
u16 max_inline;
401+
u8 min_inline_mode;
401402
u16 edge;
402403
struct device *pdev;
403404
struct mlx5e_tstamp *tstamp;

drivers/net/ethernet/mellanox/mlx5/core/en_tx.c

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,57 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
128128
return priv->channeltc_to_txq_map[channel_ix][up];
129129
}
130130

131+
static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb)
132+
{
133+
#define MLX5E_MIN_INLINE (ETH_HLEN + VLAN_HLEN)
134+
135+
return max(skb_network_offset(skb), MLX5E_MIN_INLINE);
136+
}
137+
138+
static inline int mlx5e_skb_l3_header_offset(struct sk_buff *skb)
139+
{
140+
struct flow_keys keys;
141+
142+
if (skb_transport_header_was_set(skb))
143+
return skb_transport_offset(skb);
144+
else if (skb_flow_dissect_flow_keys(skb, &keys, 0))
145+
return keys.control.thoff;
146+
else
147+
return mlx5e_skb_l2_header_offset(skb);
148+
}
149+
150+
static inline unsigned int mlx5e_calc_min_inline(enum mlx5_inline_modes mode,
151+
struct sk_buff *skb)
152+
{
153+
int hlen;
154+
155+
switch (mode) {
156+
case MLX5_INLINE_MODE_TCP_UDP:
157+
hlen = eth_get_headlen(skb->data, skb_headlen(skb));
158+
if (hlen == ETH_HLEN && !skb_vlan_tag_present(skb))
159+
hlen += VLAN_HLEN;
160+
return hlen;
161+
case MLX5_INLINE_MODE_IP:
162+
/* When transport header is set to zero, it means no transport
163+
* header. When transport header is set to 0xff's, it means
164+
* transport header wasn't set.
165+
*/
166+
if (skb_transport_offset(skb))
167+
return mlx5e_skb_l3_header_offset(skb);
168+
/* fall through */
169+
case MLX5_INLINE_MODE_L2:
170+
default:
171+
return mlx5e_skb_l2_header_offset(skb);
172+
}
173+
}
174+
131175
static inline u16 mlx5e_get_inline_hdr_size(struct mlx5e_sq *sq,
132176
struct sk_buff *skb, bool bf)
133177
{
134178
/* Some NIC TX decisions, e.g loopback, are based on the packet
135179
* headers and occur before the data gather.
136180
* Therefore these headers must be copied into the WQE
137181
*/
138-
#define MLX5E_MIN_INLINE (ETH_HLEN + VLAN_HLEN)
139-
140182
if (bf) {
141183
u16 ihs = skb_headlen(skb);
142184

@@ -146,8 +188,7 @@ static inline u16 mlx5e_get_inline_hdr_size(struct mlx5e_sq *sq,
146188
if (ihs <= sq->max_inline)
147189
return skb_headlen(skb);
148190
}
149-
150-
return max(skb_network_offset(skb), MLX5E_MIN_INLINE);
191+
return mlx5e_calc_min_inline(sq->min_inline_mode, skb);
151192
}
152193

153194
static inline void mlx5e_tx_skb_pull_inline(unsigned char **skb_data,

include/linux/mlx5/device.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@ __mlx5_mask(typ, fld))
129129
tmp; \
130130
})
131131

132+
enum mlx5_inline_modes {
133+
MLX5_INLINE_MODE_NONE,
134+
MLX5_INLINE_MODE_L2,
135+
MLX5_INLINE_MODE_IP,
136+
MLX5_INLINE_MODE_TCP_UDP,
137+
};
138+
132139
enum {
133140
MLX5_MAX_COMMANDS = 32,
134141
MLX5_CMD_DATA_BLOCK_SIZE = 512,

0 commit comments

Comments
 (0)