1 /* 2 * Copyright (c) 2006 Oracle. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 * 32 */ 33 #include <linux/kernel.h> 34 35 #include "rds.h" 36 #include "ib.h" 37 38 /* 39 * Locking for IB rings. 40 * We assume that allocation is always protected by a mutex 41 * in the caller (this is a valid assumption for the current 42 * implementation). 43 * 44 * Freeing always happens in an interrupt, and hence only 45 * races with allocations, but not with other free()s. 46 * 47 * The interaction between allocation and freeing is that 48 * the alloc code has to determine the number of free entries. 49 * To this end, we maintain two counters; an allocation counter 50 * and a free counter. Both are allowed to run freely, and wrap 51 * around. 52 * The number of used entries is always (alloc_ctr - free_ctr) % NR. 53 * 54 * The current implementation makes free_ctr atomic. When the 55 * caller finds an allocation fails, it should set an "alloc fail" 56 * bit and retry the allocation. The "alloc fail" bit essentially tells 57 * the CQ completion handlers to wake it up after freeing some 58 * more entries. 59 */ 60 61 /* 62 * This only happens on shutdown. 63 */ 64 DECLARE_WAIT_QUEUE_HEAD(rds_ib_ring_empty_wait); 65 66 void rds_ib_ring_init(struct rds_ib_work_ring *ring, u32 nr) 67 { 68 memset(ring, 0, sizeof(*ring)); 69 ring->w_nr = nr; 70 rdsdebug("ring %p nr %u\n", ring, ring->w_nr); 71 } 72 73 static inline u32 __rds_ib_ring_used(struct rds_ib_work_ring *ring) 74 { 75 u32 diff; 76 77 /* This assumes that atomic_t has at least as many bits as u32 */ 78 diff = ring->w_alloc_ctr - (u32) atomic_read(&ring->w_free_ctr); 79 BUG_ON(diff > ring->w_nr); 80 81 return diff; 82 } 83 84 void rds_ib_ring_resize(struct rds_ib_work_ring *ring, u32 nr) 85 { 86 /* We only ever get called from the connection setup code, 87 * prior to creating the QP. */ 88 BUG_ON(__rds_ib_ring_used(ring)); 89 ring->w_nr = nr; 90 } 91 92 static int __rds_ib_ring_empty(struct rds_ib_work_ring *ring) 93 { 94 return __rds_ib_ring_used(ring) == 0; 95 } 96 97 u32 rds_ib_ring_alloc(struct rds_ib_work_ring *ring, u32 val, u32 *pos) 98 { 99 u32 ret = 0, avail; 100 101 avail = ring->w_nr - __rds_ib_ring_used(ring); 102 103 rdsdebug("ring %p val %u next %u free %u\n", ring, val, 104 ring->w_alloc_ptr, avail); 105 106 if (val && avail) { 107 ret = min(val, avail); 108 *pos = ring->w_alloc_ptr; 109 110 ring->w_alloc_ptr = (ring->w_alloc_ptr + ret) % ring->w_nr; 111 ring->w_alloc_ctr += ret; 112 } 113 114 return ret; 115 } 116 117 void rds_ib_ring_free(struct rds_ib_work_ring *ring, u32 val) 118 { 119 ring->w_free_ptr = (ring->w_free_ptr + val) % ring->w_nr; 120 atomic_add(val, &ring->w_free_ctr); 121 122 if (__rds_ib_ring_empty(ring) && 123 waitqueue_active(&rds_ib_ring_empty_wait)) 124 wake_up(&rds_ib_ring_empty_wait); 125 } 126 127 void rds_ib_ring_unalloc(struct rds_ib_work_ring *ring, u32 val) 128 { 129 ring->w_alloc_ptr = (ring->w_alloc_ptr - val) % ring->w_nr; 130 ring->w_alloc_ctr -= val; 131 } 132 133 int rds_ib_ring_empty(struct rds_ib_work_ring *ring) 134 { 135 return __rds_ib_ring_empty(ring); 136 } 137 138 int rds_ib_ring_low(struct rds_ib_work_ring *ring) 139 { 140 return __rds_ib_ring_used(ring) <= (ring->w_nr >> 1); 141 } 142 143 /* 144 * returns the oldest allocated ring entry. This will be the next one 145 * freed. This can't be called if there are none allocated. 146 */ 147 u32 rds_ib_ring_oldest(struct rds_ib_work_ring *ring) 148 { 149 return ring->w_free_ptr; 150 } 151 152 /* 153 * returns the number of completed work requests. 154 */ 155 156 u32 rds_ib_ring_completed(struct rds_ib_work_ring *ring, u32 wr_id, u32 oldest) 157 { 158 u32 ret; 159 160 if (oldest <= (unsigned long long)wr_id) 161 ret = (unsigned long long)wr_id - oldest + 1; 162 else 163 ret = ring->w_nr - oldest + (unsigned long long)wr_id + 1; 164 165 rdsdebug("ring %p ret %u wr_id %u oldest %u\n", ring, ret, 166 wr_id, oldest); 167 return ret; 168 } 169
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.