Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c859e21a authored by Intiyaz Basha's avatar Intiyaz Basha Committed by David S. Miller
Browse files

liquidio: xmit_more support



Defer ringing the Tx doorbell if skb->xmit_more is set unless the Tx queue
is full or stopped.  To keep latency low, use a deferral limit of 8
packets.  We chose 8 because Octeon can fetch at most 8 packets in a single
PCI read, and our tests show that 8 results in low latency.

Signed-off-by: default avatarIntiyaz Basha <intiyaz.basha@cavium.com>
Signed-off-by: default avatarSatanand Burla <satananda.burla@cavium.com>
Signed-off-by: default avatarFelix Manlunas <felix.manlunas@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bc474751
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ void octeon_update_tx_completion_counters(void *buf, int reqtype,
	*bytes_compl += skb->len;
}

void octeon_report_sent_bytes_to_bql(void *buf, int reqtype)
int octeon_report_sent_bytes_to_bql(void *buf, int reqtype)
{
	struct octnet_buf_free_info *finfo;
	struct sk_buff *skb;
@@ -112,11 +112,13 @@ void octeon_report_sent_bytes_to_bql(void *buf, int reqtype)
		break;

	default:
		return;
		return 0;
	}

	txq = netdev_get_tx_queue(skb->dev, skb_get_queue_mapping(skb));
	netdev_tx_sent_queue(txq, skb->len);

	return netif_xmit_stopped(txq);
}

void liquidio_link_ctrl_cmd_completion(void *nctrl_ptr)
+12 −6
Original line number Diff line number Diff line
@@ -2594,7 +2594,8 @@ static void handle_timestamp(struct octeon_device *oct,
 */
static inline int send_nic_timestamp_pkt(struct octeon_device *oct,
					 struct octnic_data_pkt *ndata,
					 struct octnet_buf_free_info *finfo)
					 struct octnet_buf_free_info *finfo,
					 int xmit_more)
{
	int retval;
	struct octeon_soft_command *sc;
@@ -2629,7 +2630,7 @@ static inline int send_nic_timestamp_pkt(struct octeon_device *oct,
		len = (u32)((struct octeon_instr_ih2 *)
			    (&sc->cmd.cmd2.ih2))->dlengsz;

	ring_doorbell = 1;
	ring_doorbell = !xmit_more;

	retval = octeon_send_command(oct, sc->iq_no, ring_doorbell, &sc->cmd,
				     sc, len, ndata->reqtype);
@@ -2663,7 +2664,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
	union tx_info *tx_info;
	int status = 0;
	int q_idx = 0, iq_no = 0;
	int j;
	int j, xmit_more = 0;
	u64 dptr = 0;
	u32 tag = 0;

@@ -2868,17 +2869,19 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
		irh->vlan = skb_vlan_tag_get(skb) & 0xfff;
	}

	xmit_more = skb->xmit_more;

	if (unlikely(cmdsetup.s.timestamp))
		status = send_nic_timestamp_pkt(oct, &ndata, finfo);
		status = send_nic_timestamp_pkt(oct, &ndata, finfo, xmit_more);
	else
		status = octnet_send_nic_data_pkt(oct, &ndata);
		status = octnet_send_nic_data_pkt(oct, &ndata, xmit_more);
	if (status == IQ_SEND_FAILED)
		goto lio_xmit_failed;

	netif_info(lio, tx_queued, lio->netdev, "Transmit queued successfully\n");

	if (status == IQ_SEND_STOP)
		stop_q(lio->netdev, q_idx);
		stop_q(netdev, q_idx);

	netif_trans_update(netdev);

@@ -2897,6 +2900,9 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
	if (dptr)
		dma_unmap_single(&oct->pci_dev->dev, dptr,
				 ndata.datasize, DMA_TO_DEVICE);

	octeon_ring_doorbell_locked(oct, iq_no);

	tx_buffer_free(skb);
	return NETDEV_TX_OK;
}
+12 −5
Original line number Diff line number Diff line
@@ -1690,7 +1690,8 @@ static void handle_timestamp(struct octeon_device *oct, u32 status, void *buf)
 */
static int send_nic_timestamp_pkt(struct octeon_device *oct,
				  struct octnic_data_pkt *ndata,
				  struct octnet_buf_free_info *finfo)
				  struct octnet_buf_free_info *finfo,
				  int xmit_more)
{
	struct octeon_soft_command *sc;
	int ring_doorbell;
@@ -1720,7 +1721,7 @@ static int send_nic_timestamp_pkt(struct octeon_device *oct,

	len = (u32)((struct octeon_instr_ih3 *)(&sc->cmd.cmd3.ih3))->dlengsz;

	ring_doorbell = 1;
	ring_doorbell = !xmit_more;

	retval = octeon_send_command(oct, sc->iq_no, ring_doorbell, &sc->cmd,
				     sc, len, ndata->reqtype);
@@ -1752,6 +1753,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
	struct octeon_device *oct;
	int q_idx = 0, iq_no = 0;
	union tx_info *tx_info;
	int xmit_more = 0;
	struct lio *lio;
	int status = 0;
	u64 dptr = 0;
@@ -1940,10 +1942,12 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
		irh->vlan = skb_vlan_tag_get(skb) & VLAN_VID_MASK;
	}

	xmit_more = skb->xmit_more;

	if (unlikely(cmdsetup.s.timestamp))
		status = send_nic_timestamp_pkt(oct, &ndata, finfo);
		status = send_nic_timestamp_pkt(oct, &ndata, finfo, xmit_more);
	else
		status = octnet_send_nic_data_pkt(oct, &ndata);
		status = octnet_send_nic_data_pkt(oct, &ndata, xmit_more);
	if (status == IQ_SEND_FAILED)
		goto lio_xmit_failed;

@@ -1952,7 +1956,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
	if (status == IQ_SEND_STOP) {
		dev_err(&oct->pci_dev->dev, "Rcvd IQ_SEND_STOP signal; stopping IQ-%d\n",
			iq_no);
		stop_q(lio->netdev, q_idx);
		stop_q(netdev, q_idx);
	}

	netif_trans_update(netdev);
@@ -1972,6 +1976,9 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
	if (dptr)
		dma_unmap_single(&oct->pci_dev->dev, dptr,
				 ndata.datasize, DMA_TO_DEVICE);

	octeon_ring_doorbell_locked(oct, iq_no);

	tx_buffer_free(skb);
	return NETDEV_TX_OK;
}
+2 −0
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@
#define   MAX_OCTEON_LINKS	       MAX_OCTEON_NICIF
#define   MAX_OCTEON_MULTICAST_ADDR    32

#define   MAX_OCTEON_FILL_COUNT        8

/* CN6xxx IQ configuration macros */
#define   CN6XXX_MAX_INPUT_QUEUES      32
#define   CN6XXX_MAX_IQ_DESCRIPTORS    2048
+3 −0
Original line number Diff line number Diff line
@@ -343,6 +343,9 @@ int octeon_delete_instr_queue(struct octeon_device *octeon_dev, u32 iq_no);

int lio_wait_for_instr_fetch(struct octeon_device *oct);

void
octeon_ring_doorbell_locked(struct octeon_device *oct, u32 iq_no);

int
octeon_register_reqtype_free_fn(struct octeon_device *oct, int reqtype,
				void (*fn)(void *));
Loading