Skip to content

Commit 8b664cd

Browse files
julianwiedmanndavem330
authored andcommitted
s390/qeth: use IQD Multi-Write
For IQD devices with Multi-Write support, we can defer the queue-flush further and transmit multiple IO buffers with a single TX doorbell. The same-target restriction still applies. Signed-off-by: Julian Wiedmann <[email protected]> Reviewed-by: Alexandra Winter <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b7f143d commit 8b664cd

File tree

2 files changed

+53
-10
lines changed

2 files changed

+53
-10
lines changed

drivers/s390/net/qeth_core.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,8 @@ struct qeth_qdio_out_q {
532532
struct timer_list timer;
533533
struct qeth_hdr *prev_hdr;
534534
u8 bulk_start;
535+
u8 bulk_count;
536+
u8 bulk_max;
535537
};
536538

537539
#define qeth_for_each_output_queue(card, q, i) \
@@ -878,6 +880,13 @@ static inline u16 qeth_iqd_translate_txq(struct net_device *dev, u16 txq)
878880
return txq;
879881
}
880882

883+
static inline bool qeth_iqd_is_mcast_queue(struct qeth_card *card,
884+
struct qeth_qdio_out_q *queue)
885+
{
886+
return qeth_iqd_translate_txq(card->dev, queue->queue_no) ==
887+
QETH_IQD_MCAST_TXQ;
888+
}
889+
881890
static inline void qeth_scrub_qdio_buffer(struct qdio_buffer *buf,
882891
unsigned int elements)
883892
{

drivers/s390/net/qeth_core_main.c

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2634,6 +2634,18 @@ static int qeth_init_input_buffer(struct qeth_card *card,
26342634
return 0;
26352635
}
26362636

2637+
static unsigned int qeth_tx_select_bulk_max(struct qeth_card *card,
2638+
struct qeth_qdio_out_q *queue)
2639+
{
2640+
if (!IS_IQD(card) ||
2641+
qeth_iqd_is_mcast_queue(card, queue) ||
2642+
card->options.cq == QETH_CQ_ENABLED ||
2643+
qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd))
2644+
return 1;
2645+
2646+
return card->ssqd.mmwc ? card->ssqd.mmwc : 1;
2647+
}
2648+
26372649
int qeth_init_qdio_queues(struct qeth_card *card)
26382650
{
26392651
unsigned int i;
@@ -2673,6 +2685,8 @@ int qeth_init_qdio_queues(struct qeth_card *card)
26732685
queue->do_pack = 0;
26742686
queue->prev_hdr = NULL;
26752687
queue->bulk_start = 0;
2688+
queue->bulk_count = 0;
2689+
queue->bulk_max = qeth_tx_select_bulk_max(card, queue);
26762690
atomic_set(&queue->used_buffers, 0);
26772691
atomic_set(&queue->set_pci_flags_count, 0);
26782692
atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
@@ -3318,10 +3332,11 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
33183332

33193333
static void qeth_flush_queue(struct qeth_qdio_out_q *queue)
33203334
{
3321-
qeth_flush_buffers(queue, queue->bulk_start, 1);
3335+
qeth_flush_buffers(queue, queue->bulk_start, queue->bulk_count);
33223336

3323-
queue->bulk_start = QDIO_BUFNR(queue->bulk_start + 1);
3337+
queue->bulk_start = QDIO_BUFNR(queue->bulk_start + queue->bulk_count);
33243338
queue->prev_hdr = NULL;
3339+
queue->bulk_count = 0;
33253340
}
33263341

33273342
static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
@@ -3680,10 +3695,10 @@ static int qeth_add_hw_header(struct qeth_qdio_out_q *queue,
36803695
}
36813696

36823697
static bool qeth_iqd_may_bulk(struct qeth_qdio_out_q *queue,
3683-
struct qeth_qdio_out_buffer *buffer,
36843698
struct sk_buff *curr_skb,
36853699
struct qeth_hdr *curr_hdr)
36863700
{
3701+
struct qeth_qdio_out_buffer *buffer = queue->bufs[queue->bulk_start];
36873702
struct qeth_hdr *prev_hdr = queue->prev_hdr;
36883703

36893704
if (!prev_hdr)
@@ -3803,13 +3818,14 @@ static int __qeth_xmit(struct qeth_card *card, struct qeth_qdio_out_q *queue,
38033818
struct qeth_hdr *hdr, unsigned int offset,
38043819
unsigned int hd_len)
38053820
{
3806-
struct qeth_qdio_out_buffer *buffer = queue->bufs[queue->bulk_start];
38073821
unsigned int bytes = qdisc_pkt_len(skb);
3822+
struct qeth_qdio_out_buffer *buffer;
38083823
unsigned int next_element;
38093824
struct netdev_queue *txq;
38103825
bool stopped = false;
38113826
bool flush;
38123827

3828+
buffer = queue->bufs[QDIO_BUFNR(queue->bulk_start + queue->bulk_count)];
38133829
txq = netdev_get_tx_queue(card->dev, skb_get_queue_mapping(skb));
38143830

38153831
/* Just a sanity check, the wake/stop logic should ensure that we always
@@ -3818,11 +3834,23 @@ static int __qeth_xmit(struct qeth_card *card, struct qeth_qdio_out_q *queue,
38183834
if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
38193835
return -EBUSY;
38203836

3821-
if ((buffer->next_element_to_fill + elements > queue->max_elements) ||
3822-
!qeth_iqd_may_bulk(queue, buffer, skb, hdr)) {
3823-
atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
3824-
qeth_flush_queue(queue);
3825-
buffer = queue->bufs[queue->bulk_start];
3837+
flush = !qeth_iqd_may_bulk(queue, skb, hdr);
3838+
3839+
if (flush ||
3840+
(buffer->next_element_to_fill + elements > queue->max_elements)) {
3841+
if (buffer->next_element_to_fill > 0) {
3842+
atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
3843+
queue->bulk_count++;
3844+
}
3845+
3846+
if (queue->bulk_count >= queue->bulk_max)
3847+
flush = true;
3848+
3849+
if (flush)
3850+
qeth_flush_queue(queue);
3851+
3852+
buffer = queue->bufs[QDIO_BUFNR(queue->bulk_start +
3853+
queue->bulk_count)];
38263854

38273855
/* Sanity-check again: */
38283856
if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
@@ -3848,7 +3876,13 @@ static int __qeth_xmit(struct qeth_card *card, struct qeth_qdio_out_q *queue,
38483876

38493877
if (flush || next_element >= queue->max_elements) {
38503878
atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
3851-
qeth_flush_queue(queue);
3879+
queue->bulk_count++;
3880+
3881+
if (queue->bulk_count >= queue->bulk_max)
3882+
flush = true;
3883+
3884+
if (flush)
3885+
qeth_flush_queue(queue);
38523886
}
38533887

38543888
if (stopped && !qeth_out_queue_is_full(queue))

0 commit comments

Comments
 (0)