.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | #include <linux/module.h> |
---|
2 | 3 | #include <linux/scatterlist.h> |
---|
3 | 4 | #include <linux/mempool.h> |
---|
.. | .. |
---|
69 | 70 | /** |
---|
70 | 71 | * sg_free_table_chained - Free a previously mapped sg table |
---|
71 | 72 | * @table: The sg table header to use |
---|
72 | | - * @first_chunk: was first_chunk not NULL in sg_alloc_table_chained? |
---|
| 73 | + * @nents_first_chunk: size of the first_chunk SGL passed to |
---|
| 74 | + * sg_alloc_table_chained |
---|
73 | 75 | * |
---|
74 | 76 | * Description: |
---|
75 | 77 | * Free an sg table previously allocated and setup with |
---|
76 | 78 | * sg_alloc_table_chained(). |
---|
77 | 79 | * |
---|
| 80 | + * @nents_first_chunk has to be same with that same parameter passed |
---|
| 81 | + * to sg_alloc_table_chained(). |
---|
| 82 | + * |
---|
78 | 83 | **/ |
---|
79 | | -void sg_free_table_chained(struct sg_table *table, bool first_chunk) |
---|
| 84 | +void sg_free_table_chained(struct sg_table *table, |
---|
| 85 | + unsigned nents_first_chunk) |
---|
80 | 86 | { |
---|
81 | | - if (first_chunk && table->orig_nents <= SG_CHUNK_SIZE) |
---|
| 87 | + if (table->orig_nents <= nents_first_chunk) |
---|
82 | 88 | return; |
---|
83 | | - __sg_free_table(table, SG_CHUNK_SIZE, first_chunk, sg_pool_free); |
---|
| 89 | + |
---|
| 90 | + if (nents_first_chunk == 1) |
---|
| 91 | + nents_first_chunk = 0; |
---|
| 92 | + |
---|
| 93 | + __sg_free_table(table, SG_CHUNK_SIZE, nents_first_chunk, sg_pool_free); |
---|
84 | 94 | } |
---|
85 | 95 | EXPORT_SYMBOL_GPL(sg_free_table_chained); |
---|
86 | 96 | |
---|
.. | .. |
---|
89 | 99 | * @table: The sg table header to use |
---|
90 | 100 | * @nents: Number of entries in sg list |
---|
91 | 101 | * @first_chunk: first SGL |
---|
| 102 | + * @nents_first_chunk: number of the SGL of @first_chunk |
---|
92 | 103 | * |
---|
93 | 104 | * Description: |
---|
94 | 105 | * Allocate and chain SGLs in an sg table. If @nents@ is larger than |
---|
95 | | - * SG_CHUNK_SIZE a chained sg table will be setup. |
---|
| 106 | + * @nents_first_chunk a chained sg table will be setup. @first_chunk is |
---|
| 107 | + * ignored if nents_first_chunk <= 1 because user expects the SGL points |
---|
| 108 | + * non-chain SGL. |
---|
96 | 109 | * |
---|
97 | 110 | **/ |
---|
98 | 111 | int sg_alloc_table_chained(struct sg_table *table, int nents, |
---|
99 | | - struct scatterlist *first_chunk) |
---|
| 112 | + struct scatterlist *first_chunk, unsigned nents_first_chunk) |
---|
100 | 113 | { |
---|
101 | 114 | int ret; |
---|
102 | 115 | |
---|
103 | 116 | BUG_ON(!nents); |
---|
104 | 117 | |
---|
105 | | - if (first_chunk) { |
---|
106 | | - if (nents <= SG_CHUNK_SIZE) { |
---|
| 118 | + if (first_chunk && nents_first_chunk) { |
---|
| 119 | + if (nents <= nents_first_chunk) { |
---|
107 | 120 | table->nents = table->orig_nents = nents; |
---|
108 | 121 | sg_init_table(table->sgl, nents); |
---|
109 | 122 | return 0; |
---|
110 | 123 | } |
---|
111 | 124 | } |
---|
112 | 125 | |
---|
| 126 | + /* User supposes that the 1st SGL includes real entry */ |
---|
| 127 | + if (nents_first_chunk <= 1) { |
---|
| 128 | + first_chunk = NULL; |
---|
| 129 | + nents_first_chunk = 0; |
---|
| 130 | + } |
---|
| 131 | + |
---|
113 | 132 | ret = __sg_alloc_table(table, nents, SG_CHUNK_SIZE, |
---|
114 | | - first_chunk, GFP_ATOMIC, sg_pool_alloc); |
---|
| 133 | + first_chunk, nents_first_chunk, |
---|
| 134 | + GFP_ATOMIC, sg_pool_alloc); |
---|
115 | 135 | if (unlikely(ret)) |
---|
116 | | - sg_free_table_chained(table, (bool)first_chunk); |
---|
| 136 | + sg_free_table_chained(table, nents_first_chunk); |
---|
117 | 137 | return ret; |
---|
118 | 138 | } |
---|
119 | 139 | EXPORT_SYMBOL_GPL(sg_alloc_table_chained); |
---|
.. | .. |
---|
148 | 168 | cleanup_sdb: |
---|
149 | 169 | for (i = 0; i < SG_MEMPOOL_NR; i++) { |
---|
150 | 170 | struct sg_pool *sgp = sg_pools + i; |
---|
151 | | - if (sgp->pool) |
---|
152 | | - mempool_destroy(sgp->pool); |
---|
153 | | - if (sgp->slab) |
---|
154 | | - kmem_cache_destroy(sgp->slab); |
---|
| 171 | + |
---|
| 172 | + mempool_destroy(sgp->pool); |
---|
| 173 | + kmem_cache_destroy(sgp->slab); |
---|
155 | 174 | } |
---|
156 | 175 | |
---|
157 | 176 | return -ENOMEM; |
---|