tree: https://github.com/ammarfaizi2/linux-block dhowells/linux-fs/iov-extract head: ad732cfcd888e36990643e8b086d657fbaa87e6a commit: c9b99998ac4d6709b657adfce1e58c6d8ee6f1c9 [21/32] 9p: Pin pages rather than ref'ing if appropriate config: x86_64-rhel-8.3-rust compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/ammarfaizi2/linux-block/commit/c9b99998ac4d6709b657adfce1e58c6d8ee6f1c9 git remote add ammarfaizi2-block https://github.com/ammarfaizi2/linux-block git fetch --no-tags ammarfaizi2-block dhowells/linux-fs/iov-extract git checkout c9b99998ac4d6709b657adfce1e58c6d8ee6f1c9 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash fs/ net/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot All errors (new ones prefixed by >>): >> net/9p/trans_virtio.c:334:64: error: too few arguments to function call, expected 6, have 5 n = iov_iter_extract_pages(data, pages, count, offs, gup_flags); ~~~~~~~~~~~~~~~~~~~~~~ ^ include/linux/uio.h:376:9: note: 'iov_iter_extract_pages' declared here ssize_t iov_iter_extract_pages(struct iov_iter *i, struct page ***pages, ^ net/9p/trans_virtio.c:512:42: error: too few arguments to function call, expected 3, have 2 p9_release_pages(in_pages, in_nr_pages); ~~~~~~~~~~~~~~~~ ^ net/9p/trans_common.h:7:6: note: 'p9_release_pages' declared here void p9_release_pages(struct page **pages, int nr_pages, ^ >> net/9p/trans_virtio.c:513:40: error: too many arguments to function call, expected 2, have 3 atomic_sub(in_nr_pages, &vp_pinned, cleanup_mode); ~~~~~~~~~~ ^~~~~~~~~~~~ include/linux/atomic/atomic-instrumented.h:121:1: note: 'atomic_sub' declared here atomic_sub(int i, atomic_t *v) ^ net/9p/trans_virtio.c:516:44: error: too few arguments to function call, expected 3, have 2 p9_release_pages(out_pages, out_nr_pages); ~~~~~~~~~~~~~~~~ ^ net/9p/trans_common.h:7:6: note: 'p9_release_pages' declared here void p9_release_pages(struct page **pages, int nr_pages, ^ net/9p/trans_virtio.c:517:41: error: too many arguments to function call, expected 2, have 3 atomic_sub(out_nr_pages, &vp_pinned, cleanup_mode); ~~~~~~~~~~ ^~~~~~~~~~~~ include/linux/atomic/atomic-instrumented.h:121:1: note: 'atomic_sub' declared here atomic_sub(int i, atomic_t *v) ^ 5 errors generated. vim +334 net/9p/trans_virtio.c 307 308 static int p9_get_mapped_pages(struct virtio_chan *chan, 309 struct page ***pages, 310 struct iov_iter *data, 311 int count, 312 size_t *offs, 313 int *cleanup_mode, 314 unsigned int gup_flags) 315 { 316 int nr_pages; 317 int err; 318 int n; 319 320 if (!iov_iter_count(data)) 321 return 0; 322 323 /* 324 * We allow only p9_max_pages pinned. We wait for the 325 * Other zc request to finish here 326 */ 327 if (atomic_read(&vp_pinned) >= chan->p9_max_pages) { 328 err = wait_event_killable(vp_wq, 329 (atomic_read(&vp_pinned) < chan->p9_max_pages)); 330 if (err == -ERESTARTSYS) 331 return err; 332 } 333 > 334 n = iov_iter_extract_pages(data, pages, count, offs, gup_flags); 335 if (n < 0) 336 return n; 337 *cleanup_mode = iov_iter_extract_mode(data, gup_flags); 338 nr_pages = DIV_ROUND_UP(n + *offs, PAGE_SIZE); 339 atomic_add(nr_pages, &vp_pinned); 340 return n; 341 } 342 343 static void handle_rerror(struct p9_req_t *req, int in_hdr_len, 344 size_t offs, struct page **pages) 345 { 346 unsigned size, n; 347 void *to = req->rc.sdata + in_hdr_len; 348 349 // Fits entirely into the static data? Nothing to do. 350 if (req->rc.size < in_hdr_len) 351 return; 352 353 // Really long error message? Tough, truncate the reply. Might get 354 // rejected (we can't be arsed to adjust the size encoded in header, 355 // or string size for that matter), but it wouldn't be anything valid 356 // anyway. 357 if (unlikely(req->rc.size > P9_ZC_HDR_SZ)) 358 req->rc.size = P9_ZC_HDR_SZ; 359 360 // data won't span more than two pages 361 size = req->rc.size - in_hdr_len; 362 n = PAGE_SIZE - offs; 363 if (size > n) { 364 memcpy_from_page(to, *pages++, offs, n); 365 offs = 0; 366 to += n; 367 size -= n; 368 } 369 memcpy_from_page(to, *pages, offs, size); 370 } 371 372 /** 373 * p9_virtio_zc_request - issue a zero copy request 374 * @client: client instance issuing the request 375 * @req: request to be issued 376 * @uidata: user buffer that should be used for zero copy read 377 * @uodata: user buffer that should be used for zero copy write 378 * @inlen: read buffer size 379 * @outlen: write buffer size 380 * @in_hdr_len: reader header size, This is the size of response protocol data 381 * 382 */ 383 static int 384 p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, 385 struct iov_iter *uidata, struct iov_iter *uodata, 386 int inlen, int outlen, int in_hdr_len) 387 { 388 int in, out, err, out_sgs, in_sgs; 389 unsigned long flags; 390 int in_nr_pages = 0, out_nr_pages = 0; 391 struct page **in_pages = NULL, **out_pages = NULL; 392 struct virtio_chan *chan = client->trans; 393 struct scatterlist *sgs[4]; 394 size_t offs; 395 int cleanup_mode = 0; 396 int kicked = 0; 397 398 p9_debug(P9_DEBUG_TRANS, "virtio request\n"); 399 400 if (uodata) { 401 __le32 sz; 402 int n = p9_get_mapped_pages(chan, &out_pages, uodata, 403 outlen, &offs, &cleanup_mode, 404 FOLL_DEST_BUF); 405 if (n < 0) { 406 err = n; 407 goto err_out; 408 } 409 out_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE); 410 if (n != outlen) { 411 __le32 v = cpu_to_le32(n); 412 memcpy(&req->tc.sdata[req->tc.size - 4], &v, 4); 413 outlen = n; 414 } 415 /* The size field of the message must include the length of the 416 * header and the length of the data. We didn't actually know 417 * the length of the data until this point so add it in now. 418 */ 419 sz = cpu_to_le32(req->tc.size + outlen); 420 memcpy(&req->tc.sdata[0], &sz, sizeof(sz)); 421 } else if (uidata) { 422 int n = p9_get_mapped_pages(chan, &in_pages, uidata, 423 inlen, &offs, &cleanup_mode, 424 FOLL_SOURCE_BUF); 425 if (n < 0) { 426 err = n; 427 goto err_out; 428 } 429 in_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE); 430 if (n != inlen) { 431 __le32 v = cpu_to_le32(n); 432 memcpy(&req->tc.sdata[req->tc.size - 4], &v, 4); 433 inlen = n; 434 } 435 } 436 WRITE_ONCE(req->status, REQ_STATUS_SENT); 437 req_retry_pinned: 438 spin_lock_irqsave(&chan->lock, flags); 439 440 out_sgs = in_sgs = 0; 441 442 /* out data */ 443 out = pack_sg_list(chan->sg, 0, 444 VIRTQUEUE_NUM, req->tc.sdata, req->tc.size); 445 446 if (out) 447 sgs[out_sgs++] = chan->sg; 448 449 if (out_pages) { 450 sgs[out_sgs++] = chan->sg + out; 451 out += pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM, 452 out_pages, out_nr_pages, offs, outlen); 453 } 454 455 /* 456 * Take care of in data 457 * For example TREAD have 11. 458 * 11 is the read/write header = PDU Header(7) + IO Size (4). 459 * Arrange in such a way that server places header in the 460 * allocated memory and payload onto the user buffer. 461 */ 462 in = pack_sg_list(chan->sg, out, 463 VIRTQUEUE_NUM, req->rc.sdata, in_hdr_len); 464 if (in) 465 sgs[out_sgs + in_sgs++] = chan->sg + out; 466 467 if (in_pages) { 468 sgs[out_sgs + in_sgs++] = chan->sg + out + in; 469 in += pack_sg_list_p(chan->sg, out + in, VIRTQUEUE_NUM, 470 in_pages, in_nr_pages, offs, inlen); 471 } 472 473 BUG_ON(out_sgs + in_sgs > ARRAY_SIZE(sgs)); 474 err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req, 475 GFP_ATOMIC); 476 if (err < 0) { 477 if (err == -ENOSPC) { 478 chan->ring_bufs_avail = 0; 479 spin_unlock_irqrestore(&chan->lock, flags); 480 err = wait_event_killable(*chan->vc_wq, 481 chan->ring_bufs_avail); 482 if (err == -ERESTARTSYS) 483 goto err_out; 484 485 p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n"); 486 goto req_retry_pinned; 487 } else { 488 spin_unlock_irqrestore(&chan->lock, flags); 489 p9_debug(P9_DEBUG_TRANS, 490 "virtio rpc add_sgs returned failure\n"); 491 err = -EIO; 492 goto err_out; 493 } 494 } 495 virtqueue_kick(chan->vq); 496 spin_unlock_irqrestore(&chan->lock, flags); 497 kicked = 1; 498 p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n"); 499 err = wait_event_killable(req->wq, 500 READ_ONCE(req->status) >= REQ_STATUS_RCVD); 501 // RERROR needs reply (== error string) in static data 502 if (READ_ONCE(req->status) == REQ_STATUS_RCVD && 503 unlikely(req->rc.sdata[4] == P9_RERROR)) 504 handle_rerror(req, in_hdr_len, offs, in_pages); 505 506 /* 507 * Non kernel buffers are pinned, unpin them 508 */ 509 err_out: 510 if (cleanup_mode) { 511 if (in_pages) { 512 p9_release_pages(in_pages, in_nr_pages); > 513 atomic_sub(in_nr_pages, &vp_pinned, cleanup_mode); 514 } 515 if (out_pages) { 516 p9_release_pages(out_pages, out_nr_pages); 517 atomic_sub(out_nr_pages, &vp_pinned, cleanup_mode); 518 } 519 /* wakeup anybody waiting for slots to pin pages */ 520 wake_up(&vp_wq); 521 } 522 kvfree(in_pages); 523 kvfree(out_pages); 524 if (!kicked) { 525 /* reply won't come */ 526 p9_req_put(client, req); 527 } 528 return err; 529 } 530 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests