From: Junxian Huang huangjunxian6@hisilicon.com
driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I6Z4E9
---------------------------------------------------------------
Currently, bond_work, the struct of delayed work for RoCE bonding, is attached to hns_roce_dev. During setting bond, hns_roce_dev will be uninited and the pending works will be canceled.
This patch moves bond_work from hns_roce_dev to hns_roce_bond_group so that the pending works can be executed after setting bond rather than being cancelled.
Signed-off-by: Junxian Huang huangjunxian6@hisilicon.com --- drivers/infiniband/hw/hns/hns_roce_bond.c | 27 ++++++++++++--------- drivers/infiniband/hw/hns/hns_roce_bond.h | 1 + drivers/infiniband/hw/hns/hns_roce_device.h | 1 - 3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_bond.c b/drivers/infiniband/hw/hns/hns_roce_bond.c index c1e35792246e..17c1a84f8496 100644 --- a/drivers/infiniband/hw/hns/hns_roce_bond.c +++ b/drivers/infiniband/hw/hns/hns_roce_bond.c @@ -107,10 +107,10 @@ struct net_device *hns_roce_get_bond_netdev(struct hns_roce_dev *hr_dev) return net_dev; }
-static void hns_roce_queue_bond_work(struct hns_roce_dev *hr_dev, +static void hns_roce_queue_bond_work(struct hns_roce_bond_group *bond_grp, unsigned long delay) { - schedule_delayed_work(&hr_dev->bond_work, delay); + schedule_delayed_work(&bond_grp->bond_work, delay); }
static void hns_roce_bond_get_active_slave(struct hns_roce_bond_group *bond_grp) @@ -378,20 +378,21 @@ static void hns_roce_do_bond(struct hns_roce_bond_group *bond_grp)
void hns_roce_do_bond_work(struct work_struct *work) { + struct hns_roce_bond_group *bond_grp; struct delayed_work *delayed_work; - struct hns_roce_dev *hr_dev; int status;
delayed_work = to_delayed_work(work); - hr_dev = container_of(delayed_work, struct hns_roce_dev, bond_work); + bond_grp = container_of(delayed_work, struct hns_roce_bond_group, + bond_work); status = mutex_trylock(&roce_bond_mutex); if (!status) { /* delay 1 sec */ - hns_roce_queue_bond_work(hr_dev, HZ); + hns_roce_queue_bond_work(bond_grp, HZ); return; }
- hns_roce_do_bond(hr_dev->bond_grp); + hns_roce_do_bond(bond_grp); mutex_unlock(&roce_bond_mutex); }
@@ -399,8 +400,6 @@ int hns_roce_bond_init(struct hns_roce_dev *hr_dev) { int ret;
- INIT_DELAYED_WORK(&hr_dev->bond_work, hns_roce_do_bond_work); - hr_dev->bond_nb.notifier_call = hns_roce_bond_event; ret = register_netdevice_notifier(&hr_dev->bond_nb); if (ret) { @@ -415,10 +414,11 @@ int hns_roce_bond_init(struct hns_roce_dev *hr_dev) void hns_roce_cleanup_bond(struct hns_roce_dev *hr_dev) { unregister_netdevice_notifier(&hr_dev->bond_nb); - cancel_delayed_work(&hr_dev->bond_work);
- if (hr_dev->bond_grp && hr_dev == hr_dev->bond_grp->main_hr_dev) + if (hr_dev->bond_grp && hr_dev == hr_dev->bond_grp->main_hr_dev) { + cancel_delayed_work(&hr_dev->bond_grp->bond_work); kfree(hr_dev->bond_grp); + }
hr_dev->bond_grp = NULL; } @@ -561,6 +561,9 @@ static struct hns_roce_bond_group *hns_roce_alloc_bond_grp(struct hns_roce_dev * return NULL;
mutex_init(&bond_grp->bond_mutex); + + INIT_DELAYED_WORK(&bond_grp->bond_work, hns_roce_do_bond_work); + bond_grp->upper_dev = upper_dev; bond_grp->main_hr_dev = main_hr_dev; bond_grp->main_net_dev = main_hr_dev->iboe.netdevs[0]; @@ -698,7 +701,7 @@ int hns_roce_bond_event(struct notifier_block *self, } if (support == BOND_EXISTING_NOT_SUPPORT) { hr_dev->bond_grp->bond_ready = false; - hns_roce_queue_bond_work(hr_dev, HZ); + hns_roce_queue_bond_work(hr_dev->bond_grp, HZ); return NOTIFY_DONE; } changed = hns_roce_bond_upper_event(hr_dev, ptr); @@ -706,7 +709,7 @@ int hns_roce_bond_event(struct notifier_block *self, changed = hns_roce_bond_lowerstate_event(hr_dev, ptr); } if (changed) - hns_roce_queue_bond_work(hr_dev, HZ); + hns_roce_queue_bond_work(hr_dev->bond_grp, HZ);
return NOTIFY_DONE; } diff --git a/drivers/infiniband/hw/hns/hns_roce_bond.h b/drivers/infiniband/hw/hns/hns_roce_bond.h index 6fccf4762e86..65a19d781847 100644 --- a/drivers/infiniband/hw/hns/hns_roce_bond.h +++ b/drivers/infiniband/hw/hns/hns_roce_bond.h @@ -67,6 +67,7 @@ struct hns_roce_bond_group { */ struct mutex bond_mutex; struct hns_roce_func_info bond_func_info[ROCE_BOND_FUNC_MAX]; + struct delayed_work bond_work; };
int hns_roce_bond_init(struct hns_roce_dev *hr_dev); diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 68a9bed853a1..7fbfdbed0f4d 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -1124,7 +1124,6 @@ struct hns_roce_dev { u64 dwqe_page;
struct notifier_block bond_nb; - struct delayed_work bond_work; struct hns_roce_bond_group *bond_grp; struct netdev_lag_lower_state_info slave_state; struct hns_roce_port port_data[HNS_ROCE_MAX_PORTS];