xref: /linux/net/vmw_vsock/vmci_transport_notify_qstate.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1685a6bf8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2d021c344SAndy King /*
3d021c344SAndy King  * VMware vSockets Driver
4d021c344SAndy King  *
5d021c344SAndy King  * Copyright (C) 2009-2013 VMware, Inc. All rights reserved.
6d021c344SAndy King  */
7d021c344SAndy King 
8d021c344SAndy King #include <linux/types.h>
9d021c344SAndy King #include <linux/socket.h>
10d021c344SAndy King #include <linux/stddef.h>
11d021c344SAndy King #include <net/sock.h>
12d021c344SAndy King 
13d021c344SAndy King #include "vmci_transport_notify.h"
14d021c344SAndy King 
15d021c344SAndy King #define PKT_FIELD(vsk, field_name) \
16d021c344SAndy King 	(vmci_trans(vsk)->notify.pkt_q_state.field_name)
17d021c344SAndy King 
vmci_transport_notify_waiting_write(struct vsock_sock * vsk)18d021c344SAndy King static bool vmci_transport_notify_waiting_write(struct vsock_sock *vsk)
19d021c344SAndy King {
20d021c344SAndy King 	bool retval;
21d021c344SAndy King 	u64 notify_limit;
22d021c344SAndy King 
23d021c344SAndy King 	if (!PKT_FIELD(vsk, peer_waiting_write))
24d021c344SAndy King 		return false;
25d021c344SAndy King 
26d021c344SAndy King 	/* When the sender blocks, we take that as a sign that the sender is
27d021c344SAndy King 	 * faster than the receiver. To reduce the transmit rate of the sender,
28d021c344SAndy King 	 * we delay the sending of the read notification by decreasing the
29d021c344SAndy King 	 * write_notify_window. The notification is delayed until the number of
30d021c344SAndy King 	 * bytes used in the queue drops below the write_notify_window.
31d021c344SAndy King 	 */
32d021c344SAndy King 
33d021c344SAndy King 	if (!PKT_FIELD(vsk, peer_waiting_write_detected)) {
34d021c344SAndy King 		PKT_FIELD(vsk, peer_waiting_write_detected) = true;
35d021c344SAndy King 		if (PKT_FIELD(vsk, write_notify_window) < PAGE_SIZE) {
36d021c344SAndy King 			PKT_FIELD(vsk, write_notify_window) =
37d021c344SAndy King 			    PKT_FIELD(vsk, write_notify_min_window);
38d021c344SAndy King 		} else {
39d021c344SAndy King 			PKT_FIELD(vsk, write_notify_window) -= PAGE_SIZE;
40d021c344SAndy King 			if (PKT_FIELD(vsk, write_notify_window) <
41d021c344SAndy King 			    PKT_FIELD(vsk, write_notify_min_window))
42d021c344SAndy King 				PKT_FIELD(vsk, write_notify_window) =
43d021c344SAndy King 				    PKT_FIELD(vsk, write_notify_min_window);
44d021c344SAndy King 
45d021c344SAndy King 		}
46d021c344SAndy King 	}
47d021c344SAndy King 	notify_limit = vmci_trans(vsk)->consume_size -
48d021c344SAndy King 		PKT_FIELD(vsk, write_notify_window);
49d021c344SAndy King 
50d021c344SAndy King 	/* The notify_limit is used to delay notifications in the case where
51d021c344SAndy King 	 * flow control is enabled. Below the test is expressed in terms of
52d021c344SAndy King 	 * free space in the queue: if free_space > ConsumeSize -
53d021c344SAndy King 	 * write_notify_window then notify An alternate way of expressing this
54d021c344SAndy King 	 * is to rewrite the expression to use the data ready in the receive
55d021c344SAndy King 	 * queue: if write_notify_window > bufferReady then notify as
56d021c344SAndy King 	 * free_space == ConsumeSize - bufferReady.
57d021c344SAndy King 	 */
58d021c344SAndy King 
59d021c344SAndy King 	retval = vmci_qpair_consume_free_space(vmci_trans(vsk)->qpair) >
60d021c344SAndy King 		notify_limit;
61d021c344SAndy King 
62d021c344SAndy King 	if (retval) {
63d021c344SAndy King 		/* Once we notify the peer, we reset the detected flag so the
64d021c344SAndy King 		 * next wait will again cause a decrease in the window size.
65d021c344SAndy King 		 */
66d021c344SAndy King 
67d021c344SAndy King 		PKT_FIELD(vsk, peer_waiting_write_detected) = false;
68d021c344SAndy King 	}
69d021c344SAndy King 	return retval;
70d021c344SAndy King }
71d021c344SAndy King 
72d021c344SAndy King static void
vmci_transport_handle_read(struct sock * sk,struct vmci_transport_packet * pkt,bool bottom_half,struct sockaddr_vm * dst,struct sockaddr_vm * src)73d021c344SAndy King vmci_transport_handle_read(struct sock *sk,
74d021c344SAndy King 			   struct vmci_transport_packet *pkt,
75d021c344SAndy King 			   bool bottom_half,
76d021c344SAndy King 			   struct sockaddr_vm *dst, struct sockaddr_vm *src)
77d021c344SAndy King {
78d021c344SAndy King 	sk->sk_write_space(sk);
79d021c344SAndy King }
80d021c344SAndy King 
81d021c344SAndy King static void
vmci_transport_handle_wrote(struct sock * sk,struct vmci_transport_packet * pkt,bool bottom_half,struct sockaddr_vm * dst,struct sockaddr_vm * src)82d021c344SAndy King vmci_transport_handle_wrote(struct sock *sk,
83d021c344SAndy King 			    struct vmci_transport_packet *pkt,
84d021c344SAndy King 			    bool bottom_half,
85d021c344SAndy King 			    struct sockaddr_vm *dst, struct sockaddr_vm *src)
86d021c344SAndy King {
87*e061aed9SArseniy Krasnov 	vsock_data_ready(sk);
88d021c344SAndy King }
89d021c344SAndy King 
vsock_block_update_write_window(struct sock * sk)90d021c344SAndy King static void vsock_block_update_write_window(struct sock *sk)
91d021c344SAndy King {
92d021c344SAndy King 	struct vsock_sock *vsk = vsock_sk(sk);
93d021c344SAndy King 
94d021c344SAndy King 	if (PKT_FIELD(vsk, write_notify_window) < vmci_trans(vsk)->consume_size)
95d021c344SAndy King 		PKT_FIELD(vsk, write_notify_window) =
96d021c344SAndy King 		    min(PKT_FIELD(vsk, write_notify_window) + PAGE_SIZE,
97d021c344SAndy King 			vmci_trans(vsk)->consume_size);
98d021c344SAndy King }
99d021c344SAndy King 
vmci_transport_send_read_notification(struct sock * sk)100d021c344SAndy King static int vmci_transport_send_read_notification(struct sock *sk)
101d021c344SAndy King {
102d021c344SAndy King 	struct vsock_sock *vsk;
103d021c344SAndy King 	bool sent_read;
104d021c344SAndy King 	unsigned int retries;
105d021c344SAndy King 	int err;
106d021c344SAndy King 
107d021c344SAndy King 	vsk = vsock_sk(sk);
108d021c344SAndy King 	sent_read = false;
109d021c344SAndy King 	retries = 0;
110d021c344SAndy King 	err = 0;
111d021c344SAndy King 
112d021c344SAndy King 	if (vmci_transport_notify_waiting_write(vsk)) {
113d021c344SAndy King 		/* Notify the peer that we have read, retrying the send on
114d021c344SAndy King 		 * failure up to our maximum value.  XXX For now we just log
115d021c344SAndy King 		 * the failure, but later we should schedule a work item to
116d021c344SAndy King 		 * handle the resend until it succeeds.  That would require
117d021c344SAndy King 		 * keeping track of work items in the vsk and cleaning them up
118d021c344SAndy King 		 * upon socket close.
119d021c344SAndy King 		 */
120d021c344SAndy King 		while (!(vsk->peer_shutdown & RCV_SHUTDOWN) &&
121d021c344SAndy King 		       !sent_read &&
122d021c344SAndy King 		       retries < VMCI_TRANSPORT_MAX_DGRAM_RESENDS) {
123d021c344SAndy King 			err = vmci_transport_send_read(sk);
124d021c344SAndy King 			if (err >= 0)
125d021c344SAndy King 				sent_read = true;
126d021c344SAndy King 
127d021c344SAndy King 			retries++;
128d021c344SAndy King 		}
129d021c344SAndy King 
130d021c344SAndy King 		if (retries >= VMCI_TRANSPORT_MAX_DGRAM_RESENDS && !sent_read)
131d021c344SAndy King 			pr_err("%p unable to send read notification to peer\n",
132d021c344SAndy King 			       sk);
133d021c344SAndy King 		else
134d021c344SAndy King 			PKT_FIELD(vsk, peer_waiting_write) = false;
135d021c344SAndy King 
136d021c344SAndy King 	}
137d021c344SAndy King 	return err;
138d021c344SAndy King }
139d021c344SAndy King 
vmci_transport_notify_pkt_socket_init(struct sock * sk)140d021c344SAndy King static void vmci_transport_notify_pkt_socket_init(struct sock *sk)
141d021c344SAndy King {
142d021c344SAndy King 	struct vsock_sock *vsk = vsock_sk(sk);
143d021c344SAndy King 
144d021c344SAndy King 	PKT_FIELD(vsk, write_notify_window) = PAGE_SIZE;
145d021c344SAndy King 	PKT_FIELD(vsk, write_notify_min_window) = PAGE_SIZE;
146d021c344SAndy King 	PKT_FIELD(vsk, peer_waiting_write) = false;
147d021c344SAndy King 	PKT_FIELD(vsk, peer_waiting_write_detected) = false;
148d021c344SAndy King }
149d021c344SAndy King 
vmci_transport_notify_pkt_socket_destruct(struct vsock_sock * vsk)150d021c344SAndy King static void vmci_transport_notify_pkt_socket_destruct(struct vsock_sock *vsk)
151d021c344SAndy King {
152d021c344SAndy King 	PKT_FIELD(vsk, write_notify_window) = PAGE_SIZE;
153d021c344SAndy King 	PKT_FIELD(vsk, write_notify_min_window) = PAGE_SIZE;
154d021c344SAndy King 	PKT_FIELD(vsk, peer_waiting_write) = false;
155d021c344SAndy King 	PKT_FIELD(vsk, peer_waiting_write_detected) = false;
156d021c344SAndy King }
157d021c344SAndy King 
158d021c344SAndy King static int
vmci_transport_notify_pkt_poll_in(struct sock * sk,size_t target,bool * data_ready_now)159d021c344SAndy King vmci_transport_notify_pkt_poll_in(struct sock *sk,
160d021c344SAndy King 				  size_t target, bool *data_ready_now)
161d021c344SAndy King {
162d021c344SAndy King 	struct vsock_sock *vsk = vsock_sk(sk);
163d021c344SAndy King 
164a274f6ffSArseniy Krasnov 	if (vsock_stream_has_data(vsk) >= target) {
165d021c344SAndy King 		*data_ready_now = true;
166d021c344SAndy King 	} else {
167a274f6ffSArseniy Krasnov 		/* We can't read right now because there is not enough data
168a274f6ffSArseniy Krasnov 		 * in the queue. Ask for notifications when there is something
169a274f6ffSArseniy Krasnov 		 * to read.
170d021c344SAndy King 		 */
1713b4477d2SStefan Hajnoczi 		if (sk->sk_state == TCP_ESTABLISHED)
172d021c344SAndy King 			vsock_block_update_write_window(sk);
173d021c344SAndy King 		*data_ready_now = false;
174d021c344SAndy King 	}
175d021c344SAndy King 
176d021c344SAndy King 	return 0;
177d021c344SAndy King }
178d021c344SAndy King 
179d021c344SAndy King static int
vmci_transport_notify_pkt_poll_out(struct sock * sk,size_t target,bool * space_avail_now)180d021c344SAndy King vmci_transport_notify_pkt_poll_out(struct sock *sk,
181d021c344SAndy King 				   size_t target, bool *space_avail_now)
182d021c344SAndy King {
183d021c344SAndy King 	s64 produce_q_free_space;
184d021c344SAndy King 	struct vsock_sock *vsk = vsock_sk(sk);
185d021c344SAndy King 
186d021c344SAndy King 	produce_q_free_space = vsock_stream_has_space(vsk);
187d021c344SAndy King 	if (produce_q_free_space > 0) {
188d021c344SAndy King 		*space_avail_now = true;
189d021c344SAndy King 		return 0;
190d021c344SAndy King 	} else if (produce_q_free_space == 0) {
191d021c344SAndy King 		/* This is a connected socket but we can't currently send data.
192d021c344SAndy King 		 * Nothing else to do.
193d021c344SAndy King 		 */
194d021c344SAndy King 		*space_avail_now = false;
195d021c344SAndy King 	}
196d021c344SAndy King 
197d021c344SAndy King 	return 0;
198d021c344SAndy King }
199d021c344SAndy King 
200d021c344SAndy King static int
vmci_transport_notify_pkt_recv_init(struct sock * sk,size_t target,struct vmci_transport_recv_notify_data * data)201d021c344SAndy King vmci_transport_notify_pkt_recv_init(
202d021c344SAndy King 				struct sock *sk,
203d021c344SAndy King 				size_t target,
204d021c344SAndy King 				struct vmci_transport_recv_notify_data *data)
205d021c344SAndy King {
206d021c344SAndy King 	struct vsock_sock *vsk = vsock_sk(sk);
207d021c344SAndy King 
208d021c344SAndy King 	data->consume_head = 0;
209d021c344SAndy King 	data->produce_tail = 0;
210d021c344SAndy King 	data->notify_on_block = false;
211d021c344SAndy King 
212d021c344SAndy King 	if (PKT_FIELD(vsk, write_notify_min_window) < target + 1) {
213d021c344SAndy King 		PKT_FIELD(vsk, write_notify_min_window) = target + 1;
214d021c344SAndy King 		if (PKT_FIELD(vsk, write_notify_window) <
215d021c344SAndy King 		    PKT_FIELD(vsk, write_notify_min_window)) {
216d021c344SAndy King 			/* If the current window is smaller than the new
217d021c344SAndy King 			 * minimal window size, we need to reevaluate whether
218d021c344SAndy King 			 * we need to notify the sender. If the number of ready
219d021c344SAndy King 			 * bytes are smaller than the new window, we need to
220d021c344SAndy King 			 * send a notification to the sender before we block.
221d021c344SAndy King 			 */
222d021c344SAndy King 
223d021c344SAndy King 			PKT_FIELD(vsk, write_notify_window) =
224d021c344SAndy King 			    PKT_FIELD(vsk, write_notify_min_window);
225d021c344SAndy King 			data->notify_on_block = true;
226d021c344SAndy King 		}
227d021c344SAndy King 	}
228d021c344SAndy King 
229d021c344SAndy King 	return 0;
230d021c344SAndy King }
231d021c344SAndy King 
232d021c344SAndy King static int
vmci_transport_notify_pkt_recv_pre_block(struct sock * sk,size_t target,struct vmci_transport_recv_notify_data * data)233d021c344SAndy King vmci_transport_notify_pkt_recv_pre_block(
234d021c344SAndy King 				struct sock *sk,
235d021c344SAndy King 				size_t target,
236d021c344SAndy King 				struct vmci_transport_recv_notify_data *data)
237d021c344SAndy King {
238d021c344SAndy King 	int err = 0;
239d021c344SAndy King 
240d021c344SAndy King 	vsock_block_update_write_window(sk);
241d021c344SAndy King 
242d021c344SAndy King 	if (data->notify_on_block) {
243d021c344SAndy King 		err = vmci_transport_send_read_notification(sk);
244d021c344SAndy King 		if (err < 0)
245d021c344SAndy King 			return err;
246d021c344SAndy King 		data->notify_on_block = false;
247d021c344SAndy King 	}
248d021c344SAndy King 
249d021c344SAndy King 	return err;
250d021c344SAndy King }
251d021c344SAndy King 
252d021c344SAndy King static int
vmci_transport_notify_pkt_recv_post_dequeue(struct sock * sk,size_t target,ssize_t copied,bool data_read,struct vmci_transport_recv_notify_data * data)253d021c344SAndy King vmci_transport_notify_pkt_recv_post_dequeue(
254d021c344SAndy King 				struct sock *sk,
255d021c344SAndy King 				size_t target,
256d021c344SAndy King 				ssize_t copied,
257d021c344SAndy King 				bool data_read,
258d021c344SAndy King 				struct vmci_transport_recv_notify_data *data)
259d021c344SAndy King {
260d021c344SAndy King 	struct vsock_sock *vsk;
261d021c344SAndy King 	int err;
262d021c344SAndy King 	bool was_full = false;
263d021c344SAndy King 	u64 free_space;
264d021c344SAndy King 
265d021c344SAndy King 	vsk = vsock_sk(sk);
266d021c344SAndy King 	err = 0;
267d021c344SAndy King 
268d021c344SAndy King 	if (data_read) {
269d021c344SAndy King 		smp_mb();
270d021c344SAndy King 
271d021c344SAndy King 		free_space =
272d021c344SAndy King 			vmci_qpair_consume_free_space(vmci_trans(vsk)->qpair);
273d021c344SAndy King 		was_full = free_space == copied;
274d021c344SAndy King 
275d021c344SAndy King 		if (was_full)
276d021c344SAndy King 			PKT_FIELD(vsk, peer_waiting_write) = true;
277d021c344SAndy King 
278d021c344SAndy King 		err = vmci_transport_send_read_notification(sk);
279d021c344SAndy King 		if (err < 0)
280d021c344SAndy King 			return err;
281d021c344SAndy King 
282d021c344SAndy King 		/* See the comment in
283d021c344SAndy King 		 * vmci_transport_notify_pkt_send_post_enqueue().
284d021c344SAndy King 		 */
285*e061aed9SArseniy Krasnov 		vsock_data_ready(sk);
286d021c344SAndy King 	}
287d021c344SAndy King 
288d021c344SAndy King 	return err;
289d021c344SAndy King }
290d021c344SAndy King 
291d021c344SAndy King static int
vmci_transport_notify_pkt_send_init(struct sock * sk,struct vmci_transport_send_notify_data * data)292d021c344SAndy King vmci_transport_notify_pkt_send_init(
293d021c344SAndy King 				struct sock *sk,
294d021c344SAndy King 				struct vmci_transport_send_notify_data *data)
295d021c344SAndy King {
296d021c344SAndy King 	data->consume_head = 0;
297d021c344SAndy King 	data->produce_tail = 0;
298d021c344SAndy King 
299d021c344SAndy King 	return 0;
300d021c344SAndy King }
301d021c344SAndy King 
302d021c344SAndy King static int
vmci_transport_notify_pkt_send_post_enqueue(struct sock * sk,ssize_t written,struct vmci_transport_send_notify_data * data)303d021c344SAndy King vmci_transport_notify_pkt_send_post_enqueue(
304d021c344SAndy King 				struct sock *sk,
305d021c344SAndy King 				ssize_t written,
306d021c344SAndy King 				struct vmci_transport_send_notify_data *data)
307d021c344SAndy King {
308d021c344SAndy King 	int err = 0;
309d021c344SAndy King 	struct vsock_sock *vsk;
310d021c344SAndy King 	bool sent_wrote = false;
311d021c344SAndy King 	bool was_empty;
312d021c344SAndy King 	int retries = 0;
313d021c344SAndy King 
314d021c344SAndy King 	vsk = vsock_sk(sk);
315d021c344SAndy King 
316d021c344SAndy King 	smp_mb();
317d021c344SAndy King 
318d021c344SAndy King 	was_empty =
319d021c344SAndy King 		vmci_qpair_produce_buf_ready(vmci_trans(vsk)->qpair) == written;
320d021c344SAndy King 	if (was_empty) {
321d021c344SAndy King 		while (!(vsk->peer_shutdown & RCV_SHUTDOWN) &&
322d021c344SAndy King 		       !sent_wrote &&
323d021c344SAndy King 		       retries < VMCI_TRANSPORT_MAX_DGRAM_RESENDS) {
324d021c344SAndy King 			err = vmci_transport_send_wrote(sk);
325d021c344SAndy King 			if (err >= 0)
326d021c344SAndy King 				sent_wrote = true;
327d021c344SAndy King 
328d021c344SAndy King 			retries++;
329d021c344SAndy King 		}
330d021c344SAndy King 	}
331d021c344SAndy King 
332d021c344SAndy King 	if (retries >= VMCI_TRANSPORT_MAX_DGRAM_RESENDS && !sent_wrote) {
333d021c344SAndy King 		pr_err("%p unable to send wrote notification to peer\n",
334d021c344SAndy King 		       sk);
335d021c344SAndy King 		return err;
336d021c344SAndy King 	}
337d021c344SAndy King 
338d021c344SAndy King 	return err;
339d021c344SAndy King }
340d021c344SAndy King 
341d021c344SAndy King static void
vmci_transport_notify_pkt_handle_pkt(struct sock * sk,struct vmci_transport_packet * pkt,bool bottom_half,struct sockaddr_vm * dst,struct sockaddr_vm * src,bool * pkt_processed)342d021c344SAndy King vmci_transport_notify_pkt_handle_pkt(
343d021c344SAndy King 				struct sock *sk,
344d021c344SAndy King 				struct vmci_transport_packet *pkt,
345d021c344SAndy King 				bool bottom_half,
346d021c344SAndy King 				struct sockaddr_vm *dst,
347d021c344SAndy King 				struct sockaddr_vm *src, bool *pkt_processed)
348d021c344SAndy King {
349d021c344SAndy King 	bool processed = false;
350d021c344SAndy King 
351d021c344SAndy King 	switch (pkt->type) {
352d021c344SAndy King 	case VMCI_TRANSPORT_PACKET_TYPE_WROTE:
353d021c344SAndy King 		vmci_transport_handle_wrote(sk, pkt, bottom_half, dst, src);
354d021c344SAndy King 		processed = true;
355d021c344SAndy King 		break;
356d021c344SAndy King 	case VMCI_TRANSPORT_PACKET_TYPE_READ:
357d021c344SAndy King 		vmci_transport_handle_read(sk, pkt, bottom_half, dst, src);
358d021c344SAndy King 		processed = true;
359d021c344SAndy King 		break;
360d021c344SAndy King 	}
361d021c344SAndy King 
362d021c344SAndy King 	if (pkt_processed)
363d021c344SAndy King 		*pkt_processed = processed;
364d021c344SAndy King }
365d021c344SAndy King 
vmci_transport_notify_pkt_process_request(struct sock * sk)366d021c344SAndy King static void vmci_transport_notify_pkt_process_request(struct sock *sk)
367d021c344SAndy King {
368d021c344SAndy King 	struct vsock_sock *vsk = vsock_sk(sk);
369d021c344SAndy King 
370d021c344SAndy King 	PKT_FIELD(vsk, write_notify_window) = vmci_trans(vsk)->consume_size;
371d021c344SAndy King 	if (vmci_trans(vsk)->consume_size <
372d021c344SAndy King 		PKT_FIELD(vsk, write_notify_min_window))
373d021c344SAndy King 		PKT_FIELD(vsk, write_notify_min_window) =
374d021c344SAndy King 			vmci_trans(vsk)->consume_size;
375d021c344SAndy King }
376d021c344SAndy King 
vmci_transport_notify_pkt_process_negotiate(struct sock * sk)377d021c344SAndy King static void vmci_transport_notify_pkt_process_negotiate(struct sock *sk)
378d021c344SAndy King {
379d021c344SAndy King 	struct vsock_sock *vsk = vsock_sk(sk);
380d021c344SAndy King 
381d021c344SAndy King 	PKT_FIELD(vsk, write_notify_window) = vmci_trans(vsk)->consume_size;
382d021c344SAndy King 	if (vmci_trans(vsk)->consume_size <
383d021c344SAndy King 		PKT_FIELD(vsk, write_notify_min_window))
384d021c344SAndy King 		PKT_FIELD(vsk, write_notify_min_window) =
385d021c344SAndy King 			vmci_trans(vsk)->consume_size;
386d021c344SAndy King }
387d021c344SAndy King 
388d021c344SAndy King static int
vmci_transport_notify_pkt_recv_pre_dequeue(struct sock * sk,size_t target,struct vmci_transport_recv_notify_data * data)389d021c344SAndy King vmci_transport_notify_pkt_recv_pre_dequeue(
390d021c344SAndy King 				struct sock *sk,
391d021c344SAndy King 				size_t target,
392d021c344SAndy King 				struct vmci_transport_recv_notify_data *data)
393d021c344SAndy King {
394d021c344SAndy King 	return 0; /* NOP for QState. */
395d021c344SAndy King }
396d021c344SAndy King 
397d021c344SAndy King static int
vmci_transport_notify_pkt_send_pre_block(struct sock * sk,struct vmci_transport_send_notify_data * data)398d021c344SAndy King vmci_transport_notify_pkt_send_pre_block(
399d021c344SAndy King 				struct sock *sk,
400d021c344SAndy King 				struct vmci_transport_send_notify_data *data)
401d021c344SAndy King {
402d021c344SAndy King 	return 0; /* NOP for QState. */
403d021c344SAndy King }
404d021c344SAndy King 
405d021c344SAndy King static int
vmci_transport_notify_pkt_send_pre_enqueue(struct sock * sk,struct vmci_transport_send_notify_data * data)406d021c344SAndy King vmci_transport_notify_pkt_send_pre_enqueue(
407d021c344SAndy King 				struct sock *sk,
408d021c344SAndy King 				struct vmci_transport_send_notify_data *data)
409d021c344SAndy King {
410d021c344SAndy King 	return 0; /* NOP for QState. */
411d021c344SAndy King }
412d021c344SAndy King 
413d021c344SAndy King /* Socket always on control packet based operations. */
4143b22dae3SJulia Lawall const struct vmci_transport_notify_ops vmci_transport_notify_pkt_q_state_ops = {
41599a5e178SKees Cook 	.socket_init = vmci_transport_notify_pkt_socket_init,
41699a5e178SKees Cook 	.socket_destruct = vmci_transport_notify_pkt_socket_destruct,
41799a5e178SKees Cook 	.poll_in = vmci_transport_notify_pkt_poll_in,
41899a5e178SKees Cook 	.poll_out = vmci_transport_notify_pkt_poll_out,
41999a5e178SKees Cook 	.handle_notify_pkt = vmci_transport_notify_pkt_handle_pkt,
42099a5e178SKees Cook 	.recv_init = vmci_transport_notify_pkt_recv_init,
42199a5e178SKees Cook 	.recv_pre_block = vmci_transport_notify_pkt_recv_pre_block,
42299a5e178SKees Cook 	.recv_pre_dequeue = vmci_transport_notify_pkt_recv_pre_dequeue,
42399a5e178SKees Cook 	.recv_post_dequeue = vmci_transport_notify_pkt_recv_post_dequeue,
42499a5e178SKees Cook 	.send_init = vmci_transport_notify_pkt_send_init,
42599a5e178SKees Cook 	.send_pre_block = vmci_transport_notify_pkt_send_pre_block,
42699a5e178SKees Cook 	.send_pre_enqueue = vmci_transport_notify_pkt_send_pre_enqueue,
42799a5e178SKees Cook 	.send_post_enqueue = vmci_transport_notify_pkt_send_post_enqueue,
42899a5e178SKees Cook 	.process_request = vmci_transport_notify_pkt_process_request,
42999a5e178SKees Cook 	.process_negotiate = vmci_transport_notify_pkt_process_negotiate,
430d021c344SAndy King };
431