diff options
author | Karsten Graul <kgraul@linux.ibm.com> | 2020-05-01 12:48:03 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-05-01 16:20:04 -0700 |
commit | fb33d27727254618aaf6bc2fedcb0fda1d5c0239 (patch) | |
tree | b8431c974689ac16d39316ba7e1d258958ed08f4 /net | |
parent | 4a3641c160873fe6b6bcff00a6ea15e7430d8d42 (diff) |
net/smc: map and register buffers for a new link
Introduce support to map and register all current buffers for a new
link. smcr_buf_map_lgr() will map used buffers for a new link and
smcr_buf_reg_lgr() can be called to register used buffers on the
IB device of the new link.
Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Reviewed-by: Ursula Braun <ubraun@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/smc/smc_core.c | 60 | ||||
-rw-r--r-- | net/smc/smc_core.h | 2 |
2 files changed, 62 insertions, 0 deletions
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index d5ecea490b4e..0e87f652caea 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -1185,6 +1185,66 @@ int smcr_link_reg_rmb(struct smc_link *link, struct smc_buf_desc *rmb_desc) return 0; } +static int _smcr_buf_map_lgr(struct smc_link *lnk, struct mutex *lock, + struct list_head *lst, bool is_rmb) +{ + struct smc_buf_desc *buf_desc, *bf; + int rc = 0; + + mutex_lock(lock); + list_for_each_entry_safe(buf_desc, bf, lst, list) { + if (!buf_desc->used) + continue; + rc = smcr_buf_map_link(buf_desc, is_rmb, lnk); + if (rc) + goto out; + } +out: + mutex_unlock(lock); + return rc; +} + +/* map all used buffers of lgr for a new link */ +int smcr_buf_map_lgr(struct smc_link *lnk) +{ + struct smc_link_group *lgr = lnk->lgr; + int i, rc = 0; + + for (i = 0; i < SMC_RMBE_SIZES; i++) { + rc = _smcr_buf_map_lgr(lnk, &lgr->rmbs_lock, + &lgr->rmbs[i], true); + if (rc) + return rc; + rc = _smcr_buf_map_lgr(lnk, &lgr->sndbufs_lock, + &lgr->sndbufs[i], false); + if (rc) + return rc; + } + return 0; +} + +/* register all used buffers of lgr for a new link */ +int smcr_buf_reg_lgr(struct smc_link *lnk) +{ + struct smc_link_group *lgr = lnk->lgr; + struct smc_buf_desc *buf_desc, *bf; + int i, rc = 0; + + mutex_lock(&lgr->rmbs_lock); + for (i = 0; i < SMC_RMBE_SIZES; i++) { + list_for_each_entry_safe(buf_desc, bf, &lgr->rmbs[i], list) { + if (!buf_desc->used) + continue; + rc = smcr_link_reg_rmb(lnk, buf_desc); + if (rc) + goto out; + } + } +out: + mutex_unlock(&lgr->rmbs_lock); + return rc; +} + static struct smc_buf_desc *smcr_new_buf_create(struct smc_link_group *lgr, bool is_rmb, int bufsize) { diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h index fa532a423fd7..61ddb5264936 100644 --- a/net/smc/smc_core.h +++ b/net/smc/smc_core.h @@ -368,6 +368,8 @@ int smc_core_init(void); void smc_core_exit(void); void smcr_link_clear(struct smc_link *lnk); +int smcr_buf_map_lgr(struct smc_link *lnk); +int smcr_buf_reg_lgr(struct smc_link *lnk); int smcr_link_reg_rmb(struct smc_link *link, struct smc_buf_desc *rmb_desc); static inline struct smc_link_group *smc_get_lgr(struct smc_link *link) { |