@@ -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
/*
@@ -340,7 +362,7 @@ int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *from)
340
362
int ret = 0 ;
341
363
int length = iov_iter_count (from );
342
364
int total_copied = 0 ;
343
- struct sk_buff * skb ;
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,12 +372,11 @@ int rds_message_zcopy_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
- skb = alloc_skb ( 0 , GFP_KERNEL );
354
- if (!skb )
375
+ info = kzalloc ( sizeof ( * info ) , GFP_KERNEL );
376
+ if (!info )
355
377
return - ENOMEM ;
356
- BUILD_BUG_ON (sizeof (skb -> cb ) < max_t (int , sizeof (struct rds_znotifier ),
357
- sizeof (struct rds_zcopy_cookies )));
358
- rm -> data .op_mmp_znotifier = RDS_ZCOPY_SKB (skb );
378
+ INIT_LIST_HEAD (& info -> rs_zcookie_next );
379
+ rm -> data .op_mmp_znotifier = & info -> znotif ;
359
380
if (mm_account_pinned_pages (& rm -> data .op_mmp_znotifier -> z_mmp ,
360
381
length )) {
361
382
ret = - ENOMEM ;
@@ -389,7 +410,7 @@ int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *from)
389
410
WARN_ON_ONCE (length != 0 );
390
411
return ret ;
391
412
err :
392
- consume_skb ( skb );
413
+ kfree ( info );
393
414
rm -> data .op_mmp_znotifier = NULL ;
394
415
return ret ;
395
416
}
0 commit comments