@@ -673,6 +673,10 @@ struct igb_adapter {
struct vf_mac_filter *vf_mac_list;
/* lock for VF resources */
spinlock_t vfs_lock;
+#ifdef CONFIG_PREEMPT_RT
+ /* Used to lock VFS in interrupt context under PREEMPT_RT */
+ raw_spinlock_t raw_vfs_lock;
+#endif
};
/* flags controlling PTP/1588 function */
@@ -3657,6 +3657,47 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return err;
}
+#ifdef CONFIG_PREEMPT_RT
+static __always_inline void vfs_lock_init(struct igb_adapter *adapter)
+{
+ spin_lock_init(&adapter->vfs_lock);
+ raw_spin_lock_init(&adapter->raw_vfs_lock);
+}
+
+static __always_inline void vfs_lock_irqsave(struct igb_adapter *adapter,
+ unsigned long *flags)
+{
+ /*
+ * Remember that under PREEMPT_RT spin_lock_irqsave
+ * ignores the flags parameter
+ */
+ spin_lock_irqsave(&adapter->vfs_lock, *flags);
+ raw_spin_lock_irqsave(&adapter->raw_vfs_lock, *flags);
+}
+
+static __always_inline void vfs_unlock_irqrestore(struct igb_adapter *adapter,
+ unsigned long flags)
+{
+ raw_spin_unlock_irqrestore(&adapter->raw_vfs_lock, flags);
+ spin_unlock_irqrestore(&adapter->vfs_lock, flags);
+}
+#else
+static __always_inline void vfs_lock_init(struct igb_adapter *adapter)
+{
+ spin_lock_init(&adapter->vfs_lock);
+}
+
+static __always_inline void vfs_lock_irqsave(struct igb_adapter *adapter, unsigned long *flags)
+{
+ spin_lock_irqsave(&adapter->vfs_lock, *flags);
+}
+
+static __always_inline void vfs_unlock_irqrestore(struct igb_adapter *adapter, unsigned long flags)
+{
+ spin_unlock_irqrestore(&adapter->vfs_lock, flags);
+}
+#endif
+
#ifdef CONFIG_PCI_IOV
static int igb_sriov_reinit(struct pci_dev *dev)
{
@@ -3707,9 +3748,9 @@ static int igb_disable_sriov(struct pci_dev *pdev, bool reinit)
pci_disable_sriov(pdev);
msleep(500);
}
- spin_lock_irqsave(&adapter->vfs_lock, flags);
+ vfs_lock_irqsave(adapter, &flags);
adapter->vfs_allocated_count = 0;
- spin_unlock_irqrestore(&adapter->vfs_lock, flags);
+ vfs_unlock_irqrestore(adapter, flags);
kfree(adapter->vf_mac_list);
adapter->vf_mac_list = NULL;
kfree(adapter->vf_data);
@@ -4042,7 +4083,7 @@ static int igb_sw_init(struct igb_adapter *adapter)
spin_lock_init(&adapter->stats64_lock);
/* init spinlock to avoid concurrency of VF resources */
- spin_lock_init(&adapter->vfs_lock);
+ vfs_lock_init(adapter);
#ifdef CONFIG_PCI_IOV
switch (hw->mac.type) {
case e1000_82576:
@@ -8078,7 +8119,7 @@ static void igb_msg_task(struct igb_adapter *adapter)
unsigned long flags;
u32 vf;
- spin_lock_irqsave(&adapter->vfs_lock, flags);
+ vfs_lock_irqsave(adapter, &flags);
for (vf = 0; vf < adapter->vfs_allocated_count; vf++) {
/* process any reset requests */
if (!igb_check_for_rst(hw, vf))
@@ -8092,7 +8133,7 @@ static void igb_msg_task(struct igb_adapter *adapter)
if (!igb_check_for_ack(hw, vf))
igb_rcv_ack_from_vf(adapter, vf);
}
- spin_unlock_irqrestore(&adapter->vfs_lock, flags);
+ vfs_unlock_irqrestore(adapter, flags);
}
/**