@@ -48,17 +48,16 @@ static unsigned int rds_exthdr_size[__RDS_EXTHDR_MAX] = {
48
48
[RDS_EXTHDR_GEN_NUM ] = sizeof (u32 ),
49
49
};
50
50
51
-
52
51
void rds_message_addref (struct rds_message * rm )
53
52
{
54
53
rdsdebug ("addref rm %p ref %d\n" , rm , refcount_read (& rm -> m_refcount ));
55
54
refcount_inc (& rm -> m_refcount );
56
55
}
57
56
EXPORT_SYMBOL_GPL (rds_message_addref );
58
57
59
- static inline bool skb_zcookie_add (struct sk_buff * skb , u32 cookie )
58
+ static inline bool rds_zcookie_add (struct rds_msg_zcopy_info * info , u32 cookie )
60
59
{
61
- struct rds_zcopy_cookies * ck = ( struct rds_zcopy_cookies * ) skb -> cb ;
60
+ struct rds_zcopy_cookies * ck = & info -> zcookies ;
62
61
int ncookies = ck -> num ;
63
62
64
63
if (ncookies == RDS_MAX_ZCOOKIES )
@@ -68,38 +67,61 @@ static inline bool skb_zcookie_add(struct sk_buff *skb, u32 cookie)
68
67
return true;
69
68
}
70
69
70
+ struct rds_msg_zcopy_info * rds_info_from_znotifier (struct rds_znotifier * znotif )
71
+ {
72
+ return container_of (znotif , struct rds_msg_zcopy_info , znotif );
73
+ }
74
+
75
+ void rds_notify_msg_zcopy_purge (struct rds_msg_zcopy_queue * q )
76
+ {
77
+ unsigned long flags ;
78
+ LIST_HEAD (copy );
79
+ struct rds_msg_zcopy_info * info , * tmp ;
80
+
81
+ spin_lock_irqsave (& q -> lock , flags );
82
+ list_splice (& q -> zcookie_head , & copy );
83
+ INIT_LIST_HEAD (& q -> zcookie_head );
84
+ spin_unlock_irqrestore (& q -> lock , flags );
85
+
86
+ list_for_each_entry_safe (info , tmp , & copy , rs_zcookie_next ) {
87
+ list_del (& info -> rs_zcookie_next );
88
+ kfree (info );
89
+ }
90
+ }
91
+
71
92
static void rds_rm_zerocopy_callback (struct rds_sock * rs ,
72
93
struct rds_znotifier * znotif )
73
94
{
74
- struct sk_buff * skb , * tail ;
75
- unsigned long flags ;
76
- struct sk_buff_head * q ;
95
+ struct rds_msg_zcopy_info * info ;
96
+ struct rds_msg_zcopy_queue * q ;
77
97
u32 cookie = znotif -> z_cookie ;
78
98
struct rds_zcopy_cookies * ck ;
99
+ struct list_head * head ;
100
+ unsigned long flags ;
79
101
102
+ mm_unaccount_pinned_pages (& znotif -> z_mmp );
80
103
q = & rs -> rs_zcookie_queue ;
81
104
spin_lock_irqsave (& q -> lock , flags );
82
- tail = skb_peek_tail (q );
83
-
84
- if (tail && skb_zcookie_add (tail , cookie )) {
85
- spin_unlock_irqrestore (& q -> lock , flags );
86
- mm_unaccount_pinned_pages (& znotif -> z_mmp );
87
- consume_skb (rds_skb_from_znotifier (znotif ));
88
- /* caller invokes rds_wake_sk_sleep() */
89
- return ;
105
+ head = & q -> zcookie_head ;
106
+ if (!list_empty (head )) {
107
+ info = list_entry (head , struct rds_msg_zcopy_info ,
108
+ rs_zcookie_next );
109
+ if (info && rds_zcookie_add (info , cookie )) {
110
+ spin_unlock_irqrestore (& q -> lock , flags );
111
+ kfree (rds_info_from_znotifier (znotif ));
112
+ /* caller invokes rds_wake_sk_sleep() */
113
+ return ;
114
+ }
90
115
}
91
116
92
- skb = rds_skb_from_znotifier (znotif );
93
- ck = ( struct rds_zcopy_cookies * ) skb -> cb ;
117
+ info = rds_info_from_znotifier (znotif );
118
+ ck = & info -> zcookies ;
94
119
memset (ck , 0 , sizeof (* ck ));
95
- WARN_ON (!skb_zcookie_add (skb , cookie ));
96
-
97
- __skb_queue_tail (q , skb );
120
+ WARN_ON (!rds_zcookie_add (info , cookie ));
121
+ list_add_tail (& q -> zcookie_head , & info -> rs_zcookie_next );
98
122
99
123
spin_unlock_irqrestore (& q -> lock , flags );
100
124
/* caller invokes rds_wake_sk_sleep() */
101
-
102
- mm_unaccount_pinned_pages (& znotif -> z_mmp );
103
125
}
104
126
105
127
/*
@@ -333,14 +355,14 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
333
355
return rm ;
334
356
}
335
357
336
- int rds_message_copy_from_user (struct rds_message * rm , struct iov_iter * from ,
337
- bool zcopy )
358
+ int rds_message_zcopy_from_user (struct rds_message * rm , struct iov_iter * from )
338
359
{
339
- unsigned long to_copy , nbytes ;
340
360
unsigned long sg_off ;
341
361
struct scatterlist * sg ;
342
362
int ret = 0 ;
343
363
int length = iov_iter_count (from );
364
+ int total_copied = 0 ;
365
+ struct rds_msg_zcopy_info * info ;
344
366
345
367
rm -> m_inc .i_hdr .h_len = cpu_to_be32 (iov_iter_count (from ));
346
368
@@ -350,54 +372,65 @@ int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from,
350
372
sg = rm -> data .op_sg ;
351
373
sg_off = 0 ; /* Dear gcc, sg->page will be null from kzalloc. */
352
374
353
- if (zcopy ) {
354
- int total_copied = 0 ;
355
- struct sk_buff * skb ;
356
-
357
- skb = alloc_skb (0 , GFP_KERNEL );
358
- if (!skb )
359
- return - ENOMEM ;
360
- BUILD_BUG_ON (sizeof (skb -> cb ) <
361
- max_t (int , sizeof (struct rds_znotifier ),
362
- sizeof (struct rds_zcopy_cookies )));
363
- rm -> data .op_mmp_znotifier = RDS_ZCOPY_SKB (skb );
364
- if (mm_account_pinned_pages (& rm -> data .op_mmp_znotifier -> z_mmp ,
365
- length )) {
366
- ret = - ENOMEM ;
375
+ info = kzalloc (sizeof (* info ), GFP_KERNEL );
376
+ if (!info )
377
+ return - ENOMEM ;
378
+ INIT_LIST_HEAD (& info -> rs_zcookie_next );
379
+ rm -> data .op_mmp_znotifier = & info -> znotif ;
380
+ if (mm_account_pinned_pages (& rm -> data .op_mmp_znotifier -> z_mmp ,
381
+ length )) {
382
+ ret = - ENOMEM ;
383
+ goto err ;
384
+ }
385
+ while (iov_iter_count (from )) {
386
+ struct page * pages ;
387
+ size_t start ;
388
+ ssize_t copied ;
389
+
390
+ copied = iov_iter_get_pages (from , & pages , PAGE_SIZE ,
391
+ 1 , & start );
392
+ if (copied < 0 ) {
393
+ struct mmpin * mmp ;
394
+ int i ;
395
+
396
+ for (i = 0 ; i < rm -> data .op_nents ; i ++ )
397
+ put_page (sg_page (& rm -> data .op_sg [i ]));
398
+ mmp = & rm -> data .op_mmp_znotifier -> z_mmp ;
399
+ mm_unaccount_pinned_pages (mmp );
400
+ ret = - EFAULT ;
367
401
goto err ;
368
402
}
369
- while (iov_iter_count (from )) {
370
- struct page * pages ;
371
- size_t start ;
372
- ssize_t copied ;
373
-
374
- copied = iov_iter_get_pages (from , & pages , PAGE_SIZE ,
375
- 1 , & start );
376
- if (copied < 0 ) {
377
- struct mmpin * mmp ;
378
- int i ;
379
-
380
- for (i = 0 ; i < rm -> data .op_nents ; i ++ )
381
- put_page (sg_page (& rm -> data .op_sg [i ]));
382
- mmp = & rm -> data .op_mmp_znotifier -> z_mmp ;
383
- mm_unaccount_pinned_pages (mmp );
384
- ret = - EFAULT ;
385
- goto err ;
386
- }
387
- total_copied += copied ;
388
- iov_iter_advance (from , copied );
389
- length -= copied ;
390
- sg_set_page (sg , pages , copied , start );
391
- rm -> data .op_nents ++ ;
392
- sg ++ ;
393
- }
394
- WARN_ON_ONCE (length != 0 );
395
- return ret ;
403
+ total_copied += copied ;
404
+ iov_iter_advance (from , copied );
405
+ length -= copied ;
406
+ sg_set_page (sg , pages , copied , start );
407
+ rm -> data .op_nents ++ ;
408
+ sg ++ ;
409
+ }
410
+ WARN_ON_ONCE (length != 0 );
411
+ return ret ;
396
412
err :
397
- consume_skb (skb );
398
- rm -> data .op_mmp_znotifier = NULL ;
399
- return ret ;
400
- } /* zcopy */
413
+ kfree (info );
414
+ rm -> data .op_mmp_znotifier = NULL ;
415
+ return ret ;
416
+ }
417
+
418
+ int rds_message_copy_from_user (struct rds_message * rm , struct iov_iter * from ,
419
+ bool zcopy )
420
+ {
421
+ unsigned long to_copy , nbytes ;
422
+ unsigned long sg_off ;
423
+ struct scatterlist * sg ;
424
+ int ret = 0 ;
425
+
426
+ rm -> m_inc .i_hdr .h_len = cpu_to_be32 (iov_iter_count (from ));
427
+
428
+ /* now allocate and copy in the data payload. */
429
+ sg = rm -> data .op_sg ;
430
+ sg_off = 0 ; /* Dear gcc, sg->page will be null from kzalloc. */
431
+
432
+ if (zcopy )
433
+ return rds_message_zcopy_from_user (rm , from );
401
434
402
435
while (iov_iter_count (from )) {
403
436
if (!sg_page (sg )) {
0 commit comments