View | Details | Raw Unified | Return to bug 262571
Collapse All | Expand All

(-)b/sys/net/if_epair.c (-8 / +18 lines)
Lines 98-108 static unsigned int next_index = 0; Link Here
98
#define	EPAIR_LOCK()			mtx_lock(&epair_n_index_mtx)
98
#define	EPAIR_LOCK()			mtx_lock(&epair_n_index_mtx)
99
#define	EPAIR_UNLOCK()			mtx_unlock(&epair_n_index_mtx)
99
#define	EPAIR_UNLOCK()			mtx_unlock(&epair_n_index_mtx)
100
100
101
#define BIT_QUEUE_TASK		0
102
#define BIT_MBUF_QUEUED		1
103
101
struct epair_softc;
104
struct epair_softc;
102
struct epair_queue {
105
struct epair_queue {
103
	int			 id;
106
	int			 id;
104
	struct buf_ring		*rxring[2];
107
	struct buf_ring		*rxring[2];
105
	volatile int		 ridx;		/* 0 || 1 */
108
	volatile int		 ridx;		/* 0 || 1 */
109
	volatile int		 state;		/* queue state */
106
	struct task		 tx_task;
110
	struct task		 tx_task;
107
	struct epair_softc	*sc;
111
	struct epair_softc	*sc;
108
};
112
};
Lines 171-177 epair_tx_start_deferred(void *arg, int pending) Link Here
171
	} while (!atomic_fcmpset_int(&q->ridx, &ridx, nidx));
175
	} while (!atomic_fcmpset_int(&q->ridx, &ridx, nidx));
172
	epair_if_input(sc, q, ridx);
176
	epair_if_input(sc, q, ridx);
173
177
174
	if (! buf_ring_empty(q->rxring[nidx]))
178
	atomic_clear_int(&q->state, (1 << BIT_QUEUE_TASK));
179
	if (atomic_testandclear_int(&q->state, BIT_MBUF_QUEUED))
175
		taskqueue_enqueue(epair_tasks.tq[q->id], &q->tx_task);
180
		taskqueue_enqueue(epair_tasks.tq[q->id], &q->tx_task);
176
181
177
	if_rele(sc->ifp);
182
	if_rele(sc->ifp);
Lines 186-192 epair_menq(struct mbuf *m, struct epair_softc *osc) Link Here
186
	short mflags;
191
	short mflags;
187
	struct epair_queue *q = NULL;
192
	struct epair_queue *q = NULL;
188
	uint32_t bucket;
193
	uint32_t bucket;
189
	bool was_empty;
190
#ifdef RSS
194
#ifdef RSS
191
	struct ether_header *eh;
195
	struct ether_header *eh;
192
#endif
196
#endif
Lines 234-241 epair_menq(struct mbuf *m, struct epair_softc *osc) Link Here
234
#endif
238
#endif
235
	q = &osc->queues[bucket];
239
	q = &osc->queues[bucket];
236
240
241
	atomic_set_int(&q->state, (1 << BIT_MBUF_QUEUED));
237
	ridx = atomic_load_int(&q->ridx);
242
	ridx = atomic_load_int(&q->ridx);
238
	was_empty = buf_ring_empty(q->rxring[ridx]);
239
	ret = buf_ring_enqueue(q->rxring[ridx], m);
243
	ret = buf_ring_enqueue(q->rxring[ridx], m);
240
	if (ret != 0) {
244
	if (ret != 0) {
241
		/* Ring is full. */
245
		/* Ring is full. */
Lines 256-265 epair_menq(struct mbuf *m, struct epair_softc *osc) Link Here
256
	/* Someone else received the packet. */
260
	/* Someone else received the packet. */
257
	if_inc_counter(oifp, IFCOUNTER_IPACKETS, 1);
261
	if_inc_counter(oifp, IFCOUNTER_IPACKETS, 1);
258
262
259
done:
263
	if (!atomic_testandset_int(&q->state, BIT_QUEUE_TASK)) {
260
	if (was_empty)
261
		taskqueue_enqueue(epair_tasks.tq[bucket], &q->tx_task);
264
		taskqueue_enqueue(epair_tasks.tq[bucket], &q->tx_task);
265
	}
262
266
267
done:
263
	return (0);
268
	return (0);
264
}
269
}
265
270
Lines 304-312 epair_transmit(struct ifnet *ifp, struct mbuf *m) Link Here
304
{
309
{
305
	struct epair_softc *sc;
310
	struct epair_softc *sc;
306
	struct ifnet *oifp;
311
	struct ifnet *oifp;
307
	int error, len;
312
	int error;
313
#ifdef ALTQ
314
	int len;
308
	short mflags;
315
	short mflags;
309
316
#endif
310
	if (m == NULL)
317
	if (m == NULL)
311
		return (0);
318
		return (0);
312
	M_ASSERTPKTHDR(m);
319
	M_ASSERTPKTHDR(m);
Lines 342-351 epair_transmit(struct ifnet *ifp, struct mbuf *m) Link Here
342
		m_freem(m);
349
		m_freem(m);
343
		return (0);
350
		return (0);
344
	}
351
	}
352
353
#ifdef ALTQ
345
	len = m->m_pkthdr.len;
354
	len = m->m_pkthdr.len;
346
	mflags = m->m_flags;
355
	mflags = m->m_flags;
347
356
348
#ifdef ALTQ
349
	/* Support ALTQ via the classic if_start() path. */
357
	/* Support ALTQ via the classic if_start() path. */
350
	IF_LOCK(&ifp->if_snd);
358
	IF_LOCK(&ifp->if_snd);
351
	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
359
	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
Lines 538-543 epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) Link Here
538
		q->rxring[0] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL);
546
		q->rxring[0] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL);
539
		q->rxring[1] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL);
547
		q->rxring[1] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL);
540
		q->ridx = 0;
548
		q->ridx = 0;
549
		q->state = 0;
541
		q->sc = sca;
550
		q->sc = sca;
542
		NET_TASK_INIT(&q->tx_task, 0, epair_tx_start_deferred, q);
551
		NET_TASK_INIT(&q->tx_task, 0, epair_tx_start_deferred, q);
543
	}
552
	}
Lines 560-565 epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) Link Here
560
		q->rxring[0] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL);
569
		q->rxring[0] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL);
561
		q->rxring[1] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL);
570
		q->rxring[1] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL);
562
		q->ridx = 0;
571
		q->ridx = 0;
572
		q->state = 0;
563
		q->sc = scb;
573
		q->sc = scb;
564
		NET_TASK_INIT(&q->tx_task, 0, epair_tx_start_deferred, q);
574
		NET_TASK_INIT(&q->tx_task, 0, epair_tx_start_deferred, q);
565
	}
575
	}

Return to bug 262571