Thu Aug 29 09:45:22 2019 UTC ()
Fix panic when ncpu == 1 && sysctl -w hw.ixg0.txrx_workqueue=1. Reported by nonaka@n.o.

ok by msaitoh@n.o and nonaka@n.o

pullup-8, pullup-9


(knakahara)
diff -r1.205 -r1.206 src/sys/dev/pci/ixgbe/ixgbe.c

cvs diff -r1.205 -r1.206 src/sys/dev/pci/ixgbe/ixgbe.c (expand / switch to unified diff)

--- src/sys/dev/pci/ixgbe/ixgbe.c 2019/08/29 09:35:18 1.205
+++ src/sys/dev/pci/ixgbe/ixgbe.c 2019/08/29 09:45:22 1.206
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ixgbe.c,v 1.205 2019/08/29 09:35:18 knakahara Exp $ */ 1/* $NetBSD: ixgbe.c,v 1.206 2019/08/29 09:45:22 knakahara Exp $ */
2 2
3/****************************************************************************** 3/******************************************************************************
4 4
5 Copyright (c) 2001-2017, Intel Corporation 5 Copyright (c) 2001-2017, Intel Corporation
6 All rights reserved. 6 All rights reserved.
7 7
8 Redistribution and use in source and binary forms, with or without 8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met: 9 modification, are permitted provided that the following conditions are met:
10 10
11 1. Redistributions of source code must retain the above copyright notice, 11 1. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer. 12 this list of conditions and the following disclaimer.
13 13
14 2. Redistributions in binary form must reproduce the above copyright 14 2. Redistributions in binary form must reproduce the above copyright
@@ -6457,27 +6457,29 @@ ixgbe_handle_que_work(struct work *wk, v @@ -6457,27 +6457,29 @@ ixgbe_handle_que_work(struct work *wk, v
6457/************************************************************************ 6457/************************************************************************
6458 * ixgbe_allocate_legacy - Setup the Legacy or MSI Interrupt handler 6458 * ixgbe_allocate_legacy - Setup the Legacy or MSI Interrupt handler
6459 ************************************************************************/ 6459 ************************************************************************/
6460static int 6460static int
6461ixgbe_allocate_legacy(struct adapter *adapter, 6461ixgbe_allocate_legacy(struct adapter *adapter,
6462 const struct pci_attach_args *pa) 6462 const struct pci_attach_args *pa)
6463{ 6463{
6464 device_t dev = adapter->dev; 6464 device_t dev = adapter->dev;
6465 struct ix_queue *que = adapter->queues; 6465 struct ix_queue *que = adapter->queues;
6466 struct tx_ring *txr = adapter->tx_rings; 6466 struct tx_ring *txr = adapter->tx_rings;
6467 int counts[PCI_INTR_TYPE_SIZE]; 6467 int counts[PCI_INTR_TYPE_SIZE];
6468 pci_intr_type_t intr_type, max_type; 6468 pci_intr_type_t intr_type, max_type;
6469 char intrbuf[PCI_INTRSTR_LEN]; 6469 char intrbuf[PCI_INTRSTR_LEN];
 6470 char wqname[MAXCOMLEN];
6470 const char *intrstr = NULL; 6471 const char *intrstr = NULL;
 6472 int defertx_error = 0, error;
6471 6473
6472 /* We allocate a single interrupt resource */ 6474 /* We allocate a single interrupt resource */
6473 max_type = PCI_INTR_TYPE_MSI; 6475 max_type = PCI_INTR_TYPE_MSI;
6474 counts[PCI_INTR_TYPE_MSIX] = 0; 6476 counts[PCI_INTR_TYPE_MSIX] = 0;
6475 counts[PCI_INTR_TYPE_MSI] = 6477 counts[PCI_INTR_TYPE_MSI] =
6476 (adapter->feat_en & IXGBE_FEATURE_MSI) ? 1 : 0; 6478 (adapter->feat_en & IXGBE_FEATURE_MSI) ? 1 : 0;
6477 /* Check not feat_en but feat_cap to fallback to INTx */ 6479 /* Check not feat_en but feat_cap to fallback to INTx */
6478 counts[PCI_INTR_TYPE_INTX] = 6480 counts[PCI_INTR_TYPE_INTX] =
6479 (adapter->feat_cap & IXGBE_FEATURE_LEGACY_IRQ) ? 1 : 0; 6481 (adapter->feat_cap & IXGBE_FEATURE_LEGACY_IRQ) ? 1 : 0;
6480 6482
6481alloc_retry: 6483alloc_retry:
6482 if (pci_intr_alloc(pa, &adapter->osdep.intrs, counts, max_type) != 0) { 6484 if (pci_intr_alloc(pa, &adapter->osdep.intrs, counts, max_type) != 0) {
6483 aprint_error_dev(dev, "couldn't alloc interrupt\n"); 6485 aprint_error_dev(dev, "couldn't alloc interrupt\n");
@@ -6519,35 +6521,47 @@ alloc_retry: @@ -6519,35 +6521,47 @@ alloc_retry:
6519 if (adapter->osdep.ihs[0] == NULL) { 6521 if (adapter->osdep.ihs[0] == NULL) {
6520 aprint_error_dev(dev, 6522 aprint_error_dev(dev,
6521 "couldn't establish interrupt%s%s\n", 6523 "couldn't establish interrupt%s%s\n",
6522 intrstr ? " at " : "", intrstr ? intrstr : ""); 6524 intrstr ? " at " : "", intrstr ? intrstr : "");
6523 pci_intr_release(adapter->osdep.pc, adapter->osdep.intrs, 1); 6525 pci_intr_release(adapter->osdep.pc, adapter->osdep.intrs, 1);
6524 adapter->osdep.intrs = NULL; 6526 adapter->osdep.intrs = NULL;
6525 return ENXIO; 6527 return ENXIO;
6526 } 6528 }
6527 aprint_normal_dev(dev, "interrupting at %s\n", intrstr); 6529 aprint_normal_dev(dev, "interrupting at %s\n", intrstr);
6528 /* 6530 /*
6529 * Try allocating a fast interrupt and the associated deferred 6531 * Try allocating a fast interrupt and the associated deferred
6530 * processing contexts. 6532 * processing contexts.
6531 */ 6533 */
6532 if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX)) 6534 if (!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX)) {
6533 txr->txr_si = 6535 txr->txr_si =
6534 softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS, 6536 softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
6535 ixgbe_deferred_mq_start, txr); 6537 ixgbe_deferred_mq_start, txr);
 6538
 6539 snprintf(wqname, sizeof(wqname), "%sdeferTx", device_xname(dev));
 6540 defertx_error = workqueue_create(&adapter->txr_wq, wqname,
 6541 ixgbe_deferred_mq_start_work, adapter, IXGBE_WORKQUEUE_PRI,
 6542 IPL_NET, IXGBE_WORKQUEUE_FLAGS);
 6543 adapter->txr_wq_enqueued = percpu_alloc(sizeof(u_int));
 6544 }
6536 que->que_si = softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS, 6545 que->que_si = softint_establish(SOFTINT_NET | IXGBE_SOFTINFT_FLAGS,
6537 ixgbe_handle_que, que); 6546 ixgbe_handle_que, que);
 6547 snprintf(wqname, sizeof(wqname), "%sTxRx", device_xname(dev));
 6548 error = workqueue_create(&adapter->que_wq, wqname,
 6549 ixgbe_handle_que_work, adapter, IXGBE_WORKQUEUE_PRI, IPL_NET,
 6550 IXGBE_WORKQUEUE_FLAGS);
6538 6551
6539 if ((!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX) 6552 if ((!(adapter->feat_en & IXGBE_FEATURE_LEGACY_TX)
6540 && (txr->txr_si == NULL)) || (que->que_si == NULL)) { 6553 && ((txr->txr_si == NULL) || defertx_error != 0))
 6554 || (que->que_si == NULL) || error != 0) {
6541 aprint_error_dev(dev, 6555 aprint_error_dev(dev,
6542 "could not establish software interrupts\n"); 6556 "could not establish software interrupts\n");
6543 6557
6544 return ENXIO; 6558 return ENXIO;
6545 } 6559 }
6546 /* For simplicity in the handlers */ 6560 /* For simplicity in the handlers */
6547 adapter->active_queues = IXGBE_EIMS_ENABLE_MASK; 6561 adapter->active_queues = IXGBE_EIMS_ENABLE_MASK;
6548 6562
6549 return (0); 6563 return (0);
6550} /* ixgbe_allocate_legacy */ 6564} /* ixgbe_allocate_legacy */
6551 6565
6552/************************************************************************ 6566/************************************************************************
6553 * ixgbe_allocate_msix - Setup MSI-X Interrupt resources and handlers 6567 * ixgbe_allocate_msix - Setup MSI-X Interrupt resources and handlers