@@ -48,17 +48,16 @@ static unsigned int rds_exthdr_size[__RDS_EXTHDR_MAX] = {
4848[RDS_EXTHDR_GEN_NUM ] = sizeof (u32 ),
4949};
5050
51-
5251void rds_message_addref (struct rds_message * rm )
5352{
5453 rdsdebug ("addref rm %p ref %d\n" , rm , refcount_read (& rm -> m_refcount ));
5554 refcount_inc (& rm -> m_refcount );
5655}
5756EXPORT_SYMBOL_GPL (rds_message_addref );
5857
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 )
6059{
61- struct rds_zcopy_cookies * ck = ( struct rds_zcopy_cookies * ) skb -> cb ;
60+ struct rds_zcopy_cookies * ck = & info -> zcookies ;
6261 int ncookies = ck -> num ;
6362
6463 if (ncookies == RDS_MAX_ZCOOKIES )
@@ -68,38 +67,61 @@ static inline bool skb_zcookie_add(struct sk_buff *skb, u32 cookie)
6867 return true;
6968}
7069
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+
7192static void rds_rm_zerocopy_callback (struct rds_sock * rs ,
7293 struct rds_znotifier * znotif )
7394{
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 ;
7797 u32 cookie = znotif -> z_cookie ;
7898 struct rds_zcopy_cookies * ck ;
99+ struct list_head * head ;
100+ unsigned long flags ;
79101
102+ mm_unaccount_pinned_pages (& znotif -> z_mmp );
80103 q = & rs -> rs_zcookie_queue ;
81104 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+ }
90115 }
91116
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 ;
94119 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 );
98122
99123 spin_unlock_irqrestore (& q -> lock , flags );
100124 /* caller invokes rds_wake_sk_sleep() */
101-
102- mm_unaccount_pinned_pages (& znotif -> z_mmp );
103125}
104126
105127/*
@@ -340,7 +362,7 @@ int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *from)
340362 int ret = 0 ;
341363 int length = iov_iter_count (from );
342364 int total_copied = 0 ;
343- struct sk_buff * skb ;
365+ struct rds_msg_zcopy_info * info ;
344366
345367 rm -> m_inc .i_hdr .h_len = cpu_to_be32 (iov_iter_count (from ));
346368
@@ -350,12 +372,11 @@ int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *from)
350372 sg = rm -> data .op_sg ;
351373 sg_off = 0 ; /* Dear gcc, sg->page will be null from kzalloc. */
352374
353- skb = alloc_skb ( 0 , GFP_KERNEL );
354- if (!skb )
375+ info = kzalloc ( sizeof ( * info ) , GFP_KERNEL );
376+ if (!info )
355377 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 ;
359380 if (mm_account_pinned_pages (& rm -> data .op_mmp_znotifier -> z_mmp ,
360381 length )) {
361382 ret = - ENOMEM ;
@@ -389,7 +410,7 @@ int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter *from)
389410 WARN_ON_ONCE (length != 0 );
390411 return ret ;
391412err :
392- consume_skb ( skb );
413+ kfree ( info );
393414 rm -> data .op_mmp_znotifier = NULL ;
394415 return ret ;
395416}
0 commit comments