@@ -583,9 +583,14 @@ efx_get_channel_name(struct efx_channel *channel, char *buf, size_t len)
583583 int number ;
584584
585585 number = channel -> channel ;
586- if (efx -> tx_channel_offset == 0 ) {
586+
587+ if (number >= efx -> xdp_channel_offset &&
588+ !WARN_ON_ONCE (!efx -> n_xdp_channels )) {
589+ type = "-xdp" ;
590+ number -= efx -> xdp_channel_offset ;
591+ } else if (efx -> tx_channel_offset == 0 ) {
587592 type = "" ;
588- } else if (channel -> channel < efx -> tx_channel_offset ) {
593+ } else if (number < efx -> tx_channel_offset ) {
589594 type = "-rx" ;
590595 } else {
591596 type = "-tx" ;
@@ -803,6 +808,8 @@ static void efx_remove_channels(struct efx_nic *efx)
803808
804809 efx_for_each_channel (channel , efx )
805810 efx_remove_channel (channel );
811+
812+ kfree (efx -> xdp_tx_queues );
806813}
807814
808815int
@@ -1440,6 +1447,101 @@ static unsigned int efx_wanted_parallelism(struct efx_nic *efx)
14401447 return count ;
14411448}
14421449
1450+ static int efx_allocate_msix_channels (struct efx_nic * efx ,
1451+ unsigned int max_channels ,
1452+ unsigned int extra_channels ,
1453+ unsigned int parallelism )
1454+ {
1455+ unsigned int n_channels = parallelism ;
1456+ int vec_count ;
1457+ int n_xdp_tx ;
1458+ int n_xdp_ev ;
1459+
1460+ if (efx_separate_tx_channels )
1461+ n_channels *= 2 ;
1462+ n_channels += extra_channels ;
1463+
1464+ /* To allow XDP transmit to happen from arbitrary NAPI contexts
1465+ * we allocate a TX queue per CPU. We share event queues across
1466+ * multiple tx queues, assuming tx and ev queues are both
1467+ * maximum size.
1468+ */
1469+
1470+ n_xdp_tx = num_possible_cpus ();
1471+ n_xdp_ev = DIV_ROUND_UP (n_xdp_tx , EFX_TXQ_TYPES );
1472+
1473+ /* Check resources.
1474+ * We need a channel per event queue, plus a VI per tx queue.
1475+ * This may be more pessimistic than it needs to be.
1476+ */
1477+ if (n_channels + n_xdp_ev > max_channels ) {
1478+ netif_err (efx , drv , efx -> net_dev ,
1479+ "Insufficient resources for %d XDP event queues (%d other channels, max %d)\n" ,
1480+ n_xdp_ev , n_channels , max_channels );
1481+ efx -> n_xdp_channels = 0 ;
1482+ efx -> xdp_tx_per_channel = 0 ;
1483+ efx -> xdp_tx_queue_count = 0 ;
1484+ } else {
1485+ efx -> n_xdp_channels = n_xdp_ev ;
1486+ efx -> xdp_tx_per_channel = EFX_TXQ_TYPES ;
1487+ efx -> xdp_tx_queue_count = n_xdp_tx ;
1488+ n_channels += n_xdp_ev ;
1489+ netif_dbg (efx , drv , efx -> net_dev ,
1490+ "Allocating %d TX and %d event queues for XDP\n" ,
1491+ n_xdp_tx , n_xdp_ev );
1492+ }
1493+
1494+ n_channels = min (n_channels , max_channels );
1495+
1496+ vec_count = pci_msix_vec_count (efx -> pci_dev );
1497+ if (vec_count < 0 )
1498+ return vec_count ;
1499+ if (vec_count < n_channels ) {
1500+ netif_err (efx , drv , efx -> net_dev ,
1501+ "WARNING: Insufficient MSI-X vectors available (%d < %u).\n" ,
1502+ vec_count , n_channels );
1503+ netif_err (efx , drv , efx -> net_dev ,
1504+ "WARNING: Performance may be reduced.\n" );
1505+ n_channels = vec_count ;
1506+ }
1507+
1508+ efx -> n_channels = n_channels ;
1509+
1510+ /* Do not create the PTP TX queue(s) if PTP uses the MC directly. */
1511+ if (extra_channels && !efx_ptp_use_mac_tx_timestamps (efx ))
1512+ n_channels -- ;
1513+
1514+ /* Ignore XDP tx channels when creating rx channels. */
1515+ n_channels -= efx -> n_xdp_channels ;
1516+
1517+ if (efx_separate_tx_channels ) {
1518+ efx -> n_tx_channels =
1519+ min (max (n_channels / 2 , 1U ),
1520+ efx -> max_tx_channels );
1521+ efx -> tx_channel_offset =
1522+ n_channels - efx -> n_tx_channels ;
1523+ efx -> n_rx_channels =
1524+ max (n_channels -
1525+ efx -> n_tx_channels , 1U );
1526+ } else {
1527+ efx -> n_tx_channels = min (n_channels , efx -> max_tx_channels );
1528+ efx -> tx_channel_offset = 0 ;
1529+ efx -> n_rx_channels = n_channels ;
1530+ }
1531+
1532+ if (efx -> n_xdp_channels )
1533+ efx -> xdp_channel_offset = efx -> tx_channel_offset +
1534+ efx -> n_tx_channels ;
1535+ else
1536+ efx -> xdp_channel_offset = efx -> n_channels ;
1537+
1538+ netif_dbg (efx , drv , efx -> net_dev ,
1539+ "Allocating %u RX channels\n" ,
1540+ efx -> n_rx_channels );
1541+
1542+ return efx -> n_channels ;
1543+ }
1544+
14431545/* Probe the number and type of interrupts we are able to obtain, and
14441546 * the resulting numbers of channels and RX queues.
14451547 */
@@ -1454,19 +1556,19 @@ static int efx_probe_interrupts(struct efx_nic *efx)
14541556 ++ extra_channels ;
14551557
14561558 if (efx -> interrupt_mode == EFX_INT_MODE_MSIX ) {
1559+ unsigned int parallelism = efx_wanted_parallelism (efx );
14571560 struct msix_entry xentries [EFX_MAX_CHANNELS ];
14581561 unsigned int n_channels ;
14591562
1460- n_channels = efx_wanted_parallelism (efx );
1461- if (efx_separate_tx_channels )
1462- n_channels *= 2 ;
1463- n_channels += extra_channels ;
1464- n_channels = min (n_channels , efx -> max_channels );
1465-
1466- for (i = 0 ; i < n_channels ; i ++ )
1467- xentries [i ].entry = i ;
1468- rc = pci_enable_msix_range (efx -> pci_dev ,
1469- xentries , 1 , n_channels );
1563+ rc = efx_allocate_msix_channels (efx , efx -> max_channels ,
1564+ extra_channels , parallelism );
1565+ if (rc >= 0 ) {
1566+ n_channels = rc ;
1567+ for (i = 0 ; i < n_channels ; i ++ )
1568+ xentries [i ].entry = i ;
1569+ rc = pci_enable_msix_range (efx -> pci_dev , xentries , 1 ,
1570+ n_channels );
1571+ }
14701572 if (rc < 0 ) {
14711573 /* Fall back to single channel MSI */
14721574 netif_err (efx , drv , efx -> net_dev ,
@@ -1485,21 +1587,6 @@ static int efx_probe_interrupts(struct efx_nic *efx)
14851587 }
14861588
14871589 if (rc > 0 ) {
1488- efx -> n_channels = n_channels ;
1489- if (n_channels > extra_channels )
1490- n_channels -= extra_channels ;
1491- if (efx_separate_tx_channels ) {
1492- efx -> n_tx_channels = min (max (n_channels / 2 ,
1493- 1U ),
1494- efx -> max_tx_channels );
1495- efx -> n_rx_channels = max (n_channels -
1496- efx -> n_tx_channels ,
1497- 1U );
1498- } else {
1499- efx -> n_tx_channels = min (n_channels ,
1500- efx -> max_tx_channels );
1501- efx -> n_rx_channels = n_channels ;
1502- }
15031590 for (i = 0 ; i < efx -> n_channels ; i ++ )
15041591 efx_get_channel (efx , i )-> irq =
15051592 xentries [i ].vector ;
@@ -1511,6 +1598,8 @@ static int efx_probe_interrupts(struct efx_nic *efx)
15111598 efx -> n_channels = 1 ;
15121599 efx -> n_rx_channels = 1 ;
15131600 efx -> n_tx_channels = 1 ;
1601+ efx -> n_xdp_channels = 0 ;
1602+ efx -> xdp_channel_offset = efx -> n_channels ;
15141603 rc = pci_enable_msi (efx -> pci_dev );
15151604 if (rc == 0 ) {
15161605 efx_get_channel (efx , 0 )-> irq = efx -> pci_dev -> irq ;
@@ -1529,12 +1618,14 @@ static int efx_probe_interrupts(struct efx_nic *efx)
15291618 efx -> n_channels = 1 + (efx_separate_tx_channels ? 1 : 0 );
15301619 efx -> n_rx_channels = 1 ;
15311620 efx -> n_tx_channels = 1 ;
1621+ efx -> n_xdp_channels = 0 ;
1622+ efx -> xdp_channel_offset = efx -> n_channels ;
15321623 efx -> legacy_irq = efx -> pci_dev -> irq ;
15331624 }
15341625
1535- /* Assign extra channels if possible */
1626+ /* Assign extra channels if possible, before XDP channels */
15361627 efx -> n_extra_tx_channels = 0 ;
1537- j = efx -> n_channels ;
1628+ j = efx -> xdp_channel_offset ;
15381629 for (i = 0 ; i < EFX_MAX_EXTRA_CHANNELS ; i ++ ) {
15391630 if (!efx -> extra_channel_type [i ])
15401631 continue ;
@@ -1729,29 +1820,50 @@ static void efx_remove_interrupts(struct efx_nic *efx)
17291820 efx -> legacy_irq = 0 ;
17301821}
17311822
1732- static void efx_set_channels (struct efx_nic * efx )
1823+ static int efx_set_channels (struct efx_nic * efx )
17331824{
17341825 struct efx_channel * channel ;
17351826 struct efx_tx_queue * tx_queue ;
1827+ int xdp_queue_number ;
17361828
17371829 efx -> tx_channel_offset =
17381830 efx_separate_tx_channels ?
17391831 efx -> n_channels - efx -> n_tx_channels : 0 ;
17401832
1833+ if (efx -> xdp_tx_queue_count ) {
1834+ EFX_WARN_ON_PARANOID (efx -> xdp_tx_queues );
1835+
1836+ /* Allocate array for XDP TX queue lookup. */
1837+ efx -> xdp_tx_queues = kcalloc (efx -> xdp_tx_queue_count ,
1838+ sizeof (* efx -> xdp_tx_queues ),
1839+ GFP_KERNEL );
1840+ if (!efx -> xdp_tx_queues )
1841+ return - ENOMEM ;
1842+ }
1843+
17411844 /* We need to mark which channels really have RX and TX
17421845 * queues, and adjust the TX queue numbers if we have separate
17431846 * RX-only and TX-only channels.
17441847 */
1848+ xdp_queue_number = 0 ;
17451849 efx_for_each_channel (channel , efx ) {
17461850 if (channel -> channel < efx -> n_rx_channels )
17471851 channel -> rx_queue .core_index = channel -> channel ;
17481852 else
17491853 channel -> rx_queue .core_index = -1 ;
17501854
1751- efx_for_each_channel_tx_queue (tx_queue , channel )
1855+ efx_for_each_channel_tx_queue (tx_queue , channel ) {
17521856 tx_queue -> queue -= (efx -> tx_channel_offset *
17531857 EFX_TXQ_TYPES );
1858+
1859+ if (efx_channel_is_xdp_tx (channel ) &&
1860+ xdp_queue_number < efx -> xdp_tx_queue_count ) {
1861+ efx -> xdp_tx_queues [xdp_queue_number ] = tx_queue ;
1862+ xdp_queue_number ++ ;
1863+ }
1864+ }
17541865 }
1866+ return 0 ;
17551867}
17561868
17571869static int efx_probe_nic (struct efx_nic * efx )
@@ -1781,7 +1893,9 @@ static int efx_probe_nic(struct efx_nic *efx)
17811893 if (rc )
17821894 goto fail1 ;
17831895
1784- efx_set_channels (efx );
1896+ rc = efx_set_channels (efx );
1897+ if (rc )
1898+ goto fail1 ;
17851899
17861900 /* dimension_resources can fail with EAGAIN */
17871901 rc = efx -> type -> dimension_resources (efx );
@@ -2091,6 +2205,8 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs,
20912205 channel -> irq_moderation_us = rx_usecs ;
20922206 else if (efx_channel_has_tx_queues (channel ))
20932207 channel -> irq_moderation_us = tx_usecs ;
2208+ else if (efx_channel_is_xdp_tx (channel ))
2209+ channel -> irq_moderation_us = tx_usecs ;
20942210 }
20952211
20962212 return 0 ;
0 commit comments