Skip to content

Commit 0e3a3f6

Browse files
akiyanodavem330
authored andcommitted
net: ena: support new LLQ acceleration mode
New devices add a new hardware acceleration engine, which adds some restrictions to the driver. Metadata descriptor must be present for each packet and the maximum burst size between two doorbells is now limited to a number advertised by the device. This patch adds: 1. A handshake protocol between the driver and the device, so the device will enable the accelerated queues only when both sides support it. 2. The driver support for the new acceleration engine: 2.1. Send metadata descriptor for each Tx packet. 2.2. Limit the number of packets sent between doorbells.(*) (*) A previous driver implementation of this feature was comitted in commit 05d62ca ("net: ena: add handling of llq max tx burst size") however the design of the interface between the driver and device changed since then. This change is reflected in this commit. Signed-off-by: Netanel Belgazal <[email protected]> Signed-off-by: Arthur Kiyanovski <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c29efea commit 0e3a3f6

File tree

7 files changed

+109
-24
lines changed

7 files changed

+109
-24
lines changed

drivers/net/ethernet/amazon/ena/ena_admin_defs.h

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,36 @@ enum ena_admin_llq_stride_ctrl {
491491
ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY = 2,
492492
};
493493

494+
enum ena_admin_accel_mode_feat {
495+
ENA_ADMIN_DISABLE_META_CACHING = 0,
496+
ENA_ADMIN_LIMIT_TX_BURST = 1,
497+
};
498+
499+
struct ena_admin_accel_mode_get {
500+
/* bit field of enum ena_admin_accel_mode_feat */
501+
u16 supported_flags;
502+
503+
/* maximum burst size between two doorbells. The size is in bytes */
504+
u16 max_tx_burst_size;
505+
};
506+
507+
struct ena_admin_accel_mode_set {
508+
/* bit field of enum ena_admin_accel_mode_feat */
509+
u16 enabled_flags;
510+
511+
u16 reserved;
512+
};
513+
514+
struct ena_admin_accel_mode_req {
515+
union {
516+
u32 raw[2];
517+
518+
struct ena_admin_accel_mode_get get;
519+
520+
struct ena_admin_accel_mode_set set;
521+
} u;
522+
};
523+
494524
struct ena_admin_feature_llq_desc {
495525
u32 max_llq_num;
496526

@@ -536,10 +566,13 @@ struct ena_admin_feature_llq_desc {
536566
/* the stride control the driver selected to use */
537567
u16 descriptors_stride_ctrl_enabled;
538568

539-
/* Maximum size in bytes taken by llq entries in a single tx burst.
540-
* Set to 0 when there is no such limit.
569+
/* reserved */
570+
u32 reserved1;
571+
572+
/* accelerated low latency queues requirement. driver needs to
573+
* support those requirements in order to use accelerated llq
541574
*/
542-
u32 max_tx_burst_size;
575+
struct ena_admin_accel_mode_req accel_mode;
543576
};
544577

545578
struct ena_admin_queue_ext_feature_fields {

drivers/net/ethernet/amazon/ena/ena_com.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,8 @@ static int ena_com_init_io_sq(struct ena_com_dev *ena_dev,
403403
0x0, io_sq->llq_info.desc_list_entry_size);
404404
io_sq->llq_buf_ctrl.descs_left_in_line =
405405
io_sq->llq_info.descs_num_before_header;
406+
io_sq->disable_meta_caching =
407+
io_sq->llq_info.disable_meta_caching;
406408

407409
if (io_sq->llq_info.max_entries_in_tx_burst > 0)
408410
io_sq->entries_in_tx_burst_left =
@@ -626,6 +628,10 @@ static int ena_com_set_llq(struct ena_com_dev *ena_dev)
626628
cmd.u.llq.desc_num_before_header_enabled = llq_info->descs_num_before_header;
627629
cmd.u.llq.descriptors_stride_ctrl_enabled = llq_info->desc_stride_ctrl;
628630

631+
cmd.u.llq.accel_mode.u.set.enabled_flags =
632+
BIT(ENA_ADMIN_DISABLE_META_CACHING) |
633+
BIT(ENA_ADMIN_LIMIT_TX_BURST);
634+
629635
ret = ena_com_execute_admin_command(admin_queue,
630636
(struct ena_admin_aq_entry *)&cmd,
631637
sizeof(cmd),
@@ -643,6 +649,7 @@ static int ena_com_config_llq_info(struct ena_com_dev *ena_dev,
643649
struct ena_llq_configurations *llq_default_cfg)
644650
{
645651
struct ena_com_llq_info *llq_info = &ena_dev->llq_info;
652+
struct ena_admin_accel_mode_get llq_accel_mode_get;
646653
u16 supported_feat;
647654
int rc;
648655

@@ -742,9 +749,17 @@ static int ena_com_config_llq_info(struct ena_com_dev *ena_dev,
742749
llq_default_cfg->llq_num_decs_before_header,
743750
supported_feat, llq_info->descs_num_before_header);
744751
}
752+
/* Check for accelerated queue supported */
753+
llq_accel_mode_get = llq_features->accel_mode.u.get;
754+
755+
llq_info->disable_meta_caching =
756+
!!(llq_accel_mode_get.supported_flags &
757+
BIT(ENA_ADMIN_DISABLE_META_CACHING));
745758

746-
llq_info->max_entries_in_tx_burst =
747-
(u16)(llq_features->max_tx_burst_size / llq_default_cfg->llq_ring_entry_size_value);
759+
if (llq_accel_mode_get.supported_flags & BIT(ENA_ADMIN_LIMIT_TX_BURST))
760+
llq_info->max_entries_in_tx_burst =
761+
llq_accel_mode_get.max_tx_burst_size /
762+
llq_default_cfg->llq_ring_entry_size_value;
748763

749764
rc = ena_com_set_llq(ena_dev);
750765
if (rc)

drivers/net/ethernet/amazon/ena/ena_com.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ struct ena_com_llq_info {
127127
u16 descs_num_before_header;
128128
u16 descs_per_entry;
129129
u16 max_entries_in_tx_burst;
130+
bool disable_meta_caching;
130131
};
131132

132133
struct ena_com_io_cq {
@@ -189,6 +190,8 @@ struct ena_com_io_sq {
189190
enum queue_direction direction;
190191
enum ena_admin_placement_policy_type mem_queue_type;
191192

193+
bool disable_meta_caching;
194+
192195
u32 msix_vector;
193196
struct ena_com_tx_meta cached_tx_meta;
194197
struct ena_com_llq_info llq_info;

drivers/net/ethernet/amazon/ena/ena_eth_com.c

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,10 @@ static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
285285
return count;
286286
}
287287

288-
static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
289-
struct ena_com_tx_ctx *ena_tx_ctx)
288+
static int ena_com_create_meta(struct ena_com_io_sq *io_sq,
289+
struct ena_com_tx_meta *ena_meta)
290290
{
291291
struct ena_eth_io_tx_meta_desc *meta_desc = NULL;
292-
struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta;
293292

294293
meta_desc = get_sq_desc(io_sq);
295294
memset(meta_desc, 0x0, sizeof(struct ena_eth_io_tx_meta_desc));
@@ -309,12 +308,13 @@ static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
309308

310309
/* Extended meta desc */
311310
meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_MASK;
312-
meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_STORE_MASK;
313311
meta_desc->len_ctrl |= (io_sq->phase <<
314312
ENA_ETH_IO_TX_META_DESC_PHASE_SHIFT) &
315313
ENA_ETH_IO_TX_META_DESC_PHASE_MASK;
316314

317315
meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_FIRST_MASK;
316+
meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_STORE_MASK;
317+
318318
meta_desc->word2 |= ena_meta->l3_hdr_len &
319319
ENA_ETH_IO_TX_META_DESC_L3_HDR_LEN_MASK;
320320
meta_desc->word2 |= (ena_meta->l3_hdr_offset <<
@@ -325,13 +325,36 @@ static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
325325
ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_SHIFT) &
326326
ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_MASK;
327327

328-
meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_STORE_MASK;
328+
return ena_com_sq_update_tail(io_sq);
329+
}
330+
331+
static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
332+
struct ena_com_tx_ctx *ena_tx_ctx,
333+
bool *have_meta)
334+
{
335+
struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta;
329336

330-
/* Cached the meta desc */
331-
memcpy(&io_sq->cached_tx_meta, ena_meta,
332-
sizeof(struct ena_com_tx_meta));
337+
/* When disable meta caching is set, don't bother to save the meta and
338+
* compare it to the stored version, just create the meta
339+
*/
340+
if (io_sq->disable_meta_caching) {
341+
if (unlikely(!ena_tx_ctx->meta_valid))
342+
return -EINVAL;
333343

334-
return ena_com_sq_update_tail(io_sq);
344+
*have_meta = true;
345+
return ena_com_create_meta(io_sq, ena_meta);
346+
}
347+
348+
if (ena_com_meta_desc_changed(io_sq, ena_tx_ctx)) {
349+
*have_meta = true;
350+
/* Cache the meta desc */
351+
memcpy(&io_sq->cached_tx_meta, ena_meta,
352+
sizeof(struct ena_com_tx_meta));
353+
return ena_com_create_meta(io_sq, ena_meta);
354+
}
355+
356+
*have_meta = false;
357+
return 0;
335358
}
336359

337360
static void ena_com_rx_set_flags(struct ena_com_rx_ctx *ena_rx_ctx,
@@ -402,12 +425,10 @@ int ena_com_prepare_tx(struct ena_com_io_sq *io_sq,
402425
if (unlikely(rc))
403426
return rc;
404427

405-
have_meta = ena_tx_ctx->meta_valid && ena_com_meta_desc_changed(io_sq,
406-
ena_tx_ctx);
407-
if (have_meta) {
408-
rc = ena_com_create_and_store_tx_meta_desc(io_sq, ena_tx_ctx);
409-
if (unlikely(rc))
410-
return rc;
428+
rc = ena_com_create_and_store_tx_meta_desc(io_sq, ena_tx_ctx, &have_meta);
429+
if (unlikely(rc)) {
430+
pr_err("failed to create and store tx meta desc\n");
431+
return rc;
411432
}
412433

413434
/* If the caller doesn't want to send packets */

drivers/net/ethernet/amazon/ena/ena_eth_com.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,8 @@ static inline bool ena_com_is_doorbell_needed(struct ena_com_io_sq *io_sq,
157157
llq_info = &io_sq->llq_info;
158158
num_descs = ena_tx_ctx->num_bufs;
159159

160-
if (unlikely(ena_com_meta_desc_changed(io_sq, ena_tx_ctx)))
160+
if (llq_info->disable_meta_caching ||
161+
unlikely(ena_com_meta_desc_changed(io_sq, ena_tx_ctx)))
161162
++num_descs;
162163

163164
if (num_descs > llq_info->descs_num_before_header) {

drivers/net/ethernet/amazon/ena/ena_netdev.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@ static void ena_init_io_rings(struct ena_adapter *adapter,
655655
txr->sgl_size = adapter->max_tx_sgl_size;
656656
txr->smoothed_interval =
657657
ena_com_get_nonadaptive_moderation_interval_tx(ena_dev);
658+
txr->disable_meta_caching = adapter->disable_meta_caching;
658659

659660
/* Don't init RX queues for xdp queues */
660661
if (!ENA_IS_XDP_INDEX(adapter, i)) {
@@ -2783,7 +2784,9 @@ int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count)
27832784
return dev_was_up ? ena_open(adapter->netdev) : 0;
27842785
}
27852786

2786-
static void ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct sk_buff *skb)
2787+
static void ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx,
2788+
struct sk_buff *skb,
2789+
bool disable_meta_caching)
27872790
{
27882791
u32 mss = skb_shinfo(skb)->gso_size;
27892792
struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta;
@@ -2827,7 +2830,9 @@ static void ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct sk_buff *skb)
28272830
ena_meta->l3_hdr_len = skb_network_header_len(skb);
28282831
ena_meta->l3_hdr_offset = skb_network_offset(skb);
28292832
ena_tx_ctx->meta_valid = 1;
2830-
2833+
} else if (disable_meta_caching) {
2834+
memset(ena_meta, 0, sizeof(*ena_meta));
2835+
ena_tx_ctx->meta_valid = 1;
28312836
} else {
28322837
ena_tx_ctx->meta_valid = 0;
28332838
}
@@ -3011,7 +3016,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
30113016
ena_tx_ctx.header_len = header_len;
30123017

30133018
/* set flags and meta data */
3014-
ena_tx_csum(&ena_tx_ctx, skb);
3019+
ena_tx_csum(&ena_tx_ctx, skb, tx_ring->disable_meta_caching);
30153020

30163021
rc = ena_xmit_common(dev,
30173022
tx_ring,
@@ -4260,6 +4265,11 @@ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
42604265
adapter->xdp_num_queues = 0;
42614266

42624267
adapter->rx_copybreak = ENA_DEFAULT_RX_COPYBREAK;
4268+
if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
4269+
adapter->disable_meta_caching =
4270+
!!(get_feat_ctx.llq.accel_mode.u.get.supported_flags &
4271+
BIT(ENA_ADMIN_DISABLE_META_CACHING));
4272+
42634273
adapter->wd_state = wd_state;
42644274

42654275
snprintf(adapter->name, ENA_NAME_MAX_LEN, "ena_%d", adapters_found);

drivers/net/ethernet/amazon/ena/ena_netdev.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ struct ena_ring {
298298
u8 tx_max_header_size;
299299

300300
bool first_interrupt;
301+
bool disable_meta_caching;
301302
u16 no_interrupt_event_cnt;
302303

303304
/* cpu for TPH */
@@ -399,6 +400,7 @@ struct ena_adapter {
399400

400401
bool wd_state;
401402
bool dev_up_before_reset;
403+
bool disable_meta_caching;
402404
unsigned long last_keep_alive_jiffies;
403405

404406
struct u64_stats_sync syncp;

0 commit comments

Comments
 (0)