Skip to content

Commit 69651bd

Browse files
IoanaCiorneidavem330
authored andcommitted
soc: fsl: dpio: add Net DIM integration
Use the generic dynamic interrupt moderation (dim) framework to implement adaptive interrupt coalescing on Rx. With the per-packet interrupt scheme, a high interrupt rate has been noted for moderate traffic flows leading to high CPU utilization. The dpio driver exports new functions to enable/disable adaptive IRQ coalescing on a DPIO object, to query the state or to update Net DIM with a new set of bytes and frames dequeued. Signed-off-by: Ioana Ciornei <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a64b442 commit 69651bd

File tree

4 files changed

+85
-1
lines changed

4 files changed

+85
-1
lines changed

drivers/soc/fsl/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ config FSL_MC_DPIO
2424
tristate "QorIQ DPAA2 DPIO driver"
2525
depends on FSL_MC_BUS
2626
select SOC_BUS
27+
select DIMLIB
2728
help
2829
Driver for the DPAA2 DPIO object. A DPIO provides queue and
2930
buffer management facilities for software to interact with

drivers/soc/fsl/dpio/dpio-service.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/platform_device.h>
1313
#include <linux/interrupt.h>
1414
#include <linux/dma-mapping.h>
15+
#include <linux/dim.h>
1516
#include <linux/slab.h>
1617

1718
#include "dpio.h"
@@ -28,6 +29,14 @@ struct dpaa2_io {
2829
spinlock_t lock_notifications;
2930
struct list_head notifications;
3031
struct device *dev;
32+
33+
/* Net DIM */
34+
struct dim rx_dim;
35+
/* protect against concurrent Net DIM updates */
36+
spinlock_t dim_lock;
37+
u16 event_ctr;
38+
u64 bytes;
39+
u64 frames;
3140
};
3241

3342
struct dpaa2_io_store {
@@ -100,6 +109,17 @@ struct dpaa2_io *dpaa2_io_service_select(int cpu)
100109
}
101110
EXPORT_SYMBOL_GPL(dpaa2_io_service_select);
102111

112+
static void dpaa2_io_dim_work(struct work_struct *w)
113+
{
114+
struct dim *dim = container_of(w, struct dim, work);
115+
struct dim_cq_moder moder =
116+
net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
117+
struct dpaa2_io *d = container_of(dim, struct dpaa2_io, rx_dim);
118+
119+
dpaa2_io_set_irq_coalescing(d, moder.usec);
120+
dim->state = DIM_START_MEASURE;
121+
}
122+
103123
/**
104124
* dpaa2_io_create() - create a dpaa2_io object.
105125
* @desc: the dpaa2_io descriptor
@@ -147,6 +167,7 @@ struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc,
147167
INIT_LIST_HEAD(&obj->node);
148168
spin_lock_init(&obj->lock_mgmt_cmd);
149169
spin_lock_init(&obj->lock_notifications);
170+
spin_lock_init(&obj->dim_lock);
150171
INIT_LIST_HEAD(&obj->notifications);
151172

152173
/* For now only enable DQRR interrupts */
@@ -164,6 +185,12 @@ struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc,
164185

165186
obj->dev = dev;
166187

188+
memset(&obj->rx_dim, 0, sizeof(obj->rx_dim));
189+
INIT_WORK(&obj->rx_dim.work, dpaa2_io_dim_work);
190+
obj->event_ctr = 0;
191+
obj->bytes = 0;
192+
obj->frames = 0;
193+
167194
return obj;
168195
}
169196

@@ -203,6 +230,8 @@ irqreturn_t dpaa2_io_irq(struct dpaa2_io *obj)
203230
struct qbman_swp *swp;
204231
u32 status;
205232

233+
obj->event_ctr++;
234+
206235
swp = obj->swp;
207236
status = qbman_swp_interrupt_read_status(swp);
208237
if (!status)
@@ -817,3 +846,53 @@ void dpaa2_io_get_irq_coalescing(struct dpaa2_io *d, u32 *irq_holdoff)
817846
qbman_swp_get_irq_coalescing(swp, NULL, irq_holdoff);
818847
}
819848
EXPORT_SYMBOL(dpaa2_io_get_irq_coalescing);
849+
850+
/**
851+
* dpaa2_io_set_adaptive_coalescing() - Enable/disable adaptive coalescing
852+
* @d: the given DPIO object
853+
* @use_adaptive_rx_coalesce: adaptive coalescing state
854+
*/
855+
void dpaa2_io_set_adaptive_coalescing(struct dpaa2_io *d,
856+
int use_adaptive_rx_coalesce)
857+
{
858+
d->swp->use_adaptive_rx_coalesce = use_adaptive_rx_coalesce;
859+
}
860+
EXPORT_SYMBOL(dpaa2_io_set_adaptive_coalescing);
861+
862+
/**
863+
* dpaa2_io_get_adaptive_coalescing() - Query adaptive coalescing state
864+
* @d: the given DPIO object
865+
*
866+
* Return 1 when adaptive coalescing is enabled on the DPIO object and 0
867+
* otherwise.
868+
*/
869+
int dpaa2_io_get_adaptive_coalescing(struct dpaa2_io *d)
870+
{
871+
return d->swp->use_adaptive_rx_coalesce;
872+
}
873+
EXPORT_SYMBOL(dpaa2_io_get_adaptive_coalescing);
874+
875+
/**
876+
* dpaa2_io_update_net_dim() - Update Net DIM
877+
* @d: the given DPIO object
878+
* @frames: how many frames have been dequeued by the user since the last call
879+
* @bytes: how many bytes have been dequeued by the user since the last call
880+
*/
881+
void dpaa2_io_update_net_dim(struct dpaa2_io *d, __u64 frames, __u64 bytes)
882+
{
883+
struct dim_sample dim_sample = {};
884+
885+
if (!d->swp->use_adaptive_rx_coalesce)
886+
return;
887+
888+
spin_lock(&d->dim_lock);
889+
890+
d->bytes += bytes;
891+
d->frames += frames;
892+
893+
dim_update_sample(d->event_ctr, d->frames, d->bytes, &dim_sample);
894+
net_dim(&d->rx_dim, dim_sample);
895+
896+
spin_unlock(&d->dim_lock);
897+
}
898+
EXPORT_SYMBOL(dpaa2_io_update_net_dim);

drivers/soc/fsl/dpio/qbman-portal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ struct qbman_swp {
162162
/* Interrupt coalescing */
163163
u32 irq_threshold;
164164
u32 irq_holdoff;
165+
int use_adaptive_rx_coalesce;
165166
};
166167

167168
/* Function pointers */

include/soc/fsl/dpaa2-io.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,5 +134,8 @@ int dpaa2_io_query_bp_count(struct dpaa2_io *d, u16 bpid,
134134

135135
int dpaa2_io_set_irq_coalescing(struct dpaa2_io *d, u32 irq_holdoff);
136136
void dpaa2_io_get_irq_coalescing(struct dpaa2_io *d, u32 *irq_holdoff);
137-
137+
void dpaa2_io_set_adaptive_coalescing(struct dpaa2_io *d,
138+
int use_adaptive_rx_coalesce);
139+
int dpaa2_io_get_adaptive_coalescing(struct dpaa2_io *d);
140+
void dpaa2_io_update_net_dim(struct dpaa2_io *d, __u64 frames, __u64 bytes);
138141
#endif /* __FSL_DPAA2_IO_H */

0 commit comments

Comments
 (0)