aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorKiran Patil <kiran.patil@intel.com>2011-06-20 19:59:20 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-06-29 17:29:36 -0400
commit064287eee372e8a2effe77fb909a40da9e7a1fd7 (patch)
tree0cfda86145d0bae9dedc70206c1ff1f4bb773480 /drivers/scsi
parent1ff9918b625457ce20d450d00f9ed0a12ba191b7 (diff)
[SCSI] fcoe: Round-robin based selection of CPU for post-processing of incoming commands
Problem: Earlier mechanism of selection of CPU was, to select the same CPU which has received incoming request. Hence in case of rx_id = 0xFFFF, request was always posted to same NetRx queue, hence only 1 CPU is utilized for handling the command. It was also causing problem of "running out of exchanges from per CPU pool of exchanges (in case of DDP offload) Fix: Implemented new algo. to select CPU for post-processing of incoming commands when rx_id is unknown. This is simple Round robin algo. for CPU selection. Notes/Dependencies: N/A Signed-off-by: Kiran Patil <kiran.patil@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/fcoe/fcoe.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 6378c5883514..da73115ddf4d 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1245,6 +1245,36 @@ static int fcoe_cpu_callback(struct notifier_block *nfb,
1245} 1245}
1246 1246
1247/** 1247/**
1248 * fcoe_select_cpu() - Selects CPU to handle post-processing of incoming
1249 * command.
1250 * @curr_cpu: CPU which received request
1251 *
1252 * This routine selects next CPU based on cpumask.
1253 *
1254 * Returns: int (CPU number). Caller to verify if returned CPU is online or not.
1255 */
1256static unsigned int fcoe_select_cpu(unsigned int curr_cpu)
1257{
1258 static unsigned int selected_cpu;
1259
1260 if (num_online_cpus() == 1)
1261 return curr_cpu;
1262 /*
1263 * Doing following check, to skip "curr_cpu (smp_processor_id)"
1264 * from selection of CPU is intentional. This is to avoid same CPU
1265 * doing post-processing of command. "curr_cpu" to just receive
1266 * incoming request in case where rx_id is UNKNOWN and all other
1267 * CPU to actually process the command(s)
1268 */
1269 do {
1270 selected_cpu = cpumask_next(selected_cpu, cpu_online_mask);
1271 if (selected_cpu >= nr_cpu_ids)
1272 selected_cpu = cpumask_first(cpu_online_mask);
1273 } while (selected_cpu == curr_cpu);
1274 return selected_cpu;
1275}
1276
1277/**
1248 * fcoe_rcv() - Receive packets from a net device 1278 * fcoe_rcv() - Receive packets from a net device
1249 * @skb: The received packet 1279 * @skb: The received packet
1250 * @netdev: The net device that the packet was received on 1280 * @netdev: The net device that the packet was received on
@@ -1320,9 +1350,16 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev,
1320 */ 1350 */
1321 if (ntoh24(fh->fh_f_ctl) & FC_FC_EX_CTX) 1351 if (ntoh24(fh->fh_f_ctl) & FC_FC_EX_CTX)
1322 cpu = ntohs(fh->fh_ox_id) & fc_cpu_mask; 1352 cpu = ntohs(fh->fh_ox_id) & fc_cpu_mask;
1323 else 1353 else {
1324 cpu = smp_processor_id(); 1354 cpu = smp_processor_id();
1325 1355
1356 if ((fh->fh_type == FC_TYPE_FCP) &&
1357 (ntohs(fh->fh_rx_id) == FC_XID_UNKNOWN)) {
1358 do {
1359 cpu = fcoe_select_cpu(cpu);
1360 } while (!cpu_online(cpu));
1361 }
1362 }
1326 fps = &per_cpu(fcoe_percpu, cpu); 1363 fps = &per_cpu(fcoe_percpu, cpu);
1327 spin_lock_bh(&fps->fcoe_rx_list.lock); 1364 spin_lock_bh(&fps->fcoe_rx_list.lock);
1328 if (unlikely(!fps->thread)) { 1365 if (unlikely(!fps->thread)) {