diff options
Diffstat (limited to 'drivers/infiniband')
| -rw-r--r-- | drivers/infiniband/core/frmr_pools.c | 31 | ||||
| -rw-r--r-- | drivers/infiniband/core/frmr_pools.h | 2 | ||||
| -rw-r--r-- | drivers/infiniband/core/nldev.c | 37 |
3 files changed, 68 insertions, 2 deletions
diff --git a/drivers/infiniband/core/frmr_pools.c b/drivers/infiniband/core/frmr_pools.c index 0e1330807b88..5e992ff3d7cf 100644 --- a/drivers/infiniband/core/frmr_pools.c +++ b/drivers/infiniband/core/frmr_pools.c @@ -174,7 +174,7 @@ out: if (has_work) queue_delayed_work( pools->aging_wq, &pool->aging_work, - secs_to_jiffies(FRMR_POOLS_DEFAULT_AGING_PERIOD_SECS)); + secs_to_jiffies(READ_ONCE(pools->aging_period_sec))); } static void destroy_frmr_pool(struct ib_device *device, @@ -213,6 +213,8 @@ int ib_frmr_pools_init(struct ib_device *device, return -ENOMEM; } + pools->aging_period_sec = FRMR_POOLS_DEFAULT_AGING_PERIOD_SECS; + device->frmr_pools = pools; return 0; } @@ -245,6 +247,31 @@ void ib_frmr_pools_cleanup(struct ib_device *device) } EXPORT_SYMBOL(ib_frmr_pools_cleanup); +int ib_frmr_pools_set_aging_period(struct ib_device *device, u32 period_sec) +{ + struct ib_frmr_pools *pools = device->frmr_pools; + struct ib_frmr_pool *pool; + struct rb_node *node; + + if (!pools) + return -EINVAL; + + if (period_sec == 0) + return -EINVAL; + + WRITE_ONCE(pools->aging_period_sec, period_sec); + + read_lock(&pools->rb_lock); + for (node = rb_first(&pools->rb_root); node; node = rb_next(node)) { + pool = rb_entry(node, struct ib_frmr_pool, node); + mod_delayed_work(pools->aging_wq, &pool->aging_work, + secs_to_jiffies(period_sec)); + } + read_unlock(&pools->rb_lock); + + return 0; +} + static inline int compare_keys(struct ib_frmr_key *key1, struct ib_frmr_key *key2) { @@ -513,7 +540,7 @@ int ib_frmr_pool_push(struct ib_device *device, struct ib_mr *mr) if (ret == 0 && schedule_aging) queue_delayed_work(pools->aging_wq, &pool->aging_work, - secs_to_jiffies(FRMR_POOLS_DEFAULT_AGING_PERIOD_SECS)); + secs_to_jiffies(READ_ONCE(pools->aging_period_sec))); return ret; } diff --git a/drivers/infiniband/core/frmr_pools.h b/drivers/infiniband/core/frmr_pools.h index f7519beb6abd..67e1402169ae 100644 --- a/drivers/infiniband/core/frmr_pools.h +++ b/drivers/infiniband/core/frmr_pools.h @@ -54,8 +54,10 @@ struct ib_frmr_pools { const struct ib_frmr_pool_ops *pool_ops; struct workqueue_struct *aging_wq; + u32 aging_period_sec; }; int ib_frmr_pools_set_pinned(struct ib_device *device, struct ib_frmr_key *key, u32 pinned_handles); +int ib_frmr_pools_set_aging_period(struct ib_device *device, u32 period_sec); #endif /* RDMA_CORE_FRMR_POOLS_H */ diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c index 6637c76165be..8d004b7568b7 100644 --- a/drivers/infiniband/core/nldev.c +++ b/drivers/infiniband/core/nldev.c @@ -184,6 +184,7 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = { [RDMA_NLDEV_ATTR_FRMR_POOL_QUEUE_HANDLES] = { .type = NLA_U32 }, [RDMA_NLDEV_ATTR_FRMR_POOL_MAX_IN_USE] = { .type = NLA_U64 }, [RDMA_NLDEV_ATTR_FRMR_POOL_IN_USE] = { .type = NLA_U64 }, + [RDMA_NLDEV_ATTR_FRMR_POOLS_AGING_PERIOD] = { .type = NLA_U32 }, }; static int put_driver_name_print_type(struct sk_buff *msg, const char *name, @@ -2799,6 +2800,38 @@ err: return ret; } +static int nldev_frmr_pools_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh, + struct netlink_ext_ack *extack) +{ + struct nlattr *tb[RDMA_NLDEV_ATTR_MAX]; + struct ib_device *device; + u32 aging_period; + int err; + + err = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1, nldev_policy, + extack); + if (err) + return err; + + if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX]) + return -EINVAL; + + if (!tb[RDMA_NLDEV_ATTR_FRMR_POOLS_AGING_PERIOD]) + return -EINVAL; + + device = ib_device_get_by_index( + sock_net(skb->sk), nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX])); + if (!device) + return -EINVAL; + + aging_period = nla_get_u32(tb[RDMA_NLDEV_ATTR_FRMR_POOLS_AGING_PERIOD]); + + err = ib_frmr_pools_set_aging_period(device, aging_period); + + ib_device_put(device); + return err; +} + static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = { [RDMA_NLDEV_CMD_GET] = { .doit = nldev_get_doit, @@ -2908,6 +2941,10 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = { [RDMA_NLDEV_CMD_FRMR_POOLS_GET] = { .dump = nldev_frmr_pools_get_dumpit, }, + [RDMA_NLDEV_CMD_FRMR_POOLS_SET] = { + .doit = nldev_frmr_pools_set_doit, + .flags = RDMA_NL_ADMIN_PERM, + }, }; static int fill_mon_netdev_rename(struct sk_buff *msg, |
