linux/net/sunrpc/sysfs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2020 Anna Schumaker <Anna.Schumaker@Netapp.com>
   4 */
   5#include <linux/sunrpc/clnt.h>
   6#include <linux/kobject.h>
   7#include <linux/sunrpc/addr.h>
   8#include <linux/sunrpc/xprtsock.h>
   9
  10#include "sysfs.h"
  11
  12struct xprt_addr {
  13        const char *addr;
  14        struct rcu_head rcu;
  15};
  16
  17static void free_xprt_addr(struct rcu_head *head)
  18{
  19        struct xprt_addr *addr = container_of(head, struct xprt_addr, rcu);
  20
  21        kfree(addr->addr);
  22        kfree(addr);
  23}
  24
  25static struct kset *rpc_sunrpc_kset;
  26static struct kobject *rpc_sunrpc_client_kobj, *rpc_sunrpc_xprt_switch_kobj;
  27
  28static void rpc_sysfs_object_release(struct kobject *kobj)
  29{
  30        kfree(kobj);
  31}
  32
  33static const struct kobj_ns_type_operations *
  34rpc_sysfs_object_child_ns_type(struct kobject *kobj)
  35{
  36        return &net_ns_type_operations;
  37}
  38
  39static struct kobj_type rpc_sysfs_object_type = {
  40        .release = rpc_sysfs_object_release,
  41        .sysfs_ops = &kobj_sysfs_ops,
  42        .child_ns_type = rpc_sysfs_object_child_ns_type,
  43};
  44
  45static struct kobject *rpc_sysfs_object_alloc(const char *name,
  46                                              struct kset *kset,
  47                                              struct kobject *parent)
  48{
  49        struct kobject *kobj;
  50
  51        kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
  52        if (kobj) {
  53                kobj->kset = kset;
  54                if (kobject_init_and_add(kobj, &rpc_sysfs_object_type,
  55                                         parent, "%s", name) == 0)
  56                        return kobj;
  57                kobject_put(kobj);
  58        }
  59        return NULL;
  60}
  61
  62static inline struct rpc_xprt *
  63rpc_sysfs_xprt_kobj_get_xprt(struct kobject *kobj)
  64{
  65        struct rpc_sysfs_xprt *x = container_of(kobj,
  66                struct rpc_sysfs_xprt, kobject);
  67
  68        return xprt_get(x->xprt);
  69}
  70
  71static inline struct rpc_xprt_switch *
  72rpc_sysfs_xprt_kobj_get_xprt_switch(struct kobject *kobj)
  73{
  74        struct rpc_sysfs_xprt *x = container_of(kobj,
  75                struct rpc_sysfs_xprt, kobject);
  76
  77        return xprt_switch_get(x->xprt_switch);
  78}
  79
  80static inline struct rpc_xprt_switch *
  81rpc_sysfs_xprt_switch_kobj_get_xprt(struct kobject *kobj)
  82{
  83        struct rpc_sysfs_xprt_switch *x = container_of(kobj,
  84                struct rpc_sysfs_xprt_switch, kobject);
  85
  86        return xprt_switch_get(x->xprt_switch);
  87}
  88
  89static ssize_t rpc_sysfs_xprt_dstaddr_show(struct kobject *kobj,
  90                                           struct kobj_attribute *attr,
  91                                           char *buf)
  92{
  93        struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj);
  94        ssize_t ret;
  95
  96        if (!xprt)
  97                return 0;
  98        ret = sprintf(buf, "%s\n", xprt->address_strings[RPC_DISPLAY_ADDR]);
  99        xprt_put(xprt);
 100        return ret + 1;
 101}
 102
 103static ssize_t rpc_sysfs_xprt_info_show(struct kobject *kobj,
 104                                        struct kobj_attribute *attr,
 105                                        char *buf)
 106{
 107        struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj);
 108        ssize_t ret;
 109
 110        if (!xprt)
 111                return 0;
 112
 113        ret = sprintf(buf, "last_used=%lu\ncur_cong=%lu\ncong_win=%lu\n"
 114                       "max_num_slots=%u\nmin_num_slots=%u\nnum_reqs=%u\n"
 115                       "binding_q_len=%u\nsending_q_len=%u\npending_q_len=%u\n"
 116                       "backlog_q_len=%u\nmain_xprt=%d\nsrc_port=%u\n"
 117                       "tasks_queuelen=%ld\n",
 118                       xprt->last_used, xprt->cong, xprt->cwnd, xprt->max_reqs,
 119                       xprt->min_reqs, xprt->num_reqs, xprt->binding.qlen,
 120                       xprt->sending.qlen, xprt->pending.qlen,
 121                       xprt->backlog.qlen, xprt->main,
 122                       (xprt->xprt_class->ident == XPRT_TRANSPORT_TCP) ?
 123                       get_srcport(xprt) : 0,
 124                       atomic_long_read(&xprt->queuelen));
 125        xprt_put(xprt);
 126        return ret + 1;
 127}
 128
 129static ssize_t rpc_sysfs_xprt_state_show(struct kobject *kobj,
 130                                         struct kobj_attribute *attr,
 131                                         char *buf)
 132{
 133        struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj);
 134        ssize_t ret;
 135        int locked, connected, connecting, close_wait, bound, binding,
 136            closing, congested, cwnd_wait, write_space, offline, remove;
 137
 138        if (!xprt)
 139                return 0;
 140
 141        if (!xprt->state) {
 142                ret = sprintf(buf, "state=CLOSED\n");
 143        } else {
 144                locked = test_bit(XPRT_LOCKED, &xprt->state);
 145                connected = test_bit(XPRT_CONNECTED, &xprt->state);
 146                connecting = test_bit(XPRT_CONNECTING, &xprt->state);
 147                close_wait = test_bit(XPRT_CLOSE_WAIT, &xprt->state);
 148                bound = test_bit(XPRT_BOUND, &xprt->state);
 149                binding = test_bit(XPRT_BINDING, &xprt->state);
 150                closing = test_bit(XPRT_CLOSING, &xprt->state);
 151                congested = test_bit(XPRT_CONGESTED, &xprt->state);
 152                cwnd_wait = test_bit(XPRT_CWND_WAIT, &xprt->state);
 153                write_space = test_bit(XPRT_WRITE_SPACE, &xprt->state);
 154                offline = test_bit(XPRT_OFFLINE, &xprt->state);
 155                remove = test_bit(XPRT_REMOVE, &xprt->state);
 156
 157                ret = sprintf(buf, "state=%s %s %s %s %s %s %s %s %s %s %s %s\n",
 158                              locked ? "LOCKED" : "",
 159                              connected ? "CONNECTED" : "",
 160                              connecting ? "CONNECTING" : "",
 161                              close_wait ? "CLOSE_WAIT" : "",
 162                              bound ? "BOUND" : "",
 163                              binding ? "BOUNDING" : "",
 164                              closing ? "CLOSING" : "",
 165                              congested ? "CONGESTED" : "",
 166                              cwnd_wait ? "CWND_WAIT" : "",
 167                              write_space ? "WRITE_SPACE" : "",
 168                              offline ? "OFFLINE" : "",
 169                              remove ? "REMOVE" : "");
 170        }
 171
 172        xprt_put(xprt);
 173        return ret + 1;
 174}
 175
 176static ssize_t rpc_sysfs_xprt_switch_info_show(struct kobject *kobj,
 177                                               struct kobj_attribute *attr,
 178                                               char *buf)
 179{
 180        struct rpc_xprt_switch *xprt_switch =
 181                rpc_sysfs_xprt_switch_kobj_get_xprt(kobj);
 182        ssize_t ret;
 183
 184        if (!xprt_switch)
 185                return 0;
 186        ret = sprintf(buf, "num_xprts=%u\nnum_active=%u\nqueue_len=%ld\n",
 187                      xprt_switch->xps_nxprts, xprt_switch->xps_nactive,
 188                      atomic_long_read(&xprt_switch->xps_queuelen));
 189        xprt_switch_put(xprt_switch);
 190        return ret + 1;
 191}
 192
 193static ssize_t rpc_sysfs_xprt_dstaddr_store(struct kobject *kobj,
 194                                            struct kobj_attribute *attr,
 195                                            const char *buf, size_t count)
 196{
 197        struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj);
 198        struct sockaddr *saddr;
 199        char *dst_addr;
 200        int port;
 201        struct xprt_addr *saved_addr;
 202        size_t buf_len;
 203
 204        if (!xprt)
 205                return 0;
 206        if (!(xprt->xprt_class->ident == XPRT_TRANSPORT_TCP ||
 207              xprt->xprt_class->ident == XPRT_TRANSPORT_RDMA)) {
 208                xprt_put(xprt);
 209                return -EOPNOTSUPP;
 210        }
 211
 212        if (wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_KILLABLE)) {
 213                count = -EINTR;
 214                goto out_put;
 215        }
 216        saddr = (struct sockaddr *)&xprt->addr;
 217        port = rpc_get_port(saddr);
 218
 219        /* buf_len is the len until the first occurence of either
 220         * '\n' or '\0'
 221         */
 222        buf_len = strcspn(buf, "\n");
 223
 224        dst_addr = kstrndup(buf, buf_len, GFP_KERNEL);
 225        if (!dst_addr)
 226                goto out_err;
 227        saved_addr = kzalloc(sizeof(*saved_addr), GFP_KERNEL);
 228        if (!saved_addr)
 229                goto out_err_free;
 230        saved_addr->addr =
 231                rcu_dereference_raw(xprt->address_strings[RPC_DISPLAY_ADDR]);
 232        rcu_assign_pointer(xprt->address_strings[RPC_DISPLAY_ADDR], dst_addr);
 233        call_rcu(&saved_addr->rcu, free_xprt_addr);
 234        xprt->addrlen = rpc_pton(xprt->xprt_net, buf, buf_len, saddr,
 235                                 sizeof(*saddr));
 236        rpc_set_port(saddr, port);
 237
 238        xprt_force_disconnect(xprt);
 239out:
 240        xprt_release_write(xprt, NULL);
 241out_put:
 242        xprt_put(xprt);
 243        return count;
 244out_err_free:
 245        kfree(dst_addr);
 246out_err:
 247        count = -ENOMEM;
 248        goto out;
 249}
 250
 251static ssize_t rpc_sysfs_xprt_state_change(struct kobject *kobj,
 252                                           struct kobj_attribute *attr,
 253                                           const char *buf, size_t count)
 254{
 255        struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj);
 256        int offline = 0, online = 0, remove = 0;
 257        struct rpc_xprt_switch *xps = rpc_sysfs_xprt_kobj_get_xprt_switch(kobj);
 258
 259        if (!xprt)
 260                return 0;
 261
 262        if (!strncmp(buf, "offline", 7))
 263                offline = 1;
 264        else if (!strncmp(buf, "online", 6))
 265                online = 1;
 266        else if (!strncmp(buf, "remove", 6))
 267                remove = 1;
 268        else
 269                return -EINVAL;
 270
 271        if (wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_KILLABLE)) {
 272                count = -EINTR;
 273                goto out_put;
 274        }
 275        if (xprt->main) {
 276                count = -EINVAL;
 277                goto release_tasks;
 278        }
 279        if (offline) {
 280                set_bit(XPRT_OFFLINE, &xprt->state);
 281                spin_lock(&xps->xps_lock);
 282                xps->xps_nactive--;
 283                spin_unlock(&xps->xps_lock);
 284        } else if (online) {
 285                clear_bit(XPRT_OFFLINE, &xprt->state);
 286                spin_lock(&xps->xps_lock);
 287                xps->xps_nactive++;
 288                spin_unlock(&xps->xps_lock);
 289        } else if (remove) {
 290                if (test_bit(XPRT_OFFLINE, &xprt->state)) {
 291                        set_bit(XPRT_REMOVE, &xprt->state);
 292                        xprt_force_disconnect(xprt);
 293                        if (test_bit(XPRT_CONNECTED, &xprt->state)) {
 294                                if (!xprt->sending.qlen &&
 295                                    !xprt->pending.qlen &&
 296                                    !xprt->backlog.qlen &&
 297                                    !atomic_long_read(&xprt->queuelen))
 298                                        rpc_xprt_switch_remove_xprt(xps, xprt);
 299                        }
 300                } else {
 301                        count = -EINVAL;
 302                }
 303        }
 304
 305release_tasks:
 306        xprt_release_write(xprt, NULL);
 307out_put:
 308        xprt_put(xprt);
 309        xprt_switch_put(xps);
 310        return count;
 311}
 312
 313int rpc_sysfs_init(void)
 314{
 315        rpc_sunrpc_kset = kset_create_and_add("sunrpc", NULL, kernel_kobj);
 316        if (!rpc_sunrpc_kset)
 317                return -ENOMEM;
 318        rpc_sunrpc_client_kobj =
 319                rpc_sysfs_object_alloc("rpc-clients", rpc_sunrpc_kset, NULL);
 320        if (!rpc_sunrpc_client_kobj)
 321                goto err_client;
 322        rpc_sunrpc_xprt_switch_kobj =
 323                rpc_sysfs_object_alloc("xprt-switches", rpc_sunrpc_kset, NULL);
 324        if (!rpc_sunrpc_xprt_switch_kobj)
 325                goto err_switch;
 326        return 0;
 327err_switch:
 328        kobject_put(rpc_sunrpc_client_kobj);
 329        rpc_sunrpc_client_kobj = NULL;
 330err_client:
 331        kset_unregister(rpc_sunrpc_kset);
 332        rpc_sunrpc_kset = NULL;
 333        return -ENOMEM;
 334}
 335
 336static void rpc_sysfs_client_release(struct kobject *kobj)
 337{
 338        struct rpc_sysfs_client *c;
 339
 340        c = container_of(kobj, struct rpc_sysfs_client, kobject);
 341        kfree(c);
 342}
 343
 344static void rpc_sysfs_xprt_switch_release(struct kobject *kobj)
 345{
 346        struct rpc_sysfs_xprt_switch *xprt_switch;
 347
 348        xprt_switch = container_of(kobj, struct rpc_sysfs_xprt_switch, kobject);
 349        kfree(xprt_switch);
 350}
 351
 352static void rpc_sysfs_xprt_release(struct kobject *kobj)
 353{
 354        struct rpc_sysfs_xprt *xprt;
 355
 356        xprt = container_of(kobj, struct rpc_sysfs_xprt, kobject);
 357        kfree(xprt);
 358}
 359
 360static const void *rpc_sysfs_client_namespace(struct kobject *kobj)
 361{
 362        return container_of(kobj, struct rpc_sysfs_client, kobject)->net;
 363}
 364
 365static const void *rpc_sysfs_xprt_switch_namespace(struct kobject *kobj)
 366{
 367        return container_of(kobj, struct rpc_sysfs_xprt_switch, kobject)->net;
 368}
 369
 370static const void *rpc_sysfs_xprt_namespace(struct kobject *kobj)
 371{
 372        return container_of(kobj, struct rpc_sysfs_xprt,
 373                            kobject)->xprt->xprt_net;
 374}
 375
 376static struct kobj_attribute rpc_sysfs_xprt_dstaddr = __ATTR(dstaddr,
 377        0644, rpc_sysfs_xprt_dstaddr_show, rpc_sysfs_xprt_dstaddr_store);
 378
 379static struct kobj_attribute rpc_sysfs_xprt_info = __ATTR(xprt_info,
 380        0444, rpc_sysfs_xprt_info_show, NULL);
 381
 382static struct kobj_attribute rpc_sysfs_xprt_change_state = __ATTR(xprt_state,
 383        0644, rpc_sysfs_xprt_state_show, rpc_sysfs_xprt_state_change);
 384
 385static struct attribute *rpc_sysfs_xprt_attrs[] = {
 386        &rpc_sysfs_xprt_dstaddr.attr,
 387        &rpc_sysfs_xprt_info.attr,
 388        &rpc_sysfs_xprt_change_state.attr,
 389        NULL,
 390};
 391
 392static struct kobj_attribute rpc_sysfs_xprt_switch_info =
 393        __ATTR(xprt_switch_info, 0444, rpc_sysfs_xprt_switch_info_show, NULL);
 394
 395static struct attribute *rpc_sysfs_xprt_switch_attrs[] = {
 396        &rpc_sysfs_xprt_switch_info.attr,
 397        NULL,
 398};
 399
 400static struct kobj_type rpc_sysfs_client_type = {
 401        .release = rpc_sysfs_client_release,
 402        .sysfs_ops = &kobj_sysfs_ops,
 403        .namespace = rpc_sysfs_client_namespace,
 404};
 405
 406static struct kobj_type rpc_sysfs_xprt_switch_type = {
 407        .release = rpc_sysfs_xprt_switch_release,
 408        .default_attrs = rpc_sysfs_xprt_switch_attrs,
 409        .sysfs_ops = &kobj_sysfs_ops,
 410        .namespace = rpc_sysfs_xprt_switch_namespace,
 411};
 412
 413static struct kobj_type rpc_sysfs_xprt_type = {
 414        .release = rpc_sysfs_xprt_release,
 415        .default_attrs = rpc_sysfs_xprt_attrs,
 416        .sysfs_ops = &kobj_sysfs_ops,
 417        .namespace = rpc_sysfs_xprt_namespace,
 418};
 419
 420void rpc_sysfs_exit(void)
 421{
 422        kobject_put(rpc_sunrpc_client_kobj);
 423        kobject_put(rpc_sunrpc_xprt_switch_kobj);
 424        kset_unregister(rpc_sunrpc_kset);
 425}
 426
 427static struct rpc_sysfs_client *rpc_sysfs_client_alloc(struct kobject *parent,
 428                                                       struct net *net,
 429                                                       int clid)
 430{
 431        struct rpc_sysfs_client *p;
 432
 433        p = kzalloc(sizeof(*p), GFP_KERNEL);
 434        if (p) {
 435                p->net = net;
 436                p->kobject.kset = rpc_sunrpc_kset;
 437                if (kobject_init_and_add(&p->kobject, &rpc_sysfs_client_type,
 438                                         parent, "clnt-%d", clid) == 0)
 439                        return p;
 440                kobject_put(&p->kobject);
 441        }
 442        return NULL;
 443}
 444
 445static struct rpc_sysfs_xprt_switch *
 446rpc_sysfs_xprt_switch_alloc(struct kobject *parent,
 447                            struct rpc_xprt_switch *xprt_switch,
 448                            struct net *net,
 449                            gfp_t gfp_flags)
 450{
 451        struct rpc_sysfs_xprt_switch *p;
 452
 453        p = kzalloc(sizeof(*p), gfp_flags);
 454        if (p) {
 455                p->net = net;
 456                p->kobject.kset = rpc_sunrpc_kset;
 457                if (kobject_init_and_add(&p->kobject,
 458                                         &rpc_sysfs_xprt_switch_type,
 459                                         parent, "switch-%d",
 460                                         xprt_switch->xps_id) == 0)
 461                        return p;
 462                kobject_put(&p->kobject);
 463        }
 464        return NULL;
 465}
 466
 467static struct rpc_sysfs_xprt *rpc_sysfs_xprt_alloc(struct kobject *parent,
 468                                                   struct rpc_xprt *xprt,
 469                                                   gfp_t gfp_flags)
 470{
 471        struct rpc_sysfs_xprt *p;
 472
 473        p = kzalloc(sizeof(*p), gfp_flags);
 474        if (!p)
 475                goto out;
 476        p->kobject.kset = rpc_sunrpc_kset;
 477        if (kobject_init_and_add(&p->kobject, &rpc_sysfs_xprt_type,
 478                                 parent, "xprt-%d-%s", xprt->id,
 479                                 xprt->address_strings[RPC_DISPLAY_PROTO]) == 0)
 480                return p;
 481        kobject_put(&p->kobject);
 482out:
 483        return NULL;
 484}
 485
 486void rpc_sysfs_client_setup(struct rpc_clnt *clnt,
 487                            struct rpc_xprt_switch *xprt_switch,
 488                            struct net *net)
 489{
 490        struct rpc_sysfs_client *rpc_client;
 491
 492        rpc_client = rpc_sysfs_client_alloc(rpc_sunrpc_client_kobj,
 493                                            net, clnt->cl_clid);
 494        if (rpc_client) {
 495                char name[] = "switch";
 496                struct rpc_sysfs_xprt_switch *xswitch =
 497                        (struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs;
 498                int ret;
 499
 500                clnt->cl_sysfs = rpc_client;
 501                rpc_client->clnt = clnt;
 502                rpc_client->xprt_switch = xprt_switch;
 503                kobject_uevent(&rpc_client->kobject, KOBJ_ADD);
 504                ret = sysfs_create_link_nowarn(&rpc_client->kobject,
 505                                               &xswitch->kobject, name);
 506                if (ret)
 507                        pr_warn("can't create link to %s in sysfs (%d)\n",
 508                                name, ret);
 509        }
 510}
 511
 512void rpc_sysfs_xprt_switch_setup(struct rpc_xprt_switch *xprt_switch,
 513                                 struct rpc_xprt *xprt,
 514                                 gfp_t gfp_flags)
 515{
 516        struct rpc_sysfs_xprt_switch *rpc_xprt_switch;
 517        struct net *net;
 518
 519        if (xprt_switch->xps_net)
 520                net = xprt_switch->xps_net;
 521        else
 522                net = xprt->xprt_net;
 523        rpc_xprt_switch =
 524                rpc_sysfs_xprt_switch_alloc(rpc_sunrpc_xprt_switch_kobj,
 525                                            xprt_switch, net, gfp_flags);
 526        if (rpc_xprt_switch) {
 527                xprt_switch->xps_sysfs = rpc_xprt_switch;
 528                rpc_xprt_switch->xprt_switch = xprt_switch;
 529                rpc_xprt_switch->xprt = xprt;
 530                kobject_uevent(&rpc_xprt_switch->kobject, KOBJ_ADD);
 531        }
 532}
 533
 534void rpc_sysfs_xprt_setup(struct rpc_xprt_switch *xprt_switch,
 535                          struct rpc_xprt *xprt,
 536                          gfp_t gfp_flags)
 537{
 538        struct rpc_sysfs_xprt *rpc_xprt;
 539        struct rpc_sysfs_xprt_switch *switch_obj =
 540                (struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs;
 541
 542        rpc_xprt = rpc_sysfs_xprt_alloc(&switch_obj->kobject, xprt, gfp_flags);
 543        if (rpc_xprt) {
 544                xprt->xprt_sysfs = rpc_xprt;
 545                rpc_xprt->xprt = xprt;
 546                rpc_xprt->xprt_switch = xprt_switch;
 547                kobject_uevent(&rpc_xprt->kobject, KOBJ_ADD);
 548        }
 549}
 550
 551void rpc_sysfs_client_destroy(struct rpc_clnt *clnt)
 552{
 553        struct rpc_sysfs_client *rpc_client = clnt->cl_sysfs;
 554
 555        if (rpc_client) {
 556                char name[] = "switch";
 557
 558                sysfs_remove_link(&rpc_client->kobject, name);
 559                kobject_uevent(&rpc_client->kobject, KOBJ_REMOVE);
 560                kobject_del(&rpc_client->kobject);
 561                kobject_put(&rpc_client->kobject);
 562                clnt->cl_sysfs = NULL;
 563        }
 564}
 565
 566void rpc_sysfs_xprt_switch_destroy(struct rpc_xprt_switch *xprt_switch)
 567{
 568        struct rpc_sysfs_xprt_switch *rpc_xprt_switch = xprt_switch->xps_sysfs;
 569
 570        if (rpc_xprt_switch) {
 571                kobject_uevent(&rpc_xprt_switch->kobject, KOBJ_REMOVE);
 572                kobject_del(&rpc_xprt_switch->kobject);
 573                kobject_put(&rpc_xprt_switch->kobject);
 574                xprt_switch->xps_sysfs = NULL;
 575        }
 576}
 577
 578void rpc_sysfs_xprt_destroy(struct rpc_xprt *xprt)
 579{
 580        struct rpc_sysfs_xprt *rpc_xprt = xprt->xprt_sysfs;
 581
 582        if (rpc_xprt) {
 583                kobject_uevent(&rpc_xprt->kobject, KOBJ_REMOVE);
 584                kobject_del(&rpc_xprt->kobject);
 585                kobject_put(&rpc_xprt->kobject);
 586                xprt->xprt_sysfs = NULL;
 587        }
 588}
 589