Commit a90d5604 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'introduce-queue-and-napi-support-in-netdev-genl-was-introduce-napi-queues-support'

Amritha Nambiar says:

====================
Introduce queue and NAPI support in netdev-genl (Was: Introduce NAPI queues support)

Add the capability to export the following via netdev-genl interface:
- queue information supported by the device
- NAPI information supported by the device

Introduce support for associating queue and NAPI instance.
Extend the netdev_genl generic netlink family for netdev
with queue and NAPI data.

The queue parameters exposed are:
- queue index
- queue type
- ifindex
- NAPI id associated with the queue

Additional rx and tx queue parameters can be exposed in follow up
patches by stashing them in netdev queue structures. XDP queue type
can also be supported in future.

The NAPI fields exposed are:
- NAPI id
- NAPI device ifindex
- Interrupt number associated with the NAPI instance
- PID for the NAPI thread

This series only supports 'get' ability for retrieving
certain queue and NAPI attributes. The 'set' ability for
configuring queue and associated NAPI instance via netdev-genl
will be submitted as a separate patch series.

Previous discussion at:
https://lore.kernel.org/netdev/c8476530638a5f4381d64db0e024ed49c2db3b02.camel@gmail.com/T/#m00999652a8b4731fbdb7bf698d2e3666c65a60e7

$ ./cli.py --spec netdev.yaml --do queue-get  --json='{"ifindex": 12, "id": 0, "type": 0}'
{'id': 0, 'ifindex': 12, 'napi-id': 593, 'type': 'rx'}

$ ./cli.py --spec netdev.yaml  --do queue-get --json='{"ifindex": 12, "id": 0, "type": 1}'
{'id': 0, 'ifindex': 12, 'napi-id': 593, 'type': 'tx'}

$ ./cli.py --spec netdev.yaml  --dump queue-get --json='{"ifindex": 12}'
[{'id': 0, 'ifindex': 12, 'napi-id': 593, 'type': 'rx'},
 {'id': 1, 'ifindex': 12, 'napi-id': 594, 'type': 'rx'},
 {'id': 2, 'ifindex': 12, 'napi-id': 595, 'type': 'rx'},
 {'id': 3, 'ifindex': 12, 'napi-id': 596, 'type': 'rx'},
 {'id': 0, 'ifindex': 12, 'napi-id': 593, 'type': 'tx'},
 {'id': 1, 'ifindex': 12, 'napi-id': 594, 'type': 'tx'},
 {'id': 2, 'ifindex': 12, 'napi-id': 595, 'type': 'tx'},
 {'id': 3, 'ifindex': 12, 'napi-id': 596, 'type': 'tx'}]

$ ./cli.py --spec netdev.yaml --do napi-get --json='{"id": 593}'
{'id': 593, 'ifindex': 12, 'irq': 291, 'pid': 3727}

$ ./cli.py --spec netdev.yaml --dump napi-get --json='{"ifindex": 12}'
[{'id': 596, 'ifindex': 12, 'irq': 294, 'pid': 3724},
 {'id': 595, 'ifindex': 12, 'irq': 293, 'pid': 3725},
 {'id': 594, 'ifindex': 12, 'irq': 292, 'pid': 3726},
 {'id': 593, 'ifindex': 12, 'irq': 291, 'pid': 3727}]
====================

Link: https://lore.kernel.org/r/170147307026.5260.9300080745237900261.stgit@anambiarhost.jf.intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 3706f141 e3b57ffd
Loading
Loading
Loading
Loading
+94 −0
Original line number Diff line number Diff line
@@ -66,6 +66,10 @@ definitions:
        name: tx-checksum
        doc:
          L3 checksum HW offload is supported by the driver.
  -
    name: queue-type
    type: enum
    entries: [ rx, tx ]

attribute-sets:
  -
@@ -209,6 +213,54 @@ attribute-sets:
        name: recycle-released-refcnt
        type: uint

  -
    name: napi
    attributes:
      -
        name: ifindex
        doc: ifindex of the netdevice to which NAPI instance belongs.
        type: u32
        checks:
          min: 1
      -
        name: id
        doc: ID of the NAPI instance.
        type: u32
      -
        name: irq
        doc: The associated interrupt vector number for the napi
        type: u32
      -
        name: pid
        doc: PID of the napi thread, if NAPI is configured to operate in
             threaded mode. If NAPI is not in threaded mode (i.e. uses normal
             softirq context), the attribute will be absent.
        type: u32
  -
    name: queue
    attributes:
      -
        name: id
        doc: Queue index; most queue types are indexed like a C array, with
             indexes starting at 0 and ending at queue count - 1. Queue indexes
             are scoped to an interface and queue type.
        type: u32
      -
        name: ifindex
        doc: ifindex of the netdevice to which the queue belongs.
        type: u32
        checks:
          min: 1
      -
        name: type
        doc: Queue type as rx, tx. Each queue type defines a separate ID space.
        type: u32
        enum: queue-type
      -
        name: napi-id
        doc: ID of the NAPI instance which services this queue.
        type: u32

operations:
  list:
    -
@@ -307,6 +359,48 @@ operations:
      dump:
        reply: *pp-stats-reply
      config-cond: page-pool-stats
    -
      name: queue-get
      doc: Get queue information from the kernel.
           Only configured queues will be reported (as opposed to all available
           hardware queues).
      attribute-set: queue
      do:
        request:
          attributes:
            - ifindex
            - type
            - id
        reply: &queue-get-op
          attributes:
            - id
            - type
            - napi-id
            - ifindex
      dump:
        request:
          attributes:
            - ifindex
        reply: *queue-get-op
    -
      name: napi-get
      doc: Get information about NAPI instances configured on the system.
      attribute-set: napi
      do:
        request:
          attributes:
            - id
        reply: &napi-get-op
          attributes:
            - id
            - ifindex
            - irq
            - pid
      dump:
        request:
          attributes:
            - ifindex
        reply: *napi-get-op

mcast-groups:
  list:
+14 −0
Original line number Diff line number Diff line
@@ -4008,6 +4008,9 @@ static int bnxt_init_one_rx_ring(struct bnxt *bp, int ring_nr)
	ring = &rxr->rx_ring_struct;
	bnxt_init_rxbd_pages(ring, type);

	netif_queue_set_napi(bp->dev, ring_nr, NETDEV_QUEUE_TYPE_RX,
			     &rxr->bnapi->napi);

	if (BNXT_RX_PAGE_MODE(bp) && bp->xdp_prog) {
		bpf_prog_add(bp->xdp_prog, 1);
		rxr->xdp_prog = bp->xdp_prog;
@@ -4084,6 +4087,11 @@ static int bnxt_init_tx_rings(struct bnxt *bp)
		struct bnxt_ring_struct *ring = &txr->tx_ring_struct;

		ring->fw_ring_id = INVALID_HW_RING_ID;

		if (i >= bp->tx_nr_rings_xdp)
			netif_queue_set_napi(bp->dev, i - bp->tx_nr_rings_xdp,
					     NETDEV_QUEUE_TYPE_TX,
					     &txr->bnapi->napi);
	}

	return 0;
@@ -9930,6 +9938,7 @@ static int bnxt_request_irq(struct bnxt *bp)
		if (rc)
			break;

		netif_napi_set_irq(&bp->bnapi[i]->napi, irq->vector);
		irq->requested = 1;

		if (zalloc_cpumask_var(&irq->cpu_mask, GFP_KERNEL)) {
@@ -9957,6 +9966,11 @@ static void bnxt_del_napi(struct bnxt *bp)
	if (!bp->bnapi)
		return;

	for (i = 0; i < bp->rx_nr_rings; i++)
		netif_queue_set_napi(bp->dev, i, NETDEV_QUEUE_TYPE_RX, NULL);
	for (i = 0; i < bp->tx_nr_rings - bp->tx_nr_rings_xdp; i++)
		netif_queue_set_napi(bp->dev, i, NETDEV_QUEUE_TYPE_TX, NULL);

	for (i = 0; i < bp->cp_nr_rings; i++) {
		struct bnxt_napi *bnapi = bp->bnapi[i];

+10 −2
Original line number Diff line number Diff line
@@ -189,10 +189,18 @@ static void ice_free_q_vector(struct ice_vsi *vsi, int v_idx)
	}
	q_vector = vsi->q_vectors[v_idx];

	ice_for_each_tx_ring(tx_ring, q_vector->tx)
	ice_for_each_tx_ring(tx_ring, q_vector->tx) {
		if (vsi->netdev)
			netif_queue_set_napi(vsi->netdev, tx_ring->q_index,
					     NETDEV_QUEUE_TYPE_TX, NULL);
		tx_ring->q_vector = NULL;
	ice_for_each_rx_ring(rx_ring, q_vector->rx)
	}
	ice_for_each_rx_ring(rx_ring, q_vector->rx) {
		if (vsi->netdev)
			netif_queue_set_napi(vsi->netdev, rx_ring->q_index,
					     NETDEV_QUEUE_TYPE_RX, NULL);
		rx_ring->q_vector = NULL;
	}

	/* only VSI with an associated netdev is set up with NAPI */
	if (vsi->netdev)
+69 −0
Original line number Diff line number Diff line
@@ -2452,6 +2452,10 @@ ice_vsi_cfg_def(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params)
			goto unroll_vector_base;

		ice_vsi_map_rings_to_vectors(vsi);

		/* Associate q_vector rings to napi */
		ice_vsi_set_napi_queues(vsi, true);

		vsi->stat_offsets_loaded = false;

		if (ice_is_xdp_ena_vsi(vsi)) {
@@ -2931,6 +2935,71 @@ void ice_vsi_dis_irq(struct ice_vsi *vsi)
		synchronize_irq(vsi->q_vectors[i]->irq.virq);
}

/**
 * ice_queue_set_napi - Set the napi instance for the queue
 * @dev: device to which NAPI and queue belong
 * @queue_index: Index of queue
 * @type: queue type as RX or TX
 * @napi: NAPI context
 * @locked: is the rtnl_lock already held
 *
 * Set the napi instance for the queue
 */
static void
ice_queue_set_napi(struct net_device *dev, unsigned int queue_index,
		   enum netdev_queue_type type, struct napi_struct *napi,
		   bool locked)
{
	if (!locked)
		rtnl_lock();
	netif_queue_set_napi(dev, queue_index, type, napi);
	if (!locked)
		rtnl_unlock();
}

/**
 * ice_q_vector_set_napi_queues - Map queue[s] associated with the napi
 * @q_vector: q_vector pointer
 * @locked: is the rtnl_lock already held
 *
 * Associate the q_vector napi with all the queue[s] on the vector
 */
void ice_q_vector_set_napi_queues(struct ice_q_vector *q_vector, bool locked)
{
	struct ice_rx_ring *rx_ring;
	struct ice_tx_ring *tx_ring;

	ice_for_each_rx_ring(rx_ring, q_vector->rx)
		ice_queue_set_napi(q_vector->vsi->netdev, rx_ring->q_index,
				   NETDEV_QUEUE_TYPE_RX, &q_vector->napi,
				   locked);

	ice_for_each_tx_ring(tx_ring, q_vector->tx)
		ice_queue_set_napi(q_vector->vsi->netdev, tx_ring->q_index,
				   NETDEV_QUEUE_TYPE_TX, &q_vector->napi,
				   locked);
	/* Also set the interrupt number for the NAPI */
	netif_napi_set_irq(&q_vector->napi, q_vector->irq.virq);
}

/**
 * ice_vsi_set_napi_queues
 * @vsi: VSI pointer
 * @locked: is the rtnl_lock already held
 *
 * Associate queue[s] with napi for all vectors
 */
void ice_vsi_set_napi_queues(struct ice_vsi *vsi, bool locked)
{
	int i;

	if (!vsi->netdev)
		return;

	ice_for_each_q_vector(vsi, i)
		ice_q_vector_set_napi_queues(vsi->q_vectors[i], locked);
}

/**
 * ice_vsi_release - Delete a VSI and free its resources
 * @vsi: the VSI being removed
+4 −0
Original line number Diff line number Diff line
@@ -91,6 +91,10 @@ void ice_vsi_cfg_netdev_tc(struct ice_vsi *vsi, u8 ena_tc);
struct ice_vsi *
ice_vsi_setup(struct ice_pf *pf, struct ice_vsi_cfg_params *params);

void ice_q_vector_set_napi_queues(struct ice_q_vector *q_vector, bool locked);

void ice_vsi_set_napi_queues(struct ice_vsi *vsi, bool locked);

int ice_vsi_release(struct ice_vsi *vsi);

void ice_vsi_close(struct ice_vsi *vsi);
Loading