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

Commit 82bcee42 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'liquidio-Removed-droq-lock-from-Rx-path'



Intiyaz Basha says:

====================
liquidio: Removed droq lock from Rx path

Series of patches for removing droq lock from Rx Path.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents aad06d11 8bf6edcd
Loading
Loading
Loading
Loading
+47 −30
Original line number Diff line number Diff line
@@ -425,56 +425,73 @@ void octeon_pf_changed_vf_macaddr(struct octeon_device *oct, u8 *mac)
	 */
}

void octeon_schedule_rxq_oom_work(struct octeon_device *oct,
				  struct octeon_droq *droq)
{
	struct net_device *netdev = oct->props[0].netdev;
	struct lio *lio = GET_LIO(netdev);
	struct cavium_wq *wq = &lio->rxq_status_wq[droq->q_no];

	queue_delayed_work(wq->wq, &wq->wk.work,
			   msecs_to_jiffies(LIO_OOM_POLL_INTERVAL_MS));
}

static void octnet_poll_check_rxq_oom_status(struct work_struct *work)
{
	struct cavium_wk *wk = (struct cavium_wk *)work;
	struct lio *lio = (struct lio *)wk->ctxptr;
	struct octeon_device *oct = lio->oct_dev;
	struct octeon_droq *droq;
	int q, q_no = 0;
	int q_no = wk->ctxul;
	struct octeon_droq *droq = oct->droq[q_no];

	if (ifstate_check(lio, LIO_IFSTATE_RUNNING)) {
		for (q = 0; q < lio->linfo.num_rxpciq; q++) {
			q_no = lio->linfo.rxpciq[q].s.q_no;
			droq = oct->droq[q_no];
			if (!droq)
				continue;
			octeon_droq_check_oom(droq);
		}
	}
	queue_delayed_work(lio->rxq_status_wq.wq,
			   &lio->rxq_status_wq.wk.work,
			   msecs_to_jiffies(LIO_OOM_POLL_INTERVAL_MS));
	if (!ifstate_check(lio, LIO_IFSTATE_RUNNING) || !droq)
		return;

	if (octeon_retry_droq_refill(droq))
		octeon_schedule_rxq_oom_work(oct, droq);
}

int setup_rx_oom_poll_fn(struct net_device *netdev)
{
	struct lio *lio = GET_LIO(netdev);
	struct octeon_device *oct = lio->oct_dev;
	struct cavium_wq *wq;
	int q, q_no;

	lio->rxq_status_wq.wq = alloc_workqueue("rxq-oom-status",
	for (q = 0; q < oct->num_oqs; q++) {
		q_no = lio->linfo.rxpciq[q].s.q_no;
		wq = &lio->rxq_status_wq[q_no];
		wq->wq = alloc_workqueue("rxq-oom-status",
					 WQ_MEM_RECLAIM, 0);
	if (!lio->rxq_status_wq.wq) {
		if (!wq->wq) {
			dev_err(&oct->pci_dev->dev, "unable to create cavium rxq oom status wq\n");
			return -ENOMEM;
		}
	INIT_DELAYED_WORK(&lio->rxq_status_wq.wk.work,

		INIT_DELAYED_WORK(&wq->wk.work,
				  octnet_poll_check_rxq_oom_status);
	lio->rxq_status_wq.wk.ctxptr = lio;
	queue_delayed_work(lio->rxq_status_wq.wq,
			   &lio->rxq_status_wq.wk.work,
			   msecs_to_jiffies(LIO_OOM_POLL_INTERVAL_MS));
		wq->wk.ctxptr = lio;
		wq->wk.ctxul = q_no;
	}

	return 0;
}

void cleanup_rx_oom_poll_fn(struct net_device *netdev)
{
	struct lio *lio = GET_LIO(netdev);
	struct octeon_device *oct = lio->oct_dev;
	struct cavium_wq *wq;
	int q_no;

	if (lio->rxq_status_wq.wq) {
		cancel_delayed_work_sync(&lio->rxq_status_wq.wk.work);
		flush_workqueue(lio->rxq_status_wq.wq);
		destroy_workqueue(lio->rxq_status_wq.wq);
	for (q_no = 0; q_no < oct->num_oqs; q_no++) {
		wq = &lio->rxq_status_wq[q_no];
		if (wq->wq) {
			cancel_delayed_work_sync(&wq->wk.work);
			flush_workqueue(wq->wq);
			destroy_workqueue(wq->wq);
			wq->wq = NULL;
		}
	}
}

+7 −0
Original line number Diff line number Diff line
@@ -1115,6 +1115,8 @@ static int lio_reset_queues(struct net_device *netdev, uint32_t num_qs)
	 * steps like updating sriov_info for the octeon device need to be done.
	 */
	if (queue_count_update) {
		cleanup_rx_oom_poll_fn(netdev);

		lio_delete_glists(lio);

		/* Delete mbox for PF which is SRIOV disabled because sriov_info
@@ -1214,6 +1216,11 @@ static int lio_reset_queues(struct net_device *netdev, uint32_t num_qs)
			return -1;
		}

		if (setup_rx_oom_poll_fn(netdev)) {
			dev_err(&oct->pci_dev->dev, "lio_setup_rx_oom_poll_fn failed\n");
			return 1;
		}

		/* Send firmware the information about new number of queues
		 * if the interface is a VF or a PF that is SRIOV enabled.
		 */
+13 −1
Original line number Diff line number Diff line
@@ -1239,8 +1239,10 @@ static void send_rx_ctrl_cmd(struct lio *lio, int start_stop)
static void liquidio_destroy_nic_device(struct octeon_device *oct, int ifidx)
{
	struct net_device *netdev = oct->props[ifidx].netdev;
	struct lio *lio;
	struct octeon_device_priv *oct_priv =
		(struct octeon_device_priv *)oct->priv;
	struct napi_struct *napi, *n;
	struct lio *lio;

	if (!netdev) {
		dev_err(&oct->pci_dev->dev, "%s No netdevice ptr for index %d\n",
@@ -1269,6 +1271,8 @@ static void liquidio_destroy_nic_device(struct octeon_device *oct, int ifidx)
	list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list)
		netif_napi_del(napi);

	tasklet_enable(&oct_priv->droq_tasklet);

	if (atomic_read(&lio->ifstate) & LIO_IFSTATE_REGISTERED)
		unregister_netdev(netdev);

@@ -1805,9 +1809,13 @@ static int liquidio_open(struct net_device *netdev)
{
	struct lio *lio = GET_LIO(netdev);
	struct octeon_device *oct = lio->oct_dev;
	struct octeon_device_priv *oct_priv =
		(struct octeon_device_priv *)oct->priv;
	struct napi_struct *napi, *n;

	if (oct->props[lio->ifidx].napi_enabled == 0) {
		tasklet_disable(&oct_priv->droq_tasklet);

		list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list)
			napi_enable(napi);

@@ -1861,6 +1869,8 @@ static int liquidio_stop(struct net_device *netdev)
{
	struct lio *lio = GET_LIO(netdev);
	struct octeon_device *oct = lio->oct_dev;
	struct octeon_device_priv *oct_priv =
		(struct octeon_device_priv *)oct->priv;
	struct napi_struct *napi, *n;

	ifstate_reset(lio, LIO_IFSTATE_RUNNING);
@@ -1907,6 +1917,8 @@ static int liquidio_stop(struct net_device *netdev)

		if (OCTEON_CN23XX_PF(oct))
			oct->droq[0]->ops.poll_mode = 0;

		tasklet_enable(&oct_priv->droq_tasklet);
	}

	dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name);
+16 −0
Original line number Diff line number Diff line
@@ -444,6 +444,8 @@ static void octeon_pci_flr(struct octeon_device *oct)
 */
static void octeon_destroy_resources(struct octeon_device *oct)
{
	struct octeon_device_priv *oct_priv =
		(struct octeon_device_priv *)oct->priv;
	struct msix_entry *msix_entries;
	int i;

@@ -587,6 +589,8 @@ static void octeon_destroy_resources(struct octeon_device *oct)
		/* Nothing to be done here either */
		break;
	}

	tasklet_kill(&oct_priv->droq_tasklet);
}

/**
@@ -652,6 +656,8 @@ static void send_rx_ctrl_cmd(struct lio *lio, int start_stop)
static void liquidio_destroy_nic_device(struct octeon_device *oct, int ifidx)
{
	struct net_device *netdev = oct->props[ifidx].netdev;
	struct octeon_device_priv *oct_priv =
		(struct octeon_device_priv *)oct->priv;
	struct napi_struct *napi, *n;
	struct lio *lio;

@@ -681,6 +687,8 @@ static void liquidio_destroy_nic_device(struct octeon_device *oct, int ifidx)
	list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list)
		netif_napi_del(napi);

	tasklet_enable(&oct_priv->droq_tasklet);

	if (atomic_read(&lio->ifstate) & LIO_IFSTATE_REGISTERED)
		unregister_netdev(netdev);

@@ -898,9 +906,13 @@ static int liquidio_open(struct net_device *netdev)
{
	struct lio *lio = GET_LIO(netdev);
	struct octeon_device *oct = lio->oct_dev;
	struct octeon_device_priv *oct_priv =
		(struct octeon_device_priv *)oct->priv;
	struct napi_struct *napi, *n;

	if (!oct->props[lio->ifidx].napi_enabled) {
		tasklet_disable(&oct_priv->droq_tasklet);

		list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list)
			napi_enable(napi);

@@ -938,6 +950,8 @@ static int liquidio_stop(struct net_device *netdev)
{
	struct lio *lio = GET_LIO(netdev);
	struct octeon_device *oct = lio->oct_dev;
	struct octeon_device_priv *oct_priv =
		(struct octeon_device_priv *)oct->priv;
	struct napi_struct *napi, *n;

	/* tell Octeon to stop forwarding packets to host */
@@ -967,6 +981,8 @@ static int liquidio_stop(struct net_device *netdev)
		oct->props[lio->ifidx].napi_enabled = 0;

		oct->droq[0]->ops.poll_mode = 0;

		tasklet_enable(&oct_priv->droq_tasklet);
	}

	cancel_delayed_work_sync(&lio->stats_wk.work);
+0 −4
Original line number Diff line number Diff line
@@ -1440,12 +1440,8 @@ void lio_enable_irq(struct octeon_droq *droq, struct octeon_instr_queue *iq)
	/* the whole thing needs to be atomic, ideally */
	if (droq) {
		pkts_pend = (u32)atomic_read(&droq->pkts_pending);
		spin_lock_bh(&droq->lock);
		writel(droq->pkt_count - pkts_pend, droq->pkts_sent_reg);
		droq->pkt_count = pkts_pend;
		/* this write needs to be flushed before we release the lock */
		mmiowb();
		spin_unlock_bh(&droq->lock);
		oct = droq->oct_dev;
	}
	if (iq) {
Loading