diff options
Diffstat (limited to 'net/dccp/ccids/lib/packet_history.c')
-rw-r--r-- | net/dccp/ccids/lib/packet_history.c | 95 |
1 files changed, 49 insertions, 46 deletions
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c index b628714fb2ab..e1ab853c38df 100644 --- a/net/dccp/ccids/lib/packet_history.c +++ b/net/dccp/ccids/lib/packet_history.c | |||
@@ -114,48 +114,33 @@ EXPORT_SYMBOL_GPL(tfrc_tx_hist_rtt); | |||
114 | /* | 114 | /* |
115 | * Receiver History Routines | 115 | * Receiver History Routines |
116 | */ | 116 | */ |
117 | struct dccp_rx_hist *dccp_rx_hist_new(const char *name) | 117 | static struct kmem_cache *tfrc_rx_hist_slab; |
118 | |||
119 | struct dccp_rx_hist_entry *dccp_rx_hist_entry_new(const u32 ndp, | ||
120 | const struct sk_buff *skb, | ||
121 | const gfp_t prio) | ||
118 | { | 122 | { |
119 | struct dccp_rx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC); | 123 | struct dccp_rx_hist_entry *entry = kmem_cache_alloc(tfrc_rx_hist_slab, |
120 | static const char dccp_rx_hist_mask[] = "rx_hist_%s"; | 124 | prio); |
121 | char *slab_name; | ||
122 | |||
123 | if (hist == NULL) | ||
124 | goto out; | ||
125 | |||
126 | slab_name = kmalloc(strlen(name) + sizeof(dccp_rx_hist_mask) - 1, | ||
127 | GFP_ATOMIC); | ||
128 | if (slab_name == NULL) | ||
129 | goto out_free_hist; | ||
130 | |||
131 | sprintf(slab_name, dccp_rx_hist_mask, name); | ||
132 | hist->dccprxh_slab = kmem_cache_create(slab_name, | ||
133 | sizeof(struct dccp_rx_hist_entry), | ||
134 | 0, SLAB_HWCACHE_ALIGN, NULL); | ||
135 | if (hist->dccprxh_slab == NULL) | ||
136 | goto out_free_slab_name; | ||
137 | out: | ||
138 | return hist; | ||
139 | out_free_slab_name: | ||
140 | kfree(slab_name); | ||
141 | out_free_hist: | ||
142 | kfree(hist); | ||
143 | hist = NULL; | ||
144 | goto out; | ||
145 | } | ||
146 | 125 | ||
147 | EXPORT_SYMBOL_GPL(dccp_rx_hist_new); | 126 | if (entry != NULL) { |
127 | const struct dccp_hdr *dh = dccp_hdr(skb); | ||
148 | 128 | ||
149 | void dccp_rx_hist_delete(struct dccp_rx_hist *hist) | 129 | entry->dccphrx_seqno = DCCP_SKB_CB(skb)->dccpd_seq; |
150 | { | 130 | entry->dccphrx_ccval = dh->dccph_ccval; |
151 | const char* name = kmem_cache_name(hist->dccprxh_slab); | 131 | entry->dccphrx_type = dh->dccph_type; |
132 | entry->dccphrx_ndp = ndp; | ||
133 | entry->dccphrx_tstamp = ktime_get_real(); | ||
134 | } | ||
152 | 135 | ||
153 | kmem_cache_destroy(hist->dccprxh_slab); | 136 | return entry; |
154 | kfree(name); | ||
155 | kfree(hist); | ||
156 | } | 137 | } |
138 | EXPORT_SYMBOL_GPL(dccp_rx_hist_entry_new); | ||
157 | 139 | ||
158 | EXPORT_SYMBOL_GPL(dccp_rx_hist_delete); | 140 | static inline void dccp_rx_hist_entry_delete(struct dccp_rx_hist_entry *entry) |
141 | { | ||
142 | kmem_cache_free(tfrc_rx_hist_slab, entry); | ||
143 | } | ||
159 | 144 | ||
160 | int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq, | 145 | int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq, |
161 | u8 *ccval) | 146 | u8 *ccval) |
@@ -192,11 +177,10 @@ struct dccp_rx_hist_entry * | |||
192 | 177 | ||
193 | EXPORT_SYMBOL_GPL(dccp_rx_hist_find_data_packet); | 178 | EXPORT_SYMBOL_GPL(dccp_rx_hist_find_data_packet); |
194 | 179 | ||
195 | void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist, | 180 | void dccp_rx_hist_add_packet(struct list_head *rx_list, |
196 | struct list_head *rx_list, | 181 | struct list_head *li_list, |
197 | struct list_head *li_list, | 182 | struct dccp_rx_hist_entry *packet, |
198 | struct dccp_rx_hist_entry *packet, | 183 | u64 nonloss_seqno) |
199 | u64 nonloss_seqno) | ||
200 | { | 184 | { |
201 | struct dccp_rx_hist_entry *entry, *next; | 185 | struct dccp_rx_hist_entry *entry, *next; |
202 | u8 num_later = 0; | 186 | u8 num_later = 0; |
@@ -211,7 +195,7 @@ void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist, | |||
211 | if (after48(nonloss_seqno, | 195 | if (after48(nonloss_seqno, |
212 | entry->dccphrx_seqno)) { | 196 | entry->dccphrx_seqno)) { |
213 | list_del_init(&entry->dccphrx_node); | 197 | list_del_init(&entry->dccphrx_node); |
214 | dccp_rx_hist_entry_delete(hist, entry); | 198 | dccp_rx_hist_entry_delete(entry); |
215 | } | 199 | } |
216 | } else if (dccp_rx_hist_entry_data_packet(entry)) | 200 | } else if (dccp_rx_hist_entry_data_packet(entry)) |
217 | --num_later; | 201 | --num_later; |
@@ -253,7 +237,7 @@ void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist, | |||
253 | break; | 237 | break; |
254 | case 3: | 238 | case 3: |
255 | list_del_init(&entry->dccphrx_node); | 239 | list_del_init(&entry->dccphrx_node); |
256 | dccp_rx_hist_entry_delete(hist, entry); | 240 | dccp_rx_hist_entry_delete(entry); |
257 | break; | 241 | break; |
258 | } | 242 | } |
259 | } else if (dccp_rx_hist_entry_data_packet(entry)) | 243 | } else if (dccp_rx_hist_entry_data_packet(entry)) |
@@ -264,13 +248,13 @@ void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist, | |||
264 | 248 | ||
265 | EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet); | 249 | EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet); |
266 | 250 | ||
267 | void dccp_rx_hist_purge(struct dccp_rx_hist *hist, struct list_head *list) | 251 | void dccp_rx_hist_purge(struct list_head *list) |
268 | { | 252 | { |
269 | struct dccp_rx_hist_entry *entry, *next; | 253 | struct dccp_rx_hist_entry *entry, *next; |
270 | 254 | ||
271 | list_for_each_entry_safe(entry, next, list, dccphrx_node) { | 255 | list_for_each_entry_safe(entry, next, list, dccphrx_node) { |
272 | list_del_init(&entry->dccphrx_node); | 256 | list_del_init(&entry->dccphrx_node); |
273 | kmem_cache_free(hist->dccprxh_slab, entry); | 257 | dccp_rx_hist_entry_delete(entry); |
274 | } | 258 | } |
275 | } | 259 | } |
276 | 260 | ||
@@ -281,8 +265,22 @@ __init int packet_history_init(void) | |||
281 | tfrc_tx_hist_slab = kmem_cache_create("tfrc_tx_hist", | 265 | tfrc_tx_hist_slab = kmem_cache_create("tfrc_tx_hist", |
282 | sizeof(struct tfrc_tx_hist_entry), 0, | 266 | sizeof(struct tfrc_tx_hist_entry), 0, |
283 | SLAB_HWCACHE_ALIGN, NULL); | 267 | SLAB_HWCACHE_ALIGN, NULL); |
268 | if (tfrc_tx_hist_slab == NULL) | ||
269 | goto out_err; | ||
284 | 270 | ||
285 | return tfrc_tx_hist_slab == NULL ? -ENOBUFS : 0; | 271 | tfrc_rx_hist_slab = kmem_cache_create("tfrc_rx_hist", |
272 | sizeof(struct dccp_rx_hist_entry), 0, | ||
273 | SLAB_HWCACHE_ALIGN, NULL); | ||
274 | if (tfrc_rx_hist_slab == NULL) | ||
275 | goto out_free_tx; | ||
276 | |||
277 | return 0; | ||
278 | |||
279 | out_free_tx: | ||
280 | kmem_cache_destroy(tfrc_tx_hist_slab); | ||
281 | tfrc_tx_hist_slab = NULL; | ||
282 | out_err: | ||
283 | return -ENOBUFS; | ||
286 | } | 284 | } |
287 | 285 | ||
288 | void packet_history_exit(void) | 286 | void packet_history_exit(void) |
@@ -291,4 +289,9 @@ void packet_history_exit(void) | |||
291 | kmem_cache_destroy(tfrc_tx_hist_slab); | 289 | kmem_cache_destroy(tfrc_tx_hist_slab); |
292 | tfrc_tx_hist_slab = NULL; | 290 | tfrc_tx_hist_slab = NULL; |
293 | } | 291 | } |
292 | |||
293 | if (tfrc_rx_hist_slab != NULL) { | ||
294 | kmem_cache_destroy(tfrc_rx_hist_slab); | ||
295 | tfrc_rx_hist_slab = NULL; | ||
296 | } | ||
294 | } | 297 | } |