netmap_generic.c (341477) | netmap_generic.c (342033) |
---|---|
1/* 2 * Copyright (C) 2013-2016 Vincenzo Maffione 3 * Copyright (C) 2013-2016 Luigi Rizzo 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 51 unchanged lines hidden (view full) --- 60 * 61 * RX: 62 * 63 */ 64 65#ifdef __FreeBSD__ 66 67#include <sys/cdefs.h> /* prerequisite */ | 1/* 2 * Copyright (C) 2013-2016 Vincenzo Maffione 3 * Copyright (C) 2013-2016 Luigi Rizzo 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 51 unchanged lines hidden (view full) --- 60 * 61 * RX: 62 * 63 */ 64 65#ifdef __FreeBSD__ 66 67#include <sys/cdefs.h> /* prerequisite */ |
68__FBSDID("$FreeBSD: stable/11/sys/dev/netmap/netmap_generic.c 341477 2018-12-04 17:40:56Z vmaffione $"); | 68__FBSDID("$FreeBSD: stable/11/sys/dev/netmap/netmap_generic.c 342033 2018-12-13 10:13:29Z vmaffione $"); |
69 70#include <sys/types.h> 71#include <sys/errno.h> 72#include <sys/malloc.h> 73#include <sys/lock.h> /* PROT_EXEC */ 74#include <sys/rwlock.h> 75#include <sys/socket.h> /* sockaddrs */ 76#include <sys/selinfo.h> 77#include <net/if.h> 78#include <net/if_types.h> 79#include <net/if_var.h> 80#include <machine/bus.h> /* bus_dmamap_* in netmap_kern.h */ 81 | 69 70#include <sys/types.h> 71#include <sys/errno.h> 72#include <sys/malloc.h> 73#include <sys/lock.h> /* PROT_EXEC */ 74#include <sys/rwlock.h> 75#include <sys/socket.h> /* sockaddrs */ 76#include <sys/selinfo.h> 77#include <net/if.h> 78#include <net/if_types.h> 79#include <net/if_var.h> 80#include <machine/bus.h> /* bus_dmamap_* in netmap_kern.h */ 81 |
82// XXX temporary - D() defined here | |
83#include <net/netmap.h> 84#include <dev/netmap/netmap_kern.h> 85#include <dev/netmap/netmap_mem2.h> 86 87#define MBUF_RXQ(m) ((m)->m_pkthdr.flowid) 88#define smp_mb() 89 90#elif defined _WIN32 --- 81 unchanged lines hidden (view full) --- 172 RATE_PRINTK(rxsync); 173 RATE_PRINTK(rxirq); 174 printk("\n"); 175 176 ctx->old = cur; 177 r = mod_timer(&ctx->timer, jiffies + 178 msecs_to_jiffies(RATE_PERIOD * 1000)); 179 if (unlikely(r)) | 82#include <net/netmap.h> 83#include <dev/netmap/netmap_kern.h> 84#include <dev/netmap/netmap_mem2.h> 85 86#define MBUF_RXQ(m) ((m)->m_pkthdr.flowid) 87#define smp_mb() 88 89#elif defined _WIN32 --- 81 unchanged lines hidden (view full) --- 171 RATE_PRINTK(rxsync); 172 RATE_PRINTK(rxirq); 173 printk("\n"); 174 175 ctx->old = cur; 176 r = mod_timer(&ctx->timer, jiffies + 177 msecs_to_jiffies(RATE_PERIOD * 1000)); 178 if (unlikely(r)) |
180 D("[v1000] Error: mod_timer()"); | 179 nm_prerr("mod_timer() failed"); |
181} 182 183static struct rate_context rate_ctx; 184 185void generic_rate(int txp, int txs, int txi, int rxp, int rxs, int rxi) 186{ 187 if (txp) rate_ctx.new.txpkt++; 188 if (txs) rate_ctx.new.txsync++; --- 44 unchanged lines hidden (view full) --- 233 nm_os_catch_rx(gna, 0); 234 235 /* Release packet steering control. */ 236 nm_os_catch_tx(gna, 0); 237 } 238 239 for_each_rx_kring_h(r, kring, na) { 240 if (nm_kring_pending_off(kring)) { | 180} 181 182static struct rate_context rate_ctx; 183 184void generic_rate(int txp, int txs, int txi, int rxp, int rxs, int rxi) 185{ 186 if (txp) rate_ctx.new.txpkt++; 187 if (txs) rate_ctx.new.txsync++; --- 44 unchanged lines hidden (view full) --- 232 nm_os_catch_rx(gna, 0); 233 234 /* Release packet steering control. */ 235 nm_os_catch_tx(gna, 0); 236 } 237 238 for_each_rx_kring_h(r, kring, na) { 239 if (nm_kring_pending_off(kring)) { |
241 D("Emulated adapter: ring '%s' deactivated", kring->name); | 240 nm_prinf("Emulated adapter: ring '%s' deactivated", kring->name); |
242 kring->nr_mode = NKR_NETMAP_OFF; 243 } 244 } 245 for_each_tx_kring_h(r, kring, na) { 246 if (nm_kring_pending_off(kring)) { 247 kring->nr_mode = NKR_NETMAP_OFF; | 241 kring->nr_mode = NKR_NETMAP_OFF; 242 } 243 } 244 for_each_tx_kring_h(r, kring, na) { 245 if (nm_kring_pending_off(kring)) { 246 kring->nr_mode = NKR_NETMAP_OFF; |
248 D("Emulated adapter: ring '%s' deactivated", kring->name); | 247 nm_prinf("Emulated adapter: ring '%s' deactivated", kring->name); |
249 } 250 } 251 252 for_each_rx_kring(r, kring, na) { 253 /* Free the mbufs still pending in the RX queues, 254 * that did not end up into the corresponding netmap 255 * RX rings. */ 256 mbq_safe_purge(&kring->rx_queue); --- 36 unchanged lines hidden (view full) --- 293 } 294 } 295 nm_os_free(kring->tx_pool); 296 kring->tx_pool = NULL; 297 } 298 299#ifdef RATE_GENERIC 300 if (--rate_ctx.refcount == 0) { | 248 } 249 } 250 251 for_each_rx_kring(r, kring, na) { 252 /* Free the mbufs still pending in the RX queues, 253 * that did not end up into the corresponding netmap 254 * RX rings. */ 255 mbq_safe_purge(&kring->rx_queue); --- 36 unchanged lines hidden (view full) --- 292 } 293 } 294 nm_os_free(kring->tx_pool); 295 kring->tx_pool = NULL; 296 } 297 298#ifdef RATE_GENERIC 299 if (--rate_ctx.refcount == 0) { |
301 D("del_timer()"); | 300 nm_prinf("del_timer()"); |
302 del_timer(&rate_ctx.timer); 303 } 304#endif | 301 del_timer(&rate_ctx.timer); 302 } 303#endif |
305 D("Emulated adapter for %s deactivated", na->name); | 304 nm_prinf("Emulated adapter for %s deactivated", na->name); |
306 } 307 308 return 0; 309} 310 311/* Enable/disable netmap mode for a generic network interface. */ 312static int 313generic_netmap_register(struct netmap_adapter *na, int enable) --- 8 unchanged lines hidden (view full) --- 322 } 323 324 if (!enable) { 325 /* This is actually an unregif. */ 326 return generic_netmap_unregister(na); 327 } 328 329 if (na->active_fds == 0) { | 305 } 306 307 return 0; 308} 309 310/* Enable/disable netmap mode for a generic network interface. */ 311static int 312generic_netmap_register(struct netmap_adapter *na, int enable) --- 8 unchanged lines hidden (view full) --- 321 } 322 323 if (!enable) { 324 /* This is actually an unregif. */ 325 return generic_netmap_unregister(na); 326 } 327 328 if (na->active_fds == 0) { |
330 D("Emulated adapter for %s activated", na->name); | 329 nm_prinf("Emulated adapter for %s activated", na->name); |
331 /* Do all memory allocations when (na->active_fds == 0), to 332 * simplify error management. */ 333 334 /* Allocate memory for mitigation support on all the rx queues. */ 335 gna->mit = nm_os_malloc(na->num_rx_rings * sizeof(struct nm_generic_mit)); 336 if (!gna->mit) { | 330 /* Do all memory allocations when (na->active_fds == 0), to 331 * simplify error management. */ 332 333 /* Allocate memory for mitigation support on all the rx queues. */ 334 gna->mit = nm_os_malloc(na->num_rx_rings * sizeof(struct nm_generic_mit)); 335 if (!gna->mit) { |
337 D("mitigation allocation failed"); | 336 nm_prerr("mitigation allocation failed"); |
338 error = ENOMEM; 339 goto out; 340 } 341 342 for_each_rx_kring(r, kring, na) { 343 /* Init mitigation support. */ 344 nm_os_mitigation_init(&gna->mit[r], r, na); 345 --- 10 unchanged lines hidden (view full) --- 356 */ 357 for_each_tx_kring(r, kring, na) { 358 kring->tx_pool = NULL; 359 } 360 for_each_tx_kring(r, kring, na) { 361 kring->tx_pool = 362 nm_os_malloc(na->num_tx_desc * sizeof(struct mbuf *)); 363 if (!kring->tx_pool) { | 337 error = ENOMEM; 338 goto out; 339 } 340 341 for_each_rx_kring(r, kring, na) { 342 /* Init mitigation support. */ 343 nm_os_mitigation_init(&gna->mit[r], r, na); 344 --- 10 unchanged lines hidden (view full) --- 355 */ 356 for_each_tx_kring(r, kring, na) { 357 kring->tx_pool = NULL; 358 } 359 for_each_tx_kring(r, kring, na) { 360 kring->tx_pool = 361 nm_os_malloc(na->num_tx_desc * sizeof(struct mbuf *)); 362 if (!kring->tx_pool) { |
364 D("tx_pool allocation failed"); | 363 nm_prerr("tx_pool allocation failed"); |
365 error = ENOMEM; 366 goto free_tx_pools; 367 } 368 mtx_init(&kring->tx_event_lock, "tx_event_lock", 369 NULL, MTX_SPIN); 370 } 371 } 372 373 for_each_rx_kring_h(r, kring, na) { 374 if (nm_kring_pending_on(kring)) { | 364 error = ENOMEM; 365 goto free_tx_pools; 366 } 367 mtx_init(&kring->tx_event_lock, "tx_event_lock", 368 NULL, MTX_SPIN); 369 } 370 } 371 372 for_each_rx_kring_h(r, kring, na) { 373 if (nm_kring_pending_on(kring)) { |
375 D("Emulated adapter: ring '%s' activated", kring->name); | 374 nm_prinf("Emulated adapter: ring '%s' activated", kring->name); |
376 kring->nr_mode = NKR_NETMAP_ON; 377 } 378 379 } 380 for_each_tx_kring_h(r, kring, na) { 381 if (nm_kring_pending_on(kring)) { | 375 kring->nr_mode = NKR_NETMAP_ON; 376 } 377 378 } 379 for_each_tx_kring_h(r, kring, na) { 380 if (nm_kring_pending_on(kring)) { |
382 D("Emulated adapter: ring '%s' activated", kring->name); | 381 nm_prinf("Emulated adapter: ring '%s' activated", kring->name); |
383 kring->nr_mode = NKR_NETMAP_ON; 384 } 385 } 386 387 for_each_tx_kring(r, kring, na) { 388 /* Initialize tx_pool and tx_event. */ 389 for (i=0; i<na->num_tx_desc; i++) { 390 kring->tx_pool[i] = NULL; 391 } 392 393 kring->tx_event = NULL; 394 } 395 396 if (na->active_fds == 0) { 397 /* Prepare to intercept incoming traffic. */ 398 error = nm_os_catch_rx(gna, 1); 399 if (error) { | 382 kring->nr_mode = NKR_NETMAP_ON; 383 } 384 } 385 386 for_each_tx_kring(r, kring, na) { 387 /* Initialize tx_pool and tx_event. */ 388 for (i=0; i<na->num_tx_desc; i++) { 389 kring->tx_pool[i] = NULL; 390 } 391 392 kring->tx_event = NULL; 393 } 394 395 if (na->active_fds == 0) { 396 /* Prepare to intercept incoming traffic. */ 397 error = nm_os_catch_rx(gna, 1); 398 if (error) { |
400 D("nm_os_catch_rx(1) failed (%d)", error); | 399 nm_prerr("nm_os_catch_rx(1) failed (%d)", error); |
401 goto free_tx_pools; 402 } 403 404 /* Let netmap control the packet steering. */ 405 error = nm_os_catch_tx(gna, 1); 406 if (error) { | 400 goto free_tx_pools; 401 } 402 403 /* Let netmap control the packet steering. */ 404 error = nm_os_catch_tx(gna, 1); 405 if (error) { |
407 D("nm_os_catch_tx(1) failed (%d)", error); | 406 nm_prerr("nm_os_catch_tx(1) failed (%d)", error); |
408 goto catch_rx; 409 } 410 411 na->na_flags |= NAF_NETMAP_ON; 412 413#ifdef RATE_GENERIC 414 if (rate_ctx.refcount == 0) { | 407 goto catch_rx; 408 } 409 410 na->na_flags |= NAF_NETMAP_ON; 411 412#ifdef RATE_GENERIC 413 if (rate_ctx.refcount == 0) { |
415 D("setup_timer()"); | 414 nm_prinf("setup_timer()"); |
416 memset(&rate_ctx, 0, sizeof(rate_ctx)); 417 setup_timer(&rate_ctx.timer, &rate_callback, (unsigned long)&rate_ctx); 418 if (mod_timer(&rate_ctx.timer, jiffies + msecs_to_jiffies(1500))) { | 415 memset(&rate_ctx, 0, sizeof(rate_ctx)); 416 setup_timer(&rate_ctx.timer, &rate_callback, (unsigned long)&rate_ctx); 417 if (mod_timer(&rate_ctx.timer, jiffies + msecs_to_jiffies(1500))) { |
419 D("Error: mod_timer()"); | 418 nm_prerr("Error: mod_timer()"); |
420 } 421 } 422 rate_ctx.refcount++; 423#endif /* RATE */ 424 } 425 426 return 0; 427 --- 27 unchanged lines hidden (view full) --- 455generic_mbuf_destructor(struct mbuf *m) 456{ 457 struct netmap_adapter *na = NA(GEN_TX_MBUF_IFP(m)); 458 struct netmap_kring *kring; 459 unsigned int r = MBUF_TXQ(m); 460 unsigned int r_orig = r; 461 462 if (unlikely(!nm_netmap_on(na) || r >= na->num_tx_rings)) { | 419 } 420 } 421 rate_ctx.refcount++; 422#endif /* RATE */ 423 } 424 425 return 0; 426 --- 27 unchanged lines hidden (view full) --- 454generic_mbuf_destructor(struct mbuf *m) 455{ 456 struct netmap_adapter *na = NA(GEN_TX_MBUF_IFP(m)); 457 struct netmap_kring *kring; 458 unsigned int r = MBUF_TXQ(m); 459 unsigned int r_orig = r; 460 461 if (unlikely(!nm_netmap_on(na) || r >= na->num_tx_rings)) { |
463 D("Error: no netmap adapter on device %p", | 462 nm_prerr("Error: no netmap adapter on device %p", |
464 GEN_TX_MBUF_IFP(m)); 465 return; 466 } 467 468 /* 469 * First, clear the event mbuf. 470 * In principle, the event 'm' should match the one stored 471 * on ring 'r'. However we check it explicitely to stay --- 9 unchanged lines hidden (view full) --- 481 if (kring->tx_event == m) { 482 kring->tx_event = NULL; 483 match = true; 484 } 485 mtx_unlock_spin(&kring->tx_event_lock); 486 487 if (match) { 488 if (r != r_orig) { | 463 GEN_TX_MBUF_IFP(m)); 464 return; 465 } 466 467 /* 468 * First, clear the event mbuf. 469 * In principle, the event 'm' should match the one stored 470 * on ring 'r'. However we check it explicitely to stay --- 9 unchanged lines hidden (view full) --- 480 if (kring->tx_event == m) { 481 kring->tx_event = NULL; 482 match = true; 483 } 484 mtx_unlock_spin(&kring->tx_event_lock); 485 486 if (match) { 487 if (r != r_orig) { |
489 RD(1, "event %p migrated: ring %u --> %u", | 488 nm_prlim(1, "event %p migrated: ring %u --> %u", |
490 m, r_orig, r); 491 } 492 break; 493 } 494 495 if (++r == na->num_tx_rings) r = 0; 496 497 if (r == r_orig) { | 489 m, r_orig, r); 490 } 491 break; 492 } 493 494 if (++r == na->num_tx_rings) r = 0; 495 496 if (r == r_orig) { |
498 RD(1, "Cannot match event %p", m); | 497 nm_prlim(1, "Cannot match event %p", m); |
499 return; 500 } 501 } 502 503 /* Second, wake up clients. They will reclaim the event through 504 * txsync. */ 505 netmap_generic_irq(na, r, NULL); 506#ifdef __FreeBSD__ --- 14 unchanged lines hidden (view full) --- 521generic_netmap_tx_clean(struct netmap_kring *kring, int txqdisc) 522{ 523 u_int const lim = kring->nkr_num_slots - 1; 524 u_int nm_i = nm_next(kring->nr_hwtail, lim); 525 u_int hwcur = kring->nr_hwcur; 526 u_int n = 0; 527 struct mbuf **tx_pool = kring->tx_pool; 528 | 498 return; 499 } 500 } 501 502 /* Second, wake up clients. They will reclaim the event through 503 * txsync. */ 504 netmap_generic_irq(na, r, NULL); 505#ifdef __FreeBSD__ --- 14 unchanged lines hidden (view full) --- 520generic_netmap_tx_clean(struct netmap_kring *kring, int txqdisc) 521{ 522 u_int const lim = kring->nkr_num_slots - 1; 523 u_int nm_i = nm_next(kring->nr_hwtail, lim); 524 u_int hwcur = kring->nr_hwcur; 525 u_int n = 0; 526 struct mbuf **tx_pool = kring->tx_pool; 527 |
529 ND("hwcur = %d, hwtail = %d", kring->nr_hwcur, kring->nr_hwtail); | 528 nm_prdis("hwcur = %d, hwtail = %d", kring->nr_hwcur, kring->nr_hwtail); |
530 531 while (nm_i != hwcur) { /* buffers not completed */ 532 struct mbuf *m = tx_pool[nm_i]; 533 534 if (txqdisc) { 535 if (m == NULL) { 536 /* Nothing to do, this is going 537 * to be replenished. */ | 529 530 while (nm_i != hwcur) { /* buffers not completed */ 531 struct mbuf *m = tx_pool[nm_i]; 532 533 if (txqdisc) { 534 if (m == NULL) { 535 /* Nothing to do, this is going 536 * to be replenished. */ |
538 RD(3, "Is this happening?"); | 537 nm_prlim(3, "Is this happening?"); |
539 540 } else if (MBUF_QUEUED(m)) { 541 break; /* Not dequeued yet. */ 542 543 } else if (MBUF_REFCNT(m) != 1) { 544 /* This mbuf has been dequeued but is still busy 545 * (refcount is 2). 546 * Leave it to the driver and replenish. */ --- 22 unchanged lines hidden (view full) --- 569 break; 570 } 571 } 572 573 n++; 574 nm_i = nm_next(nm_i, lim); 575 } 576 kring->nr_hwtail = nm_prev(nm_i, lim); | 538 539 } else if (MBUF_QUEUED(m)) { 540 break; /* Not dequeued yet. */ 541 542 } else if (MBUF_REFCNT(m) != 1) { 543 /* This mbuf has been dequeued but is still busy 544 * (refcount is 2). 545 * Leave it to the driver and replenish. */ --- 22 unchanged lines hidden (view full) --- 568 break; 569 } 570 } 571 572 n++; 573 nm_i = nm_next(nm_i, lim); 574 } 575 kring->nr_hwtail = nm_prev(nm_i, lim); |
577 ND("tx completed [%d] -> hwtail %d", n, kring->nr_hwtail); | 576 nm_prdis("tx completed [%d] -> hwtail %d", n, kring->nr_hwtail); |
578 579 return n; 580} 581 582/* Compute a slot index in the middle between inf and sup. */ 583static inline u_int 584ring_middle(u_int inf, u_int sup, u_int lim) 585{ --- 5 unchanged lines hidden (view full) --- 591 } else { /* wrap around */ 592 e = (sup + n + inf) / 2; 593 if (e >= n) { 594 e -= n; 595 } 596 } 597 598 if (unlikely(e >= n)) { | 577 578 return n; 579} 580 581/* Compute a slot index in the middle between inf and sup. */ 582static inline u_int 583ring_middle(u_int inf, u_int sup, u_int lim) 584{ --- 5 unchanged lines hidden (view full) --- 590 } else { /* wrap around */ 591 e = (sup + n + inf) / 2; 592 if (e >= n) { 593 e -= n; 594 } 595 } 596 597 if (unlikely(e >= n)) { |
599 D("This cannot happen"); | 598 nm_prerr("This cannot happen"); |
600 e = 0; 601 } 602 603 return e; 604} 605 606static void 607generic_set_tx_event(struct netmap_kring *kring, u_int hwcur) --- 39 unchanged lines hidden (view full) --- 647 } 648 649 SET_MBUF_DESTRUCTOR(m, generic_mbuf_destructor); 650 kring->tx_event = m; 651 mtx_unlock_spin(&kring->tx_event_lock); 652 653 kring->tx_pool[e] = NULL; 654 | 599 e = 0; 600 } 601 602 return e; 603} 604 605static void 606generic_set_tx_event(struct netmap_kring *kring, u_int hwcur) --- 39 unchanged lines hidden (view full) --- 646 } 647 648 SET_MBUF_DESTRUCTOR(m, generic_mbuf_destructor); 649 kring->tx_event = m; 650 mtx_unlock_spin(&kring->tx_event_lock); 651 652 kring->tx_pool[e] = NULL; 653 |
655 ND(5, "Request Event at %d mbuf %p refcnt %d", e, m, m ? MBUF_REFCNT(m) : -2 ); | 654 nm_prdis("Request Event at %d mbuf %p refcnt %d", e, m, m ? MBUF_REFCNT(m) : -2 ); |
656 657 /* Decrement the refcount. This will free it if we lose the race 658 * with the driver. */ 659 m_freem(m); 660 smp_mb(); 661} 662 663 --- 28 unchanged lines hidden (view full) --- 692 struct nm_os_gen_arg a; 693 u_int event = -1; 694 695 if (gna->txqdisc && nm_kr_txempty(kring)) { 696 /* In txqdisc mode, we ask for a delayed notification, 697 * but only when cur == hwtail, which means that the 698 * client is going to block. */ 699 event = ring_middle(nm_i, head, lim); | 655 656 /* Decrement the refcount. This will free it if we lose the race 657 * with the driver. */ 658 m_freem(m); 659 smp_mb(); 660} 661 662 --- 28 unchanged lines hidden (view full) --- 691 struct nm_os_gen_arg a; 692 u_int event = -1; 693 694 if (gna->txqdisc && nm_kr_txempty(kring)) { 695 /* In txqdisc mode, we ask for a delayed notification, 696 * but only when cur == hwtail, which means that the 697 * client is going to block. */ 698 event = ring_middle(nm_i, head, lim); |
700 ND(3, "Place txqdisc event (hwcur=%u,event=%u," | 699 nm_prdis("Place txqdisc event (hwcur=%u,event=%u," |
701 "head=%u,hwtail=%u)", nm_i, event, head, 702 kring->nr_hwtail); 703 } 704 705 a.ifp = ifp; 706 a.ring_nr = ring_nr; 707 a.head = a.tail = NULL; 708 --- 9 unchanged lines hidden (view full) --- 718 719 /* Tale a mbuf from the tx pool (replenishing the pool 720 * entry if necessary) and copy in the user packet. */ 721 m = kring->tx_pool[nm_i]; 722 if (unlikely(m == NULL)) { 723 kring->tx_pool[nm_i] = m = 724 nm_os_get_mbuf(ifp, NETMAP_BUF_SIZE(na)); 725 if (m == NULL) { | 700 "head=%u,hwtail=%u)", nm_i, event, head, 701 kring->nr_hwtail); 702 } 703 704 a.ifp = ifp; 705 a.ring_nr = ring_nr; 706 a.head = a.tail = NULL; 707 --- 9 unchanged lines hidden (view full) --- 717 718 /* Tale a mbuf from the tx pool (replenishing the pool 719 * entry if necessary) and copy in the user packet. */ 720 m = kring->tx_pool[nm_i]; 721 if (unlikely(m == NULL)) { 722 kring->tx_pool[nm_i] = m = 723 nm_os_get_mbuf(ifp, NETMAP_BUF_SIZE(na)); 724 if (m == NULL) { |
726 RD(2, "Failed to replenish mbuf"); | 725 nm_prlim(2, "Failed to replenish mbuf"); |
727 /* Here we could schedule a timer which 728 * retries to replenish after a while, 729 * and notifies the client when it 730 * manages to replenish some slots. In 731 * any case we break early to avoid 732 * crashes. */ 733 break; 734 } --- 112 unchanged lines hidden (view full) --- 847 return 0; 848 } 849 850 /* limit the size of the queue */ 851 if (unlikely(!gna->rxsg && MBUF_LEN(m) > NETMAP_BUF_SIZE(na))) { 852 /* This may happen when GRO/LRO features are enabled for 853 * the NIC driver when the generic adapter does not 854 * support RX scatter-gather. */ | 726 /* Here we could schedule a timer which 727 * retries to replenish after a while, 728 * and notifies the client when it 729 * manages to replenish some slots. In 730 * any case we break early to avoid 731 * crashes. */ 732 break; 733 } --- 112 unchanged lines hidden (view full) --- 846 return 0; 847 } 848 849 /* limit the size of the queue */ 850 if (unlikely(!gna->rxsg && MBUF_LEN(m) > NETMAP_BUF_SIZE(na))) { 851 /* This may happen when GRO/LRO features are enabled for 852 * the NIC driver when the generic adapter does not 853 * support RX scatter-gather. */ |
855 RD(2, "Warning: driver pushed up big packet " | 854 nm_prlim(2, "Warning: driver pushed up big packet " |
856 "(size=%d)", (int)MBUF_LEN(m)); 857 m_freem(m); 858 } else if (unlikely(mbq_len(&kring->rx_queue) > 1024)) { 859 m_freem(m); 860 } else { 861 mbq_safe_enqueue(&kring->rx_queue, m); 862 } 863 --- 177 unchanged lines hidden (view full) --- 1041 netmap_adapter_put(prev_na); 1042 if (nm_iszombie(na)) { 1043 /* 1044 * The driver has been removed without releasing 1045 * the reference so we need to do it here. 1046 */ 1047 netmap_adapter_put(prev_na); 1048 } | 855 "(size=%d)", (int)MBUF_LEN(m)); 856 m_freem(m); 857 } else if (unlikely(mbq_len(&kring->rx_queue) > 1024)) { 858 m_freem(m); 859 } else { 860 mbq_safe_enqueue(&kring->rx_queue, m); 861 } 862 --- 177 unchanged lines hidden (view full) --- 1040 netmap_adapter_put(prev_na); 1041 if (nm_iszombie(na)) { 1042 /* 1043 * The driver has been removed without releasing 1044 * the reference so we need to do it here. 1045 */ 1046 netmap_adapter_put(prev_na); 1047 } |
1049 D("Native netmap adapter %p restored", prev_na); | 1048 nm_prinf("Native netmap adapter %p restored", prev_na); |
1050 } 1051 NM_RESTORE_NA(ifp, prev_na); 1052 /* 1053 * netmap_detach_common(), that it's called after this function, 1054 * overrides WNA(ifp) if na->ifp is not NULL. 1055 */ 1056 na->ifp = NULL; | 1049 } 1050 NM_RESTORE_NA(ifp, prev_na); 1051 /* 1052 * netmap_detach_common(), that it's called after this function, 1053 * overrides WNA(ifp) if na->ifp is not NULL. 1054 */ 1055 na->ifp = NULL; |
1057 D("Emulated netmap adapter for %s destroyed", na->name); | 1056 nm_prinf("Emulated netmap adapter for %s destroyed", na->name); |
1058} 1059 1060int 1061na_is_generic(struct netmap_adapter *na) 1062{ 1063 return na->nm_register == generic_netmap_register; 1064} 1065 --- 13 unchanged lines hidden (view full) --- 1079{ 1080 struct netmap_adapter *na; 1081 struct netmap_generic_adapter *gna; 1082 int retval; 1083 u_int num_tx_desc, num_rx_desc; 1084 1085#ifdef __FreeBSD__ 1086 if (ifp->if_type == IFT_LOOP) { | 1057} 1058 1059int 1060na_is_generic(struct netmap_adapter *na) 1061{ 1062 return na->nm_register == generic_netmap_register; 1063} 1064 --- 13 unchanged lines hidden (view full) --- 1078{ 1079 struct netmap_adapter *na; 1080 struct netmap_generic_adapter *gna; 1081 int retval; 1082 u_int num_tx_desc, num_rx_desc; 1083 1084#ifdef __FreeBSD__ 1085 if (ifp->if_type == IFT_LOOP) { |
1087 D("if_loop is not supported by %s", __func__); | 1086 nm_prerr("if_loop is not supported by %s", __func__); |
1088 return EINVAL; 1089 } 1090#endif 1091 1092 if (NM_NA_CLASH(ifp)) { 1093 /* If NA(ifp) is not null but there is no valid netmap 1094 * adapter it means that someone else is using the same 1095 * pointer (e.g. ax25_ptr on linux). This happens for 1096 * instance when also PF_RING is in use. */ | 1087 return EINVAL; 1088 } 1089#endif 1090 1091 if (NM_NA_CLASH(ifp)) { 1092 /* If NA(ifp) is not null but there is no valid netmap 1093 * adapter it means that someone else is using the same 1094 * pointer (e.g. ax25_ptr on linux). This happens for 1095 * instance when also PF_RING is in use. */ |
1097 D("Error: netmap adapter hook is busy"); | 1096 nm_prerr("Error: netmap adapter hook is busy"); |
1098 return EBUSY; 1099 } 1100 1101 num_tx_desc = num_rx_desc = netmap_generic_ringsize; /* starting point */ 1102 1103 nm_os_generic_find_num_desc(ifp, &num_tx_desc, &num_rx_desc); /* ignore errors */ | 1097 return EBUSY; 1098 } 1099 1100 num_tx_desc = num_rx_desc = netmap_generic_ringsize; /* starting point */ 1101 1102 nm_os_generic_find_num_desc(ifp, &num_tx_desc, &num_rx_desc); /* ignore errors */ |
1104 ND("Netmap ring size: TX = %d, RX = %d", num_tx_desc, num_rx_desc); | |
1105 if (num_tx_desc == 0 || num_rx_desc == 0) { | 1103 if (num_tx_desc == 0 || num_rx_desc == 0) { |
1106 D("Device has no hw slots (tx %u, rx %u)", num_tx_desc, num_rx_desc); | 1104 nm_prerr("Device has no hw slots (tx %u, rx %u)", num_tx_desc, num_rx_desc); |
1107 return EINVAL; 1108 } 1109 1110 gna = nm_os_malloc(sizeof(*gna)); 1111 if (gna == NULL) { | 1105 return EINVAL; 1106 } 1107 1108 gna = nm_os_malloc(sizeof(*gna)); 1109 if (gna == NULL) { |
1112 D("no memory on attach, give up"); | 1110 nm_prerr("no memory on attach, give up"); |
1113 return ENOMEM; 1114 } 1115 na = (struct netmap_adapter *)gna; | 1111 return ENOMEM; 1112 } 1113 na = (struct netmap_adapter *)gna; |
1116 strncpy(na->name, ifp->if_xname, sizeof(na->name)); | 1114 strlcpy(na->name, ifp->if_xname, sizeof(na->name)); |
1117 na->ifp = ifp; 1118 na->num_tx_desc = num_tx_desc; 1119 na->num_rx_desc = num_rx_desc; 1120 na->rx_buf_maxsize = 32768; 1121 na->nm_register = &generic_netmap_register; 1122 na->nm_txsync = &generic_netmap_txsync; 1123 na->nm_rxsync = &generic_netmap_rxsync; 1124 na->nm_dtor = &generic_netmap_dtor; 1125 /* when using generic, NAF_NETMAP_ON is set so we force 1126 * NAF_SKIP_INTR to use the regular interrupt handler 1127 */ 1128 na->na_flags = NAF_SKIP_INTR | NAF_HOST_RINGS; 1129 | 1115 na->ifp = ifp; 1116 na->num_tx_desc = num_tx_desc; 1117 na->num_rx_desc = num_rx_desc; 1118 na->rx_buf_maxsize = 32768; 1119 na->nm_register = &generic_netmap_register; 1120 na->nm_txsync = &generic_netmap_txsync; 1121 na->nm_rxsync = &generic_netmap_rxsync; 1122 na->nm_dtor = &generic_netmap_dtor; 1123 /* when using generic, NAF_NETMAP_ON is set so we force 1124 * NAF_SKIP_INTR to use the regular interrupt handler 1125 */ 1126 na->na_flags = NAF_SKIP_INTR | NAF_HOST_RINGS; 1127 |
1130 ND("[GNA] num_tx_queues(%d), real_num_tx_queues(%d), len(%lu)", | 1128 nm_prdis("[GNA] num_tx_queues(%d), real_num_tx_queues(%d), len(%lu)", |
1131 ifp->num_tx_queues, ifp->real_num_tx_queues, 1132 ifp->tx_queue_len); | 1129 ifp->num_tx_queues, ifp->real_num_tx_queues, 1130 ifp->tx_queue_len); |
1133 ND("[GNA] num_rx_queues(%d), real_num_rx_queues(%d)", | 1131 nm_prdis("[GNA] num_rx_queues(%d), real_num_rx_queues(%d)", |
1134 ifp->num_rx_queues, ifp->real_num_rx_queues); 1135 1136 nm_os_generic_find_num_queues(ifp, &na->num_tx_rings, &na->num_rx_rings); 1137 1138 retval = netmap_attach_common(na); 1139 if (retval) { 1140 nm_os_free(gna); 1141 return retval; 1142 } 1143 1144 if (NM_NA_VALID(ifp)) { 1145 gna->prev = NA(ifp); /* save old na */ 1146 netmap_adapter_get(gna->prev); 1147 } 1148 NM_ATTACH_NA(ifp, na); 1149 1150 nm_os_generic_set_features(gna); 1151 | 1132 ifp->num_rx_queues, ifp->real_num_rx_queues); 1133 1134 nm_os_generic_find_num_queues(ifp, &na->num_tx_rings, &na->num_rx_rings); 1135 1136 retval = netmap_attach_common(na); 1137 if (retval) { 1138 nm_os_free(gna); 1139 return retval; 1140 } 1141 1142 if (NM_NA_VALID(ifp)) { 1143 gna->prev = NA(ifp); /* save old na */ 1144 netmap_adapter_get(gna->prev); 1145 } 1146 NM_ATTACH_NA(ifp, na); 1147 1148 nm_os_generic_set_features(gna); 1149 |
1152 D("Emulated adapter for %s created (prev was %p)", na->name, gna->prev); | 1150 nm_prinf("Emulated adapter for %s created (prev was %p)", na->name, gna->prev); |
1153 1154 return retval; 1155} | 1151 1152 return retval; 1153} |