Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

intel_th: msu: Get rid of the window size limit

Currently, the window size is limited to the maximum number of sg entries
in one table. This is because the code addresses individual blocks within
the window by their numeric index. In reality, though, the blocks most
often are iterated through sequentially. By rewriting the logic to use sg
pointers instead of block indices we loose the necessity to dereference
them directly and gain the ability to use multiple chained tables if
necessary.

Get rid of the limitation by replacing index-based block accesses with
sequential block accesses.

Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20190705141425.19894-4-alexander.shishkin@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Alexander Shishkin and committed by
Greg Kroah-Hartman
57b69a1f f220df66

+68 -71
+68 -71
drivers/hwtracing/intel_th/msu.c
··· 95 95 struct msc_window *start_win; 96 96 struct msc_window *win; 97 97 unsigned long offset; 98 - int start_block; 99 - int block; 98 + struct scatterlist *start_block; 99 + struct scatterlist *block; 100 100 unsigned int block_off; 101 101 unsigned int wrap_count; 102 102 unsigned int eof; ··· 269 269 return false; 270 270 } 271 271 272 - static inline struct msc_block_desc * 273 - msc_win_block(struct msc_window *win, unsigned int block) 272 + static inline struct scatterlist *msc_win_base_sg(struct msc_window *win) 274 273 { 275 - return sg_virt(&win->sgt->sgl[block]); 274 + return win->sgt->sgl; 276 275 } 277 276 278 - static inline size_t 279 - msc_win_actual_bsz(struct msc_window *win, unsigned int block) 277 + static inline struct msc_block_desc *msc_win_base(struct msc_window *win) 280 278 { 281 - return win->sgt->sgl[block].length; 279 + return sg_virt(msc_win_base_sg(win)); 282 280 } 283 281 284 - static inline dma_addr_t 285 - msc_win_baddr(struct msc_window *win, unsigned int block) 282 + static inline dma_addr_t msc_win_base_dma(struct msc_window *win) 286 283 { 287 - return sg_dma_address(&win->sgt->sgl[block]); 284 + return sg_dma_address(msc_win_base_sg(win)); 288 285 } 289 286 290 287 static inline unsigned long 291 - msc_win_bpfn(struct msc_window *win, unsigned int block) 288 + msc_win_base_pfn(struct msc_window *win) 292 289 { 293 - return msc_win_baddr(win, block) >> PAGE_SHIFT; 290 + return PFN_DOWN(msc_win_base_dma(win)); 294 291 } 295 292 296 293 /** ··· 317 320 318 321 static size_t msc_win_total_sz(struct msc_window *win) 319 322 { 323 + struct scatterlist *sg; 320 324 unsigned int blk; 321 325 size_t size = 0; 322 326 323 - for (blk = 0; blk < win->nr_segs; blk++) { 324 - struct msc_block_desc *bdesc = msc_win_block(win, blk); 327 + for_each_sg(win->sgt->sgl, sg, win->nr_segs, blk) { 328 + struct msc_block_desc *bdesc = sg_virt(sg); 325 329 326 330 if (msc_block_wrapped(bdesc)) 327 331 return win->nr_blocks << PAGE_SHIFT; ··· 363 365 found++; 364 366 365 367 /* skip the empty ones */ 366 - if (nonempty && msc_block_is_empty(msc_win_block(win, 0))) 368 + if (nonempty && msc_block_is_empty(msc_win_base(win))) 367 369 continue; 368 370 369 371 if (found) ··· 397 399 } 398 400 399 401 /** 400 - * msc_win_oldest_block() - locate the oldest block in a given window 402 + * msc_win_oldest_sg() - locate the oldest block in a given window 401 403 * @win: window to look at 402 404 * 403 405 * Return: index of the block with the oldest data 404 406 */ 405 - static unsigned int msc_win_oldest_block(struct msc_window *win) 407 + static struct scatterlist *msc_win_oldest_sg(struct msc_window *win) 406 408 { 407 409 unsigned int blk; 408 - struct msc_block_desc *bdesc = msc_win_block(win, 0); 410 + struct scatterlist *sg; 411 + struct msc_block_desc *bdesc = msc_win_base(win); 409 412 410 413 /* without wrapping, first block is the oldest */ 411 414 if (!msc_block_wrapped(bdesc)) 412 - return 0; 415 + return msc_win_base_sg(win); 413 416 414 417 /* 415 418 * with wrapping, last written block contains both the newest and the 416 419 * oldest data for this window. 417 420 */ 418 - for (blk = 0; blk < win->nr_segs; blk++) { 419 - bdesc = msc_win_block(win, blk); 421 + for_each_sg(win->sgt->sgl, sg, win->nr_segs, blk) { 422 + struct msc_block_desc *bdesc = sg_virt(sg); 420 423 421 424 if (msc_block_last_written(bdesc)) 422 - return blk; 425 + return sg; 423 426 } 424 427 425 - return 0; 428 + return msc_win_base_sg(win); 426 429 } 427 430 428 431 static struct msc_block_desc *msc_iter_bdesc(struct msc_iter *iter) 429 432 { 430 - return msc_win_block(iter->win, iter->block); 431 - } 432 - 433 - static void msc_iter_init(struct msc_iter *iter) 434 - { 435 - memset(iter, 0, sizeof(*iter)); 436 - iter->start_block = -1; 437 - iter->block = -1; 433 + return sg_virt(iter->block); 438 434 } 439 435 440 436 static struct msc_iter *msc_iter_install(struct msc *msc) ··· 453 461 goto unlock; 454 462 } 455 463 456 - msc_iter_init(iter); 457 464 iter->msc = msc; 458 465 459 466 list_add_tail(&iter->entry, &msc->iter_list); ··· 473 482 474 483 static void msc_iter_block_start(struct msc_iter *iter) 475 484 { 476 - if (iter->start_block != -1) 485 + if (iter->start_block) 477 486 return; 478 487 479 - iter->start_block = msc_win_oldest_block(iter->win); 488 + iter->start_block = msc_win_oldest_sg(iter->win); 480 489 iter->block = iter->start_block; 481 490 iter->wrap_count = 0; 482 491 ··· 500 509 return -EINVAL; 501 510 502 511 iter->win = iter->start_win; 503 - iter->start_block = -1; 512 + iter->start_block = NULL; 504 513 505 514 msc_iter_block_start(iter); 506 515 ··· 510 519 static int msc_iter_win_advance(struct msc_iter *iter) 511 520 { 512 521 iter->win = msc_next_window(iter->win); 513 - iter->start_block = -1; 522 + iter->start_block = NULL; 514 523 515 524 if (iter->win == iter->start_win) { 516 525 iter->eof++; ··· 540 549 return msc_iter_win_advance(iter); 541 550 542 551 /* block advance */ 543 - if (++iter->block == iter->win->nr_segs) 544 - iter->block = 0; 552 + if (sg_is_last(iter->block)) 553 + iter->block = msc_win_base_sg(iter->win); 554 + else 555 + iter->block = sg_next(iter->block); 545 556 546 557 /* no wrapping, sanity check in case there is no last written block */ 547 558 if (!iter->wrap_count && iter->block == iter->start_block) ··· 648 655 static void msc_buffer_clear_hw_header(struct msc *msc) 649 656 { 650 657 struct msc_window *win; 658 + struct scatterlist *sg; 651 659 652 660 list_for_each_entry(win, &msc->win_list, entry) { 653 661 unsigned int blk; 654 662 size_t hw_sz = sizeof(struct msc_block_desc) - 655 663 offsetof(struct msc_block_desc, hw_tag); 656 664 657 - for (blk = 0; blk < win->nr_segs; blk++) { 658 - struct msc_block_desc *bdesc = msc_win_block(win, blk); 665 + for_each_sg(win->sgt->sgl, sg, win->nr_segs, blk) { 666 + struct msc_block_desc *bdesc = sg_virt(sg); 659 667 660 668 memset(&bdesc->hw_tag, 0, hw_sz); 661 669 } ··· 999 1005 return nr_segs; 1000 1006 1001 1007 err_nomem: 1002 - for (i--; i >= 0; i--) 1008 + for_each_sg(win->sgt->sgl, sg_ptr, i, ret) 1003 1009 dma_free_coherent(msc_dev(win->msc)->parent->parent, PAGE_SIZE, 1004 - msc_win_block(win, i), 1005 - msc_win_baddr(win, i)); 1010 + sg_virt(sg_ptr), sg_dma_address(sg_ptr)); 1006 1011 1007 1012 sg_free_table(win->sgt); 1008 1013 ··· 1011 1018 #ifdef CONFIG_X86 1012 1019 static void msc_buffer_set_uc(struct msc_window *win, unsigned int nr_segs) 1013 1020 { 1021 + struct scatterlist *sg_ptr; 1014 1022 int i; 1015 1023 1016 - for (i = 0; i < nr_segs; i++) 1024 + for_each_sg(win->sgt->sgl, sg_ptr, nr_segs, i) { 1017 1025 /* Set the page as uncached */ 1018 - set_memory_uc((unsigned long)msc_win_block(win, i), 1); 1026 + set_memory_uc((unsigned long)sg_virt(sg_ptr), 1027 + PFN_DOWN(sg_ptr->length)); 1028 + } 1019 1029 } 1020 1030 1021 1031 static void msc_buffer_set_wb(struct msc_window *win) 1022 1032 { 1033 + struct scatterlist *sg_ptr; 1023 1034 int i; 1024 1035 1025 - for (i = 0; i < win->nr_segs; i++) 1036 + for_each_sg(win->sgt->sgl, sg_ptr, win->nr_segs, i) { 1026 1037 /* Reset the page to write-back */ 1027 - set_memory_wb((unsigned long)msc_win_block(win, i), 1); 1038 + set_memory_wb((unsigned long)sg_virt(sg_ptr), 1039 + PFN_DOWN(sg_ptr->length)); 1040 + } 1028 1041 } 1029 1042 #else /* !X86 */ 1030 1043 static inline void ··· 1055 1056 1056 1057 if (!nr_blocks) 1057 1058 return 0; 1058 - 1059 - /* 1060 - * This limitation hold as long as we need random access to the 1061 - * block. When that changes, this can go away. 1062 - */ 1063 - if (nr_blocks > SG_MAX_SINGLE_ALLOC) 1064 - return -EINVAL; 1065 1059 1066 1060 win = kzalloc(sizeof(*win), GFP_KERNEL); 1067 1061 if (!win) ··· 1088 1096 win->nr_blocks = nr_blocks; 1089 1097 1090 1098 if (list_empty(&msc->win_list)) { 1091 - msc->base = msc_win_block(win, 0); 1092 - msc->base_addr = msc_win_baddr(win, 0); 1099 + msc->base = msc_win_base(win); 1100 + msc->base_addr = msc_win_base_dma(win); 1093 1101 msc->cur_win = win; 1094 1102 } 1095 1103 ··· 1106 1114 1107 1115 static void __msc_buffer_win_free(struct msc *msc, struct msc_window *win) 1108 1116 { 1117 + struct scatterlist *sg; 1109 1118 int i; 1110 1119 1111 - for (i = 0; i < win->nr_segs; i++) { 1112 - struct page *page = sg_page(&win->sgt->sgl[i]); 1120 + for_each_sg(win->sgt->sgl, sg, win->nr_segs, i) { 1121 + struct page *page = sg_page(sg); 1113 1122 1114 1123 page->mapping = NULL; 1115 1124 dma_free_coherent(msc_dev(win->msc)->parent->parent, PAGE_SIZE, 1116 - msc_win_block(win, i), msc_win_baddr(win, i)); 1125 + sg_virt(sg), sg_dma_address(sg)); 1117 1126 } 1118 1127 sg_free_table(win->sgt); 1119 1128 } ··· 1160 1167 1161 1168 /* call with msc::mutex locked */ 1162 1169 list_for_each_entry(win, &msc->win_list, entry) { 1170 + struct scatterlist *sg; 1163 1171 unsigned int blk; 1164 1172 u32 sw_tag = 0; 1165 1173 ··· 1176 1182 next_win = list_next_entry(win, entry); 1177 1183 } 1178 1184 1179 - for (blk = 0; blk < win->nr_segs; blk++) { 1180 - struct msc_block_desc *bdesc = msc_win_block(win, blk); 1185 + for_each_sg(win->sgt->sgl, sg, win->nr_segs, blk) { 1186 + struct msc_block_desc *bdesc = sg_virt(sg); 1181 1187 1182 1188 memset(bdesc, 0, sizeof(*bdesc)); 1183 1189 1184 - bdesc->next_win = msc_win_bpfn(next_win, 0); 1190 + bdesc->next_win = msc_win_base_pfn(next_win); 1185 1191 1186 1192 /* 1187 1193 * Similarly to last window, last block should point ··· 1189 1195 */ 1190 1196 if (blk == win->nr_segs - 1) { 1191 1197 sw_tag |= MSC_SW_TAG_LASTBLK; 1192 - bdesc->next_blk = msc_win_bpfn(win, 0); 1198 + bdesc->next_blk = msc_win_base_pfn(win); 1193 1199 } else { 1194 - bdesc->next_blk = msc_win_bpfn(win, blk + 1); 1200 + dma_addr_t addr = sg_dma_address(sg_next(sg)); 1201 + 1202 + bdesc->next_blk = PFN_DOWN(addr); 1195 1203 } 1196 1204 1197 1205 bdesc->sw_tag = sw_tag; 1198 - bdesc->block_sz = msc_win_actual_bsz(win, blk) / 64; 1206 + bdesc->block_sz = sg->length / 64; 1199 1207 } 1200 1208 } 1201 1209 ··· 1356 1360 static struct page *msc_buffer_get_page(struct msc *msc, unsigned long pgoff) 1357 1361 { 1358 1362 struct msc_window *win; 1363 + struct scatterlist *sg; 1359 1364 unsigned int blk; 1360 1365 1361 1366 if (msc->mode == MSC_MODE_SINGLE) ··· 1371 1374 found: 1372 1375 pgoff -= win->pgoff; 1373 1376 1374 - for (blk = 0; blk < win->nr_segs; blk++) { 1375 - struct page *page = sg_page(&win->sgt->sgl[blk]); 1376 - size_t pgsz = PFN_DOWN(msc_win_actual_bsz(win, blk)); 1377 + for_each_sg(win->sgt->sgl, sg, win->nr_segs, blk) { 1378 + struct page *page = sg_page(sg); 1379 + size_t pgsz = PFN_DOWN(sg->length); 1377 1380 1378 1381 if (pgoff < pgsz) 1379 1382 return page + pgoff; ··· 1677 1680 else 1678 1681 msc->cur_win = list_next_entry(msc->cur_win, entry); 1679 1682 1680 - msc->base = msc_win_block(msc->cur_win, 0); 1681 - msc->base_addr = msc_win_baddr(msc->cur_win, 0); 1683 + msc->base = msc_win_base(msc->cur_win); 1684 + msc->base_addr = msc_win_base_dma(msc->cur_win); 1682 1685 1683 1686 intel_th_trace_switch(msc->thdev); 1684 1687 }