/* * Copyright (c) 2006, 2020 Oracle and/or its affiliates. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU * General Public License (GPL) Version 2, available from the file * COPYING in the main directory of this source tree, or the * OpenIB.org BSD license below: * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/export.h> #include <linux/skbuff.h> #include <linux/list.h> #include <linux/errqueue.h> #include "rds.h" static unsigned int rds_exthdr_size[__RDS_EXTHDR_MAX] = …; void rds_message_addref(struct rds_message *rm) { … } EXPORT_SYMBOL_GPL(…); static inline bool rds_zcookie_add(struct rds_msg_zcopy_info *info, u32 cookie) { … } static struct rds_msg_zcopy_info *rds_info_from_znotifier(struct rds_znotifier *znotif) { … } void rds_notify_msg_zcopy_purge(struct rds_msg_zcopy_queue *q) { … } static void rds_rm_zerocopy_callback(struct rds_sock *rs, struct rds_znotifier *znotif) { … } /* * This relies on dma_map_sg() not touching sg[].page during merging. */ static void rds_message_purge(struct rds_message *rm) { … } void rds_message_put(struct rds_message *rm) { … } EXPORT_SYMBOL_GPL(…); void rds_message_populate_header(struct rds_header *hdr, __be16 sport, __be16 dport, u64 seq) { … } EXPORT_SYMBOL_GPL(…); int rds_message_add_extension(struct rds_header *hdr, unsigned int type, const void *data, unsigned int len) { … } EXPORT_SYMBOL_GPL(…); /* * If a message has extension headers, retrieve them here. * Call like this: * * unsigned int pos = 0; * * while (1) { * buflen = sizeof(buffer); * type = rds_message_next_extension(hdr, &pos, buffer, &buflen); * if (type == RDS_EXTHDR_NONE) * break; * ... * } */ int rds_message_next_extension(struct rds_header *hdr, unsigned int *pos, void *buf, unsigned int *buflen) { … } int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset) { … } EXPORT_SYMBOL_GPL(…); /* * Each rds_message is allocated with extra space for the scatterlist entries * rds ops will need. This is to minimize memory allocation count. Then, each rds op * can grab SGs when initializing its part of the rds_message. */ struct rds_message *rds_message_alloc(unsigned int extra_len, gfp_t gfp) { … } /* * RDS ops use this to grab SG entries from the rm's sg pool. */ struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents) { … } struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len) { … } static int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *from) { … } int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from, bool zcopy) { … } int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to) { … } /* * If the message is still on the send queue, wait until the transport * is done with it. This is particularly important for RDMA operations. */ void rds_message_wait(struct rds_message *rm) { … } void rds_message_unmapped(struct rds_message *rm) { … } EXPORT_SYMBOL_GPL(…);