]> Git Repo - linux.git/blob - drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
drm/nouveau/kms: Don't change EDID when it hasn't actually changed
[linux.git] / drivers / infiniband / ulp / rtrs / rtrs-srv-sysfs.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * RDMA Transport Layer
4  *
5  * Copyright (c) 2014 - 2018 ProfitBricks GmbH. All rights reserved.
6  * Copyright (c) 2018 - 2019 1&1 IONOS Cloud GmbH. All rights reserved.
7  * Copyright (c) 2019 - 2020 1&1 IONOS SE. All rights reserved.
8  */
9 #undef pr_fmt
10 #define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt
11
12 #include "rtrs-pri.h"
13 #include "rtrs-srv.h"
14 #include "rtrs-log.h"
15
16 static void rtrs_srv_release(struct kobject *kobj)
17 {
18         struct rtrs_srv_sess *sess;
19
20         sess = container_of(kobj, struct rtrs_srv_sess, kobj);
21         kfree(sess);
22 }
23
24 static struct kobj_type ktype = {
25         .sysfs_ops      = &kobj_sysfs_ops,
26         .release        = rtrs_srv_release,
27 };
28
29 static ssize_t rtrs_srv_disconnect_show(struct kobject *kobj,
30                                          struct kobj_attribute *attr,
31                                          char *page)
32 {
33         return scnprintf(page, PAGE_SIZE, "Usage: echo 1 > %s\n",
34                          attr->attr.name);
35 }
36
37 static ssize_t rtrs_srv_disconnect_store(struct kobject *kobj,
38                                           struct kobj_attribute *attr,
39                                           const char *buf, size_t count)
40 {
41         struct rtrs_srv_sess *sess;
42         struct rtrs_sess *s;
43         char str[MAXHOSTNAMELEN];
44
45         sess = container_of(kobj, struct rtrs_srv_sess, kobj);
46         s = &sess->s;
47         if (!sysfs_streq(buf, "1")) {
48                 rtrs_err(s, "%s: invalid value: '%s'\n",
49                           attr->attr.name, buf);
50                 return -EINVAL;
51         }
52
53         sockaddr_to_str((struct sockaddr *)&sess->s.dst_addr, str, sizeof(str));
54
55         rtrs_info(s, "disconnect for path %s requested\n", str);
56         close_sess(sess);
57
58         return count;
59 }
60
61 static struct kobj_attribute rtrs_srv_disconnect_attr =
62         __ATTR(disconnect, 0644,
63                rtrs_srv_disconnect_show, rtrs_srv_disconnect_store);
64
65 static ssize_t rtrs_srv_hca_port_show(struct kobject *kobj,
66                                        struct kobj_attribute *attr,
67                                        char *page)
68 {
69         struct rtrs_srv_sess *sess;
70         struct rtrs_con *usr_con;
71
72         sess = container_of(kobj, typeof(*sess), kobj);
73         usr_con = sess->s.con[0];
74
75         return scnprintf(page, PAGE_SIZE, "%u\n",
76                          usr_con->cm_id->port_num);
77 }
78
79 static struct kobj_attribute rtrs_srv_hca_port_attr =
80         __ATTR(hca_port, 0444, rtrs_srv_hca_port_show, NULL);
81
82 static ssize_t rtrs_srv_hca_name_show(struct kobject *kobj,
83                                        struct kobj_attribute *attr,
84                                        char *page)
85 {
86         struct rtrs_srv_sess *sess;
87
88         sess = container_of(kobj, struct rtrs_srv_sess, kobj);
89
90         return scnprintf(page, PAGE_SIZE, "%s\n",
91                          sess->s.dev->ib_dev->name);
92 }
93
94 static struct kobj_attribute rtrs_srv_hca_name_attr =
95         __ATTR(hca_name, 0444, rtrs_srv_hca_name_show, NULL);
96
97 static ssize_t rtrs_srv_src_addr_show(struct kobject *kobj,
98                                        struct kobj_attribute *attr,
99                                        char *page)
100 {
101         struct rtrs_srv_sess *sess;
102         int cnt;
103
104         sess = container_of(kobj, struct rtrs_srv_sess, kobj);
105         cnt = sockaddr_to_str((struct sockaddr *)&sess->s.dst_addr,
106                               page, PAGE_SIZE);
107         return cnt + scnprintf(page + cnt, PAGE_SIZE - cnt, "\n");
108 }
109
110 static struct kobj_attribute rtrs_srv_src_addr_attr =
111         __ATTR(src_addr, 0444, rtrs_srv_src_addr_show, NULL);
112
113 static ssize_t rtrs_srv_dst_addr_show(struct kobject *kobj,
114                                        struct kobj_attribute *attr,
115                                        char *page)
116 {
117         struct rtrs_srv_sess *sess;
118         int cnt;
119
120         sess = container_of(kobj, struct rtrs_srv_sess, kobj);
121         cnt = sockaddr_to_str((struct sockaddr *)&sess->s.src_addr,
122                               page, PAGE_SIZE);
123         return cnt + scnprintf(page + cnt, PAGE_SIZE - cnt, "\n");
124 }
125
126 static struct kobj_attribute rtrs_srv_dst_addr_attr =
127         __ATTR(dst_addr, 0444, rtrs_srv_dst_addr_show, NULL);
128
129 static struct attribute *rtrs_srv_sess_attrs[] = {
130         &rtrs_srv_hca_name_attr.attr,
131         &rtrs_srv_hca_port_attr.attr,
132         &rtrs_srv_src_addr_attr.attr,
133         &rtrs_srv_dst_addr_attr.attr,
134         &rtrs_srv_disconnect_attr.attr,
135         NULL,
136 };
137
138 static struct attribute_group rtrs_srv_sess_attr_group = {
139         .attrs = rtrs_srv_sess_attrs,
140 };
141
142 STAT_ATTR(struct rtrs_srv_stats, rdma,
143           rtrs_srv_stats_rdma_to_str,
144           rtrs_srv_reset_rdma_stats);
145
146 static struct attribute *rtrs_srv_stats_attrs[] = {
147         &rdma_attr.attr,
148         NULL,
149 };
150
151 static struct attribute_group rtrs_srv_stats_attr_group = {
152         .attrs = rtrs_srv_stats_attrs,
153 };
154
155 static void rtrs_srv_dev_release(struct device *dev)
156 {
157         struct rtrs_srv *srv = container_of(dev, struct rtrs_srv, dev);
158
159         kfree(srv);
160 }
161
162 static int rtrs_srv_create_once_sysfs_root_folders(struct rtrs_srv_sess *sess)
163 {
164         struct rtrs_srv *srv = sess->srv;
165         int err = 0;
166
167         mutex_lock(&srv->paths_mutex);
168         if (srv->dev_ref++) {
169                 /*
170                  * Device needs to be registered only on the first session
171                  */
172                 goto unlock;
173         }
174         srv->dev.class = rtrs_dev_class;
175         srv->dev.release = rtrs_srv_dev_release;
176         err = dev_set_name(&srv->dev, "%s", sess->s.sessname);
177         if (err)
178                 goto unlock;
179
180         /*
181          * Suppress user space notification until
182          * sysfs files are created
183          */
184         dev_set_uevent_suppress(&srv->dev, true);
185         err = device_register(&srv->dev);
186         if (err) {
187                 pr_err("device_register(): %d\n", err);
188                 goto put;
189         }
190         srv->kobj_paths = kobject_create_and_add("paths", &srv->dev.kobj);
191         if (!srv->kobj_paths) {
192                 err = -ENOMEM;
193                 pr_err("kobject_create_and_add(): %d\n", err);
194                 device_unregister(&srv->dev);
195                 goto unlock;
196         }
197         dev_set_uevent_suppress(&srv->dev, false);
198         kobject_uevent(&srv->dev.kobj, KOBJ_ADD);
199         goto unlock;
200
201 put:
202         put_device(&srv->dev);
203 unlock:
204         mutex_unlock(&srv->paths_mutex);
205
206         return err;
207 }
208
209 static void
210 rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_sess *sess)
211 {
212         struct rtrs_srv *srv = sess->srv;
213
214         mutex_lock(&srv->paths_mutex);
215         if (!--srv->dev_ref) {
216                 kobject_del(srv->kobj_paths);
217                 kobject_put(srv->kobj_paths);
218                 mutex_unlock(&srv->paths_mutex);
219                 device_unregister(&srv->dev);
220         } else {
221                 mutex_unlock(&srv->paths_mutex);
222         }
223 }
224
225 static void rtrs_srv_sess_stats_release(struct kobject *kobj)
226 {
227         struct rtrs_srv_stats *stats;
228
229         stats = container_of(kobj, struct rtrs_srv_stats, kobj_stats);
230
231         kfree(stats);
232 }
233
234 static struct kobj_type ktype_stats = {
235         .sysfs_ops = &kobj_sysfs_ops,
236         .release = rtrs_srv_sess_stats_release,
237 };
238
239 static int rtrs_srv_create_stats_files(struct rtrs_srv_sess *sess)
240 {
241         int err;
242         struct rtrs_sess *s = &sess->s;
243
244         err = kobject_init_and_add(&sess->stats->kobj_stats, &ktype_stats,
245                                    &sess->kobj, "stats");
246         if (err) {
247                 rtrs_err(s, "kobject_init_and_add(): %d\n", err);
248                 return err;
249         }
250         err = sysfs_create_group(&sess->stats->kobj_stats,
251                                  &rtrs_srv_stats_attr_group);
252         if (err) {
253                 rtrs_err(s, "sysfs_create_group(): %d\n", err);
254                 goto err;
255         }
256
257         return 0;
258
259 err:
260         kobject_del(&sess->stats->kobj_stats);
261         kobject_put(&sess->stats->kobj_stats);
262
263         return err;
264 }
265
266 int rtrs_srv_create_sess_files(struct rtrs_srv_sess *sess)
267 {
268         struct rtrs_srv *srv = sess->srv;
269         struct rtrs_sess *s = &sess->s;
270         char str[NAME_MAX];
271         int err, cnt;
272
273         cnt = sockaddr_to_str((struct sockaddr *)&sess->s.dst_addr,
274                               str, sizeof(str));
275         cnt += scnprintf(str + cnt, sizeof(str) - cnt, "@");
276         sockaddr_to_str((struct sockaddr *)&sess->s.src_addr,
277                         str + cnt, sizeof(str) - cnt);
278
279         err = rtrs_srv_create_once_sysfs_root_folders(sess);
280         if (err)
281                 return err;
282
283         err = kobject_init_and_add(&sess->kobj, &ktype, srv->kobj_paths,
284                                    "%s", str);
285         if (err) {
286                 rtrs_err(s, "kobject_init_and_add(): %d\n", err);
287                 goto destroy_root;
288         }
289         err = sysfs_create_group(&sess->kobj, &rtrs_srv_sess_attr_group);
290         if (err) {
291                 rtrs_err(s, "sysfs_create_group(): %d\n", err);
292                 goto put_kobj;
293         }
294         err = rtrs_srv_create_stats_files(sess);
295         if (err)
296                 goto remove_group;
297
298         return 0;
299
300 remove_group:
301         sysfs_remove_group(&sess->kobj, &rtrs_srv_sess_attr_group);
302 put_kobj:
303         kobject_del(&sess->kobj);
304         kobject_put(&sess->kobj);
305 destroy_root:
306         rtrs_srv_destroy_once_sysfs_root_folders(sess);
307
308         return err;
309 }
310
311 void rtrs_srv_destroy_sess_files(struct rtrs_srv_sess *sess)
312 {
313         if (sess->kobj.state_in_sysfs) {
314                 kobject_del(&sess->stats->kobj_stats);
315                 kobject_put(&sess->stats->kobj_stats);
316                 kobject_del(&sess->kobj);
317                 kobject_put(&sess->kobj);
318
319                 rtrs_srv_destroy_once_sysfs_root_folders(sess);
320         }
321 }
This page took 0.052525 seconds and 4 git commands to generate.