Merge branch 'smc-last-part-of-termination-improvements'
Karsten Graul says: ==================== last part of termination improvements Patches 1 and 2 finish the set of termination patches, introducing a reboot handler that terminates all link groups. Patch 3 adds an rcu_barrier before the module is unloaded, and patch 4 is cleanup. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
3af7ff93e4
|
@ -25,6 +25,7 @@
|
|||
#include <linux/in.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/rcupdate_wait.h>
|
||||
|
||||
#include <net/sock.h>
|
||||
#include <net/tcp.h>
|
||||
|
@ -2038,22 +2039,28 @@ static int __init smc_init(void)
|
|||
if (rc)
|
||||
goto out_pernet_subsys;
|
||||
|
||||
rc = smc_core_init();
|
||||
if (rc) {
|
||||
pr_err("%s: smc_core_init fails with %d\n", __func__, rc);
|
||||
goto out_pnet;
|
||||
}
|
||||
|
||||
rc = smc_llc_init();
|
||||
if (rc) {
|
||||
pr_err("%s: smc_llc_init fails with %d\n", __func__, rc);
|
||||
goto out_pnet;
|
||||
goto out_core;
|
||||
}
|
||||
|
||||
rc = smc_cdc_init();
|
||||
if (rc) {
|
||||
pr_err("%s: smc_cdc_init fails with %d\n", __func__, rc);
|
||||
goto out_pnet;
|
||||
goto out_core;
|
||||
}
|
||||
|
||||
rc = proto_register(&smc_proto, 1);
|
||||
if (rc) {
|
||||
pr_err("%s: proto_register(v4) fails with %d\n", __func__, rc);
|
||||
goto out_pnet;
|
||||
goto out_core;
|
||||
}
|
||||
|
||||
rc = proto_register(&smc_proto6, 1);
|
||||
|
@ -2085,6 +2092,8 @@ out_proto6:
|
|||
proto_unregister(&smc_proto6);
|
||||
out_proto:
|
||||
proto_unregister(&smc_proto);
|
||||
out_core:
|
||||
smc_core_exit();
|
||||
out_pnet:
|
||||
smc_pnet_exit();
|
||||
out_pernet_subsys:
|
||||
|
@ -2095,14 +2104,15 @@ out_pernet_subsys:
|
|||
|
||||
static void __exit smc_exit(void)
|
||||
{
|
||||
smc_core_exit();
|
||||
static_branch_disable(&tcp_have_smc);
|
||||
smc_ib_unregister_client();
|
||||
sock_unregister(PF_SMC);
|
||||
smc_core_exit();
|
||||
smc_ib_unregister_client();
|
||||
proto_unregister(&smc_proto6);
|
||||
proto_unregister(&smc_proto);
|
||||
smc_pnet_exit();
|
||||
unregister_pernet_subsys(&smc_net_ops);
|
||||
rcu_barrier();
|
||||
}
|
||||
|
||||
module_init(smc_init);
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#include "smc_cdc.h"
|
||||
#include "smc_close.h"
|
||||
|
||||
#define SMC_CLOSE_WAIT_LISTEN_CLCSOCK_TIME (5 * HZ)
|
||||
|
||||
/* release the clcsock that is assigned to the smc_sock */
|
||||
void smc_clcsock_release(struct smc_sock *smc)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <linux/if_vlan.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <net/tcp.h>
|
||||
#include <net/sock.h>
|
||||
#include <rdma/ib_verbs.h>
|
||||
|
@ -39,6 +41,9 @@ static struct smc_lgr_list smc_lgr_list = { /* established link groups */
|
|||
.num = 0,
|
||||
};
|
||||
|
||||
static atomic_t lgr_cnt; /* number of existing link groups */
|
||||
static DECLARE_WAIT_QUEUE_HEAD(lgrs_deleted);
|
||||
|
||||
static void smc_buf_free(struct smc_link_group *lgr, bool is_rmb,
|
||||
struct smc_buf_desc *buf_desc);
|
||||
|
||||
|
@ -319,6 +324,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
|
|||
rc = smc_wr_create_link(lnk);
|
||||
if (rc)
|
||||
goto destroy_qp;
|
||||
atomic_inc(&lgr_cnt);
|
||||
atomic_inc(&ini->ib_dev->lnk_cnt);
|
||||
}
|
||||
smc->conn.lgr = lgr;
|
||||
spin_lock_bh(lgr_lock);
|
||||
|
@ -406,6 +413,8 @@ static void smc_link_clear(struct smc_link *lnk)
|
|||
smc_ib_destroy_queue_pair(lnk);
|
||||
smc_ib_dealloc_protection_domain(lnk);
|
||||
smc_wr_free_link_mem(lnk);
|
||||
if (!atomic_dec_return(&lnk->smcibdev->lnk_cnt))
|
||||
wake_up(&lnk->smcibdev->lnks_deleted);
|
||||
}
|
||||
|
||||
static void smcr_buf_free(struct smc_link_group *lgr, bool is_rmb,
|
||||
|
@ -492,6 +501,8 @@ static void smc_lgr_free(struct smc_link_group *lgr)
|
|||
} else {
|
||||
smc_link_clear(&lgr->lnk[SMC_SINGLE_LINK]);
|
||||
put_device(&lgr->lnk[SMC_SINGLE_LINK].smcibdev->ibdev->dev);
|
||||
if (!atomic_dec_return(&lgr_cnt))
|
||||
wake_up(&lgrs_deleted);
|
||||
}
|
||||
kfree(lgr);
|
||||
}
|
||||
|
@ -729,6 +740,15 @@ void smc_smcr_terminate_all(struct smc_ib_device *smcibdev)
|
|||
list_del_init(&lgr->list);
|
||||
__smc_lgr_terminate(lgr, false);
|
||||
}
|
||||
|
||||
if (smcibdev) {
|
||||
if (atomic_read(&smcibdev->lnk_cnt))
|
||||
wait_event(smcibdev->lnks_deleted,
|
||||
!atomic_read(&smcibdev->lnk_cnt));
|
||||
} else {
|
||||
if (atomic_read(&lgr_cnt))
|
||||
wait_event(lgrs_deleted, !atomic_read(&lgr_cnt));
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine vlan of internal TCP socket.
|
||||
|
@ -1263,8 +1283,27 @@ static void smc_lgrs_shutdown(void)
|
|||
spin_unlock(&smcd_dev_list.lock);
|
||||
}
|
||||
|
||||
static int smc_core_reboot_event(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
smc_lgrs_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block smc_reboot_notifier = {
|
||||
.notifier_call = smc_core_reboot_event,
|
||||
};
|
||||
|
||||
int __init smc_core_init(void)
|
||||
{
|
||||
atomic_set(&lgr_cnt, 0);
|
||||
return register_reboot_notifier(&smc_reboot_notifier);
|
||||
}
|
||||
|
||||
/* Called (from smc_exit) when module is removed */
|
||||
void smc_core_exit(void)
|
||||
{
|
||||
unregister_reboot_notifier(&smc_reboot_notifier);
|
||||
smc_lgrs_shutdown();
|
||||
}
|
||||
|
|
|
@ -318,6 +318,7 @@ void smc_conn_free(struct smc_connection *conn);
|
|||
int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini);
|
||||
void smcd_conn_free(struct smc_connection *conn);
|
||||
void smc_lgr_schedule_free_work_fast(struct smc_link_group *lgr);
|
||||
int smc_core_init(void);
|
||||
void smc_core_exit(void);
|
||||
|
||||
static inline struct smc_link_group *smc_get_lgr(struct smc_link *link)
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/random.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/wait.h>
|
||||
#include <rdma/ib_verbs.h>
|
||||
#include <rdma/ib_cache.h>
|
||||
|
||||
|
@ -543,7 +544,8 @@ static void smc_ib_add_dev(struct ib_device *ibdev)
|
|||
|
||||
smcibdev->ibdev = ibdev;
|
||||
INIT_WORK(&smcibdev->port_event_work, smc_ib_port_event_work);
|
||||
|
||||
atomic_set(&smcibdev->lnk_cnt, 0);
|
||||
init_waitqueue_head(&smcibdev->lnks_deleted);
|
||||
spin_lock(&smc_ib_devices.lock);
|
||||
list_add_tail(&smcibdev->list, &smc_ib_devices.list);
|
||||
spin_unlock(&smc_ib_devices.lock);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/wait.h>
|
||||
#include <rdma/ib_verbs.h>
|
||||
#include <net/smc.h>
|
||||
|
||||
|
@ -48,6 +49,8 @@ struct smc_ib_device { /* ib-device infos for smc */
|
|||
struct work_struct port_event_work;
|
||||
unsigned long port_event_mask;
|
||||
DECLARE_BITMAP(ports_going_away, SMC_MAX_PORTS);
|
||||
atomic_t lnk_cnt; /* number of links on ibdev */
|
||||
wait_queue_head_t lnks_deleted; /* wait 4 removal of all links*/
|
||||
};
|
||||
|
||||
struct smc_buf_desc;
|
||||
|
|
Loading…
Reference in a new issue