aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2016-07-05 19:52:46 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-08 23:11:20 -0400
commit99a50bb11cad44cd1d478256d2388e7afce982ac (patch)
tree208a238d8af1ccf5cd1f04c927859624e9ead078
parentbba7eb5d9b4ebccacd30331121ee29764212a29d (diff)
netvsc: Use the new in-place consumption APIs in the rx path
Use the new APIs for eliminating a copy on the receive path. These new APIs also help in minimizing the number of memory barriers we end up issuing (in the ringbuffer code) since we can better control when we want to expose the ring state to the host. The patch is being resent to address earlier email issues. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/hyperv/netvsc.c88
1 files changed, 59 insertions, 29 deletions
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 6909c322de4e..20e09174ff62 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -1128,6 +1128,39 @@ static inline void netvsc_receive_inband(struct hv_device *hdev,
1128 } 1128 }
1129} 1129}
1130 1130
1131static void netvsc_process_raw_pkt(struct hv_device *device,
1132 struct vmbus_channel *channel,
1133 struct netvsc_device *net_device,
1134 struct net_device *ndev,
1135 u64 request_id,
1136 struct vmpacket_descriptor *desc)
1137{
1138 struct nvsp_message *nvmsg;
1139
1140 nvmsg = (struct nvsp_message *)((unsigned long)
1141 desc + (desc->offset8 << 3));
1142
1143 switch (desc->type) {
1144 case VM_PKT_COMP:
1145 netvsc_send_completion(net_device, channel, device, desc);
1146 break;
1147
1148 case VM_PKT_DATA_USING_XFER_PAGES:
1149 netvsc_receive(net_device, channel, device, desc);
1150 break;
1151
1152 case VM_PKT_DATA_INBAND:
1153 netvsc_receive_inband(device, net_device, nvmsg);
1154 break;
1155
1156 default:
1157 netdev_err(ndev, "unhandled packet type %d, tid %llx\n",
1158 desc->type, request_id);
1159 break;
1160 }
1161}
1162
1163
1131void netvsc_channel_cb(void *context) 1164void netvsc_channel_cb(void *context)
1132{ 1165{
1133 int ret; 1166 int ret;
@@ -1140,7 +1173,7 @@ void netvsc_channel_cb(void *context)
1140 unsigned char *buffer; 1173 unsigned char *buffer;
1141 int bufferlen = NETVSC_PACKET_SIZE; 1174 int bufferlen = NETVSC_PACKET_SIZE;
1142 struct net_device *ndev; 1175 struct net_device *ndev;
1143 struct nvsp_message *nvmsg; 1176 bool need_to_commit = false;
1144 1177
1145 if (channel->primary_channel != NULL) 1178 if (channel->primary_channel != NULL)
1146 device = channel->primary_channel->device_obj; 1179 device = channel->primary_channel->device_obj;
@@ -1154,39 +1187,36 @@ void netvsc_channel_cb(void *context)
1154 buffer = get_per_channel_state(channel); 1187 buffer = get_per_channel_state(channel);
1155 1188
1156 do { 1189 do {
1190 desc = get_next_pkt_raw(channel);
1191 if (desc != NULL) {
1192 netvsc_process_raw_pkt(device,
1193 channel,
1194 net_device,
1195 ndev,
1196 desc->trans_id,
1197 desc);
1198
1199 put_pkt_raw(channel, desc);
1200 need_to_commit = true;
1201 continue;
1202 }
1203 if (need_to_commit) {
1204 need_to_commit = false;
1205 commit_rd_index(channel);
1206 }
1207
1157 ret = vmbus_recvpacket_raw(channel, buffer, bufferlen, 1208 ret = vmbus_recvpacket_raw(channel, buffer, bufferlen,
1158 &bytes_recvd, &request_id); 1209 &bytes_recvd, &request_id);
1159 if (ret == 0) { 1210 if (ret == 0) {
1160 if (bytes_recvd > 0) { 1211 if (bytes_recvd > 0) {
1161 desc = (struct vmpacket_descriptor *)buffer; 1212 desc = (struct vmpacket_descriptor *)buffer;
1162 nvmsg = (struct nvsp_message *)((unsigned long) 1213 netvsc_process_raw_pkt(device,
1163 desc + (desc->offset8 << 3)); 1214 channel,
1164 switch (desc->type) { 1215 net_device,
1165 case VM_PKT_COMP: 1216 ndev,
1166 netvsc_send_completion(net_device, 1217 request_id,
1167 channel, 1218 desc);
1168 device, desc); 1219
1169 break;
1170
1171 case VM_PKT_DATA_USING_XFER_PAGES:
1172 netvsc_receive(net_device, channel,
1173 device, desc);
1174 break;
1175
1176 case VM_PKT_DATA_INBAND:
1177 netvsc_receive_inband(device,
1178 net_device,
1179 nvmsg);
1180 break;
1181
1182 default:
1183 netdev_err(ndev,
1184 "unhandled packet type %d, "
1185 "tid %llx len %d\n",
1186 desc->type, request_id,
1187 bytes_recvd);
1188 break;
1189 }
1190 1220
1191 } else { 1221 } else {
1192 /* 1222 /*