Commit 08125454 authored by Yunsheng Lin's avatar Yunsheng Lin Committed by David S. Miller

net: hns3: add interrupt affinity support for misc interrupt

The misc interrupt is used to schedule the reset and mailbox
subtask, and service_task delayed_work is used to do periodic
management work each second.

This patch sets the above three subtask's affinity using the
misc interrupt' affinity.

Also this patch setups a affinity notify for misc interrupt to
allow user to change the above three subtask's affinity.
Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: default avatarPeng Li <lipeng321@huawei.com>
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7be1b9f3
...@@ -1270,6 +1270,12 @@ static int hclge_configure(struct hclge_dev *hdev) ...@@ -1270,6 +1270,12 @@ static int hclge_configure(struct hclge_dev *hdev)
hclge_init_kdump_kernel_config(hdev); hclge_init_kdump_kernel_config(hdev);
/* Set the init affinity based on pci func number */
i = cpumask_weight(cpumask_of_node(dev_to_node(&hdev->pdev->dev)));
i = i ? PCI_FUNC(hdev->pdev->devfn) % i : 0;
cpumask_set_cpu(cpumask_local_spread(i, dev_to_node(&hdev->pdev->dev)),
&hdev->affinity_mask);
return ret; return ret;
} }
...@@ -2499,14 +2505,16 @@ static void hclge_mbx_task_schedule(struct hclge_dev *hdev) ...@@ -2499,14 +2505,16 @@ static void hclge_mbx_task_schedule(struct hclge_dev *hdev)
{ {
if (!test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state) && if (!test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state) &&
!test_and_set_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state)) !test_and_set_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state))
schedule_work(&hdev->mbx_service_task); queue_work_on(cpumask_first(&hdev->affinity_mask), system_wq,
&hdev->mbx_service_task);
} }
static void hclge_reset_task_schedule(struct hclge_dev *hdev) static void hclge_reset_task_schedule(struct hclge_dev *hdev)
{ {
if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) && if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) &&
!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state)) !test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state))
schedule_work(&hdev->rst_service_task); queue_work_on(cpumask_first(&hdev->affinity_mask), system_wq,
&hdev->rst_service_task);
} }
static void hclge_task_schedule(struct hclge_dev *hdev) static void hclge_task_schedule(struct hclge_dev *hdev)
...@@ -2516,8 +2524,9 @@ static void hclge_task_schedule(struct hclge_dev *hdev) ...@@ -2516,8 +2524,9 @@ static void hclge_task_schedule(struct hclge_dev *hdev)
!test_and_set_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state)) { !test_and_set_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state)) {
hdev->hw_stats.stats_timer++; hdev->hw_stats.stats_timer++;
hdev->fd_arfs_expire_timer++; hdev->fd_arfs_expire_timer++;
mod_delayed_work(system_wq, &hdev->service_task, mod_delayed_work_on(cpumask_first(&hdev->affinity_mask),
round_jiffies_relative(HZ)); system_wq, &hdev->service_task,
round_jiffies_relative(HZ));
} }
} }
...@@ -2903,6 +2912,36 @@ static void hclge_get_misc_vector(struct hclge_dev *hdev) ...@@ -2903,6 +2912,36 @@ static void hclge_get_misc_vector(struct hclge_dev *hdev)
hdev->num_msi_used += 1; hdev->num_msi_used += 1;
} }
static void hclge_irq_affinity_notify(struct irq_affinity_notify *notify,
const cpumask_t *mask)
{
struct hclge_dev *hdev = container_of(notify, struct hclge_dev,
affinity_notify);
cpumask_copy(&hdev->affinity_mask, mask);
}
static void hclge_irq_affinity_release(struct kref *ref)
{
}
static void hclge_misc_affinity_setup(struct hclge_dev *hdev)
{
irq_set_affinity_hint(hdev->misc_vector.vector_irq,
&hdev->affinity_mask);
hdev->affinity_notify.notify = hclge_irq_affinity_notify;
hdev->affinity_notify.release = hclge_irq_affinity_release;
irq_set_affinity_notifier(hdev->misc_vector.vector_irq,
&hdev->affinity_notify);
}
static void hclge_misc_affinity_teardown(struct hclge_dev *hdev)
{
irq_set_affinity_notifier(hdev->misc_vector.vector_irq, NULL);
irq_set_affinity_hint(hdev->misc_vector.vector_irq, NULL);
}
static int hclge_misc_irq_init(struct hclge_dev *hdev) static int hclge_misc_irq_init(struct hclge_dev *hdev)
{ {
int ret; int ret;
...@@ -8794,6 +8833,11 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) ...@@ -8794,6 +8833,11 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
INIT_WORK(&hdev->rst_service_task, hclge_reset_service_task); INIT_WORK(&hdev->rst_service_task, hclge_reset_service_task);
INIT_WORK(&hdev->mbx_service_task, hclge_mailbox_service_task); INIT_WORK(&hdev->mbx_service_task, hclge_mailbox_service_task);
/* Setup affinity after service timer setup because add_timer_on
* is called in affinity notify.
*/
hclge_misc_affinity_setup(hdev);
hclge_clear_all_event_cause(hdev); hclge_clear_all_event_cause(hdev);
hclge_clear_resetting_state(hdev); hclge_clear_resetting_state(hdev);
...@@ -8955,6 +8999,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) ...@@ -8955,6 +8999,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
struct hclge_dev *hdev = ae_dev->priv; struct hclge_dev *hdev = ae_dev->priv;
struct hclge_mac *mac = &hdev->hw.mac; struct hclge_mac *mac = &hdev->hw.mac;
hclge_misc_affinity_teardown(hdev);
hclge_state_uninit(hdev); hclge_state_uninit(hdev);
if (mac->phydev) if (mac->phydev)
......
...@@ -863,6 +863,10 @@ struct hclge_dev { ...@@ -863,6 +863,10 @@ struct hclge_dev {
DECLARE_KFIFO(mac_tnl_log, struct hclge_mac_tnl_stats, DECLARE_KFIFO(mac_tnl_log, struct hclge_mac_tnl_stats,
HCLGE_MAC_TNL_LOG_SIZE); HCLGE_MAC_TNL_LOG_SIZE);
/* affinity mask and notify for misc interrupt */
cpumask_t affinity_mask;
struct irq_affinity_notify affinity_notify;
}; };
/* VPort level vlan tag configuration for TX direction */ /* VPort level vlan tag configuration for TX direction */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment