700-v6.10-net-create-a-dummy-net_device-allocator.patch 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. From c661050f93d3fd37a33c06041bb18a89688de7d2 Mon Sep 17 00:00:00 2001
  2. From: Breno Leitao <[email protected]>
  3. Date: Mon, 22 Apr 2024 05:38:56 -0700
  4. Subject: [PATCH] net: create a dummy net_device allocator
  5. It is impossible to use init_dummy_netdev together with alloc_netdev()
  6. as the 'setup' argument.
  7. This is because alloc_netdev() initializes some fields in the net_device
  8. structure, and later init_dummy_netdev() memzero them all. This causes
  9. some problems as reported here:
  10. https://lore.kernel.org/all/[email protected]/
  11. Split the init_dummy_netdev() function in two. Create a new function called
  12. init_dummy_netdev_core() that does not memzero the net_device structure.
  13. Then have init_dummy_netdev() memzero-ing and calling
  14. init_dummy_netdev_core(), keeping the old behaviour.
  15. init_dummy_netdev_core() is the new function that could be called as an
  16. argument for alloc_netdev().
  17. Also, create a helper to allocate and initialize dummy net devices,
  18. leveraging init_dummy_netdev_core() as the setup argument. This function
  19. basically simplify the allocation of dummy devices, by allocating and
  20. initializing it. Freeing the device continue to be done through
  21. free_netdev()
  22. Suggested-by: Jakub Kicinski <[email protected]>
  23. Signed-off-by: Breno Leitao <[email protected]>
  24. Reviewed-by: Ido Schimmel <[email protected]>
  25. Signed-off-by: David S. Miller <[email protected]>
  26. ---
  27. include/linux/netdevice.h | 3 +++
  28. net/core/dev.c | 56 ++++++++++++++++++++++++++-------------
  29. 2 files changed, 41 insertions(+), 18 deletions(-)
  30. --- a/include/linux/netdevice.h
  31. +++ b/include/linux/netdevice.h
  32. @@ -4561,6 +4561,9 @@ static inline void netif_addr_unlock_bh(
  33. void ether_setup(struct net_device *dev);
  34. +/* Allocate dummy net_device */
  35. +struct net_device *alloc_netdev_dummy(int sizeof_priv);
  36. +
  37. /* Support for loadable net-drivers */
  38. struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
  39. unsigned char name_assign_type,
  40. --- a/net/core/dev.c
  41. +++ b/net/core/dev.c
  42. @@ -10355,25 +10355,12 @@ err_free_name:
  43. }
  44. EXPORT_SYMBOL(register_netdevice);
  45. -/**
  46. - * init_dummy_netdev - init a dummy network device for NAPI
  47. - * @dev: device to init
  48. - *
  49. - * This takes a network device structure and initialize the minimum
  50. - * amount of fields so it can be used to schedule NAPI polls without
  51. - * registering a full blown interface. This is to be used by drivers
  52. - * that need to tie several hardware interfaces to a single NAPI
  53. - * poll scheduler due to HW limitations.
  54. +/* Initialize the core of a dummy net device.
  55. + * This is useful if you are calling this function after alloc_netdev(),
  56. + * since it does not memset the net_device fields.
  57. */
  58. -int init_dummy_netdev(struct net_device *dev)
  59. +static void init_dummy_netdev_core(struct net_device *dev)
  60. {
  61. - /* Clear everything. Note we don't initialize spinlocks
  62. - * are they aren't supposed to be taken by any of the
  63. - * NAPI code and this dummy netdev is supposed to be
  64. - * only ever used for NAPI polls
  65. - */
  66. - memset(dev, 0, sizeof(struct net_device));
  67. -
  68. /* make sure we BUG if trying to hit standard
  69. * register/unregister code path
  70. */
  71. @@ -10393,12 +10380,32 @@ int init_dummy_netdev(struct net_device
  72. * because users of this 'device' dont need to change
  73. * its refcount.
  74. */
  75. +}
  76. +
  77. +/**
  78. + * init_dummy_netdev - init a dummy network device for NAPI
  79. + * @dev: device to init
  80. + *
  81. + * This takes a network device structure and initializes the minimum
  82. + * amount of fields so it can be used to schedule NAPI polls without
  83. + * registering a full blown interface. This is to be used by drivers
  84. + * that need to tie several hardware interfaces to a single NAPI
  85. + * poll scheduler due to HW limitations.
  86. + */
  87. +int init_dummy_netdev(struct net_device *dev)
  88. +{
  89. + /* Clear everything. Note we don't initialize spinlocks
  90. + * as they aren't supposed to be taken by any of the
  91. + * NAPI code and this dummy netdev is supposed to be
  92. + * only ever used for NAPI polls
  93. + */
  94. + memset(dev, 0, sizeof(struct net_device));
  95. + init_dummy_netdev_core(dev);
  96. return 0;
  97. }
  98. EXPORT_SYMBOL_GPL(init_dummy_netdev);
  99. -
  100. /**
  101. * register_netdev - register a network device
  102. * @dev: device to register
  103. @@ -10992,6 +10999,19 @@ void free_netdev(struct net_device *dev)
  104. EXPORT_SYMBOL(free_netdev);
  105. /**
  106. + * alloc_netdev_dummy - Allocate and initialize a dummy net device.
  107. + * @sizeof_priv: size of private data to allocate space for
  108. + *
  109. + * Return: the allocated net_device on success, NULL otherwise
  110. + */
  111. +struct net_device *alloc_netdev_dummy(int sizeof_priv)
  112. +{
  113. + return alloc_netdev(sizeof_priv, "dummy#", NET_NAME_UNKNOWN,
  114. + init_dummy_netdev_core);
  115. +}
  116. +EXPORT_SYMBOL_GPL(alloc_netdev_dummy);
  117. +
  118. +/**
  119. * synchronize_net - Synchronize with packet receive processing
  120. *
  121. * Wait for packets currently being received to be done.