30 * copyright notice, this list of conditions and the following
31 * disclaimer in the documentation and/or other materials
32 * provided with the distribution.
33 *
34 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
35 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
37 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
38 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
39 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
40 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
41 * SOFTWARE.
42 *
43 */
44 #include <sys/rds.h>
45
46 #include <sys/ib/clients/rdsv3/rdsv3.h>
47 #include <sys/ib/clients/rdsv3/rdma.h>
48 #include <sys/ib/clients/rdsv3/rdsv3_debug.h>
49
50 #ifndef __lock_lint
51 static unsigned int rdsv3_exthdr_size[__RDSV3_EXTHDR_MAX] = {
52 [RDSV3_EXTHDR_NONE] = 0,
53 [RDSV3_EXTHDR_VERSION] = sizeof (struct rdsv3_ext_header_version),
54 [RDSV3_EXTHDR_RDMA] = sizeof (struct rdsv3_ext_header_rdma),
55 [RDSV3_EXTHDR_RDMA_DEST] = sizeof (struct rdsv3_ext_header_rdma_dest),
56 };
57 #else
58 static unsigned int rdsv3_exthdr_size[__RDSV3_EXTHDR_MAX] = {
59 0,
60 sizeof (struct rdsv3_ext_header_version),
61 sizeof (struct rdsv3_ext_header_rdma),
62 sizeof (struct rdsv3_ext_header_rdma_dest),
63 };
64 #endif
65
66 void
67 rdsv3_message_addref(struct rdsv3_message *rm)
68 {
69 RDSV3_DPRINTF5("rdsv3_message_addref", "addref rm %p ref %d",
70 rm, atomic_get(&rm->m_refcount));
71 atomic_inc_32(&rm->m_refcount);
72 }
73
74 /*
75 * This relies on dma_map_sg() not touching sg[].page during merging.
76 */
77 static void
78 rdsv3_message_purge(struct rdsv3_message *rm)
79 {
80 unsigned long i;
81
82 RDSV3_DPRINTF4("rdsv3_message_purge", "Enter(rm: %p)", rm);
83
84 if (test_bit(RDSV3_MSG_PAGEVEC, &rm->m_flags))
288
289 rm->m_refcount = 1;
290 list_link_init(&rm->m_sock_item);
291 list_link_init(&rm->m_conn_item);
292 mutex_init(&rm->m_rs_lock, NULL, MUTEX_DRIVER, NULL);
293 rdsv3_init_waitqueue(&rm->m_flush_wait);
294
295 RDSV3_DPRINTF4("rdsv3_message_alloc", "Return(rm: %p)", rm);
296 out:
297 return (rm);
298 }
299
300 struct rdsv3_message *
301 rdsv3_message_map_pages(unsigned long *page_addrs, unsigned int total_len)
302 {
303 struct rdsv3_message *rm;
304 unsigned int i;
305
306 RDSV3_DPRINTF4("rdsv3_message_map_pages", "Enter(len: %d)", total_len);
307
308 #ifndef __lock_lint
309 rm = rdsv3_message_alloc(ceil(total_len, PAGE_SIZE), KM_NOSLEEP);
310 #else
311 rm = NULL;
312 #endif
313 if (rm == NULL)
314 return (ERR_PTR(-ENOMEM));
315
316 set_bit(RDSV3_MSG_PAGEVEC, &rm->m_flags);
317 rm->m_inc.i_hdr.h_len = htonl(total_len);
318 #ifndef __lock_lint
319 rm->m_nents = ceil(total_len, PAGE_SIZE);
320 #else
321 rm->m_nents = 0;
322 #endif
323
324 for (i = 0; i < rm->m_nents; ++i) {
325 rdsv3_sg_set_page(&rm->m_sg[i],
326 page_addrs[i],
327 PAGE_SIZE, 0);
328 }
329
330 return (rm);
331 }
332
333 struct rdsv3_message *
334 rdsv3_message_copy_from_user(struct uio *uiop,
335 size_t total_len)
336 {
337 struct rdsv3_message *rm;
338 struct rdsv3_scatterlist *sg;
339 int ret;
340
341 RDSV3_DPRINTF4("rdsv3_message_copy_from_user", "Enter: %d", total_len);
342
343 #ifndef __lock_lint
344 rm = rdsv3_message_alloc(ceil(total_len, PAGE_SIZE), KM_NOSLEEP);
345 #else
346 rm = NULL;
347 #endif
348 if (rm == NULL) {
349 ret = -ENOMEM;
350 goto out;
351 }
352
353 rm->m_inc.i_hdr.h_len = htonl(total_len);
354
355 /*
356 * now allocate and copy in the data payload.
357 */
358 sg = rm->m_sg;
359
360 while (total_len) {
361 if (rdsv3_sg_page(sg) == NULL) {
362 ret = rdsv3_page_remainder_alloc(sg, total_len, 0);
363 if (ret)
364 goto out;
365 rm->m_nents++;
366 }
367
|
30 * copyright notice, this list of conditions and the following
31 * disclaimer in the documentation and/or other materials
32 * provided with the distribution.
33 *
34 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
35 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
37 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
38 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
39 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
40 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
41 * SOFTWARE.
42 *
43 */
44 #include <sys/rds.h>
45
46 #include <sys/ib/clients/rdsv3/rdsv3.h>
47 #include <sys/ib/clients/rdsv3/rdma.h>
48 #include <sys/ib/clients/rdsv3/rdsv3_debug.h>
49
50 static unsigned int rdsv3_exthdr_size[__RDSV3_EXTHDR_MAX] = {
51 [RDSV3_EXTHDR_NONE] = 0,
52 [RDSV3_EXTHDR_VERSION] = sizeof (struct rdsv3_ext_header_version),
53 [RDSV3_EXTHDR_RDMA] = sizeof (struct rdsv3_ext_header_rdma),
54 [RDSV3_EXTHDR_RDMA_DEST] = sizeof (struct rdsv3_ext_header_rdma_dest),
55 };
56
57 void
58 rdsv3_message_addref(struct rdsv3_message *rm)
59 {
60 RDSV3_DPRINTF5("rdsv3_message_addref", "addref rm %p ref %d",
61 rm, atomic_get(&rm->m_refcount));
62 atomic_inc_32(&rm->m_refcount);
63 }
64
65 /*
66 * This relies on dma_map_sg() not touching sg[].page during merging.
67 */
68 static void
69 rdsv3_message_purge(struct rdsv3_message *rm)
70 {
71 unsigned long i;
72
73 RDSV3_DPRINTF4("rdsv3_message_purge", "Enter(rm: %p)", rm);
74
75 if (test_bit(RDSV3_MSG_PAGEVEC, &rm->m_flags))
279
280 rm->m_refcount = 1;
281 list_link_init(&rm->m_sock_item);
282 list_link_init(&rm->m_conn_item);
283 mutex_init(&rm->m_rs_lock, NULL, MUTEX_DRIVER, NULL);
284 rdsv3_init_waitqueue(&rm->m_flush_wait);
285
286 RDSV3_DPRINTF4("rdsv3_message_alloc", "Return(rm: %p)", rm);
287 out:
288 return (rm);
289 }
290
291 struct rdsv3_message *
292 rdsv3_message_map_pages(unsigned long *page_addrs, unsigned int total_len)
293 {
294 struct rdsv3_message *rm;
295 unsigned int i;
296
297 RDSV3_DPRINTF4("rdsv3_message_map_pages", "Enter(len: %d)", total_len);
298
299 rm = rdsv3_message_alloc(ceil(total_len, PAGE_SIZE), KM_NOSLEEP);
300 if (rm == NULL)
301 return (ERR_PTR(-ENOMEM));
302
303 set_bit(RDSV3_MSG_PAGEVEC, &rm->m_flags);
304 rm->m_inc.i_hdr.h_len = htonl(total_len);
305 rm->m_nents = ceil(total_len, PAGE_SIZE);
306 for (i = 0; i < rm->m_nents; ++i) {
307 rdsv3_sg_set_page(&rm->m_sg[i],
308 page_addrs[i],
309 PAGE_SIZE, 0);
310 }
311
312 return (rm);
313 }
314
315 struct rdsv3_message *
316 rdsv3_message_copy_from_user(struct uio *uiop,
317 size_t total_len)
318 {
319 struct rdsv3_message *rm;
320 struct rdsv3_scatterlist *sg;
321 int ret;
322
323 RDSV3_DPRINTF4("rdsv3_message_copy_from_user", "Enter: %d", total_len);
324
325 rm = rdsv3_message_alloc(ceil(total_len, PAGE_SIZE), KM_NOSLEEP);
326 if (rm == NULL) {
327 ret = -ENOMEM;
328 goto out;
329 }
330
331 rm->m_inc.i_hdr.h_len = htonl(total_len);
332
333 /*
334 * now allocate and copy in the data payload.
335 */
336 sg = rm->m_sg;
337
338 while (total_len) {
339 if (rdsv3_sg_page(sg) == NULL) {
340 ret = rdsv3_page_remainder_alloc(sg, total_len, 0);
341 if (ret)
342 goto out;
343 rm->m_nents++;
344 }
345
|