diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-11-12 09:09:01 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-11-12 09:09:01 -0500 |
commit | 890ca861f868a10617029ffc87eae7d48ea6876c (patch) | |
tree | 713383f4e3bbd94ddb9816a25e6b3911511908f1 /lib/scatterlist.c | |
parent | 03452d27c6cd9cebb59a6bb0fb6bd8557916c263 (diff) | |
parent | 206c5f60a3d902bc4b56dab2de3e88de5eb06108 (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.c | 29 |
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 | **/ |
74 | struct scatterlist *sg_last(struct scatterlist *sgl, unsigned int nents) | 74 | struct 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 | **/ |
176 | void __sg_free_table(struct sg_table *table, unsigned int max_ents, | 177 | void __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 | **/ |
218 | void sg_free_table(struct sg_table *table) | 222 | void 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 | } |
222 | EXPORT_SYMBOL(sg_free_table); | 226 | EXPORT_SYMBOL(sg_free_table); |
223 | 227 | ||
@@ -241,8 +245,8 @@ EXPORT_SYMBOL(sg_free_table); | |||
241 | * | 245 | * |
242 | **/ | 246 | **/ |
243 | int __sg_alloc_table(struct sg_table *table, unsigned int nents, | 247 | int __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 | } |