Skip to content

Commit 7423546

Browse files
sanpeqfnamjaejeon
authored andcommitted
exfat: using hweight instead of internal logic
Replace the internal table lookup algorithm with the hweight library, which has instruction set acceleration capabilities. Use it to increase the length of a single calculation of the exfat_find_free_bitmap function to the long type. Signed-off-by: John Sanpe <sanpeqf@gmail.com> Acked-by: Sungjong Seo <sj1557.seo@samsung.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
1 parent 0dd3ee3 commit 7423546

File tree

1 file changed

+21
-27
lines changed

1 file changed

+21
-27
lines changed

fs/exfat/balloc.c

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,22 @@
55

66
#include <linux/blkdev.h>
77
#include <linux/slab.h>
8+
#include <linux/bitmap.h>
89
#include <linux/buffer_head.h>
910

1011
#include "exfat_raw.h"
1112
#include "exfat_fs.h"
1213

14+
#if BITS_PER_LONG == 32
15+
#define __le_long __le32
16+
#define lel_to_cpu(A) le32_to_cpu(A)
17+
#elif BITS_PER_LONG == 64
18+
#define __le_long __le64
19+
#define lel_to_cpu(A) le64_to_cpu(A)
20+
#else
21+
#error "BITS_PER_LONG not 32 or 64"
22+
#endif
23+
1324
static const unsigned char free_bit[] = {
1425
0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2,/* 0 ~ 19*/
1526
0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3,/* 20 ~ 39*/
@@ -26,22 +37,6 @@ static const unsigned char free_bit[] = {
2637
0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /*240 ~ 254*/
2738
};
2839

29-
static const unsigned char used_bit[] = {
30-
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3,/* 0 ~ 19*/
31-
2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4,/* 20 ~ 39*/
32-
2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5,/* 40 ~ 59*/
33-
4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,/* 60 ~ 79*/
34-
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,/* 80 ~ 99*/
35-
3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,/*100 ~ 119*/
36-
4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4,/*120 ~ 139*/
37-
3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,/*140 ~ 159*/
38-
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5,/*160 ~ 179*/
39-
4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,/*180 ~ 199*/
40-
3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6,/*200 ~ 219*/
41-
5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,/*220 ~ 239*/
42-
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 /*240 ~ 255*/
43-
};
44-
4540
/*
4641
* Allocation Bitmap Management Functions
4742
*/
@@ -244,25 +239,24 @@ int exfat_count_used_clusters(struct super_block *sb, unsigned int *ret_count)
244239
unsigned int count = 0;
245240
unsigned int i, map_i = 0, map_b = 0;
246241
unsigned int total_clus = EXFAT_DATA_CLUSTER_COUNT(sbi);
247-
unsigned int last_mask = total_clus & BITS_PER_BYTE_MASK;
248-
unsigned char clu_bits;
249-
const unsigned char last_bit_mask[] = {0, 0b00000001, 0b00000011,
250-
0b00000111, 0b00001111, 0b00011111, 0b00111111, 0b01111111};
242+
unsigned int last_mask = total_clus & (BITS_PER_LONG - 1);
243+
unsigned long *bitmap, clu_bits;
251244

252245
total_clus &= ~last_mask;
253-
for (i = 0; i < total_clus; i += BITS_PER_BYTE) {
254-
clu_bits = *(sbi->vol_amap[map_i]->b_data + map_b);
255-
count += used_bit[clu_bits];
256-
if (++map_b >= (unsigned int)sb->s_blocksize) {
246+
for (i = 0; i < total_clus; i += BITS_PER_LONG) {
247+
bitmap = (void *)(sbi->vol_amap[map_i]->b_data + map_b);
248+
count += hweight_long(*bitmap);
249+
map_b += sizeof(long);
250+
if (map_b >= (unsigned int)sb->s_blocksize) {
257251
map_i++;
258252
map_b = 0;
259253
}
260254
}
261255

262256
if (last_mask) {
263-
clu_bits = *(sbi->vol_amap[map_i]->b_data + map_b);
264-
clu_bits &= last_bit_mask[last_mask];
265-
count += used_bit[clu_bits];
257+
bitmap = (void *)(sbi->vol_amap[map_i]->b_data + map_b);
258+
clu_bits = lel_to_cpu(*(__le_long *)bitmap);
259+
count += hweight_long(clu_bits & BITMAP_LAST_WORD_MASK(last_mask));
266260
}
267261

268262
*ret_count = count;

0 commit comments

Comments
 (0)