struct list_head rbp_msgs; /* messages blocking
for a buffer */
int rbp_npages; /* # pages in each buffer */
- int rbp_nbuffers; /* # buffers */
+ /* requested number of buffers */
+ int rbp_req_nbuffers;
+ /* # buffers actually allocated */
+ int rbp_nbuffers;
int rbp_credits; /* # free buffers /
blocked messages */
int rbp_mincredits; /* low water mark */
* buffers in this pool. Make sure we never put back
* more buffers than the stated number.
*/
- if (rbp->rbp_credits >= rbp->rbp_nbuffers) {
+ if (unlikely(rbp->rbp_credits >= rbp->rbp_req_nbuffers)) {
/* Discard this buffer so we don't have too many. */
lnet_destroy_rtrbuf(rb, rbp->rbp_npages);
+ rbp->rbp_nbuffers--;
} else {
list_add(&rb->rb_list, &rbp->rbp_bufs);
rbp->rbp_credits++;
lnet_net_lock(cpt);
lnet_drop_routed_msgs_locked(&rbp->rbp_msgs, cpt);
list_splice_init(&rbp->rbp_bufs, &tmp);
+ rbp->rbp_req_nbuffers = 0;
rbp->rbp_nbuffers = 0;
rbp->rbp_credits = 0;
rbp->rbp_mincredits = 0;
lnet_rtrbuf_t *rb;
int num_rb;
int num_buffers = 0;
+ int old_req_nbufs;
int npages = rbp->rbp_npages;
+ lnet_net_lock(cpt);
/*
* If we are called for less buffers than already in the pool, we
- * just lower the nbuffers number and excess buffers will be
+ * just lower the req_nbuffers number and excess buffers will be
* thrown away as they are returned to the free list. Credits
* then get adjusted as well.
+ * If we already have enough buffers allocated to serve the
+ * increase requested, then we can treat that the same way as we
+ * do the decrease.
*/
- if (nbufs <= rbp->rbp_nbuffers) {
- lnet_net_lock(cpt);
- rbp->rbp_nbuffers = nbufs;
+ num_rb = nbufs - rbp->rbp_nbuffers;
+ if (nbufs <= rbp->rbp_req_nbuffers || num_rb <= 0) {
+ rbp->rbp_req_nbuffers = nbufs;
lnet_net_unlock(cpt);
return 0;
}
+ /*
+ * store the older value of rbp_req_nbuffers and then set it to
+ * the new request to prevent lnet_return_rx_credits_locked() from
+ * freeing buffers that we need to keep around
+ */
+ old_req_nbufs = rbp->rbp_req_nbuffers;
+ rbp->rbp_req_nbuffers = nbufs;
+ lnet_net_unlock(cpt);
INIT_LIST_HEAD(&rb_list);
* allocated successfully then join this list to the rbp buffer
* list. If not then free all allocated buffers.
*/
- num_rb = rbp->rbp_nbuffers;
-
- while (num_rb < nbufs) {
+ while (num_rb-- > 0) {
rb = lnet_new_rtrbuf(rbp, cpt);
if (!rb) {
CERROR("Failed to allocate %d route bufs of %d pages\n",
nbufs, npages);
+
+ lnet_net_lock(cpt);
+ rbp->rbp_req_nbuffers = old_req_nbufs;
+ lnet_net_unlock(cpt);
+
goto failed;
}
list_add(&rb->rb_list, &rb_list);
num_buffers++;
- num_rb++;
}
lnet_net_lock(cpt);