Skip to content

Commit 9426bbc

Browse files
sowminivdavem330
authored andcommitted
rds: use list structure to track information for zerocopy completion notification
Commit 401910d ("rds: deliver zerocopy completion notification with data") removes support fo r zerocopy completion notification on the sk_error_queue, thus we no longer need to track the cookie information in sk_buff structures. This commit removes the struct sk_buff_head rs_zcookie_queue by a simpler list that results in a smaller memory footprint as well as more efficient memory_allocation time. Signed-off-by: Sowmini Varadhan <[email protected]> Acked-by: Willem de Bruijn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d40a126 commit 9426bbc

File tree

4 files changed

+85
-44
lines changed

4 files changed

+85
-44
lines changed

net/rds/af_rds.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static int rds_release(struct socket *sock)
7777
rds_send_drop_to(rs, NULL);
7878
rds_rdma_drop_keys(rs);
7979
rds_notify_queue_get(rs, NULL);
80-
__skb_queue_purge(&rs->rs_zcookie_queue);
80+
rds_notify_msg_zcopy_purge(&rs->rs_zcookie_queue);
8181

8282
spin_lock_bh(&rds_sock_lock);
8383
list_del_init(&rs->rs_item);
@@ -180,7 +180,7 @@ static __poll_t rds_poll(struct file *file, struct socket *sock,
180180
}
181181
if (!list_empty(&rs->rs_recv_queue) ||
182182
!list_empty(&rs->rs_notify_queue) ||
183-
!skb_queue_empty(&rs->rs_zcookie_queue))
183+
!list_empty(&rs->rs_zcookie_queue.zcookie_head))
184184
mask |= (EPOLLIN | EPOLLRDNORM);
185185
if (rs->rs_snd_bytes < rds_sk_sndbuf(rs))
186186
mask |= (EPOLLOUT | EPOLLWRNORM);
@@ -515,7 +515,7 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
515515
INIT_LIST_HEAD(&rs->rs_recv_queue);
516516
INIT_LIST_HEAD(&rs->rs_notify_queue);
517517
INIT_LIST_HEAD(&rs->rs_cong_list);
518-
skb_queue_head_init(&rs->rs_zcookie_queue);
518+
rds_message_zcopy_queue_init(&rs->rs_zcookie_queue);
519519
spin_lock_init(&rs->rs_rdma_lock);
520520
rs->rs_rdma_keys = RB_ROOT;
521521
rs->rs_rx_traces = 0;

net/rds/message.c

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,16 @@ static unsigned int rds_exthdr_size[__RDS_EXTHDR_MAX] = {
4848
[RDS_EXTHDR_GEN_NUM] = sizeof(u32),
4949
};
5050

51-
5251
void 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
}
5756
EXPORT_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+
7192
static 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;
391412
err:
392-
consume_skb(skb);
413+
kfree(info);
393414
rm->data.op_mmp_znotifier = NULL;
394415
return ret;
395416
}

net/rds/rds.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -357,16 +357,27 @@ static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie)
357357
#define RDS_MSG_FLUSH 8
358358

359359
struct rds_znotifier {
360-
struct list_head z_list;
361360
struct mmpin z_mmp;
362361
u32 z_cookie;
363362
};
364363

365-
#define RDS_ZCOPY_SKB(__skb) ((struct rds_znotifier *)&((__skb)->cb[0]))
364+
struct rds_msg_zcopy_info {
365+
struct list_head rs_zcookie_next;
366+
union {
367+
struct rds_znotifier znotif;
368+
struct rds_zcopy_cookies zcookies;
369+
};
370+
};
366371

367-
static inline struct sk_buff *rds_skb_from_znotifier(struct rds_znotifier *z)
372+
struct rds_msg_zcopy_queue {
373+
struct list_head zcookie_head;
374+
spinlock_t lock; /* protects zcookie_head queue */
375+
};
376+
377+
static inline void rds_message_zcopy_queue_init(struct rds_msg_zcopy_queue *q)
368378
{
369-
return container_of((void *)z, struct sk_buff, cb);
379+
spin_lock_init(&q->lock);
380+
INIT_LIST_HEAD(&q->zcookie_head);
370381
}
371382

372383
struct rds_message {
@@ -603,8 +614,7 @@ struct rds_sock {
603614
/* Socket receive path trace points*/
604615
u8 rs_rx_traces;
605616
u8 rs_rx_trace[RDS_MSG_RX_DGRAM_TRACE_MAX];
606-
607-
struct sk_buff_head rs_zcookie_queue;
617+
struct rds_msg_zcopy_queue rs_zcookie_queue;
608618
};
609619

610620
static inline struct rds_sock *rds_sk_to_rs(const struct sock *sk)
@@ -803,6 +813,7 @@ void rds_message_addref(struct rds_message *rm);
803813
void rds_message_put(struct rds_message *rm);
804814
void rds_message_wait(struct rds_message *rm);
805815
void rds_message_unmapped(struct rds_message *rm);
816+
void rds_notify_msg_zcopy_purge(struct rds_msg_zcopy_queue *info);
806817

807818
static inline void rds_message_make_checksum(struct rds_header *hdr)
808819
{

net/rds/recv.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -579,9 +579,10 @@ static int rds_cmsg_recv(struct rds_incoming *inc, struct msghdr *msg,
579579

580580
static bool rds_recvmsg_zcookie(struct rds_sock *rs, struct msghdr *msg)
581581
{
582-
struct sk_buff *skb;
583-
struct sk_buff_head *q = &rs->rs_zcookie_queue;
582+
struct rds_msg_zcopy_queue *q = &rs->rs_zcookie_queue;
583+
struct rds_msg_zcopy_info *info = NULL;
584584
struct rds_zcopy_cookies *done;
585+
unsigned long flags;
585586

586587
if (!msg->msg_control)
587588
return false;
@@ -590,16 +591,24 @@ static bool rds_recvmsg_zcookie(struct rds_sock *rs, struct msghdr *msg)
590591
msg->msg_controllen < CMSG_SPACE(sizeof(*done)))
591592
return false;
592593

593-
skb = skb_dequeue(q);
594-
if (!skb)
594+
spin_lock_irqsave(&q->lock, flags);
595+
if (!list_empty(&q->zcookie_head)) {
596+
info = list_entry(q->zcookie_head.next,
597+
struct rds_msg_zcopy_info, rs_zcookie_next);
598+
list_del(&info->rs_zcookie_next);
599+
}
600+
spin_unlock_irqrestore(&q->lock, flags);
601+
if (!info)
595602
return false;
596-
done = (struct rds_zcopy_cookies *)skb->cb;
603+
done = &info->zcookies;
597604
if (put_cmsg(msg, SOL_RDS, RDS_CMSG_ZCOPY_COMPLETION, sizeof(*done),
598605
done)) {
599-
skb_queue_head(q, skb);
606+
spin_lock_irqsave(&q->lock, flags);
607+
list_add(&info->rs_zcookie_next, &q->zcookie_head);
608+
spin_unlock_irqrestore(&q->lock, flags);
600609
return false;
601610
}
602-
consume_skb(skb);
611+
kfree(info);
603612
return true;
604613
}
605614

0 commit comments

Comments
 (0)