aboutsummaryrefslogtreecommitdiffstats
path: root/lib/scatterlist.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-11-12 09:09:01 -0500
committerIngo Molnar <mingo@kernel.org>2014-11-12 09:09:01 -0500
commit890ca861f868a10617029ffc87eae7d48ea6876c (patch)
tree713383f4e3bbd94ddb9816a25e6b3911511908f1 /lib/scatterlist.c
parent03452d27c6cd9cebb59a6bb0fb6bd8557916c263 (diff)
parent206c5f60a3d902bc4b56dab2de3e88de5eb06108 (diff)
Merge tag 'v3.18-rc4' into x86/cleanups, to refresh the tree before pulling new changes.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'lib/scatterlist.c')
-rw-r--r--lib/scatterlist.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index 3a8e8e8fb2a5..c9f2e8c6ccc9 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -73,7 +73,7 @@ EXPORT_SYMBOL(sg_nents);
73 **/ 73 **/
74struct scatterlist *sg_last(struct scatterlist *sgl, unsigned int nents) 74struct scatterlist *sg_last(struct scatterlist *sgl, unsigned int nents)
75{ 75{
76#ifndef ARCH_HAS_SG_CHAIN 76#ifndef CONFIG_ARCH_HAS_SG_CHAIN
77 struct scatterlist *ret = &sgl[nents - 1]; 77 struct scatterlist *ret = &sgl[nents - 1];
78#else 78#else
79 struct scatterlist *sg, *ret = NULL; 79 struct scatterlist *sg, *ret = NULL;
@@ -165,6 +165,7 @@ static void sg_kfree(struct scatterlist *sg, unsigned int nents)
165 * __sg_free_table - Free a previously mapped sg table 165 * __sg_free_table - Free a previously mapped sg table
166 * @table: The sg table header to use 166 * @table: The sg table header to use
167 * @max_ents: The maximum number of entries per single scatterlist 167 * @max_ents: The maximum number of entries per single scatterlist
168 * @skip_first_chunk: don't free the (preallocated) first scatterlist chunk
168 * @free_fn: Free function 169 * @free_fn: Free function
169 * 170 *
170 * Description: 171 * Description:
@@ -174,7 +175,7 @@ static void sg_kfree(struct scatterlist *sg, unsigned int nents)
174 * 175 *
175 **/ 176 **/
176void __sg_free_table(struct sg_table *table, unsigned int max_ents, 177void __sg_free_table(struct sg_table *table, unsigned int max_ents,
177 sg_free_fn *free_fn) 178 bool skip_first_chunk, sg_free_fn *free_fn)
178{ 179{
179 struct scatterlist *sgl, *next; 180 struct scatterlist *sgl, *next;
180 181
@@ -202,7 +203,10 @@ void __sg_free_table(struct sg_table *table, unsigned int max_ents,
202 } 203 }
203 204
204 table->orig_nents -= sg_size; 205 table->orig_nents -= sg_size;
205 free_fn(sgl, alloc_size); 206 if (skip_first_chunk)
207 skip_first_chunk = false;
208 else
209 free_fn(sgl, alloc_size);
206 sgl = next; 210 sgl = next;
207 } 211 }
208 212
@@ -217,7 +221,7 @@ EXPORT_SYMBOL(__sg_free_table);
217 **/ 221 **/
218void sg_free_table(struct sg_table *table) 222void sg_free_table(struct sg_table *table)
219{ 223{
220 __sg_free_table(table, SG_MAX_SINGLE_ALLOC, sg_kfree); 224 __sg_free_table(table, SG_MAX_SINGLE_ALLOC, false, sg_kfree);
221} 225}
222EXPORT_SYMBOL(sg_free_table); 226EXPORT_SYMBOL(sg_free_table);
223 227
@@ -241,8 +245,8 @@ EXPORT_SYMBOL(sg_free_table);
241 * 245 *
242 **/ 246 **/
243int __sg_alloc_table(struct sg_table *table, unsigned int nents, 247int __sg_alloc_table(struct sg_table *table, unsigned int nents,
244 unsigned int max_ents, gfp_t gfp_mask, 248 unsigned int max_ents, struct scatterlist *first_chunk,
245 sg_alloc_fn *alloc_fn) 249 gfp_t gfp_mask, sg_alloc_fn *alloc_fn)
246{ 250{
247 struct scatterlist *sg, *prv; 251 struct scatterlist *sg, *prv;
248 unsigned int left; 252 unsigned int left;
@@ -251,7 +255,7 @@ int __sg_alloc_table(struct sg_table *table, unsigned int nents,
251 255
252 if (nents == 0) 256 if (nents == 0)
253 return -EINVAL; 257 return -EINVAL;
254#ifndef ARCH_HAS_SG_CHAIN 258#ifndef CONFIG_ARCH_HAS_SG_CHAIN
255 if (WARN_ON_ONCE(nents > max_ents)) 259 if (WARN_ON_ONCE(nents > max_ents))
256 return -EINVAL; 260 return -EINVAL;
257#endif 261#endif
@@ -269,7 +273,12 @@ int __sg_alloc_table(struct sg_table *table, unsigned int nents,
269 273
270 left -= sg_size; 274 left -= sg_size;
271 275
272 sg = alloc_fn(alloc_size, gfp_mask); 276 if (first_chunk) {
277 sg = first_chunk;
278 first_chunk = NULL;
279 } else {
280 sg = alloc_fn(alloc_size, gfp_mask);
281 }
273 if (unlikely(!sg)) { 282 if (unlikely(!sg)) {
274 /* 283 /*
275 * Adjust entry count to reflect that the last 284 * Adjust entry count to reflect that the last
@@ -324,9 +333,9 @@ int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)
324 int ret; 333 int ret;
325 334
326 ret = __sg_alloc_table(table, nents, SG_MAX_SINGLE_ALLOC, 335 ret = __sg_alloc_table(table, nents, SG_MAX_SINGLE_ALLOC,
327 gfp_mask, sg_kmalloc); 336 NULL, gfp_mask, sg_kmalloc);
328 if (unlikely(ret)) 337 if (unlikely(ret))
329 __sg_free_table(table, SG_MAX_SINGLE_ALLOC, sg_kfree); 338 __sg_free_table(table, SG_MAX_SINGLE_ALLOC, false, sg_kfree);
330 339
331 return ret; 340 return ret;
332} 341}