Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'ipa-RX-replenish'

Alex Elder says:

====================
net: ipa: improve RX buffer replenishing

This series revises the algorithm used for replenishing receive
buffers on RX endpoints. Currently there are two atomic variables
that track how many receive buffers can be sent to the hardware.
The new algorithm obviates the need for those, by just assuming we
always want to provide the hardware with buffers until it can hold
no more.

The first patch eliminates an atomic variable that's not required.
The next moves some code into the main replenish function's caller,
making one of the called function's arguments unnecessary. The
next six refactor things a bit more, adding a new helper function
that allows us to eliminate an additional atomic variable. And the
final two implement two more minor improvements.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+60 -81
+11
drivers/net/ipa/gsi_trans.c
··· 320 320 atomic_add(tre_count, &trans_info->tre_avail); 321 321 } 322 322 323 + /* Return true if no transactions are allocated, false otherwise */ 324 + bool gsi_channel_trans_idle(struct gsi *gsi, u32 channel_id) 325 + { 326 + u32 tre_max = gsi_channel_tre_max(gsi, channel_id); 327 + struct gsi_trans_info *trans_info; 328 + 329 + trans_info = &gsi->channel[channel_id].trans_info; 330 + 331 + return atomic_read(&trans_info->tre_avail) == tre_max; 332 + } 333 + 323 334 /* Allocate a GSI transaction on a channel */ 324 335 struct gsi_trans *gsi_channel_trans_alloc(struct gsi *gsi, u32 channel_id, 325 336 u32 tre_count,
+10
drivers/net/ipa/gsi_trans.h
··· 130 130 void gsi_trans_pool_exit_dma(struct device *dev, struct gsi_trans_pool *pool); 131 131 132 132 /** 133 + * gsi_channel_trans_idle() - Return whether no transactions are allocated 134 + * @gsi: GSI pointer 135 + * @channel_id: Channel the transaction is associated with 136 + * 137 + * Return: True if no transactions are allocated, false otherwise 138 + * 139 + */ 140 + bool gsi_channel_trans_idle(struct gsi *gsi, u32 channel_id); 141 + 142 + /** 133 143 * gsi_channel_trans_alloc() - Allocate a GSI transaction on a channel 134 144 * @gsi: GSI pointer 135 145 * @channel_id: Channel the transaction is associated with
+37 -75
drivers/net/ipa/ipa_endpoint.c
··· 25 25 26 26 #define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) 27 27 28 - #define IPA_REPLENISH_BATCH 16 28 + /* Hardware is told about receive buffers once a "batch" has been queued */ 29 + #define IPA_REPLENISH_BATCH 16 /* Must be non-zero */ 29 30 30 31 /* The amount of RX buffer space consumed by standard skb overhead */ 31 32 #define IPA_RX_BUFFER_OVERHEAD (PAGE_SIZE - SKB_MAX_ORDER(NET_SKB_PAD, 0)) ··· 1037 1036 iowrite32(val, ipa->reg_virt + offset); 1038 1037 } 1039 1038 1040 - static int ipa_endpoint_replenish_one(struct ipa_endpoint *endpoint) 1039 + static int ipa_endpoint_replenish_one(struct ipa_endpoint *endpoint, 1040 + struct gsi_trans *trans) 1041 1041 { 1042 - struct gsi_trans *trans; 1043 - bool doorbell = false; 1044 1042 struct page *page; 1045 1043 u32 buffer_size; 1046 1044 u32 offset; ··· 1051 1051 if (!page) 1052 1052 return -ENOMEM; 1053 1053 1054 - trans = ipa_endpoint_trans_alloc(endpoint, 1); 1055 - if (!trans) 1056 - goto err_free_pages; 1057 - 1058 1054 /* Offset the buffer to make space for skb headroom */ 1059 1055 offset = NET_SKB_PAD; 1060 1056 len = buffer_size - offset; 1061 1057 1062 1058 ret = gsi_trans_page_add(trans, page, len, offset); 1063 1059 if (ret) 1064 - goto err_trans_free; 1065 - trans->data = page; /* transaction owns page now */ 1060 + __free_pages(page, get_order(buffer_size)); 1061 + else 1062 + trans->data = page; /* transaction owns page now */ 1066 1063 1067 - if (++endpoint->replenish_ready == IPA_REPLENISH_BATCH) { 1068 - doorbell = true; 1069 - endpoint->replenish_ready = 0; 1070 - } 1071 - 1072 - gsi_trans_commit(trans, doorbell); 1073 - 1074 - return 0; 1075 - 1076 - err_trans_free: 1077 - gsi_trans_free(trans); 1078 - err_free_pages: 1079 - __free_pages(page, get_order(buffer_size)); 1080 - 1081 - return -ENOMEM; 1064 + return ret; 1082 1065 } 1083 1066 1084 1067 /** 1085 1068 * ipa_endpoint_replenish() - Replenish endpoint receive buffers 1086 1069 * @endpoint: Endpoint to be replenished 1087 - * @add_one: Whether this is replacing a just-consumed buffer 1088 1070 * 1089 1071 * The IPA hardware can hold a fixed number of receive buffers for an RX 1090 1072 * endpoint, based on the number of entries in the underlying channel ring 1091 1073 * buffer. If an endpoint's "backlog" is non-zero, it indicates how many 1092 1074 * more receive buffers can be supplied to the hardware. Replenishing for 1093 - * an endpoint can be disabled, in which case requests to replenish a 1094 - * buffer are "saved", and transferred to the backlog once it is re-enabled 1095 - * again. 1075 + * an endpoint can be disabled, in which case buffers are not queued to 1076 + * the hardware. 1096 1077 */ 1097 - static void ipa_endpoint_replenish(struct ipa_endpoint *endpoint, bool add_one) 1078 + static void ipa_endpoint_replenish(struct ipa_endpoint *endpoint) 1098 1079 { 1099 - struct gsi *gsi; 1100 - u32 backlog; 1101 - int delta; 1080 + struct gsi_trans *trans; 1102 1081 1103 - if (!test_bit(IPA_REPLENISH_ENABLED, endpoint->replenish_flags)) { 1104 - if (add_one) 1105 - atomic_inc(&endpoint->replenish_saved); 1082 + if (!test_bit(IPA_REPLENISH_ENABLED, endpoint->replenish_flags)) 1106 1083 return; 1107 - } 1108 1084 1109 - /* If already active, just update the backlog */ 1110 - if (test_and_set_bit(IPA_REPLENISH_ACTIVE, endpoint->replenish_flags)) { 1111 - if (add_one) 1112 - atomic_inc(&endpoint->replenish_backlog); 1085 + /* Skip it if it's already active */ 1086 + if (test_and_set_bit(IPA_REPLENISH_ACTIVE, endpoint->replenish_flags)) 1113 1087 return; 1114 - } 1115 1088 1116 - while (atomic_dec_not_zero(&endpoint->replenish_backlog)) 1117 - if (ipa_endpoint_replenish_one(endpoint)) 1089 + while ((trans = ipa_endpoint_trans_alloc(endpoint, 1))) { 1090 + bool doorbell; 1091 + 1092 + if (ipa_endpoint_replenish_one(endpoint, trans)) 1118 1093 goto try_again_later; 1119 1094 1120 - clear_bit(IPA_REPLENISH_ACTIVE, endpoint->replenish_flags); 1121 1095 1122 - if (add_one) 1123 - atomic_inc(&endpoint->replenish_backlog); 1096 + /* Ring the doorbell if we've got a full batch */ 1097 + doorbell = !(++endpoint->replenish_count % IPA_REPLENISH_BATCH); 1098 + gsi_trans_commit(trans, doorbell); 1099 + } 1100 + 1101 + clear_bit(IPA_REPLENISH_ACTIVE, endpoint->replenish_flags); 1124 1102 1125 1103 return; 1126 1104 1127 1105 try_again_later: 1106 + gsi_trans_free(trans); 1128 1107 clear_bit(IPA_REPLENISH_ACTIVE, endpoint->replenish_flags); 1129 - 1130 - /* The last one didn't succeed, so fix the backlog */ 1131 - delta = add_one ? 2 : 1; 1132 - backlog = atomic_add_return(delta, &endpoint->replenish_backlog); 1133 1108 1134 1109 /* Whenever a receive buffer transaction completes we'll try to 1135 1110 * replenish again. It's unlikely, but if we fail to supply even 1136 1111 * one buffer, nothing will trigger another replenish attempt. 1137 - * Receive buffer transactions use one TRE, so schedule work to 1138 - * try replenishing again if our backlog is *all* available TREs. 1112 + * If the hardware has no receive buffers queued, schedule work to 1113 + * try replenishing again. 1139 1114 */ 1140 - gsi = &endpoint->ipa->gsi; 1141 - if (backlog == gsi_channel_tre_max(gsi, endpoint->channel_id)) 1115 + if (gsi_channel_trans_idle(&endpoint->ipa->gsi, endpoint->channel_id)) 1142 1116 schedule_delayed_work(&endpoint->replenish_work, 1143 1117 msecs_to_jiffies(1)); 1144 1118 } 1145 1119 1146 1120 static void ipa_endpoint_replenish_enable(struct ipa_endpoint *endpoint) 1147 1121 { 1148 - struct gsi *gsi = &endpoint->ipa->gsi; 1149 - u32 max_backlog; 1150 - u32 saved; 1151 - 1152 1122 set_bit(IPA_REPLENISH_ENABLED, endpoint->replenish_flags); 1153 - while ((saved = atomic_xchg(&endpoint->replenish_saved, 0))) 1154 - atomic_add(saved, &endpoint->replenish_backlog); 1155 1123 1156 1124 /* Start replenishing if hardware currently has no buffers */ 1157 - max_backlog = gsi_channel_tre_max(gsi, endpoint->channel_id); 1158 - if (atomic_read(&endpoint->replenish_backlog) == max_backlog) 1159 - ipa_endpoint_replenish(endpoint, false); 1125 + if (gsi_channel_trans_idle(&endpoint->ipa->gsi, endpoint->channel_id)) 1126 + ipa_endpoint_replenish(endpoint); 1160 1127 } 1161 1128 1162 1129 static void ipa_endpoint_replenish_disable(struct ipa_endpoint *endpoint) 1163 1130 { 1164 - u32 backlog; 1165 - 1166 1131 clear_bit(IPA_REPLENISH_ENABLED, endpoint->replenish_flags); 1167 - while ((backlog = atomic_xchg(&endpoint->replenish_backlog, 0))) 1168 - atomic_add(backlog, &endpoint->replenish_saved); 1169 1132 } 1170 1133 1171 1134 static void ipa_endpoint_replenish_work(struct work_struct *work) ··· 1138 1175 1139 1176 endpoint = container_of(dwork, struct ipa_endpoint, replenish_work); 1140 1177 1141 - ipa_endpoint_replenish(endpoint, false); 1178 + ipa_endpoint_replenish(endpoint); 1142 1179 } 1143 1180 1144 1181 static void ipa_endpoint_skb_copy(struct ipa_endpoint *endpoint, ··· 1343 1380 { 1344 1381 struct page *page; 1345 1382 1346 - ipa_endpoint_replenish(endpoint, true); 1347 - 1348 1383 if (trans->cancelled) 1349 - return; 1384 + goto done; 1350 1385 1351 1386 /* Parse or build a socket buffer using the actual received length */ 1352 1387 page = trans->data; ··· 1352 1391 ipa_endpoint_status_parse(endpoint, page, trans->len); 1353 1392 else if (ipa_endpoint_skb_build(endpoint, page, trans->len)) 1354 1393 trans->data = NULL; /* Pages have been consumed */ 1394 + done: 1395 + ipa_endpoint_replenish(endpoint); 1355 1396 } 1356 1397 1357 1398 void ipa_endpoint_trans_complete(struct ipa_endpoint *endpoint, ··· 1690 1727 */ 1691 1728 clear_bit(IPA_REPLENISH_ENABLED, endpoint->replenish_flags); 1692 1729 clear_bit(IPA_REPLENISH_ACTIVE, endpoint->replenish_flags); 1693 - atomic_set(&endpoint->replenish_saved, 1694 - gsi_channel_tre_max(gsi, endpoint->channel_id)); 1695 - atomic_set(&endpoint->replenish_backlog, 0); 1696 1730 INIT_DELAYED_WORK(&endpoint->replenish_work, 1697 1731 ipa_endpoint_replenish_work); 1698 1732 } ··· 1864 1904 { 1865 1905 enum ipa_endpoint_name name; 1866 1906 u32 filter_map; 1907 + 1908 + BUILD_BUG_ON(!IPA_REPLENISH_BATCH); 1867 1909 1868 1910 if (!ipa_endpoint_data_valid(ipa, count, data)) 1869 1911 return 0; /* Error */
+2 -6
drivers/net/ipa/ipa_endpoint.h
··· 65 65 * @evt_ring_id: GSI event ring used by the endpoint 66 66 * @netdev: Network device pointer, if endpoint uses one 67 67 * @replenish_flags: Replenishing state flags 68 - * @replenish_ready: Number of replenish transactions without doorbell 69 - * @replenish_saved: Replenish requests held while disabled 70 - * @replenish_backlog: Number of buffers needed to fill hardware queue 68 + * @replenish_count: Total number of replenish transactions committed 71 69 * @replenish_work: Work item used for repeated replenish failures 72 70 */ 73 71 struct ipa_endpoint { ··· 84 86 85 87 /* Receive buffer replenishing for RX endpoints */ 86 88 DECLARE_BITMAP(replenish_flags, IPA_REPLENISH_COUNT); 87 - u32 replenish_ready; 88 - atomic_t replenish_saved; 89 - atomic_t replenish_backlog; 89 + u64 replenish_count; 90 90 struct delayed_work replenish_work; /* global wq */ 91 91 }; 92 92