1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2024 Marvell. 3 */ 4 5 #include <rte_compressdev_pmd.h> 6 #include <rte_errno.h> 7 #include <rte_malloc.h> 8 #include <rte_hexdump.h> 9 10 #include "nitrox_comp_reqmgr.h" 11 #include "nitrox_logs.h" 12 #include "rte_comp.h" 13 14 #define NITROX_INSTR_BUFFER_DEBUG 0 15 #define NITROX_ZIP_SGL_COUNT 16 16 #define NITROX_ZIP_MAX_ZPTRS 2048 17 #define NITROX_ZIP_MAX_DATASIZE ((1 << 24) - 1) 18 #define NITROX_ZIP_MAX_ONFSIZE 1024 19 #define CMD_TIMEOUT 2 20 21 union nitrox_zip_instr_word0 { 22 uint64_t u64; 23 struct { 24 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 25 uint64_t raz0 : 8; 26 uint64_t tol : 24; 27 uint64_t raz1 : 5; 28 uint64_t exn : 3; 29 uint64_t raz2 : 1; 30 uint64_t exbits : 7; 31 uint64_t raz3 : 3; 32 uint64_t ca : 1; 33 uint64_t sf : 1; 34 uint64_t ss : 2; 35 uint64_t cc : 2; 36 uint64_t ef : 1; 37 uint64_t bf : 1; 38 uint64_t co : 1; 39 uint64_t raz4 : 1; 40 uint64_t ds : 1; 41 uint64_t dg : 1; 42 uint64_t hg : 1; 43 #else 44 uint64_t hg : 1; 45 uint64_t dg : 1; 46 uint64_t ds : 1; 47 uint64_t raz4 : 1; 48 uint64_t co : 1; 49 uint64_t bf : 1; 50 uint64_t ef : 1; 51 uint64_t cc : 2; 52 uint64_t ss : 2; 53 uint64_t sf : 1; 54 uint64_t ca : 1; 55 uint64_t raz3 : 3; 56 uint64_t exbits : 7; 57 uint64_t raz2 : 1; 58 uint64_t exn : 3; 59 uint64_t raz1 : 5; 60 uint64_t tol : 24; 61 uint64_t raz0 : 8; 62 #endif 63 64 }; 65 }; 66 67 union nitrox_zip_instr_word1 { 68 uint64_t u64; 69 struct { 70 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 71 uint64_t hl : 16; 72 uint64_t raz0 : 16; 73 uint64_t adlercrc32 : 32; 74 #else 75 uint64_t adlercrc32 : 32; 76 uint64_t raz0 : 16; 77 uint64_t hl : 16; 78 #endif 79 }; 80 }; 81 82 union nitrox_zip_instr_word2 { 83 uint64_t u64; 84 struct { 85 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 86 uint64_t raz0 : 20; 87 uint64_t cptr : 44; 88 #else 89 uint64_t cptr : 44; 90 uint64_t raz0 : 20; 91 #endif 92 }; 93 }; 94 95 union nitrox_zip_instr_word3 { 96 uint64_t u64; 97 struct { 98 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 99 uint64_t raz0 : 4; 100 uint64_t hlen : 16; 101 uint64_t hptr : 44; 102 #else 103 uint64_t hptr : 44; 104 uint64_t hlen : 16; 105 uint64_t raz0 : 4; 106 #endif 107 }; 108 }; 109 110 union nitrox_zip_instr_word4 { 111 uint64_t u64; 112 struct { 113 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 114 uint64_t raz0 : 4; 115 uint64_t ilen : 16; 116 uint64_t iptr : 44; 117 #else 118 uint64_t iptr : 44; 119 uint64_t ilen : 16; 120 uint64_t raz0 : 4; 121 #endif 122 }; 123 }; 124 125 union nitrox_zip_instr_word5 { 126 uint64_t u64; 127 struct { 128 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 129 uint64_t raz0 : 4; 130 uint64_t olen : 16; 131 uint64_t optr : 44; 132 #else 133 uint64_t optr : 44; 134 uint64_t olen : 16; 135 uint64_t raz0 : 4; 136 #endif 137 }; 138 }; 139 140 union nitrox_zip_instr_word6 { 141 uint64_t u64; 142 struct { 143 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 144 uint64_t raz0 : 20; 145 uint64_t rptr : 44; 146 #else 147 uint64_t rptr : 44; 148 uint64_t raz0 : 20; 149 #endif 150 }; 151 }; 152 153 union nitrox_zip_instr_word7 { 154 uint64_t u64; 155 struct { 156 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 157 uint64_t grp : 3; 158 uint64_t raz0 : 41; 159 uint64_t addr_msb: 20; 160 #else 161 uint64_t addr_msb: 20; 162 uint64_t raz0 : 41; 163 uint64_t grp : 3; 164 #endif 165 }; 166 }; 167 168 struct nitrox_zip_instr { 169 union nitrox_zip_instr_word0 w0; 170 union nitrox_zip_instr_word1 w1; 171 union nitrox_zip_instr_word2 w2; 172 union nitrox_zip_instr_word3 w3; 173 union nitrox_zip_instr_word4 w4; 174 union nitrox_zip_instr_word5 w5; 175 union nitrox_zip_instr_word6 w6; 176 union nitrox_zip_instr_word7 w7; 177 }; 178 179 union nitrox_zip_result_word0 { 180 uint64_t u64; 181 struct { 182 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 183 uint64_t crc32 : 32; 184 uint64_t adler32: 32; 185 #else 186 uint64_t adler32: 32; 187 uint64_t crc32 : 32; 188 #endif 189 }; 190 }; 191 192 union nitrox_zip_result_word1 { 193 uint64_t u64; 194 struct { 195 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 196 uint64_t tbyteswritten : 32; 197 uint64_t tbytesread : 32; 198 #else 199 uint64_t tbytesread : 32; 200 uint64_t tbyteswritten : 32; 201 #endif 202 }; 203 }; 204 205 union nitrox_zip_result_word2 { 206 uint64_t u64; 207 struct { 208 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 209 uint64_t tbits : 32; 210 uint64_t raz0 : 5; 211 uint64_t exn : 3; 212 uint64_t raz1 : 1; 213 uint64_t exbits : 7; 214 uint64_t raz2 : 7; 215 uint64_t ef : 1; 216 uint64_t compcode: 8; 217 #else 218 uint64_t compcode: 8; 219 uint64_t ef : 1; 220 uint64_t raz2 : 7; 221 uint64_t exbits : 7; 222 uint64_t raz1 : 1; 223 uint64_t exn : 3; 224 uint64_t raz0 : 5; 225 uint64_t tbits : 32; 226 #endif 227 }; 228 }; 229 230 struct nitrox_zip_result { 231 union nitrox_zip_result_word0 w0; 232 union nitrox_zip_result_word1 w1; 233 union nitrox_zip_result_word2 w2; 234 }; 235 236 union nitrox_zip_zptr { 237 uint64_t u64; 238 struct { 239 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 240 uint64_t raz0 : 3; 241 uint64_t le : 1; 242 uint64_t length : 16; 243 uint64_t addr : 44; 244 #else 245 uint64_t addr : 44; 246 uint64_t length : 16; 247 uint64_t le : 1; 248 uint64_t raz0 : 3; 249 #endif 250 } s; 251 }; 252 253 struct nitrox_zip_iova_addr { 254 union { 255 uint64_t u64; 256 struct { 257 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 258 uint64_t addr_msb: 20; 259 uint64_t addr : 44; 260 #else 261 uint64_t addr : 44; 262 uint64_t addr_msb: 20; 263 #endif 264 } zda; 265 266 struct { 267 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 268 uint64_t addr_msb: 20; 269 uint64_t addr : 41; 270 uint64_t align_8bytes: 3; 271 #else 272 uint64_t align_8bytes: 3; 273 uint64_t addr : 41; 274 uint64_t addr_msb: 20; 275 #endif 276 } z8a; 277 }; 278 }; 279 280 enum nitrox_zip_comp_code { 281 NITROX_CC_NOTDONE = 0, 282 NITROX_CC_SUCCESS = 1, 283 NITROX_CC_DTRUNC = 2, 284 NITROX_CC_STOP = 3, 285 NITROX_CC_ITRUNK = 4, 286 NITROX_CC_RBLOCK = 5, 287 NITROX_CC_NLEN = 6, 288 NITROX_CC_BADCODE = 7, 289 NITROX_CC_BADCODE2 = 8, 290 NITROX_CC_ZERO_LEN = 9, 291 NITROX_CC_PARITY = 10, 292 NITROX_CC_FATAL = 11, 293 NITROX_CC_TIMEOUT = 12, 294 NITROX_CC_NPCI_ERR = 13, 295 }; 296 297 struct nitrox_sgtable { 298 union nitrox_zip_zptr *sgl; 299 uint64_t addr_msb; 300 uint32_t total_bytes; 301 uint16_t nb_sgls; 302 uint16_t filled_sgls; 303 }; 304 305 struct nitrox_softreq { 306 struct nitrox_zip_instr instr; 307 alignas(8) struct nitrox_zip_result zip_res; 308 uint8_t decomp_threshold[NITROX_ZIP_MAX_ONFSIZE]; 309 struct rte_comp_op *op; 310 struct nitrox_sgtable src; 311 struct nitrox_sgtable dst; 312 uint64_t timeout; 313 }; 314 315 #if NITROX_INSTR_BUFFER_DEBUG 316 static void nitrox_dump_databuf(const char *name, struct rte_mbuf *m, 317 uint32_t off, uint32_t datalen) 318 { 319 uint32_t mlen; 320 321 if (!rte_log_can_log(nitrox_logtype, RTE_LOG_DEBUG)) 322 return; 323 324 for (; m && off > rte_pktmbuf_data_len(m); m = m->next) 325 off -= rte_pktmbuf_data_len(m); 326 327 mlen = rte_pktmbuf_data_len(m) - off; 328 if (datalen <= mlen) 329 mlen = datalen; 330 331 rte_hexdump(rte_log_get_stream(), name, 332 rte_pktmbuf_mtod_offset(m, char *, off), mlen); 333 for (m = m->next; m && datalen; m = m->next) { 334 mlen = rte_pktmbuf_data_len(m) < datalen ? 335 rte_pktmbuf_data_len(m) : datalen; 336 rte_hexdump(rte_log_get_stream(), name, 337 rte_pktmbuf_mtod(m, char *), mlen); 338 } 339 340 NITROX_LOG_LINE(DEBUG,); 341 } 342 343 static void nitrox_dump_zip_instr(struct nitrox_zip_instr *instr, 344 union nitrox_zip_zptr *hptr_arr, 345 union nitrox_zip_zptr *iptr_arr, 346 union nitrox_zip_zptr *optr_arr) 347 { 348 uint64_t value; 349 int i = 0; 350 351 NITROX_LOG_LINE(DEBUG, "\nZIP instruction..(%p)", instr); 352 NITROX_LOG_LINE(DEBUG, "\tWORD0 = 0x%016"PRIx64, instr->w0.u64); 353 NITROX_LOG_LINE(DEBUG, "\t\tTOL = %d", instr->w0.tol); 354 NITROX_LOG_LINE(DEBUG, "\t\tEXNUM = %d", instr->w0.exn); 355 NITROX_LOG_LINE(DEBUG, "\t\tEXBITS = %x", instr->w0.exbits); 356 NITROX_LOG_LINE(DEBUG, "\t\tCA = %d", instr->w0.ca); 357 NITROX_LOG_LINE(DEBUG, "\t\tSF = %d", instr->w0.sf); 358 NITROX_LOG_LINE(DEBUG, "\t\tSS = %d", instr->w0.ss); 359 NITROX_LOG_LINE(DEBUG, "\t\tCC = %d", instr->w0.cc); 360 NITROX_LOG_LINE(DEBUG, "\t\tEF = %d", instr->w0.ef); 361 NITROX_LOG_LINE(DEBUG, "\t\tBF = %d", instr->w0.bf); 362 NITROX_LOG_LINE(DEBUG, "\t\tCO = %d", instr->w0.co); 363 NITROX_LOG_LINE(DEBUG, "\t\tDS = %d", instr->w0.ds); 364 NITROX_LOG_LINE(DEBUG, "\t\tDG = %d", instr->w0.dg); 365 NITROX_LOG_LINE(DEBUG, "\t\tHG = %d", instr->w0.hg); 366 NITROX_LOG_LINE(DEBUG,); 367 368 NITROX_LOG_LINE(DEBUG, "\tWORD1 = 0x%016"PRIx64, instr->w1.u64); 369 NITROX_LOG_LINE(DEBUG, "\t\tHL = %d", instr->w1.hl); 370 NITROX_LOG_LINE(DEBUG, "\t\tADLERCRC32 = 0x%08x", instr->w1.adlercrc32); 371 NITROX_LOG_LINE(DEBUG,); 372 373 value = instr->w2.cptr; 374 NITROX_LOG_LINE(DEBUG, "\tWORD2 = 0x%016"PRIx64, instr->w2.u64); 375 NITROX_LOG_LINE(DEBUG, "\t\tCPTR = 0x%11"PRIx64, value); 376 NITROX_LOG_LINE(DEBUG,); 377 378 value = instr->w3.hptr; 379 NITROX_LOG_LINE(DEBUG, "\tWORD3 = 0x%016"PRIx64, instr->w3.u64); 380 NITROX_LOG_LINE(DEBUG, "\t\tHLEN = %d", instr->w3.hlen); 381 NITROX_LOG_LINE(DEBUG, "\t\tHPTR = 0x%11"PRIx64, value); 382 383 if (instr->w0.hg && hptr_arr) { 384 for (i = 0; i < instr->w3.hlen; i++) { 385 value = hptr_arr[i].s.addr; 386 NITROX_LOG_LINE(DEBUG, "\t\t\tZPTR[%d] : Length = %d Addr = 0x%11"PRIx64, 387 i, hptr_arr[i].s.length, value); 388 } 389 } 390 391 NITROX_LOG_LINE(DEBUG,); 392 393 value = instr->w4.iptr; 394 NITROX_LOG_LINE(DEBUG, "\tWORD4 = 0x%016"PRIx64, instr->w4.u64); 395 NITROX_LOG_LINE(DEBUG, "\t\tILEN = %d", instr->w4.ilen); 396 NITROX_LOG_LINE(DEBUG, "\t\tIPTR = 0x%11"PRIx64, value); 397 if (instr->w0.dg && iptr_arr) { 398 for (i = 0; i < instr->w4.ilen; i++) { 399 value = iptr_arr[i].s.addr; 400 NITROX_LOG_LINE(DEBUG, "\t\t\tZPTR[%d] : Length = %d Addr = 0x%11"PRIx64, 401 i, iptr_arr[i].s.length, value); 402 } 403 } 404 405 NITROX_LOG_LINE(DEBUG,); 406 407 value = instr->w5.optr; 408 NITROX_LOG_LINE(DEBUG, "\tWORD5 = 0x%016"PRIx64, instr->w5.u64); 409 NITROX_LOG_LINE(DEBUG, "\t\t OLEN = %d", instr->w5.olen); 410 NITROX_LOG_LINE(DEBUG, "\t\t OPTR = 0x%11"PRIx64, value); 411 if (instr->w0.ds && optr_arr) { 412 for (i = 0; i < instr->w5.olen; i++) { 413 value = optr_arr[i].s.addr; 414 NITROX_LOG_LINE(DEBUG, "\t\t\tZPTR[%d] : Length = %d Addr = 0x%11"PRIx64, 415 i, optr_arr[i].s.length, value); 416 } 417 } 418 419 NITROX_LOG_LINE(DEBUG,); 420 421 value = instr->w6.rptr; 422 NITROX_LOG_LINE(DEBUG, "\tWORD6 = 0x%016"PRIx64, instr->w6.u64); 423 NITROX_LOG_LINE(DEBUG, "\t\tRPTR = 0x%11"PRIx64, value); 424 NITROX_LOG_LINE(DEBUG,); 425 426 NITROX_LOG_LINE(DEBUG, "\tWORD7 = 0x%016"PRIx64, instr->w7.u64); 427 NITROX_LOG_LINE(DEBUG, "\t\tGRP = %x", instr->w7.grp); 428 NITROX_LOG_LINE(DEBUG, "\t\tADDR_MSB = 0x%5x", instr->w7.addr_msb); 429 NITROX_LOG_LINE(DEBUG,); 430 } 431 432 static void nitrox_dump_zip_result(struct nitrox_zip_instr *instr, 433 struct nitrox_zip_result *result) 434 { 435 NITROX_LOG_LINE(DEBUG, "ZIP result..(instr %p)", instr); 436 NITROX_LOG_LINE(DEBUG, "\tWORD0 = 0x%016"PRIx64, result->w0.u64); 437 NITROX_LOG_LINE(DEBUG, "\t\tCRC32 = 0x%8x", result->w0.crc32); 438 NITROX_LOG_LINE(DEBUG, "\t\tADLER32 = 0x%8x", result->w0.adler32); 439 NITROX_LOG_LINE(DEBUG,); 440 441 NITROX_LOG_LINE(DEBUG, "\tWORD1 = 0x%016"PRIx64, result->w1.u64); 442 NITROX_LOG_LINE(DEBUG, "\t\tTBYTESWRITTEN = %u", result->w1.tbyteswritten); 443 NITROX_LOG_LINE(DEBUG, "\t\tTBYTESREAD = %u", result->w1.tbytesread); 444 NITROX_LOG_LINE(DEBUG,); 445 446 NITROX_LOG_LINE(DEBUG, "\tWORD2 = 0x%016"PRIx64, result->w2.u64); 447 NITROX_LOG_LINE(DEBUG, "\t\tTBITS = %u", result->w2.tbits); 448 NITROX_LOG_LINE(DEBUG, "\t\tEXN = %d", result->w2.exn); 449 NITROX_LOG_LINE(DEBUG, "\t\tEBITS = %x", result->w2.exbits); 450 NITROX_LOG_LINE(DEBUG, "\t\tEF = %d", result->w2.ef); 451 NITROX_LOG_LINE(DEBUG, "\t\tCOMPCODE = 0x%2x", result->w2.compcode); 452 NITROX_LOG_LINE(DEBUG,); 453 } 454 #else 455 #define nitrox_dump_databuf(name, m, off, datalen) 456 #define nitrox_dump_zip_instr(instr, hptr_arr, iptr_arr, optr_arr) 457 #define nitrox_dump_zip_result(instr, result) 458 #endif 459 460 static int handle_zero_length_compression(struct nitrox_softreq *sr, 461 struct nitrox_comp_xform *xform) 462 { 463 union { 464 uint32_t num; 465 uint8_t bytes[4]; 466 } fblk; 467 uint32_t dstlen, rlen; 468 struct rte_mbuf *m; 469 uint32_t off; 470 uint32_t mlen; 471 uint32_t i = 0; 472 uint8_t *ptr; 473 474 fblk.num = xform->exn ? (xform->exbits & 0x7F) : 0; 475 fblk.num |= (0x3 << xform->exn); 476 memset(&sr->zip_res, 0, sizeof(sr->zip_res)); 477 sr->zip_res.w1.tbytesread = xform->hlen; 478 sr->zip_res.w1.tbyteswritten = 2; 479 sr->zip_res.w2.ef = 1; 480 if (xform->exn == 7) 481 sr->zip_res.w1.tbyteswritten++; 482 483 rlen = sr->zip_res.w1.tbyteswritten; 484 dstlen = rte_pktmbuf_pkt_len(sr->op->m_dst) - sr->op->dst.offset; 485 if (unlikely(dstlen < rlen)) 486 return -EIO; 487 488 off = sr->op->dst.offset; 489 for (m = sr->op->m_dst; m && off > rte_pktmbuf_data_len(m); m = m->next) 490 off -= rte_pktmbuf_data_len(m); 491 492 if (unlikely(!m)) 493 return -EIO; 494 495 mlen = rte_pktmbuf_data_len(m) - off; 496 if (rlen <= mlen) 497 mlen = rlen; 498 499 ptr = rte_pktmbuf_mtod_offset(m, uint8_t *, off); 500 memcpy(ptr, fblk.bytes, mlen); 501 i += mlen; 502 rlen -= mlen; 503 for (m = m->next; m && rlen; m = m->next) { 504 mlen = rte_pktmbuf_data_len(m) < rlen ? 505 rte_pktmbuf_data_len(m) : rlen; 506 ptr = rte_pktmbuf_mtod(m, uint8_t *); 507 memcpy(ptr, &fblk.bytes[i], mlen); 508 i += mlen; 509 rlen -= mlen; 510 } 511 512 if (unlikely(rlen != 0)) 513 return -EIO; 514 515 sr->zip_res.w2.compcode = NITROX_CC_SUCCESS; 516 sr->op->status = RTE_COMP_OP_STATUS_SUCCESS; 517 sr->zip_res.w0.u64 = rte_cpu_to_be_64(sr->zip_res.w0.u64); 518 sr->zip_res.w1.u64 = rte_cpu_to_be_64(sr->zip_res.w1.u64); 519 sr->zip_res.w2.u64 = rte_cpu_to_be_64(sr->zip_res.w2.u64); 520 return 0; 521 } 522 523 static int create_sglist_from_mbuf(struct nitrox_sgtable *sgtbl, 524 struct rte_mbuf *mbuf, uint32_t off, 525 uint32_t datalen, uint8_t extra_segs, 526 int socket_id) 527 { 528 struct rte_mbuf *m; 529 union nitrox_zip_zptr *sgl; 530 struct nitrox_zip_iova_addr zip_addr; 531 uint16_t nb_segs; 532 uint16_t i; 533 uint32_t mlen; 534 535 if (unlikely(datalen > NITROX_ZIP_MAX_DATASIZE)) { 536 NITROX_LOG_LINE(ERR, "Unsupported datalen %d, max supported %d", 537 datalen, NITROX_ZIP_MAX_DATASIZE); 538 return -ENOTSUP; 539 } 540 541 nb_segs = mbuf->nb_segs + extra_segs; 542 for (m = mbuf; m && off > rte_pktmbuf_data_len(m); m = m->next) { 543 off -= rte_pktmbuf_data_len(m); 544 nb_segs--; 545 } 546 547 if (unlikely(nb_segs > NITROX_ZIP_MAX_ZPTRS)) { 548 NITROX_LOG_LINE(ERR, "Mbuf has more segments %d than supported", 549 nb_segs); 550 return -ENOTSUP; 551 } 552 553 if (unlikely(nb_segs > sgtbl->nb_sgls)) { 554 union nitrox_zip_zptr *sgl; 555 556 NITROX_LOG_LINE(INFO, "Mbuf has more segs %d than allocated %d", 557 nb_segs, sgtbl->nb_sgls); 558 sgl = rte_realloc_socket(sgtbl->sgl, 559 sizeof(*sgtbl->sgl) * nb_segs, 560 8, socket_id); 561 if (unlikely(!sgl)) { 562 NITROX_LOG_LINE(ERR, "Failed to expand sglist memory"); 563 return -ENOMEM; 564 } 565 566 sgtbl->sgl = sgl; 567 sgtbl->nb_sgls = nb_segs; 568 } 569 570 sgtbl->filled_sgls = 0; 571 sgtbl->total_bytes = 0; 572 sgl = sgtbl->sgl; 573 if (!m) 574 return 0; 575 576 mlen = rte_pktmbuf_data_len(m) - off; 577 if (datalen <= mlen) 578 mlen = datalen; 579 580 i = 0; 581 zip_addr.u64 = rte_pktmbuf_iova_offset(m, off); 582 sgl[i].s.addr = zip_addr.zda.addr; 583 sgl[i].s.length = mlen; 584 sgl[i].s.le = 0; 585 sgtbl->total_bytes += mlen; 586 sgtbl->addr_msb = zip_addr.zda.addr_msb; 587 datalen -= mlen; 588 i++; 589 for (m = m->next; m && datalen; m = m->next) { 590 mlen = rte_pktmbuf_data_len(m) < datalen ? 591 rte_pktmbuf_data_len(m) : datalen; 592 zip_addr.u64 = rte_pktmbuf_iova(m); 593 if (unlikely(zip_addr.zda.addr_msb != sgtbl->addr_msb)) { 594 NITROX_LOG_LINE(ERR, "zip_ptrs have different msb addr"); 595 return -ENOTSUP; 596 } 597 598 sgl[i].s.addr = zip_addr.zda.addr; 599 sgl[i].s.length = mlen; 600 sgl[i].s.le = 0; 601 sgtbl->total_bytes += mlen; 602 datalen -= mlen; 603 i++; 604 } 605 606 sgtbl->filled_sgls = i; 607 return 0; 608 } 609 610 static int softreq_init(struct nitrox_softreq *sr, 611 struct nitrox_comp_xform *xform) 612 { 613 struct rte_mempool *mp; 614 int err; 615 bool need_decomp_threshold; 616 617 mp = rte_mempool_from_obj(sr); 618 if (unlikely(mp == NULL)) 619 return -EINVAL; 620 621 err = create_sglist_from_mbuf(&sr->src, sr->op->m_src, 622 sr->op->src.offset, 623 sr->op->src.length, 0, mp->socket_id); 624 if (unlikely(err)) 625 return err; 626 627 need_decomp_threshold = (sr->op->op_type == RTE_COMP_OP_STATELESS && 628 xform->op == NITROX_COMP_OP_DECOMPRESS); 629 err = create_sglist_from_mbuf(&sr->dst, sr->op->m_dst, 630 sr->op->dst.offset, 631 rte_pktmbuf_pkt_len(sr->op->m_dst) - sr->op->dst.offset, 632 need_decomp_threshold ? 1 : 0, 633 mp->socket_id); 634 if (unlikely(err)) 635 return err; 636 637 if (need_decomp_threshold) { 638 struct nitrox_zip_iova_addr zip_addr; 639 int i; 640 641 zip_addr.u64 = rte_mempool_virt2iova(sr) + 642 offsetof(struct nitrox_softreq, decomp_threshold); 643 i = sr->dst.filled_sgls; 644 sr->dst.sgl[i].s.addr = zip_addr.zda.addr; 645 sr->dst.sgl[i].s.length = NITROX_ZIP_MAX_ONFSIZE; 646 sr->dst.sgl[i].s.le = 0; 647 sr->dst.total_bytes += NITROX_ZIP_MAX_ONFSIZE; 648 sr->dst.filled_sgls++; 649 } 650 651 return 0; 652 } 653 654 static void nitrox_zip_instr_to_b64(struct nitrox_softreq *sr) 655 { 656 struct nitrox_zip_instr *instr = &sr->instr; 657 int i; 658 659 for (i = 0; instr->w0.dg && (i < instr->w4.ilen); i++) 660 sr->src.sgl[i].u64 = rte_cpu_to_be_64(sr->src.sgl[i].u64); 661 662 for (i = 0; instr->w0.ds && (i < instr->w5.olen); i++) 663 sr->dst.sgl[i].u64 = rte_cpu_to_be_64(sr->dst.sgl[i].u64); 664 665 instr->w0.u64 = rte_cpu_to_be_64(instr->w0.u64); 666 instr->w1.u64 = rte_cpu_to_be_64(instr->w1.u64); 667 instr->w2.u64 = rte_cpu_to_be_64(instr->w2.u64); 668 instr->w3.u64 = rte_cpu_to_be_64(instr->w3.u64); 669 instr->w4.u64 = rte_cpu_to_be_64(instr->w4.u64); 670 instr->w5.u64 = rte_cpu_to_be_64(instr->w5.u64); 671 instr->w6.u64 = rte_cpu_to_be_64(instr->w6.u64); 672 instr->w7.u64 = rte_cpu_to_be_64(instr->w7.u64); 673 } 674 675 static int process_zip_request(struct nitrox_softreq *sr) 676 { 677 struct nitrox_zip_instr *instr; 678 struct nitrox_comp_xform *xform; 679 struct nitrox_zip_iova_addr zip_addr; 680 uint64_t iptr_msb, optr_msb, rptr_msb, cptr_msb, hptr_msb; 681 int err; 682 683 xform = sr->op->private_xform; 684 if (unlikely(xform == NULL)) { 685 NITROX_LOG_LINE(ERR, "Invalid stateless comp op"); 686 return -EINVAL; 687 } 688 689 if (unlikely(sr->op->op_type == RTE_COMP_OP_STATEFUL && 690 xform->op == NITROX_COMP_OP_COMPRESS && 691 sr->op->flush_flag == RTE_COMP_FLUSH_FINAL && 692 sr->op->src.length == 0)) 693 return handle_zero_length_compression(sr, xform); 694 695 if (unlikely(sr->op->op_type == RTE_COMP_OP_STATELESS && 696 xform->op == NITROX_COMP_OP_COMPRESS && 697 sr->op->flush_flag != RTE_COMP_FLUSH_FULL && 698 sr->op->flush_flag != RTE_COMP_FLUSH_FINAL)) { 699 NITROX_LOG_LINE(ERR, "Invalid flush flag %d in stateless op", 700 sr->op->flush_flag); 701 return -EINVAL; 702 } 703 704 err = softreq_init(sr, xform); 705 if (unlikely(err)) 706 return err; 707 708 instr = &sr->instr; 709 memset(instr, 0, sizeof(*instr)); 710 /* word 0 */ 711 instr->w0.tol = sr->dst.total_bytes; 712 instr->w0.exn = xform->exn; 713 instr->w0.exbits = xform->exbits; 714 instr->w0.ca = 0; 715 if (xform->op == NITROX_COMP_OP_DECOMPRESS || 716 sr->op->flush_flag == RTE_COMP_FLUSH_SYNC || 717 sr->op->flush_flag == RTE_COMP_FLUSH_FULL) 718 instr->w0.sf = 1; 719 else 720 instr->w0.sf = 0; 721 722 instr->w0.ss = xform->level; 723 instr->w0.cc = xform->algo; 724 if (sr->op->flush_flag == RTE_COMP_FLUSH_FINAL) 725 instr->w0.ef = 1; 726 else 727 instr->w0.ef = 0; 728 729 instr->w0.bf = xform->bf; 730 instr->w0.co = xform->op; 731 if (sr->dst.filled_sgls > 1) 732 instr->w0.ds = 1; 733 else 734 instr->w0.ds = 0; 735 736 if (sr->src.filled_sgls > 1) 737 instr->w0.dg = 1; 738 else 739 instr->w0.dg = 0; 740 741 instr->w0.hg = 0; 742 743 /* word 1 */ 744 instr->w1.hl = xform->hlen; 745 if (sr->op->op_type == RTE_COMP_OP_STATEFUL && !xform->bf) 746 instr->w1.adlercrc32 = xform->chksum; 747 else if (sr->op->op_type == RTE_COMP_OP_STATELESS && 748 sr->op->input_chksum != 0) 749 instr->w1.adlercrc32 = sr->op->input_chksum; 750 else if (xform->chksum_type == NITROX_CHKSUM_TYPE_ADLER32) 751 instr->w1.adlercrc32 = 1; 752 else if (xform->chksum_type == NITROX_CHKSUM_TYPE_CRC32) 753 instr->w1.adlercrc32 = 0; 754 755 /* word 2 */ 756 if (xform->context) 757 zip_addr.u64 = rte_malloc_virt2iova(xform->context); 758 else 759 zip_addr.u64 = 0; 760 761 instr->w2.cptr = zip_addr.zda.addr; 762 cptr_msb = zip_addr.zda.addr_msb; 763 764 /* word 3 */ 765 instr->w3.hlen = xform->hlen; 766 if (xform->history_window) 767 zip_addr.u64 = rte_malloc_virt2iova(xform->history_window); 768 else 769 zip_addr.u64 = 0; 770 771 instr->w3.hptr = zip_addr.zda.addr; 772 hptr_msb = zip_addr.zda.addr_msb; 773 774 /* word 4 */ 775 if (sr->src.filled_sgls == 1) { 776 instr->w4.ilen = sr->src.sgl[0].s.length; 777 instr->w4.iptr = sr->src.sgl[0].s.addr; 778 iptr_msb = sr->src.addr_msb; 779 } else { 780 zip_addr.u64 = rte_malloc_virt2iova(sr->src.sgl); 781 instr->w4.ilen = sr->src.filled_sgls; 782 instr->w4.iptr = zip_addr.zda.addr; 783 iptr_msb = zip_addr.zda.addr_msb; 784 } 785 786 /* word 5 */ 787 if (sr->dst.filled_sgls == 1) { 788 instr->w5.olen = sr->dst.sgl[0].s.length; 789 instr->w5.optr = sr->dst.sgl[0].s.addr; 790 optr_msb = sr->dst.addr_msb; 791 } else { 792 zip_addr.u64 = rte_malloc_virt2iova(sr->dst.sgl); 793 instr->w5.olen = sr->dst.filled_sgls; 794 instr->w5.optr = zip_addr.zda.addr; 795 optr_msb = zip_addr.zda.addr_msb; 796 } 797 798 /* word 6 */ 799 memset(&sr->zip_res, 0, sizeof(sr->zip_res)); 800 zip_addr.u64 = rte_mempool_virt2iova(sr) + 801 offsetof(struct nitrox_softreq, zip_res); 802 instr->w6.rptr = zip_addr.zda.addr; 803 rptr_msb = zip_addr.zda.addr_msb; 804 805 if (unlikely(iptr_msb != optr_msb || iptr_msb != rptr_msb || 806 (xform->history_window && (iptr_msb != hptr_msb)) || 807 (xform->context && (iptr_msb != cptr_msb)))) { 808 NITROX_LOG_LINE(ERR, "addr_msb is not same for all addresses"); 809 return -ENOTSUP; 810 } 811 812 /* word 7 */ 813 instr->w7.addr_msb = iptr_msb; 814 instr->w7.grp = 0; 815 816 nitrox_dump_zip_instr(instr, NULL, sr->src.sgl, sr->dst.sgl); 817 nitrox_dump_databuf("IN", sr->op->m_src, sr->op->src.offset, 818 sr->op->src.length); 819 nitrox_zip_instr_to_b64(sr); 820 return 0; 821 } 822 823 int 824 nitrox_process_comp_req(struct rte_comp_op *op, struct nitrox_softreq *sr) 825 { 826 int err; 827 828 sr->op = op; 829 sr->op->status = RTE_COMP_OP_STATUS_NOT_PROCESSED; 830 err = process_zip_request(sr); 831 if (unlikely(err)) 832 goto err_exit; 833 834 sr->timeout = rte_get_timer_cycles() + CMD_TIMEOUT * rte_get_timer_hz(); 835 return 0; 836 err_exit: 837 if (err == -ENOMEM) 838 sr->op->status = RTE_COMP_OP_STATUS_ERROR; 839 else 840 sr->op->status = RTE_COMP_OP_STATUS_INVALID_ARGS; 841 842 return err; 843 } 844 845 static struct nitrox_zip_result zip_result_to_cpu64(struct nitrox_zip_result *r) 846 { 847 struct nitrox_zip_result out_res; 848 849 out_res.w2.u64 = rte_be_to_cpu_64(r->w2.u64); 850 out_res.w1.u64 = rte_be_to_cpu_64(r->w1.u64); 851 out_res.w0.u64 = rte_be_to_cpu_64(r->w0.u64); 852 return out_res; 853 } 854 855 static int post_process_zip_stateless(struct nitrox_softreq *sr, 856 struct nitrox_comp_xform *xform, 857 struct nitrox_zip_result *zip_res) 858 { 859 int output_unused_bytes; 860 861 if (unlikely(zip_res->w2.compcode != NITROX_CC_SUCCESS)) { 862 struct rte_comp_op *op = sr->op; 863 864 NITROX_LOG_LINE(ERR, "Dequeue error 0x%x", 865 zip_res->w2.compcode); 866 if (zip_res->w2.compcode == NITROX_CC_STOP || 867 zip_res->w2.compcode == NITROX_CC_DTRUNC) 868 op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED; 869 else 870 op->status = RTE_COMP_OP_STATUS_ERROR; 871 872 op->consumed = 0; 873 op->produced = 0; 874 return -EFAULT; 875 } 876 877 output_unused_bytes = sr->dst.total_bytes - zip_res->w1.tbyteswritten; 878 if (unlikely(xform->op == NITROX_COMP_OP_DECOMPRESS && 879 output_unused_bytes < NITROX_ZIP_MAX_ONFSIZE)) { 880 NITROX_LOG_LINE(ERR, "TOL %d, Total bytes written %d", 881 sr->dst.total_bytes, zip_res->w1.tbyteswritten); 882 sr->op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED; 883 sr->op->consumed = 0; 884 sr->op->produced = sr->dst.total_bytes - NITROX_ZIP_MAX_ONFSIZE; 885 return -EIO; 886 } 887 888 if (xform->chksum_type == NITROX_CHKSUM_TYPE_CRC32) 889 sr->op->output_chksum = zip_res->w0.crc32; 890 else if (xform->chksum_type == NITROX_CHKSUM_TYPE_ADLER32) 891 sr->op->output_chksum = zip_res->w0.adler32; 892 893 sr->op->consumed = RTE_MIN(sr->op->src.length, 894 (uint32_t)zip_res->w1.tbytesread); 895 sr->op->produced = zip_res->w1.tbyteswritten; 896 sr->op->status = RTE_COMP_OP_STATUS_SUCCESS; 897 return 0; 898 } 899 900 static int update_history(struct rte_mbuf *mbuf, uint32_t off, uint16_t datalen, 901 uint8_t *dst) 902 { 903 struct rte_mbuf *m; 904 uint32_t mlen; 905 uint16_t copied = 0; 906 907 for (m = mbuf; m && off > rte_pktmbuf_data_len(m); m = m->next) 908 off -= rte_pktmbuf_data_len(m); 909 910 if (unlikely(!m)) { 911 NITROX_LOG_LINE(ERR, "Failed to update history. Invalid mbuf"); 912 return -EINVAL; 913 } 914 915 mlen = rte_pktmbuf_data_len(m) - off; 916 if (datalen <= mlen) 917 mlen = datalen; 918 919 memcpy(&dst[copied], rte_pktmbuf_mtod_offset(m, char *, off), mlen); 920 copied += mlen; 921 datalen -= mlen; 922 for (m = m->next; m && datalen; m = m->next) { 923 mlen = rte_pktmbuf_data_len(m) < datalen ? 924 rte_pktmbuf_data_len(m) : datalen; 925 memcpy(&dst[copied], rte_pktmbuf_mtod(m, char *), mlen); 926 copied += mlen; 927 datalen -= mlen; 928 } 929 930 if (unlikely(datalen != 0)) { 931 NITROX_LOG_LINE(ERR, "Failed to update history. Invalid datalen"); 932 return -EINVAL; 933 } 934 935 return 0; 936 } 937 938 static void reset_nitrox_xform(struct nitrox_comp_xform *xform) 939 { 940 xform->hlen = 0; 941 xform->exn = 0; 942 xform->exbits = 0; 943 xform->bf = true; 944 } 945 946 static int post_process_zip_stateful(struct nitrox_softreq *sr, 947 struct nitrox_comp_xform *xform, 948 struct nitrox_zip_result *zip_res) 949 { 950 uint32_t bytesread = 0; 951 uint32_t chksum = 0; 952 953 if (unlikely(zip_res->w2.compcode == NITROX_CC_DTRUNC)) { 954 sr->op->consumed = 0; 955 sr->op->produced = 0; 956 xform->hlen = 0; 957 sr->op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE; 958 NITROX_LOG_LINE(ERR, "Dequeue compress DTRUNC error"); 959 return 0; 960 } else if (unlikely(zip_res->w2.compcode == NITROX_CC_STOP)) { 961 sr->op->status = RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE; 962 NITROX_LOG_LINE(NOTICE, "Dequeue decompress dynamic STOP"); 963 } else if (zip_res->w2.compcode == NITROX_CC_SUCCESS) { 964 sr->op->status = RTE_COMP_OP_STATUS_SUCCESS; 965 } else { 966 xform->hlen = 0; 967 xform->exn = 0; 968 xform->exbits = 0; 969 xform->bf = true; 970 sr->op->status = RTE_COMP_OP_STATUS_ERROR; 971 NITROX_LOG_LINE(ERR, "Dequeue error 0x%x", 972 zip_res->w2.compcode); 973 return -EFAULT; 974 } 975 976 if (xform->op == NITROX_COMP_OP_COMPRESS) { 977 if (zip_res->w1.tbytesread < xform->hlen) { 978 NITROX_LOG_LINE(ERR, "Invalid bytesread"); 979 reset_nitrox_xform(xform); 980 sr->op->status = RTE_COMP_OP_STATUS_ERROR; 981 return -EFAULT; 982 } 983 984 bytesread = zip_res->w1.tbytesread - xform->hlen; 985 } else { 986 bytesread = RTE_MIN(sr->op->src.length, 987 (uint32_t)zip_res->w1.tbytesread); 988 } 989 990 if ((xform->op == NITROX_COMP_OP_COMPRESS && 991 (sr->op->flush_flag == RTE_COMP_FLUSH_NONE || 992 sr->op->flush_flag == RTE_COMP_FLUSH_SYNC)) || 993 (xform->op == NITROX_COMP_OP_DECOMPRESS && !zip_res->w2.ef)) { 994 struct rte_mbuf *mbuf; 995 uint32_t pktlen, m_off; 996 int err; 997 998 if (xform->op == NITROX_COMP_OP_COMPRESS) { 999 mbuf = sr->op->m_src; 1000 pktlen = bytesread; 1001 m_off = sr->op->src.offset; 1002 } else { 1003 mbuf = sr->op->m_dst; 1004 pktlen = zip_res->w1.tbyteswritten; 1005 m_off = sr->op->dst.offset; 1006 } 1007 1008 if (pktlen >= xform->window_size) { 1009 m_off += pktlen - xform->window_size; 1010 err = update_history(mbuf, m_off, xform->window_size, 1011 xform->history_window); 1012 xform->hlen = xform->window_size; 1013 } else if ((xform->hlen + pktlen) <= xform->window_size) { 1014 err = update_history(mbuf, m_off, pktlen, 1015 &xform->history_window[xform->hlen]); 1016 xform->hlen += pktlen; 1017 } else { 1018 uint16_t shift_off, shift_len; 1019 1020 shift_off = pktlen + xform->hlen - xform->window_size; 1021 shift_len = xform->hlen - shift_off; 1022 memmove(xform->history_window, 1023 &xform->history_window[shift_off], 1024 shift_len); 1025 err = update_history(mbuf, m_off, pktlen, 1026 &xform->history_window[shift_len]); 1027 xform->hlen = xform->window_size; 1028 1029 } 1030 1031 if (unlikely(err)) { 1032 sr->op->status = RTE_COMP_OP_STATUS_ERROR; 1033 return err; 1034 } 1035 1036 if (xform->op == NITROX_COMP_OP_COMPRESS) { 1037 xform->exn = zip_res->w2.exn; 1038 xform->exbits = zip_res->w2.exbits; 1039 } 1040 1041 xform->bf = false; 1042 } else { 1043 reset_nitrox_xform(xform); 1044 } 1045 1046 if (xform->chksum_type == NITROX_CHKSUM_TYPE_CRC32) 1047 chksum = zip_res->w0.crc32; 1048 else if (xform->chksum_type == NITROX_CHKSUM_TYPE_ADLER32) 1049 chksum = zip_res->w0.adler32; 1050 1051 if (xform->bf) 1052 sr->op->output_chksum = chksum; 1053 else 1054 xform->chksum = chksum; 1055 1056 sr->op->consumed = bytesread; 1057 sr->op->produced = zip_res->w1.tbyteswritten; 1058 return 0; 1059 } 1060 1061 int 1062 nitrox_check_comp_req(struct nitrox_softreq *sr, struct rte_comp_op **op) 1063 { 1064 struct nitrox_zip_result zip_res; 1065 struct nitrox_comp_xform *xform; 1066 int err = 0; 1067 1068 zip_res = zip_result_to_cpu64(&sr->zip_res); 1069 if (zip_res.w2.compcode == NITROX_CC_NOTDONE) { 1070 if (rte_get_timer_cycles() >= sr->timeout) { 1071 NITROX_LOG_LINE(ERR, "Op timedout"); 1072 sr->op->status = RTE_COMP_OP_STATUS_ERROR; 1073 err = -ETIMEDOUT; 1074 goto exit; 1075 } else { 1076 return -EAGAIN; 1077 } 1078 } 1079 1080 xform = sr->op->private_xform; 1081 if (sr->op->op_type == RTE_COMP_OP_STATELESS) 1082 err = post_process_zip_stateless(sr, xform, &zip_res); 1083 else 1084 err = post_process_zip_stateful(sr, xform, &zip_res); 1085 1086 if (sr->op->status == RTE_COMP_OP_STATUS_SUCCESS && 1087 xform->op == NITROX_COMP_OP_COMPRESS && 1088 sr->op->flush_flag == RTE_COMP_FLUSH_FINAL && 1089 zip_res.w2.exn) { 1090 uint32_t datalen = zip_res.w1.tbyteswritten; 1091 uint32_t off = sr->op->dst.offset; 1092 struct rte_mbuf *m = sr->op->m_dst; 1093 uint32_t mlen; 1094 uint8_t *last_byte; 1095 1096 for (; m && off > rte_pktmbuf_data_len(m); m = m->next) 1097 off -= rte_pktmbuf_data_len(m); 1098 1099 if (unlikely(m == NULL)) { 1100 err = -EINVAL; 1101 goto exit; 1102 } 1103 1104 mlen = rte_pktmbuf_data_len(m) - off; 1105 for (; m && (datalen > mlen); m = m->next) 1106 datalen -= mlen; 1107 1108 if (unlikely(m == NULL)) { 1109 err = -EINVAL; 1110 goto exit; 1111 } 1112 1113 last_byte = rte_pktmbuf_mtod_offset(m, uint8_t *, datalen - 1); 1114 *last_byte = zip_res.w2.exbits & 0xFF; 1115 } 1116 1117 exit: 1118 *op = sr->op; 1119 nitrox_dump_zip_result(&sr->instr, &zip_res); 1120 nitrox_dump_databuf("OUT after", sr->op->m_dst, sr->op->dst.offset, 1121 sr->op->produced); 1122 return err; 1123 } 1124 1125 void * 1126 nitrox_comp_instr_addr(struct nitrox_softreq *sr) 1127 { 1128 return &sr->instr; 1129 } 1130 1131 static void req_pool_obj_free(struct rte_mempool *mp, void *opaque, void *obj, 1132 unsigned int obj_idx) 1133 { 1134 struct nitrox_softreq *sr; 1135 1136 RTE_SET_USED(mp); 1137 RTE_SET_USED(opaque); 1138 RTE_SET_USED(obj_idx); 1139 sr = obj; 1140 rte_free(sr->src.sgl); 1141 sr->src.sgl = NULL; 1142 rte_free(sr->dst.sgl); 1143 sr->dst.sgl = NULL; 1144 } 1145 1146 void 1147 nitrox_comp_req_pool_free(struct rte_mempool *mp) 1148 { 1149 rte_mempool_obj_iter(mp, req_pool_obj_free, NULL); 1150 rte_mempool_free(mp); 1151 } 1152 1153 static void req_pool_obj_init(struct rte_mempool *mp, void *arg, void *obj, 1154 unsigned int obj_idx) 1155 { 1156 struct nitrox_softreq *sr; 1157 int *err = arg; 1158 1159 RTE_SET_USED(mp); 1160 RTE_SET_USED(obj_idx); 1161 sr = obj; 1162 sr->src.sgl = rte_zmalloc_socket(NULL, 1163 sizeof(*sr->src.sgl) * NITROX_ZIP_SGL_COUNT, 1164 8, mp->socket_id); 1165 sr->dst.sgl = rte_zmalloc_socket(NULL, 1166 sizeof(*sr->dst.sgl) * NITROX_ZIP_SGL_COUNT, 1167 8, mp->socket_id); 1168 if (sr->src.sgl == NULL || sr->dst.sgl == NULL) { 1169 NITROX_LOG_LINE(ERR, "Failed to allocate zip_sgl memory"); 1170 *err = -ENOMEM; 1171 } 1172 1173 sr->src.nb_sgls = NITROX_ZIP_SGL_COUNT; 1174 sr->src.filled_sgls = 0; 1175 sr->dst.nb_sgls = NITROX_ZIP_SGL_COUNT; 1176 sr->dst.filled_sgls = 0; 1177 } 1178 1179 struct rte_mempool * 1180 nitrox_comp_req_pool_create(struct rte_compressdev *dev, uint32_t nobjs, 1181 uint16_t qp_id, int socket_id) 1182 { 1183 char softreq_pool_name[RTE_RING_NAMESIZE]; 1184 struct rte_mempool *mp; 1185 int err = 0; 1186 1187 snprintf(softreq_pool_name, RTE_RING_NAMESIZE, "%s_sr_%d", 1188 dev->data->name, qp_id); 1189 mp = rte_mempool_create(softreq_pool_name, 1190 RTE_ALIGN_MUL_CEIL(nobjs, 64), 1191 sizeof(struct nitrox_softreq), 1192 64, 0, NULL, NULL, req_pool_obj_init, &err, 1193 socket_id, 0); 1194 if (unlikely(!mp)) 1195 NITROX_LOG_LINE(ERR, "Failed to create req pool, qid %d, err %d", 1196 qp_id, rte_errno); 1197 1198 if (unlikely(err)) { 1199 nitrox_comp_req_pool_free(mp); 1200 return NULL; 1201 } 1202 1203 return mp; 1204 } 1205