On 5/27/21 10:43 PM, Noah Goldstein wrote: > On Mon, May 24, 2021 at 7:51 PM Pavel Begunkov <asml.silence@xxxxxxxxx> wrote: >> -static void io_free_file_tables(struct io_file_table *table, unsigned nr_files) >> +static void io_free_page_table(void **table, size_t size) >> { >> - unsigned i, nr_tables = DIV_ROUND_UP(nr_files, IORING_MAX_FILES_TABLE); >> + unsigned i, nr_tables = DIV_ROUND_UP(size, PAGE_SIZE); >> >> for (i = 0; i < nr_tables; i++) >> - kfree(table->files[i]); >> - kfree(table->files); >> - table->files = NULL; >> + kfree(table[i]); >> + kfree(table); >> +} >> + >> +static void **io_alloc_page_table(size_t size) >> +{ >> + unsigned i, nr_tables = DIV_ROUND_UP(size, PAGE_SIZE); >> + size_t init_size = size; >> + void **table; >> + >> + table = kcalloc(nr_tables, sizeof(*table), GFP_KERNEL); >> + if (!table) >> + return NULL; >> + >> + for (i = 0; i < nr_tables; i++) { >> + unsigned int this_size = min(size, PAGE_SIZE); >> + >> + table[i] = kzalloc(this_size, GFP_KERNEL); >> + if (!table[i]) { >> + io_free_page_table(table, init_size); >> + return NULL; > Unless zalloc returns non-NULL for size == 0, you are guranteed to do > this for size <= PAGE_SIZE * (nr_tables - 1). Possibly worth calculating early? Far from being a fast path, so would rather keep it simpler and cleaner > > If you calculate early you could then make the loop: > > for (i = 0; i < nr_tables - 1; i++) { > table[i] = kzalloc(PAGE_SIZE, GFP_KERNEL); > if (!table[i]) { > io_free_page_table(table, init_size); > return NULL; > } > } > > table[i] = kzalloc(size - (nr_tables - 1) * PAGE_SIZE, GFP_KERNEL); > if (!table[i]) { > io_free_page_table(table, init_size); > return NULL; > } > > Which is almost certainly faster. -- Pavel Begunkov