For each queue, from the most- to least-constrained: * find an LSB that can be assigned to the queue. If there are N queues that * can only use M LSBs, where N > M, fail; otherwise, every queue will get a * dedicated LSB. Remaining LSB regions become a shared resource. * If we have fewer LSBs than queues, all LSB regions become shared * resources. */
| 428 | * resources. |
| 429 | */ |
| 430 | static int |
| 431 | ccp_assign_lsbs(struct ccp_device *ccp) |
| 432 | { |
| 433 | unsigned long lsb_pub = 0, qlsb = 0; |
| 434 | int n_lsbs = 0; |
| 435 | int bitno; |
| 436 | int i, lsb_cnt; |
| 437 | int rc = 0; |
| 438 | |
| 439 | rte_spinlock_init(&ccp->lsb_lock); |
| 440 | |
| 441 | /* Create an aggregate bitmap to get a total count of available LSBs */ |
| 442 | for (i = 0; i < ccp->cmd_q_count; i++) |
| 443 | lsb_pub |= ccp->cmd_q[i].lsbmask; |
| 444 | |
| 445 | for (i = 0; i < MAX_LSB_CNT; i++) |
| 446 | if (ccp_get_bit(&lsb_pub, i)) |
| 447 | n_lsbs++; |
| 448 | |
| 449 | if (n_lsbs >= ccp->cmd_q_count) { |
| 450 | /* We have enough LSBS to give every queue a private LSB. |
| 451 | * Brute force search to start with the queues that are more |
| 452 | * constrained in LSB choice. When an LSB is privately |
| 453 | * assigned, it is removed from the public mask. |
| 454 | * This is an ugly N squared algorithm with some optimization. |
| 455 | */ |
| 456 | for (lsb_cnt = 1; n_lsbs && (lsb_cnt <= MAX_LSB_CNT); |
| 457 | lsb_cnt++) { |
| 458 | rc = ccp_find_and_assign_lsb_to_q(ccp, lsb_cnt, n_lsbs, |
| 459 | &lsb_pub); |
| 460 | if (rc < 0) |
| 461 | return -EINVAL; |
| 462 | n_lsbs = rc; |
| 463 | } |
| 464 | } |
| 465 | |
| 466 | rc = 0; |
| 467 | /* What's left of the LSBs, according to the public mask, now become |
| 468 | * shared. Any zero bits in the lsb_pub mask represent an LSB region |
| 469 | * that can't be used as a shared resource, so mark the LSB slots for |
| 470 | * them as "in use". |
| 471 | */ |
| 472 | qlsb = lsb_pub; |
| 473 | bitno = ccp_find_first_zero_bit(&qlsb, MAX_LSB_CNT); |
| 474 | while (bitno < MAX_LSB_CNT) { |
| 475 | ccp_bitmap_set(ccp->lsbmap, bitno * LSB_SIZE, LSB_SIZE); |
| 476 | ccp_set_bit(&qlsb, bitno); |
| 477 | bitno = ccp_find_first_zero_bit(&qlsb, MAX_LSB_CNT); |
| 478 | } |
| 479 | |
| 480 | return rc; |
| 481 | } |
| 482 | |
| 483 | static int |
| 484 | ccp_add_device(struct ccp_device *dev) |
no test coverage detected