Skip to content

Commit 0b87432

Browse files
author
Nelson Escobar
committed
enic: enic rq code reorg
JIRA: https://issues.redhat.com/browse/RHEL-84863 commit eaa23db Author: Satish Kharat <satishkh@cisco.com> Date: Tue Mar 4 19:56:38 2025 -0500 enic: enic rq code reorg Separates enic rx path from generic vnic api. Removes some complexity of doign enic callbacks through vnic api in rx. This is in preparation for enabling enic extended cq which applies only to enic rx path. Co-developed-by: Nelson Escobar <neescoba@cisco.com> Signed-off-by: Nelson Escobar <neescoba@cisco.com> Co-developed-by: John Daley <johndale@cisco.com> Signed-off-by: John Daley <johndale@cisco.com> Signed-off-by: Satish Kharat <satishkh@cisco.com> Link: https://patch.msgid.link/20250304-enic_cleanup_and_ext_cq-v2-2-85804263dad8@cisco.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Nelson Escobar <nescobar@redhat.com>
1 parent 82804bd commit 0b87432

File tree

4 files changed

+106
-39
lines changed

4 files changed

+106
-39
lines changed

drivers/net/ethernet/cisco/enic/enic_main.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,8 +1386,7 @@ static int enic_poll(struct napi_struct *napi, int budget)
13861386
enic_wq_service, NULL);
13871387

13881388
if (budget > 0)
1389-
rq_work_done = vnic_cq_service(&enic->cq[cq_rq],
1390-
rq_work_to_do, enic_rq_service, NULL);
1389+
rq_work_done = enic_rq_cq_service(enic, cq_rq, rq_work_to_do);
13911390

13921391
/* Accumulate intr event credits for this polling
13931392
* cycle. An intr event is the completion of a
@@ -1516,8 +1515,7 @@ static int enic_poll_msix_rq(struct napi_struct *napi, int budget)
15161515
*/
15171516

15181517
if (budget > 0)
1519-
work_done = vnic_cq_service(&enic->cq[cq],
1520-
work_to_do, enic_rq_service, NULL);
1518+
work_done = enic_rq_cq_service(enic, cq, work_to_do);
15211519

15221520
/* Return intr event credits for this polling
15231521
* cycle. An intr event is the completion of a

drivers/net/ethernet/cisco/enic/enic_rq.c

Lines changed: 88 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,26 @@ static void enic_intr_update_pkt_size(struct vnic_rx_bytes_counter *pkt_size,
2121
pkt_size->small_pkt_bytes_cnt += pkt_len;
2222
}
2323

24-
int enic_rq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, u8 type,
25-
u16 q_number, u16 completed_index, void *opaque)
24+
static void enic_rq_cq_desc_dec(struct cq_enet_rq_desc *desc, u8 *type,
25+
u8 *color, u16 *q_number, u16 *completed_index)
2626
{
27-
struct enic *enic = vnic_dev_priv(vdev);
28-
29-
vnic_rq_service(&enic->rq[q_number].vrq, cq_desc, completed_index,
30-
VNIC_RQ_RETURN_DESC, enic_rq_indicate_buf, opaque);
31-
return 0;
27+
/* type_color is the last field for all cq structs */
28+
u8 type_color = desc->type_color;
29+
30+
/* Make sure color bit is read from desc *before* other fields
31+
* are read from desc. Hardware guarantees color bit is last
32+
* bit (byte) written. Adding the rmb() prevents the compiler
33+
* and/or CPU from reordering the reads which would potentially
34+
* result in reading stale values.
35+
*/
36+
rmb();
37+
38+
*q_number = le16_to_cpu(desc->q_number_rss_type_flags) &
39+
CQ_DESC_Q_NUM_MASK;
40+
*completed_index = le16_to_cpu(desc->completed_index_flags) &
41+
CQ_DESC_COMP_NDX_MASK;
42+
*color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK;
43+
*type = type_color & CQ_DESC_TYPE_MASK;
3244
}
3345

3446
static void enic_rq_set_skb_flags(struct vnic_rq *vrq, u8 type, u32 rss_hash,
@@ -101,10 +113,9 @@ static void enic_rq_set_skb_flags(struct vnic_rq *vrq, u8 type, u32 rss_hash,
101113
}
102114
}
103115

104-
static void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc, u8 *type,
105-
u8 *color, u16 *q_number, u16 *completed_index,
106-
u8 *ingress_port, u8 *fcoe, u8 *eop, u8 *sop,
107-
u8 *rss_type, u8 *csum_not_calc, u32 *rss_hash,
116+
static void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc, u8 *ingress_port,
117+
u8 *fcoe, u8 *eop, u8 *sop, u8 *rss_type,
118+
u8 *csum_not_calc, u32 *rss_hash,
108119
u16 *bytes_written, u8 *packet_error,
109120
u8 *vlan_stripped, u16 *vlan_tci,
110121
u16 *checksum, u8 *fcoe_sof,
@@ -117,9 +128,6 @@ static void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc, u8 *type,
117128
u16 q_number_rss_type_flags;
118129
u16 bytes_written_flags;
119130

120-
cq_desc_dec((struct cq_desc *)desc, type,
121-
color, q_number, completed_index);
122-
123131
completed_index_flags = le16_to_cpu(desc->completed_index_flags);
124132
q_number_rss_type_flags =
125133
le16_to_cpu(desc->q_number_rss_type_flags);
@@ -249,37 +257,33 @@ void enic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf)
249257
buf->os_buf = NULL;
250258
}
251259

252-
void enic_rq_indicate_buf(struct vnic_rq *rq, struct cq_desc *cq_desc,
253-
struct vnic_rq_buf *buf, int skipped, void *opaque)
260+
static void enic_rq_indicate_buf(struct enic *enic, struct vnic_rq *rq,
261+
struct vnic_rq_buf *buf,
262+
struct cq_enet_rq_desc *cq_desc, u8 type,
263+
u16 q_number, u16 completed_index)
254264
{
255-
struct enic *enic = vnic_dev_priv(rq->vdev);
256265
struct sk_buff *skb;
257266
struct vnic_cq *cq = &enic->cq[enic_cq_rq(enic, rq->index)];
258267
struct enic_rq_stats *rqstats = &enic->rq[rq->index].stats;
259268
struct napi_struct *napi;
260269

261-
u8 type, color, eop, sop, ingress_port, vlan_stripped;
270+
u8 eop, sop, ingress_port, vlan_stripped;
262271
u8 fcoe, fcoe_sof, fcoe_fc_crc_ok, fcoe_enc_error, fcoe_eof;
263272
u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok;
264273
u8 ipv6, ipv4, ipv4_fragment, fcs_ok, rss_type, csum_not_calc;
265274
u8 packet_error;
266-
u16 q_number, completed_index, bytes_written, vlan_tci, checksum;
275+
u16 bytes_written, vlan_tci, checksum;
267276
u32 rss_hash;
268277

269278
rqstats->packets++;
270-
if (skipped) {
271-
rqstats->desc_skip++;
272-
return;
273-
}
274279

275-
cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc, &type, &color,
276-
&q_number, &completed_index, &ingress_port, &fcoe,
277-
&eop, &sop, &rss_type, &csum_not_calc, &rss_hash,
278-
&bytes_written, &packet_error, &vlan_stripped,
279-
&vlan_tci, &checksum, &fcoe_sof, &fcoe_fc_crc_ok,
280-
&fcoe_enc_error, &fcoe_eof, &tcp_udp_csum_ok, &udp,
281-
&tcp, &ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment,
282-
&fcs_ok);
280+
cq_enet_rq_desc_dec(cq_desc, &ingress_port,
281+
&fcoe, &eop, &sop, &rss_type, &csum_not_calc,
282+
&rss_hash, &bytes_written, &packet_error,
283+
&vlan_stripped, &vlan_tci, &checksum, &fcoe_sof,
284+
&fcoe_fc_crc_ok, &fcoe_enc_error, &fcoe_eof,
285+
&tcp_udp_csum_ok, &udp, &tcp, &ipv4_csum_ok, &ipv6,
286+
&ipv4, &ipv4_fragment, &fcs_ok);
283287

284288
if (enic_rq_pkt_error(rq, packet_error, fcs_ok, bytes_written))
285289
return;
@@ -324,3 +328,56 @@ void enic_rq_indicate_buf(struct vnic_rq *rq, struct cq_desc *cq_desc,
324328
rqstats->pkt_truncated++;
325329
}
326330
}
331+
332+
static void enic_rq_service(struct enic *enic, struct cq_enet_rq_desc *cq_desc,
333+
u8 type, u16 q_number, u16 completed_index)
334+
{
335+
struct enic_rq_stats *rqstats = &enic->rq[q_number].stats;
336+
struct vnic_rq *vrq = &enic->rq[q_number].vrq;
337+
struct vnic_rq_buf *vrq_buf = vrq->to_clean;
338+
int skipped;
339+
340+
while (1) {
341+
skipped = (vrq_buf->index != completed_index);
342+
if (!skipped)
343+
enic_rq_indicate_buf(enic, vrq, vrq_buf, cq_desc, type,
344+
q_number, completed_index);
345+
else
346+
rqstats->desc_skip++;
347+
348+
vrq->ring.desc_avail++;
349+
vrq->to_clean = vrq_buf->next;
350+
vrq_buf = vrq_buf->next;
351+
if (!skipped)
352+
break;
353+
}
354+
}
355+
356+
unsigned int enic_rq_cq_service(struct enic *enic, unsigned int cq_index,
357+
unsigned int work_to_do)
358+
{
359+
struct vnic_cq *cq = &enic->cq[cq_index];
360+
struct cq_enet_rq_desc *cq_desc;
361+
u16 q_number, completed_index;
362+
unsigned int work_done = 0;
363+
u8 type, color;
364+
365+
cq_desc = (struct cq_enet_rq_desc *)vnic_cq_to_clean(cq);
366+
367+
enic_rq_cq_desc_dec(cq_desc, &type, &color, &q_number,
368+
&completed_index);
369+
370+
while (color != cq->last_color) {
371+
enic_rq_service(enic, cq_desc, type, q_number, completed_index);
372+
vnic_cq_inc_to_clean(cq);
373+
374+
if (++work_done >= work_to_do)
375+
break;
376+
377+
cq_desc = (struct cq_enet_rq_desc *)vnic_cq_to_clean(cq);
378+
enic_rq_cq_desc_dec(cq_desc, &type, &color, &q_number,
379+
&completed_index);
380+
}
381+
382+
return work_done;
383+
}

drivers/net/ethernet/cisco/enic/enic_rq.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
* Copyright 2024 Cisco Systems, Inc. All rights reserved.
33
*/
44

5-
int enic_rq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, u8 type,
6-
u16 q_number, u16 completed_index, void *opaque);
7-
void enic_rq_indicate_buf(struct vnic_rq *rq, struct cq_desc *cq_desc,
8-
struct vnic_rq_buf *buf, int skipped, void *opaque);
5+
unsigned int enic_rq_cq_service(struct enic *enic, unsigned int cq_index,
6+
unsigned int work_to_do);
97
int enic_rq_alloc_buf(struct vnic_rq *rq);
108
void enic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf);

drivers/net/ethernet/cisco/enic/vnic_cq.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,20 @@ static inline unsigned int vnic_cq_service(struct vnic_cq *cq,
9797
return work_done;
9898
}
9999

100+
static inline void *vnic_cq_to_clean(struct vnic_cq *cq)
101+
{
102+
return ((u8 *)cq->ring.descs + cq->ring.desc_size * cq->to_clean);
103+
}
104+
105+
static inline void vnic_cq_inc_to_clean(struct vnic_cq *cq)
106+
{
107+
cq->to_clean++;
108+
if (cq->to_clean == cq->ring.desc_count) {
109+
cq->to_clean = 0;
110+
cq->last_color = cq->last_color ? 0 : 1;
111+
}
112+
}
113+
100114
void vnic_cq_free(struct vnic_cq *cq);
101115
int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index,
102116
unsigned int desc_count, unsigned int desc_size);

0 commit comments

Comments
 (0)