linux/net/vmw_vsock/vmci_transport_notify.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * VMware vSockets Driver
   4 *
   5 * Copyright (C) 2009-2013 VMware, Inc. All rights reserved.
   6 */
   7
   8#include <linux/types.h>
   9#include <linux/socket.h>
  10#include <linux/stddef.h>
  11#include <net/sock.h>
  12
  13#include "vmci_transport_notify.h"
  14
  15#define PKT_FIELD(vsk, field_name) (vmci_trans(vsk)->notify.pkt.field_name)
  16
  17static bool vmci_transport_notify_waiting_write(struct vsock_sock *vsk)
  18{
  19#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
  20        bool retval;
  21        u64 notify_limit;
  22
  23        if (!PKT_FIELD(vsk, peer_waiting_write))
  24                return false;
  25
  26#ifdef VSOCK_OPTIMIZATION_FLOW_CONTROL
  27        /* When the sender blocks, we take that as a sign that the sender is
  28         * faster than the receiver. To reduce the transmit rate of the sender,
  29         * we delay the sending of the read notification by decreasing the
  30         * write_notify_window. The notification is delayed until the number of
  31         * bytes used in the queue drops below the write_notify_window.
  32         */
  33
  34        if (!PKT_FIELD(vsk, peer_waiting_write_detected)) {
  35                PKT_FIELD(vsk, peer_waiting_write_detected) = true;
  36                if (PKT_FIELD(vsk, write_notify_window) < PAGE_SIZE) {
  37                        PKT_FIELD(vsk, write_notify_window) =
  38                            PKT_FIELD(vsk, write_notify_min_window);
  39                } else {
  40                        PKT_FIELD(vsk, write_notify_window) -= PAGE_SIZE;
  41                        if (PKT_FIELD(vsk, write_notify_window) <
  42                            PKT_FIELD(vsk, write_notify_min_window))
  43                                PKT_FIELD(vsk, write_notify_window) =
  44                                    PKT_FIELD(vsk, write_notify_min_window);
  45
  46                }
  47        }
  48        notify_limit = vmci_trans(vsk)->consume_size -
  49                PKT_FIELD(vsk, write_notify_window);
  50#else
  51        notify_limit = 0;
  52#endif
  53
  54        /* For now we ignore the wait information and just see if the free
  55         * space exceeds the notify limit.  Note that improving this function
  56         * to be more intelligent will not require a protocol change and will
  57         * retain compatibility between endpoints with mixed versions of this
  58         * function.
  59         *
  60         * The notify_limit is used to delay notifications in the case where
  61         * flow control is enabled. Below the test is expressed in terms of
  62         * free space in the queue: if free_space > ConsumeSize -
  63         * write_notify_window then notify An alternate way of expressing this
  64         * is to rewrite the expression to use the data ready in the receive
  65         * queue: if write_notify_window > bufferReady then notify as
  66         * free_space == ConsumeSize - bufferReady.
  67         */
  68        retval = vmci_qpair_consume_free_space(vmci_trans(vsk)->qpair) >
  69                notify_limit;
  70#ifdef VSOCK_OPTIMIZATION_FLOW_CONTROL
  71        if (retval) {
  72                /*
  73                 * Once we notify the peer, we reset the detected flag so the
  74                 * next wait will again cause a decrease in the window size.
  75                 */
  76
  77                PKT_FIELD(vsk, peer_waiting_write_detected) = false;
  78        }
  79#endif
  80        return retval;
  81#else
  82        return true;
  83#endif
  84}
  85
  86static bool vmci_transport_notify_waiting_read(struct vsock_sock *vsk)
  87{
  88#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
  89        if (!PKT_FIELD(vsk, peer_waiting_read))
  90                return false;
  91
  92        /* For now we ignore the wait information and just see if there is any
  93         * data for our peer to read.  Note that improving this function to be
  94         * more intelligent will not require a protocol change and will retain
  95         * compatibility between endpoints with mixed versions of this
  96         * function.
  97         */
  98        return vmci_qpair_produce_buf_ready(vmci_trans(vsk)->qpair) > 0;
  99#else
 100        return true;
 101#endif
 102}
 103
 104static void
 105vmci_transport_handle_waiting_read(struct sock *sk,
 106                                   struct vmci_transport_packet *pkt,
 107                                   bool bottom_half,
 108                                   struct sockaddr_vm *dst,
 109                                   struct sockaddr_vm *src)
 110{
 111#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 112        struct vsock_sock *vsk;
 113
 114        vsk = vsock_sk(sk);
 115
 116        PKT_FIELD(vsk, peer_waiting_read) = true;
 117        memcpy(&PKT_FIELD(vsk, peer_waiting_read_info), &pkt->u.wait,
 118               sizeof(PKT_FIELD(vsk, peer_waiting_read_info)));
 119
 120        if (vmci_transport_notify_waiting_read(vsk)) {
 121                bool sent;
 122
 123                if (bottom_half)
 124                        sent = vmci_transport_send_wrote_bh(dst, src) > 0;
 125                else
 126                        sent = vmci_transport_send_wrote(sk) > 0;
 127
 128                if (sent)
 129                        PKT_FIELD(vsk, peer_waiting_read) = false;
 130        }
 131#endif
 132}
 133
 134static void
 135vmci_transport_handle_waiting_write(struct sock *sk,
 136                                    struct vmci_transport_packet *pkt,
 137                                    bool bottom_half,
 138                                    struct sockaddr_vm *dst,
 139                                    struct sockaddr_vm *src)
 140{
 141#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 142        struct vsock_sock *vsk;
 143
 144        vsk = vsock_sk(sk);
 145
 146        PKT_FIELD(vsk, peer_waiting_write) = true;
 147        memcpy(&PKT_FIELD(vsk, peer_waiting_write_info), &pkt->u.wait,
 148               sizeof(PKT_FIELD(vsk, peer_waiting_write_info)));
 149
 150        if (vmci_transport_notify_waiting_write(vsk)) {
 151                bool sent;
 152
 153                if (bottom_half)
 154                        sent = vmci_transport_send_read_bh(dst, src) > 0;
 155                else
 156                        sent = vmci_transport_send_read(sk) > 0;
 157
 158                if (sent)
 159                        PKT_FIELD(vsk, peer_waiting_write) = false;
 160        }
 161#endif
 162}
 163
 164static void
 165vmci_transport_handle_read(struct sock *sk,
 166                           struct vmci_transport_packet *pkt,
 167                           bool bottom_half,
 168                           struct sockaddr_vm *dst, struct sockaddr_vm *src)
 169{
 170#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 171        struct vsock_sock *vsk;
 172
 173        vsk = vsock_sk(sk);
 174        PKT_FIELD(vsk, sent_waiting_write) = false;
 175#endif
 176
 177        sk->sk_write_space(sk);
 178}
 179
 180static bool send_waiting_read(struct sock *sk, u64 room_needed)
 181{
 182#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 183        struct vsock_sock *vsk;
 184        struct vmci_transport_waiting_info waiting_info;
 185        u64 tail;
 186        u64 head;
 187        u64 room_left;
 188        bool ret;
 189
 190        vsk = vsock_sk(sk);
 191
 192        if (PKT_FIELD(vsk, sent_waiting_read))
 193                return true;
 194
 195        if (PKT_FIELD(vsk, write_notify_window) <
 196                        vmci_trans(vsk)->consume_size)
 197                PKT_FIELD(vsk, write_notify_window) =
 198                    min(PKT_FIELD(vsk, write_notify_window) + PAGE_SIZE,
 199                        vmci_trans(vsk)->consume_size);
 200
 201        vmci_qpair_get_consume_indexes(vmci_trans(vsk)->qpair, &tail, &head);
 202        room_left = vmci_trans(vsk)->consume_size - head;
 203        if (room_needed >= room_left) {
 204                waiting_info.offset = room_needed - room_left;
 205                waiting_info.generation =
 206                    PKT_FIELD(vsk, consume_q_generation) + 1;
 207        } else {
 208                waiting_info.offset = head + room_needed;
 209                waiting_info.generation = PKT_FIELD(vsk, consume_q_generation);
 210        }
 211
 212        ret = vmci_transport_send_waiting_read(sk, &waiting_info) > 0;
 213        if (ret)
 214                PKT_FIELD(vsk, sent_waiting_read) = true;
 215
 216        return ret;
 217#else
 218        return true;
 219#endif
 220}
 221
 222static bool send_waiting_write(struct sock *sk, u64 room_needed)
 223{
 224#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 225        struct vsock_sock *vsk;
 226        struct vmci_transport_waiting_info waiting_info;
 227        u64 tail;
 228        u64 head;
 229        u64 room_left;
 230        bool ret;
 231
 232        vsk = vsock_sk(sk);
 233
 234        if (PKT_FIELD(vsk, sent_waiting_write))
 235                return true;
 236
 237        vmci_qpair_get_produce_indexes(vmci_trans(vsk)->qpair, &tail, &head);
 238        room_left = vmci_trans(vsk)->produce_size - tail;
 239        if (room_needed + 1 >= room_left) {
 240                /* Wraps around to current generation. */
 241                waiting_info.offset = room_needed + 1 - room_left;
 242                waiting_info.generation = PKT_FIELD(vsk, produce_q_generation);
 243        } else {
 244                waiting_info.offset = tail + room_needed + 1;
 245                waiting_info.generation =
 246                    PKT_FIELD(vsk, produce_q_generation) - 1;
 247        }
 248
 249        ret = vmci_transport_send_waiting_write(sk, &waiting_info) > 0;
 250        if (ret)
 251                PKT_FIELD(vsk, sent_waiting_write) = true;
 252
 253        return ret;
 254#else
 255        return true;
 256#endif
 257}
 258
 259static int vmci_transport_send_read_notification(struct sock *sk)
 260{
 261        struct vsock_sock *vsk;
 262        bool sent_read;
 263        unsigned int retries;
 264        int err;
 265
 266        vsk = vsock_sk(sk);
 267        sent_read = false;
 268        retries = 0;
 269        err = 0;
 270
 271        if (vmci_transport_notify_waiting_write(vsk)) {
 272                /* Notify the peer that we have read, retrying the send on
 273                 * failure up to our maximum value.  XXX For now we just log
 274                 * the failure, but later we should schedule a work item to
 275                 * handle the resend until it succeeds.  That would require
 276                 * keeping track of work items in the vsk and cleaning them up
 277                 * upon socket close.
 278                 */
 279                while (!(vsk->peer_shutdown & RCV_SHUTDOWN) &&
 280                       !sent_read &&
 281                       retries < VMCI_TRANSPORT_MAX_DGRAM_RESENDS) {
 282                        err = vmci_transport_send_read(sk);
 283                        if (err >= 0)
 284                                sent_read = true;
 285
 286                        retries++;
 287                }
 288
 289                if (retries >= VMCI_TRANSPORT_MAX_DGRAM_RESENDS)
 290                        pr_err("%p unable to send read notify to peer\n", sk);
 291                else
 292#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 293                        PKT_FIELD(vsk, peer_waiting_write) = false;
 294#endif
 295
 296        }
 297        return err;
 298}
 299
 300static void
 301vmci_transport_handle_wrote(struct sock *sk,
 302                            struct vmci_transport_packet *pkt,
 303                            bool bottom_half,
 304                            struct sockaddr_vm *dst, struct sockaddr_vm *src)
 305{
 306#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 307        struct vsock_sock *vsk = vsock_sk(sk);
 308        PKT_FIELD(vsk, sent_waiting_read) = false;
 309#endif
 310        sk->sk_data_ready(sk);
 311}
 312
 313static void vmci_transport_notify_pkt_socket_init(struct sock *sk)
 314{
 315        struct vsock_sock *vsk = vsock_sk(sk);
 316
 317        PKT_FIELD(vsk, write_notify_window) = PAGE_SIZE;
 318        PKT_FIELD(vsk, write_notify_min_window) = PAGE_SIZE;
 319        PKT_FIELD(vsk, peer_waiting_read) = false;
 320        PKT_FIELD(vsk, peer_waiting_write) = false;
 321        PKT_FIELD(vsk, peer_waiting_write_detected) = false;
 322        PKT_FIELD(vsk, sent_waiting_read) = false;
 323        PKT_FIELD(vsk, sent_waiting_write) = false;
 324        PKT_FIELD(vsk, produce_q_generation) = 0;
 325        PKT_FIELD(vsk, consume_q_generation) = 0;
 326
 327        memset(&PKT_FIELD(vsk, peer_waiting_read_info), 0,
 328               sizeof(PKT_FIELD(vsk, peer_waiting_read_info)));
 329        memset(&PKT_FIELD(vsk, peer_waiting_write_info), 0,
 330               sizeof(PKT_FIELD(vsk, peer_waiting_write_info)));
 331}
 332
 333static void vmci_transport_notify_pkt_socket_destruct(struct vsock_sock *vsk)
 334{
 335}
 336
 337static int
 338vmci_transport_notify_pkt_poll_in(struct sock *sk,
 339                                  size_t target, bool *data_ready_now)
 340{
 341        struct vsock_sock *vsk = vsock_sk(sk);
 342
 343        if (vsock_stream_has_data(vsk)) {
 344                *data_ready_now = true;
 345        } else {
 346                /* We can't read right now because there is nothing in the
 347                 * queue. Ask for notifications when there is something to
 348                 * read.
 349                 */
 350                if (sk->sk_state == TCP_ESTABLISHED) {
 351                        if (!send_waiting_read(sk, 1))
 352                                return -1;
 353
 354                }
 355                *data_ready_now = false;
 356        }
 357
 358        return 0;
 359}
 360
 361static int
 362vmci_transport_notify_pkt_poll_out(struct sock *sk,
 363                                   size_t target, bool *space_avail_now)
 364{
 365        s64 produce_q_free_space;
 366        struct vsock_sock *vsk = vsock_sk(sk);
 367
 368        produce_q_free_space = vsock_stream_has_space(vsk);
 369        if (produce_q_free_space > 0) {
 370                *space_avail_now = true;
 371                return 0;
 372        } else if (produce_q_free_space == 0) {
 373                /* This is a connected socket but we can't currently send data.
 374                 * Notify the peer that we are waiting if the queue is full. We
 375                 * only send a waiting write if the queue is full because
 376                 * otherwise we end up in an infinite WAITING_WRITE, READ,
 377                 * WAITING_WRITE, READ, etc. loop. Treat failing to send the
 378                 * notification as a socket error, passing that back through
 379                 * the mask.
 380                 */
 381                if (!send_waiting_write(sk, 1))
 382                        return -1;
 383
 384                *space_avail_now = false;
 385        }
 386
 387        return 0;
 388}
 389
 390static int
 391vmci_transport_notify_pkt_recv_init(
 392                        struct sock *sk,
 393                        size_t target,
 394                        struct vmci_transport_recv_notify_data *data)
 395{
 396        struct vsock_sock *vsk = vsock_sk(sk);
 397
 398#ifdef VSOCK_OPTIMIZATION_WAITING_NOTIFY
 399        data->consume_head = 0;
 400        data->produce_tail = 0;
 401#ifdef VSOCK_OPTIMIZATION_FLOW_CONTROL
 402        data->notify_on_block = false;
 403
 404        if (PKT_FIELD(vsk, write_notify_min_window) < target + 1) {
 405                PKT_FIELD(vsk, write_notify_min_window) = target + 1;
 406                if (PKT_FIELD(vsk, write_notify_window) <
 407                    PKT_FIELD(vsk, write_notify_min_window)) {
 408                        /* If the current window is smaller than the new
 409                         * minimal window size, we need to reevaluate whether
 410                         * we need to notify the sender. If the number of ready
 411                         * bytes are smaller than the new window, we need to
 412                         * send a notification to the sender before we block.
 413                         */
 414
 415                        PKT_FIELD(vsk, write_notify_window) =
 416                            PKT_FIELD(vsk, write_notify_min_window);
 417                        data->notify_on_block = true;
 418                }
 419        }
 420#endif
 421#endif
 422
 423        return 0;
 424}
 425
 426static int
 427vmci_transport_notify_pkt_recv_pre_block(
 428                                struct sock *sk,
 429                                size_t target,
 430                                struct vmci_transport_recv_notify_data *data)
 431{
 432        int err = 0;
 433
 434        /* Notify our peer that we are waiting for data to read. */
 435        if (!send_waiting_read(sk, target)) {
 436                err = -EHOSTUNREACH;
 437                return err;
 438        }
 439#ifdef VSOCK_OPTIMIZATION_FLOW_CONTROL
 440        if (data->notify_on_block) {
 441                err = vmci_transport_send_read_notification(sk);
 442                if (err < 0)
 443                        return err;
 444
 445                data->notify_on_block = false;
 446        }
 447#endif
 448
 449        return err;
 450}
 451
 452static int
 453vmci_transport_notify_pkt_recv_pre_dequeue(
 454                                struct sock *sk,
 455                                size_t target,
 456                                struct vmci_transport_recv_notify_data *data)
 457{
 458        struct vsock_sock *vsk = vsock_sk(sk);
 459
 460        /* Now consume up to len bytes from the queue.  Note that since we have
 461         * the socket locked we should copy at least ready bytes.
 462         */
 463#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 464        vmci_qpair_get_consume_indexes(vmci_trans(vsk)->qpair,
 465                                       &data->produce_tail,
 466                                       &data->consume_head);
 467#endif
 468
 469        return 0;
 470}
 471
 472static int
 473vmci_transport_notify_pkt_recv_post_dequeue(
 474                                struct sock *sk,
 475                                size_t target,
 476                                ssize_t copied,
 477                                bool data_read,
 478                                struct vmci_transport_recv_notify_data *data)
 479{
 480        struct vsock_sock *vsk;
 481        int err;
 482
 483        vsk = vsock_sk(sk);
 484        err = 0;
 485
 486        if (data_read) {
 487#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 488                /* Detect a wrap-around to maintain queue generation.  Note
 489                 * that this is safe since we hold the socket lock across the
 490                 * two queue pair operations.
 491                 */
 492                if (copied >=
 493                        vmci_trans(vsk)->consume_size - data->consume_head)
 494                        PKT_FIELD(vsk, consume_q_generation)++;
 495#endif
 496
 497                err = vmci_transport_send_read_notification(sk);
 498                if (err < 0)
 499                        return err;
 500
 501        }
 502        return err;
 503}
 504
 505static int
 506vmci_transport_notify_pkt_send_init(
 507                        struct sock *sk,
 508                        struct vmci_transport_send_notify_data *data)
 509{
 510#ifdef VSOCK_OPTIMIZATION_WAITING_NOTIFY
 511        data->consume_head = 0;
 512        data->produce_tail = 0;
 513#endif
 514
 515        return 0;
 516}
 517
 518static int
 519vmci_transport_notify_pkt_send_pre_block(
 520                                struct sock *sk,
 521                                struct vmci_transport_send_notify_data *data)
 522{
 523        /* Notify our peer that we are waiting for room to write. */
 524        if (!send_waiting_write(sk, 1))
 525                return -EHOSTUNREACH;
 526
 527        return 0;
 528}
 529
 530static int
 531vmci_transport_notify_pkt_send_pre_enqueue(
 532                                struct sock *sk,
 533                                struct vmci_transport_send_notify_data *data)
 534{
 535        struct vsock_sock *vsk = vsock_sk(sk);
 536
 537#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 538        vmci_qpair_get_produce_indexes(vmci_trans(vsk)->qpair,
 539                                       &data->produce_tail,
 540                                       &data->consume_head);
 541#endif
 542
 543        return 0;
 544}
 545
 546static int
 547vmci_transport_notify_pkt_send_post_enqueue(
 548                                struct sock *sk,
 549                                ssize_t written,
 550                                struct vmci_transport_send_notify_data *data)
 551{
 552        int err = 0;
 553        struct vsock_sock *vsk;
 554        bool sent_wrote = false;
 555        int retries = 0;
 556
 557        vsk = vsock_sk(sk);
 558
 559#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 560        /* Detect a wrap-around to maintain queue generation.  Note that this
 561         * is safe since we hold the socket lock across the two queue pair
 562         * operations.
 563         */
 564        if (written >= vmci_trans(vsk)->produce_size - data->produce_tail)
 565                PKT_FIELD(vsk, produce_q_generation)++;
 566
 567#endif
 568
 569        if (vmci_transport_notify_waiting_read(vsk)) {
 570                /* Notify the peer that we have written, retrying the send on
 571                 * failure up to our maximum value. See the XXX comment for the
 572                 * corresponding piece of code in StreamRecvmsg() for potential
 573                 * improvements.
 574                 */
 575                while (!(vsk->peer_shutdown & RCV_SHUTDOWN) &&
 576                       !sent_wrote &&
 577                       retries < VMCI_TRANSPORT_MAX_DGRAM_RESENDS) {
 578                        err = vmci_transport_send_wrote(sk);
 579                        if (err >= 0)
 580                                sent_wrote = true;
 581
 582                        retries++;
 583                }
 584
 585                if (retries >= VMCI_TRANSPORT_MAX_DGRAM_RESENDS) {
 586                        pr_err("%p unable to send wrote notify to peer\n", sk);
 587                        return err;
 588                } else {
 589#if defined(VSOCK_OPTIMIZATION_WAITING_NOTIFY)
 590                        PKT_FIELD(vsk, peer_waiting_read) = false;
 591#endif
 592                }
 593        }
 594        return err;
 595}
 596
 597static void
 598vmci_transport_notify_pkt_handle_pkt(
 599                        struct sock *sk,
 600                        struct vmci_transport_packet *pkt,
 601                        bool bottom_half,
 602                        struct sockaddr_vm *dst,
 603                        struct sockaddr_vm *src, bool *pkt_processed)
 604{
 605        bool processed = false;
 606
 607        switch (pkt->type) {
 608        case VMCI_TRANSPORT_PACKET_TYPE_WROTE:
 609                vmci_transport_handle_wrote(sk, pkt, bottom_half, dst, src);
 610                processed = true;
 611                break;
 612        case VMCI_TRANSPORT_PACKET_TYPE_READ:
 613                vmci_transport_handle_read(sk, pkt, bottom_half, dst, src);
 614                processed = true;
 615                break;
 616        case VMCI_TRANSPORT_PACKET_TYPE_WAITING_WRITE:
 617                vmci_transport_handle_waiting_write(sk, pkt, bottom_half,
 618                                                    dst, src);
 619                processed = true;
 620                break;
 621
 622        case VMCI_TRANSPORT_PACKET_TYPE_WAITING_READ:
 623                vmci_transport_handle_waiting_read(sk, pkt, bottom_half,
 624                                                   dst, src);
 625                processed = true;
 626                break;
 627        }
 628
 629        if (pkt_processed)
 630                *pkt_processed = processed;
 631}
 632
 633static void vmci_transport_notify_pkt_process_request(struct sock *sk)
 634{
 635        struct vsock_sock *vsk = vsock_sk(sk);
 636
 637        PKT_FIELD(vsk, write_notify_window) = vmci_trans(vsk)->consume_size;
 638        if (vmci_trans(vsk)->consume_size <
 639                PKT_FIELD(vsk, write_notify_min_window))
 640                PKT_FIELD(vsk, write_notify_min_window) =
 641                        vmci_trans(vsk)->consume_size;
 642}
 643
 644static void vmci_transport_notify_pkt_process_negotiate(struct sock *sk)
 645{
 646        struct vsock_sock *vsk = vsock_sk(sk);
 647
 648        PKT_FIELD(vsk, write_notify_window) = vmci_trans(vsk)->consume_size;
 649        if (vmci_trans(vsk)->consume_size <
 650                PKT_FIELD(vsk, write_notify_min_window))
 651                PKT_FIELD(vsk, write_notify_min_window) =
 652                        vmci_trans(vsk)->consume_size;
 653}
 654
 655/* Socket control packet based operations. */
 656const struct vmci_transport_notify_ops vmci_transport_notify_pkt_ops = {
 657        .socket_init = vmci_transport_notify_pkt_socket_init,
 658        .socket_destruct = vmci_transport_notify_pkt_socket_destruct,
 659        .poll_in = vmci_transport_notify_pkt_poll_in,
 660        .poll_out = vmci_transport_notify_pkt_poll_out,
 661        .handle_notify_pkt = vmci_transport_notify_pkt_handle_pkt,
 662        .recv_init = vmci_transport_notify_pkt_recv_init,
 663        .recv_pre_block = vmci_transport_notify_pkt_recv_pre_block,
 664        .recv_pre_dequeue = vmci_transport_notify_pkt_recv_pre_dequeue,
 665        .recv_post_dequeue = vmci_transport_notify_pkt_recv_post_dequeue,
 666        .send_init = vmci_transport_notify_pkt_send_init,
 667        .send_pre_block = vmci_transport_notify_pkt_send_pre_block,
 668        .send_pre_enqueue = vmci_transport_notify_pkt_send_pre_enqueue,
 669        .send_post_enqueue = vmci_transport_notify_pkt_send_post_enqueue,
 670        .process_request = vmci_transport_notify_pkt_process_request,
 671        .process_negotiate = vmci_transport_notify_pkt_process_negotiate,
 672};
 673