0001
0002
0003
0004
0005
0006
0007
0008
0009 #undef pr_fmt
0010 #define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt
0011
0012 #include "rtrs-pri.h"
0013 #include "rtrs-srv.h"
0014 #include "rtrs-log.h"
0015
0016 static void rtrs_srv_release(struct kobject *kobj)
0017 {
0018 struct rtrs_srv_path *srv_path;
0019
0020 srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
0021 kfree(srv_path);
0022 }
0023
0024 static struct kobj_type ktype = {
0025 .sysfs_ops = &kobj_sysfs_ops,
0026 .release = rtrs_srv_release,
0027 };
0028
0029 static ssize_t rtrs_srv_disconnect_show(struct kobject *kobj,
0030 struct kobj_attribute *attr, char *buf)
0031 {
0032 return sysfs_emit(buf, "Usage: echo 1 > %s\n", attr->attr.name);
0033 }
0034
0035 static ssize_t rtrs_srv_disconnect_store(struct kobject *kobj,
0036 struct kobj_attribute *attr,
0037 const char *buf, size_t count)
0038 {
0039 struct rtrs_srv_path *srv_path;
0040 struct rtrs_path *s;
0041 char str[MAXHOSTNAMELEN];
0042
0043 srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
0044 s = &srv_path->s;
0045 if (!sysfs_streq(buf, "1")) {
0046 rtrs_err(s, "%s: invalid value: '%s'\n",
0047 attr->attr.name, buf);
0048 return -EINVAL;
0049 }
0050
0051 sockaddr_to_str((struct sockaddr *)&srv_path->s.dst_addr, str,
0052 sizeof(str));
0053
0054 rtrs_info(s, "disconnect for path %s requested\n", str);
0055
0056 sysfs_remove_file_self(&srv_path->kobj, &attr->attr);
0057 close_path(srv_path);
0058
0059 return count;
0060 }
0061
0062 static struct kobj_attribute rtrs_srv_disconnect_attr =
0063 __ATTR(disconnect, 0644,
0064 rtrs_srv_disconnect_show, rtrs_srv_disconnect_store);
0065
0066 static ssize_t rtrs_srv_hca_port_show(struct kobject *kobj,
0067 struct kobj_attribute *attr,
0068 char *page)
0069 {
0070 struct rtrs_srv_path *srv_path;
0071 struct rtrs_con *usr_con;
0072
0073 srv_path = container_of(kobj, typeof(*srv_path), kobj);
0074 usr_con = srv_path->s.con[0];
0075
0076 return sysfs_emit(page, "%u\n", usr_con->cm_id->port_num);
0077 }
0078
0079 static struct kobj_attribute rtrs_srv_hca_port_attr =
0080 __ATTR(hca_port, 0444, rtrs_srv_hca_port_show, NULL);
0081
0082 static ssize_t rtrs_srv_hca_name_show(struct kobject *kobj,
0083 struct kobj_attribute *attr,
0084 char *page)
0085 {
0086 struct rtrs_srv_path *srv_path;
0087
0088 srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
0089
0090 return sysfs_emit(page, "%s\n", srv_path->s.dev->ib_dev->name);
0091 }
0092
0093 static struct kobj_attribute rtrs_srv_hca_name_attr =
0094 __ATTR(hca_name, 0444, rtrs_srv_hca_name_show, NULL);
0095
0096 static ssize_t rtrs_srv_src_addr_show(struct kobject *kobj,
0097 struct kobj_attribute *attr,
0098 char *page)
0099 {
0100 struct rtrs_srv_path *srv_path;
0101 int cnt;
0102
0103 srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
0104 cnt = sockaddr_to_str((struct sockaddr *)&srv_path->s.dst_addr,
0105 page, PAGE_SIZE);
0106 return cnt + sysfs_emit_at(page, cnt, "\n");
0107 }
0108
0109 static struct kobj_attribute rtrs_srv_src_addr_attr =
0110 __ATTR(src_addr, 0444, rtrs_srv_src_addr_show, NULL);
0111
0112 static ssize_t rtrs_srv_dst_addr_show(struct kobject *kobj,
0113 struct kobj_attribute *attr,
0114 char *page)
0115 {
0116 struct rtrs_srv_path *srv_path;
0117 int len;
0118
0119 srv_path = container_of(kobj, struct rtrs_srv_path, kobj);
0120 len = sockaddr_to_str((struct sockaddr *)&srv_path->s.src_addr, page,
0121 PAGE_SIZE);
0122 len += sysfs_emit_at(page, len, "\n");
0123 return len;
0124 }
0125
0126 static struct kobj_attribute rtrs_srv_dst_addr_attr =
0127 __ATTR(dst_addr, 0444, rtrs_srv_dst_addr_show, NULL);
0128
0129 static struct attribute *rtrs_srv_path_attrs[] = {
0130 &rtrs_srv_hca_name_attr.attr,
0131 &rtrs_srv_hca_port_attr.attr,
0132 &rtrs_srv_src_addr_attr.attr,
0133 &rtrs_srv_dst_addr_attr.attr,
0134 &rtrs_srv_disconnect_attr.attr,
0135 NULL,
0136 };
0137
0138 static const struct attribute_group rtrs_srv_path_attr_group = {
0139 .attrs = rtrs_srv_path_attrs,
0140 };
0141
0142 STAT_ATTR(struct rtrs_srv_stats, rdma,
0143 rtrs_srv_stats_rdma_to_str,
0144 rtrs_srv_reset_rdma_stats);
0145
0146 static struct attribute *rtrs_srv_stats_attrs[] = {
0147 &rdma_attr.attr,
0148 NULL,
0149 };
0150
0151 static const struct attribute_group rtrs_srv_stats_attr_group = {
0152 .attrs = rtrs_srv_stats_attrs,
0153 };
0154
0155 static int rtrs_srv_create_once_sysfs_root_folders(struct rtrs_srv_path *srv_path)
0156 {
0157 struct rtrs_srv_sess *srv = srv_path->srv;
0158 int err = 0;
0159
0160 mutex_lock(&srv->paths_mutex);
0161 if (srv->dev_ref++) {
0162
0163
0164
0165 goto unlock;
0166 }
0167 srv->dev.class = rtrs_dev_class;
0168 err = dev_set_name(&srv->dev, "%s", srv_path->s.sessname);
0169 if (err)
0170 goto unlock;
0171
0172
0173
0174
0175
0176 dev_set_uevent_suppress(&srv->dev, true);
0177 err = device_add(&srv->dev);
0178 if (err) {
0179 pr_err("device_add(): %d\n", err);
0180 put_device(&srv->dev);
0181 goto unlock;
0182 }
0183 srv->kobj_paths = kobject_create_and_add("paths", &srv->dev.kobj);
0184 if (!srv->kobj_paths) {
0185 err = -ENOMEM;
0186 pr_err("kobject_create_and_add(): %d\n", err);
0187 device_del(&srv->dev);
0188 put_device(&srv->dev);
0189 goto unlock;
0190 }
0191 dev_set_uevent_suppress(&srv->dev, false);
0192 kobject_uevent(&srv->dev.kobj, KOBJ_ADD);
0193 unlock:
0194 mutex_unlock(&srv->paths_mutex);
0195
0196 return err;
0197 }
0198
0199 static void
0200 rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_path *srv_path)
0201 {
0202 struct rtrs_srv_sess *srv = srv_path->srv;
0203
0204 mutex_lock(&srv->paths_mutex);
0205 if (!--srv->dev_ref) {
0206 kobject_del(srv->kobj_paths);
0207 kobject_put(srv->kobj_paths);
0208 mutex_unlock(&srv->paths_mutex);
0209 device_del(&srv->dev);
0210 put_device(&srv->dev);
0211 } else {
0212 put_device(&srv->dev);
0213 mutex_unlock(&srv->paths_mutex);
0214 }
0215 }
0216
0217 static void rtrs_srv_path_stats_release(struct kobject *kobj)
0218 {
0219 struct rtrs_srv_stats *stats;
0220
0221 stats = container_of(kobj, struct rtrs_srv_stats, kobj_stats);
0222
0223 free_percpu(stats->rdma_stats);
0224
0225 kfree(stats);
0226 }
0227
0228 static struct kobj_type ktype_stats = {
0229 .sysfs_ops = &kobj_sysfs_ops,
0230 .release = rtrs_srv_path_stats_release,
0231 };
0232
0233 static int rtrs_srv_create_stats_files(struct rtrs_srv_path *srv_path)
0234 {
0235 int err;
0236 struct rtrs_path *s = &srv_path->s;
0237
0238 err = kobject_init_and_add(&srv_path->stats->kobj_stats, &ktype_stats,
0239 &srv_path->kobj, "stats");
0240 if (err) {
0241 rtrs_err(s, "kobject_init_and_add(): %d\n", err);
0242 kobject_put(&srv_path->stats->kobj_stats);
0243 return err;
0244 }
0245 err = sysfs_create_group(&srv_path->stats->kobj_stats,
0246 &rtrs_srv_stats_attr_group);
0247 if (err) {
0248 rtrs_err(s, "sysfs_create_group(): %d\n", err);
0249 goto err;
0250 }
0251
0252 return 0;
0253
0254 err:
0255 kobject_del(&srv_path->stats->kobj_stats);
0256 kobject_put(&srv_path->stats->kobj_stats);
0257
0258 return err;
0259 }
0260
0261 int rtrs_srv_create_path_files(struct rtrs_srv_path *srv_path)
0262 {
0263 struct rtrs_srv_sess *srv = srv_path->srv;
0264 struct rtrs_path *s = &srv_path->s;
0265 char str[NAME_MAX];
0266 int err;
0267 struct rtrs_addr path = {
0268 .src = &srv_path->s.dst_addr,
0269 .dst = &srv_path->s.src_addr,
0270 };
0271
0272 rtrs_addr_to_str(&path, str, sizeof(str));
0273 err = rtrs_srv_create_once_sysfs_root_folders(srv_path);
0274 if (err)
0275 return err;
0276
0277 err = kobject_init_and_add(&srv_path->kobj, &ktype, srv->kobj_paths,
0278 "%s", str);
0279 if (err) {
0280 rtrs_err(s, "kobject_init_and_add(): %d\n", err);
0281 goto destroy_root;
0282 }
0283 err = sysfs_create_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
0284 if (err) {
0285 rtrs_err(s, "sysfs_create_group(): %d\n", err);
0286 goto put_kobj;
0287 }
0288 err = rtrs_srv_create_stats_files(srv_path);
0289 if (err)
0290 goto remove_group;
0291
0292 return 0;
0293
0294 remove_group:
0295 sysfs_remove_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
0296 put_kobj:
0297 kobject_del(&srv_path->kobj);
0298 destroy_root:
0299 kobject_put(&srv_path->kobj);
0300 rtrs_srv_destroy_once_sysfs_root_folders(srv_path);
0301
0302 return err;
0303 }
0304
0305 void rtrs_srv_destroy_path_files(struct rtrs_srv_path *srv_path)
0306 {
0307 if (srv_path->kobj.state_in_sysfs) {
0308 kobject_del(&srv_path->stats->kobj_stats);
0309 kobject_put(&srv_path->stats->kobj_stats);
0310 sysfs_remove_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
0311 kobject_put(&srv_path->kobj);
0312
0313 rtrs_srv_destroy_once_sysfs_root_folders(srv_path);
0314 }
0315 }