@@ -762,12 +762,12 @@ dp_packet_batch_size(const struct dp_packet_batch *batch)
return batch->count;
}
-/* Clear 'batch' for refill. Use dp_packet_batch_refill() to add
+/* Clear 'batch' from 'offset' for refill. Use dp_packet_batch_refill() to add
* packets back into the 'batch'. */
static inline void
-dp_packet_batch_refill_init(struct dp_packet_batch *batch)
+dp_packet_batch_refill_prepare(struct dp_packet_batch *batch, size_t offset)
{
- batch->count = 0;
+ batch->count = offset;
};
static inline void
@@ -801,6 +801,10 @@ dp_packet_batch_is_full(const struct dp_packet_batch *batch)
for (size_t IDX = 0; IDX < dp_packet_batch_size(BATCH); IDX++) \
if (PACKET = BATCH->packets[IDX], true)
+#define DP_PACKET_BATCH_FOR_EACH_WITH_SIZE(IDX, SIZE, PACKET, BATCH) \
+ for (size_t IDX = 0; IDX < SIZE; IDX++) \
+ if (PACKET = BATCH->packets[IDX], true)
+
/* Use this macro for cases where some packets in the 'BATCH' may be
* dropped after going through each packet in the 'BATCH'.
*
@@ -813,7 +817,7 @@ dp_packet_batch_is_full(const struct dp_packet_batch *batch)
* the 'const' modifier since it should not be modified by
* the iterator. */
#define DP_PACKET_BATCH_REFILL_FOR_EACH(IDX, SIZE, PACKET, BATCH) \
- for (dp_packet_batch_refill_init(BATCH), IDX=0; IDX < SIZE; IDX++) \
+ for (dp_packet_batch_refill_prepare(BATCH, 0), IDX=0; IDX < SIZE; IDX++) \
if (PACKET = BATCH->packets[IDX], true)
static inline void
@@ -838,15 +838,22 @@ netdev_send_prepare_batch(const struct netdev *netdev,
struct dp_packet_batch *batch)
{
struct dp_packet *packet;
- size_t i, size = dp_packet_batch_size(batch);
+ size_t batch_cnt = dp_packet_batch_size(batch);;
+ bool refill = false;
- DP_PACKET_BATCH_REFILL_FOR_EACH (i, size, packet, batch) {
+ DP_PACKET_BATCH_FOR_EACH_WITH_SIZE (i, batch_cnt, packet, batch) {
char *errormsg = NULL;
if (netdev_send_prepare_packet(netdev->ol_flags, packet, &errormsg)) {
- dp_packet_batch_refill(batch, packet, i);
+ if ( OVS_UNLIKELY(refill) ) {
+ dp_packet_batch_refill(batch, packet, i);
+ }
} else {
dp_packet_delete(packet);
+ if( !refill ) {
+ dp_packet_batch_refill_prepare(batch, i);
+ refill = true;
+ }
COVERAGE_INC(netdev_send_prepare_drops);
VLOG_WARN_RL(&rl, "%s: Packet dropped: %s",
netdev_get_name(netdev), errormsg);