701-net-0271-net-mscc-ocelot-use-skb-queue-instead-of-skbs-list.patch 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. From e7e0b3b89da97e3186fbe3774a1ca9b77402d893 Mon Sep 17 00:00:00 2001
  2. From: Yangbo Lu <[email protected]>
  3. Date: Wed, 27 Nov 2019 15:27:57 +0800
  4. Subject: [PATCH] net: mscc: ocelot: use skb queue instead of skbs list
  5. Convert to use skb queue instead of the list of skbs.
  6. The skb queue could provide protection with lock.
  7. Signed-off-by: Yangbo Lu <[email protected]>
  8. Signed-off-by: David S. Miller <[email protected]>
  9. ---
  10. drivers/net/ethernet/mscc/ocelot.c | 54 +++++++++++++-------------------------
  11. include/soc/mscc/ocelot.h | 9 +------
  12. 2 files changed, 19 insertions(+), 44 deletions(-)
  13. --- a/drivers/net/ethernet/mscc/ocelot.c
  14. +++ b/drivers/net/ethernet/mscc/ocelot.c
  15. @@ -583,18 +583,10 @@ int ocelot_port_add_txtstamp_skb(struct
  16. if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP &&
  17. ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
  18. - struct ocelot_skb *oskb =
  19. - kzalloc(sizeof(struct ocelot_skb), GFP_ATOMIC);
  20. -
  21. - if (unlikely(!oskb))
  22. - return -ENOMEM;
  23. -
  24. shinfo->tx_flags |= SKBTX_IN_PROGRESS;
  25. -
  26. - oskb->skb = skb;
  27. - oskb->id = ocelot_port->ts_id % 4;
  28. -
  29. - list_add_tail(&oskb->head, &ocelot_port->skbs);
  30. + /* Store timestamp ID in cb[0] of sk_buff */
  31. + skb->cb[0] = ocelot_port->ts_id % 4;
  32. + skb_queue_tail(&ocelot_port->tx_skbs, skb);
  33. return 0;
  34. }
  35. return -ENODATA;
  36. @@ -704,12 +696,11 @@ void ocelot_get_txtstamp(struct ocelot *
  37. int budget = OCELOT_PTP_QUEUE_SZ;
  38. while (budget--) {
  39. + struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
  40. struct skb_shared_hwtstamps shhwtstamps;
  41. - struct list_head *pos, *tmp;
  42. - struct sk_buff *skb = NULL;
  43. - struct ocelot_skb *entry;
  44. struct ocelot_port *port;
  45. struct timespec64 ts;
  46. + unsigned long flags;
  47. u32 val, id, txport;
  48. val = ocelot_read(ocelot, SYS_PTP_STATUS);
  49. @@ -727,22 +718,22 @@ void ocelot_get_txtstamp(struct ocelot *
  50. /* Retrieve its associated skb */
  51. port = ocelot->ports[txport];
  52. - list_for_each_safe(pos, tmp, &port->skbs) {
  53. - entry = list_entry(pos, struct ocelot_skb, head);
  54. - if (entry->id != id)
  55. - continue;
  56. + spin_lock_irqsave(&port->tx_skbs.lock, flags);
  57. - skb = entry->skb;
  58. -
  59. - list_del(pos);
  60. - kfree(entry);
  61. + skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) {
  62. + if (skb->cb[0] != id)
  63. + continue;
  64. + __skb_unlink(skb, &port->tx_skbs);
  65. + skb_match = skb;
  66. break;
  67. }
  68. + spin_unlock_irqrestore(&port->tx_skbs.lock, flags);
  69. +
  70. /* Next ts */
  71. ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);
  72. - if (unlikely(!skb))
  73. + if (unlikely(!skb_match))
  74. continue;
  75. /* Get the h/w timestamp */
  76. @@ -751,9 +742,9 @@ void ocelot_get_txtstamp(struct ocelot *
  77. /* Set the timestamp into the skb */
  78. memset(&shhwtstamps, 0, sizeof(shhwtstamps));
  79. shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
  80. - skb_tstamp_tx(skb, &shhwtstamps);
  81. + skb_tstamp_tx(skb_match, &shhwtstamps);
  82. - dev_kfree_skb_any(skb);
  83. + dev_kfree_skb_any(skb_match);
  84. }
  85. }
  86. EXPORT_SYMBOL(ocelot_get_txtstamp);
  87. @@ -2208,7 +2199,7 @@ void ocelot_init_port(struct ocelot *oce
  88. {
  89. struct ocelot_port *ocelot_port = ocelot->ports[port];
  90. - INIT_LIST_HEAD(&ocelot_port->skbs);
  91. + skb_queue_head_init(&ocelot_port->tx_skbs);
  92. /* Basic L2 initialization */
  93. @@ -2493,9 +2484,7 @@ EXPORT_SYMBOL(ocelot_init);
  94. void ocelot_deinit(struct ocelot *ocelot)
  95. {
  96. - struct list_head *pos, *tmp;
  97. struct ocelot_port *port;
  98. - struct ocelot_skb *entry;
  99. int i;
  100. cancel_delayed_work(&ocelot->stats_work);
  101. @@ -2507,14 +2496,7 @@ void ocelot_deinit(struct ocelot *ocelot
  102. for (i = 0; i < ocelot->num_phys_ports; i++) {
  103. port = ocelot->ports[i];
  104. -
  105. - list_for_each_safe(pos, tmp, &port->skbs) {
  106. - entry = list_entry(pos, struct ocelot_skb, head);
  107. -
  108. - list_del(pos);
  109. - dev_kfree_skb_any(entry->skb);
  110. - kfree(entry);
  111. - }
  112. + skb_queue_purge(&port->tx_skbs);
  113. }
  114. }
  115. EXPORT_SYMBOL(ocelot_deinit);
  116. --- a/include/soc/mscc/ocelot.h
  117. +++ b/include/soc/mscc/ocelot.h
  118. @@ -406,13 +406,6 @@ struct ocelot_ops {
  119. int (*reset)(struct ocelot *ocelot);
  120. };
  121. -struct ocelot_skb {
  122. - struct list_head head;
  123. - struct sk_buff *skb;
  124. - u8 id;
  125. -};
  126. -
  127. -
  128. struct ocelot_port {
  129. struct ocelot *ocelot;
  130. @@ -425,7 +418,7 @@ struct ocelot_port {
  131. u16 vid;
  132. u8 ptp_cmd;
  133. - struct list_head skbs;
  134. + struct sk_buff_head tx_skbs;
  135. u8 ts_id;
  136. };