diff options
Diffstat (limited to 'drivers/net/ethernet/intel/iavf/iavf_main.c')
| -rw-r--r-- | drivers/net/ethernet/intel/iavf/iavf_main.c | 113 | 
1 files changed, 51 insertions, 62 deletions
| diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index adc02adef83a..4b09785d2147 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -49,7 +49,6 @@ MODULE_DESCRIPTION("Intel(R) Ethernet Adaptive Virtual Function Network Driver")  MODULE_LICENSE("GPL v2");  static const struct net_device_ops iavf_netdev_ops; -struct workqueue_struct *iavf_wq;  int iavf_status_to_errno(enum iavf_status status)  { @@ -277,7 +276,7 @@ void iavf_schedule_reset(struct iavf_adapter *adapter)  	if (!(adapter->flags &  	      (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED))) {  		adapter->flags |= IAVF_FLAG_RESET_NEEDED; -		queue_work(iavf_wq, &adapter->reset_task); +		queue_work(adapter->wq, &adapter->reset_task);  	}  } @@ -291,7 +290,7 @@ void iavf_schedule_reset(struct iavf_adapter *adapter)  void iavf_schedule_request_stats(struct iavf_adapter *adapter)  {  	adapter->aq_required |= IAVF_FLAG_AQ_REQUEST_STATS; -	mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0); +	mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);  }  /** @@ -411,7 +410,7 @@ static irqreturn_t iavf_msix_aq(int irq, void *data)  	if (adapter->state != __IAVF_REMOVE)  		/* schedule work on the private workqueue */ -		queue_work(iavf_wq, &adapter->adminq_task); +		queue_work(adapter->wq, &adapter->adminq_task);  	return IRQ_HANDLED;  } @@ -1034,7 +1033,7 @@ int iavf_replace_primary_mac(struct iavf_adapter *adapter,  	/* schedule the watchdog task to immediately process the request */  	if (f) { -		queue_work(iavf_wq, &adapter->watchdog_task.work); +		mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);  		return 0;  	}  	return -ENOMEM; @@ -1257,7 +1256,7 @@ static void iavf_up_complete(struct iavf_adapter *adapter)  	adapter->aq_required |= IAVF_FLAG_AQ_ENABLE_QUEUES;  	if (CLIENT_ENABLED(adapter))  		adapter->flags |= IAVF_FLAG_CLIENT_NEEDS_OPEN; -	mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0); +	mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);  }  /** @@ -1414,7 +1413,7 @@ void iavf_down(struct iavf_adapter *adapter)  		adapter->aq_required |= IAVF_FLAG_AQ_DISABLE_QUEUES;  	} -	mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0); +	mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);  }  /** @@ -2248,7 +2247,7 @@ iavf_set_vlan_offload_features(struct iavf_adapter *adapter,  	if (aq_required) {  		adapter->aq_required |= aq_required; -		mod_delayed_work(iavf_wq, &adapter->watchdog_task, 0); +		mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0);  	}  } @@ -2693,6 +2692,15 @@ static void iavf_watchdog_task(struct work_struct *work)  		goto restart_watchdog;  	} +	if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES) && +	    adapter->netdev_registered && +	    !test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section) && +	    rtnl_trylock()) { +		netdev_update_features(adapter->netdev); +		rtnl_unlock(); +		adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES; +	} +  	if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)  		iavf_change_state(adapter, __IAVF_COMM_FAILED); @@ -2700,7 +2708,7 @@ static void iavf_watchdog_task(struct work_struct *work)  		adapter->aq_required = 0;  		adapter->current_op = VIRTCHNL_OP_UNKNOWN;  		mutex_unlock(&adapter->crit_lock); -		queue_work(iavf_wq, &adapter->reset_task); +		queue_work(adapter->wq, &adapter->reset_task);  		return;  	} @@ -2708,31 +2716,31 @@ static void iavf_watchdog_task(struct work_struct *work)  	case __IAVF_STARTUP:  		iavf_startup(adapter);  		mutex_unlock(&adapter->crit_lock); -		queue_delayed_work(iavf_wq, &adapter->watchdog_task, +		queue_delayed_work(adapter->wq, &adapter->watchdog_task,  				   msecs_to_jiffies(30));  		return;  	case __IAVF_INIT_VERSION_CHECK:  		iavf_init_version_check(adapter);  		mutex_unlock(&adapter->crit_lock); -		queue_delayed_work(iavf_wq, &adapter->watchdog_task, +		queue_delayed_work(adapter->wq, &adapter->watchdog_task,  				   msecs_to_jiffies(30));  		return;  	case __IAVF_INIT_GET_RESOURCES:  		iavf_init_get_resources(adapter);  		mutex_unlock(&adapter->crit_lock); -		queue_delayed_work(iavf_wq, &adapter->watchdog_task, +		queue_delayed_work(adapter->wq, &adapter->watchdog_task,  				   msecs_to_jiffies(1));  		return;  	case __IAVF_INIT_EXTENDED_CAPS:  		iavf_init_process_extended_caps(adapter);  		mutex_unlock(&adapter->crit_lock); -		queue_delayed_work(iavf_wq, &adapter->watchdog_task, +		queue_delayed_work(adapter->wq, &adapter->watchdog_task,  				   msecs_to_jiffies(1));  		return;  	case __IAVF_INIT_CONFIG_ADAPTER:  		iavf_init_config_adapter(adapter);  		mutex_unlock(&adapter->crit_lock); -		queue_delayed_work(iavf_wq, &adapter->watchdog_task, +		queue_delayed_work(adapter->wq, &adapter->watchdog_task,  				   msecs_to_jiffies(1));  		return;  	case __IAVF_INIT_FAILED: @@ -2751,14 +2759,14 @@ static void iavf_watchdog_task(struct work_struct *work)  			adapter->flags |= IAVF_FLAG_PF_COMMS_FAILED;  			iavf_shutdown_adminq(hw);  			mutex_unlock(&adapter->crit_lock); -			queue_delayed_work(iavf_wq, +			queue_delayed_work(adapter->wq,  					   &adapter->watchdog_task, (5 * HZ));  			return;  		}  		/* Try again from failed step*/  		iavf_change_state(adapter, adapter->last_state);  		mutex_unlock(&adapter->crit_lock); -		queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ); +		queue_delayed_work(adapter->wq, &adapter->watchdog_task, HZ);  		return;  	case __IAVF_COMM_FAILED:  		if (test_bit(__IAVF_IN_REMOVE_TASK, @@ -2789,13 +2797,14 @@ static void iavf_watchdog_task(struct work_struct *work)  		adapter->aq_required = 0;  		adapter->current_op = VIRTCHNL_OP_UNKNOWN;  		mutex_unlock(&adapter->crit_lock); -		queue_delayed_work(iavf_wq, +		queue_delayed_work(adapter->wq,  				   &adapter->watchdog_task,  				   msecs_to_jiffies(10));  		return;  	case __IAVF_RESETTING:  		mutex_unlock(&adapter->crit_lock); -		queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ * 2); +		queue_delayed_work(adapter->wq, &adapter->watchdog_task, +				   HZ * 2);  		return;  	case __IAVF_DOWN:  	case __IAVF_DOWN_PENDING: @@ -2834,9 +2843,9 @@ static void iavf_watchdog_task(struct work_struct *work)  		adapter->aq_required = 0;  		adapter->current_op = VIRTCHNL_OP_UNKNOWN;  		dev_err(&adapter->pdev->dev, "Hardware reset detected\n"); -		queue_work(iavf_wq, &adapter->reset_task); +		queue_work(adapter->wq, &adapter->reset_task);  		mutex_unlock(&adapter->crit_lock); -		queue_delayed_work(iavf_wq, +		queue_delayed_work(adapter->wq,  				   &adapter->watchdog_task, HZ * 2);  		return;  	} @@ -2845,12 +2854,13 @@ static void iavf_watchdog_task(struct work_struct *work)  	mutex_unlock(&adapter->crit_lock);  restart_watchdog:  	if (adapter->state >= __IAVF_DOWN) -		queue_work(iavf_wq, &adapter->adminq_task); +		queue_work(adapter->wq, &adapter->adminq_task);  	if (adapter->aq_required) -		queue_delayed_work(iavf_wq, &adapter->watchdog_task, +		queue_delayed_work(adapter->wq, &adapter->watchdog_task,  				   msecs_to_jiffies(20));  	else -		queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ * 2); +		queue_delayed_work(adapter->wq, &adapter->watchdog_task, +				   HZ * 2);  }  /** @@ -2952,7 +2962,7 @@ static void iavf_reset_task(struct work_struct *work)  	 */  	if (!mutex_trylock(&adapter->crit_lock)) {  		if (adapter->state != __IAVF_REMOVE) -			queue_work(iavf_wq, &adapter->reset_task); +			queue_work(adapter->wq, &adapter->reset_task);  		goto reset_finish;  	} @@ -3116,7 +3126,7 @@ continue_reset:  	bitmap_clear(adapter->vsi.active_cvlans, 0, VLAN_N_VID);  	bitmap_clear(adapter->vsi.active_svlans, 0, VLAN_N_VID); -	mod_delayed_work(iavf_wq, &adapter->watchdog_task, 2); +	mod_delayed_work(adapter->wq, &adapter->watchdog_task, 2);  	/* We were running when the reset started, so we need to restore some  	 * state here. @@ -3208,7 +3218,7 @@ static void iavf_adminq_task(struct work_struct *work)  		if (adapter->state == __IAVF_REMOVE)  			return; -		queue_work(iavf_wq, &adapter->adminq_task); +		queue_work(adapter->wq, &adapter->adminq_task);  		goto out;  	} @@ -3232,24 +3242,6 @@ static void iavf_adminq_task(struct work_struct *work)  	} while (pending);  	mutex_unlock(&adapter->crit_lock); -	if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES)) { -		if (adapter->netdev_registered || -		    !test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) { -			struct net_device *netdev = adapter->netdev; - -			rtnl_lock(); -			netdev_update_features(netdev); -			rtnl_unlock(); -			/* Request VLAN offload settings */ -			if (VLAN_V2_ALLOWED(adapter)) -				iavf_set_vlan_offload_features -					(adapter, 0, netdev->features); - -			iavf_set_queue_vlan_tag_loc(adapter); -		} - -		adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES; -	}  	if ((adapter->flags &  	     (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED)) ||  	    adapter->state == __IAVF_RESETTING) @@ -4349,7 +4341,7 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu)  	if (netif_running(netdev)) {  		adapter->flags |= IAVF_FLAG_RESET_NEEDED; -		queue_work(iavf_wq, &adapter->reset_task); +		queue_work(adapter->wq, &adapter->reset_task);  	}  	return 0; @@ -4898,6 +4890,13 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	hw = &adapter->hw;  	hw->back = adapter; +	adapter->wq = alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM, +					      iavf_driver_name); +	if (!adapter->wq) { +		err = -ENOMEM; +		goto err_alloc_wq; +	} +  	adapter->msg_enable = BIT(DEFAULT_DEBUG_LEVEL_SHIFT) - 1;  	iavf_change_state(adapter, __IAVF_STARTUP); @@ -4942,7 +4941,7 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	INIT_WORK(&adapter->adminq_task, iavf_adminq_task);  	INIT_DELAYED_WORK(&adapter->watchdog_task, iavf_watchdog_task);  	INIT_DELAYED_WORK(&adapter->client_task, iavf_client_task); -	queue_delayed_work(iavf_wq, &adapter->watchdog_task, +	queue_delayed_work(adapter->wq, &adapter->watchdog_task,  			   msecs_to_jiffies(5 * (pdev->devfn & 0x07)));  	/* Setup the wait queue for indicating transition to down status */ @@ -4954,6 +4953,8 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	return 0;  err_ioremap: +	destroy_workqueue(adapter->wq); +err_alloc_wq:  	free_netdev(netdev);  err_alloc_etherdev:  	pci_disable_pcie_error_reporting(pdev); @@ -5023,7 +5024,7 @@ static int __maybe_unused iavf_resume(struct device *dev_d)  		return err;  	} -	queue_work(iavf_wq, &adapter->reset_task); +	queue_work(adapter->wq, &adapter->reset_task);  	netif_device_attach(adapter->netdev); @@ -5170,6 +5171,8 @@ static void iavf_remove(struct pci_dev *pdev)  	}  	spin_unlock_bh(&adapter->adv_rss_lock); +	destroy_workqueue(adapter->wq); +  	free_netdev(netdev);  	pci_disable_pcie_error_reporting(pdev); @@ -5196,24 +5199,11 @@ static struct pci_driver iavf_driver = {   **/  static int __init iavf_init_module(void)  { -	int ret; -  	pr_info("iavf: %s\n", iavf_driver_string);  	pr_info("%s\n", iavf_copyright); -	iavf_wq = alloc_workqueue("%s", WQ_UNBOUND | WQ_MEM_RECLAIM, 1, -				  iavf_driver_name); -	if (!iavf_wq) { -		pr_err("%s: Failed to create workqueue\n", iavf_driver_name); -		return -ENOMEM; -	} - -	ret = pci_register_driver(&iavf_driver); -	if (ret) -		destroy_workqueue(iavf_wq); - -	return ret; +	return pci_register_driver(&iavf_driver);  }  module_init(iavf_init_module); @@ -5227,7 +5217,6 @@ module_init(iavf_init_module);  static void __exit iavf_exit_module(void)  {  	pci_unregister_driver(&iavf_driver); -	destroy_workqueue(iavf_wq);  }  module_exit(iavf_exit_module); |