hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/lib/sg_pool.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 #include <linux/module.h>
23 #include <linux/scatterlist.h>
34 #include <linux/mempool.h>
....@@ -69,18 +70,27 @@
6970 /**
7071 * sg_free_table_chained - Free a previously mapped sg table
7172 * @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
7375 *
7476 * Description:
7577 * Free an sg table previously allocated and setup with
7678 * sg_alloc_table_chained().
7779 *
80
+ * @nents_first_chunk has to be same with that same parameter passed
81
+ * to sg_alloc_table_chained().
82
+ *
7883 **/
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)
8086 {
81
- if (first_chunk && table->orig_nents <= SG_CHUNK_SIZE)
87
+ if (table->orig_nents <= nents_first_chunk)
8288 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);
8494 }
8595 EXPORT_SYMBOL_GPL(sg_free_table_chained);
8696
....@@ -89,31 +99,41 @@
8999 * @table: The sg table header to use
90100 * @nents: Number of entries in sg list
91101 * @first_chunk: first SGL
102
+ * @nents_first_chunk: number of the SGL of @first_chunk
92103 *
93104 * Description:
94105 * 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.
96109 *
97110 **/
98111 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)
100113 {
101114 int ret;
102115
103116 BUG_ON(!nents);
104117
105
- if (first_chunk) {
106
- if (nents <= SG_CHUNK_SIZE) {
118
+ if (first_chunk && nents_first_chunk) {
119
+ if (nents <= nents_first_chunk) {
107120 table->nents = table->orig_nents = nents;
108121 sg_init_table(table->sgl, nents);
109122 return 0;
110123 }
111124 }
112125
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
+
113132 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);
115135 if (unlikely(ret))
116
- sg_free_table_chained(table, (bool)first_chunk);
136
+ sg_free_table_chained(table, nents_first_chunk);
117137 return ret;
118138 }
119139 EXPORT_SYMBOL_GPL(sg_alloc_table_chained);
....@@ -148,10 +168,9 @@
148168 cleanup_sdb:
149169 for (i = 0; i < SG_MEMPOOL_NR; i++) {
150170 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);
155174 }
156175
157176 return -ENOMEM;