From 0b1706071ada170bebc19c3ae16c81bad856b61c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 28 Sep 2010 17:47:49 +0000 Subject: [PATCH] Inlined several patches instead of downloading these because apparently downloading these patches doesn't work reliably. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@2300 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scripts/generate-kernel-with-srp-patches | 1562 +++++++++++++++++++++- 1 file changed, 1552 insertions(+), 10 deletions(-) diff --git a/scripts/generate-kernel-with-srp-patches b/scripts/generate-kernel-with-srp-patches index 8917094a6..93455e60b 100755 --- a/scripts/generate-kernel-with-srp-patches +++ b/scripts/generate-kernel-with-srp-patches @@ -13,6 +13,882 @@ usage() { echo "$0 " } +# Source: http://git.kernel.org/?p=linux/kernel/git/roland/infiniband.git;a=patch;h=$commit +get_2_6_36_patch() { +case "$1" in + 7a7008110b94dfaa90db4b0cc5b0c3f964c80506) + cat <buf; + + if (0) { +- int i; +- + shost_printk(KERN_ERR, target->scsi_host, + PFX "recv completion, opcode 0x%02x\n", opcode); +- +- for (i = 0; i < wc->byte_len; ++i) { +- if (i % 8 == 0) +- printk(KERN_ERR " [%02x] ", i); +- printk(" %02x", ((u8 *) iu->buf)[i]); +- if ((i + 1) % 8 == 0) +- printk("\n"); +- } +- +- if (wc->byte_len % 8) +- printk("\n"); ++ print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 8, 1, ++ iu->buf, wc->byte_len, true); + } + + switch (opcode) { +-- +1.7.3 + +EOF + ;; + c996bb47bb419b7c2f75499e11750142775e5da9) + cat <scsi_host->host_lock, flags); ++ ++ next = target->rx_head & (SRP_RQ_SIZE - 1); ++ wr.wr_id = next; ++ iu = target->rx_ring[next]; ++ ++ list.addr = iu->dma; ++ list.length = iu->size; ++ list.lkey = target->srp_host->srp_dev->mr->lkey; ++ ++ wr.next = NULL; ++ wr.sg_list = &list; ++ wr.num_sge = 1; ++ ++ ret = ib_post_recv(target->qp, &wr, &bad_wr); ++ if (!ret) ++ ++target->rx_head; ++ ++ spin_unlock_irqrestore(target->scsi_host->host_lock, flags); ++ ++ return ret; ++} ++ + static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) + { + struct srp_request *req; +@@ -868,6 +900,7 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) + { + struct ib_device *dev; + struct srp_iu *iu; ++ int res; + u8 opcode; + + iu = target->rx_ring[wc->wr_id]; +@@ -904,6 +937,11 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) + + ib_dma_sync_single_for_device(dev, iu->dma, target->max_ti_iu_len, + DMA_FROM_DEVICE); ++ ++ res = srp_post_recv(target); ++ if (res != 0) ++ shost_printk(KERN_ERR, target->scsi_host, ++ PFX "Recv failed with error code %d\n", res); + } + + static void srp_recv_completion(struct ib_cq *cq, void *target_ptr) +@@ -943,45 +981,6 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr) + } + } + +-static int __srp_post_recv(struct srp_target_port *target) +-{ +- struct srp_iu *iu; +- struct ib_sge list; +- struct ib_recv_wr wr, *bad_wr; +- unsigned int next; +- int ret; +- +- next = target->rx_head & (SRP_RQ_SIZE - 1); +- wr.wr_id = next; +- iu = target->rx_ring[next]; +- +- list.addr = iu->dma; +- list.length = iu->size; +- list.lkey = target->srp_host->srp_dev->mr->lkey; +- +- wr.next = NULL; +- wr.sg_list = &list; +- wr.num_sge = 1; +- +- ret = ib_post_recv(target->qp, &wr, &bad_wr); +- if (!ret) +- ++target->rx_head; +- +- return ret; +-} +- +-static int srp_post_recv(struct srp_target_port *target) +-{ +- unsigned long flags; +- int ret; +- +- spin_lock_irqsave(target->scsi_host->host_lock, flags); +- ret = __srp_post_recv(target); +- spin_unlock_irqrestore(target->scsi_host->host_lock, flags); +- +- return ret; +-} +- + /* + * Must be called with target->scsi_host->host_lock held to protect + * req_lim and tx_head. Lock cannot be dropped between call here and +@@ -1091,11 +1090,6 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, + goto err; + } + +- if (__srp_post_recv(target)) { +- shost_printk(KERN_ERR, target->scsi_host, PFX "Recv failed\n"); +- goto err_unmap; +- } +- + ib_dma_sync_single_for_device(dev, iu->dma, srp_max_iu_len, + DMA_TO_DEVICE); + +@@ -1238,6 +1232,7 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) + int attr_mask = 0; + int comp = 0; + int opcode = 0; ++ int i; + + switch (event->event) { + case IB_CM_REQ_ERROR: +@@ -1287,7 +1282,11 @@ static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event) + if (target->status) + break; + +- target->status = srp_post_recv(target); ++ for (i = 0; i < SRP_RQ_SIZE; i++) { ++ target->status = srp_post_recv(target); ++ if (target->status) ++ break; ++ } + if (target->status) + break; + +-- +1.7.3 + +EOF + ;; + 89de74866b846cc48780fda3de7fd223296aaca9) + cat <orig_dgid); + } + ++static ssize_t show_req_lim(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct srp_target_port *target = host_to_target(class_to_shost(dev)); ++ ++ if (target->state == SRP_TARGET_DEAD || ++ target->state == SRP_TARGET_REMOVED) ++ return -ENODEV; ++ ++ return sprintf(buf, "%d\n", target->req_lim); ++} ++ + static ssize_t show_zero_req_lim(struct device *dev, + struct device_attribute *attr, char *buf) + { +@@ -1586,6 +1598,7 @@ static DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL); + static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL); + static DEVICE_ATTR(dgid, S_IRUGO, show_dgid, NULL); + static DEVICE_ATTR(orig_dgid, S_IRUGO, show_orig_dgid, NULL); ++static DEVICE_ATTR(req_lim, S_IRUGO, show_req_lim, NULL); + static DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); + static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); + static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); +@@ -1597,6 +1610,7 @@ static struct device_attribute *srp_host_attrs[] = { + &dev_attr_pkey, + &dev_attr_dgid, + &dev_attr_orig_dgid, ++ &dev_attr_req_lim, + &dev_attr_zero_req_lim, + &dev_attr_local_ib_port, + &dev_attr_local_ib_device, +-- +1.7.3 + +EOF + ;; + *) + echo ERROR + ;; + esac +} + +# Source: https://patchwork.kernel.org/patch/$p/raw/ +get_2_6_37_patch() { +case "$1" in + 143381) + cat <srp_host, target->rx_ring[i]); +- for (i = 0; i < SRP_SQ_SIZE + 1; ++i) ++ for (i = 0; i < SRP_SQ_SIZE; ++i) + srp_free_iu(target->srp_host, target->tx_ring[i]); + } + +@@ -822,7 +822,7 @@ static int srp_post_recv(struct srp_target_port *target) + + spin_lock_irqsave(target->scsi_host->host_lock, flags); + +- next = target->rx_head & (SRP_RQ_SIZE - 1); ++ next = target->rx_head & SRP_RQ_MASK; + wr.wr_id = next; + iu = target->rx_ring[next]; + +@@ -989,19 +989,19 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr) + static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target, + enum srp_request_type req_type) + { +- s32 min = (req_type == SRP_REQ_TASK_MGMT) ? 1 : 2; ++ s32 rsv = (req_type == SRP_REQ_TASK_MGMT) ? 0 : SRP_TSK_MGMT_SQ_SIZE; + + srp_send_completion(target->send_cq, target); + + if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE) + return NULL; + +- if (target->req_lim < min) { ++ if (target->req_lim <= rsv) { + ++target->zero_req_lim; + return NULL; + } + +- return target->tx_ring[target->tx_head & SRP_SQ_SIZE]; ++ return target->tx_ring[target->tx_head & SRP_SQ_MASK]; + } + + /* +@@ -1020,7 +1020,7 @@ static int __srp_post_send(struct srp_target_port *target, + list.lkey = target->srp_host->srp_dev->mr->lkey; + + wr.next = NULL; +- wr.wr_id = target->tx_head & SRP_SQ_SIZE; ++ wr.wr_id = target->tx_head & SRP_SQ_MASK; + wr.sg_list = &list; + wr.num_sge = 1; + wr.opcode = IB_WR_SEND; +@@ -1121,7 +1121,7 @@ static int srp_alloc_iu_bufs(struct srp_target_port *target) + goto err; + } + +- for (i = 0; i < SRP_SQ_SIZE + 1; ++i) { ++ for (i = 0; i < SRP_SQ_SIZE; ++i) { + target->tx_ring[i] = srp_alloc_iu(target->srp_host, + srp_max_iu_len, + GFP_KERNEL, DMA_TO_DEVICE); +@@ -1137,7 +1137,7 @@ err: + target->rx_ring[i] = NULL; + } + +- for (i = 0; i < SRP_SQ_SIZE + 1; ++i) { ++ for (i = 0; i < SRP_SQ_SIZE; ++i) { + srp_free_iu(target->srp_host, target->tx_ring[i]); + target->tx_ring[i] = NULL; + } +@@ -1626,9 +1626,9 @@ static struct scsi_host_template srp_template = { + .eh_abort_handler = srp_abort, + .eh_device_reset_handler = srp_reset_device, + .eh_host_reset_handler = srp_reset_host, +- .can_queue = SRP_SQ_SIZE, ++ .can_queue = SRP_CMD_SQ_SIZE, + .this_id = -1, +- .cmd_per_lun = SRP_SQ_SIZE, ++ .cmd_per_lun = SRP_CMD_SQ_SIZE, + .use_clustering = ENABLE_CLUSTERING, + .shost_attrs = srp_host_attrs + }; +@@ -1813,7 +1813,8 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) + printk(KERN_WARNING PFX "bad max cmd_per_lun parameter '%s'\n", p); + goto out; + } +- target->scsi_host->cmd_per_lun = min(token, SRP_SQ_SIZE); ++ target->scsi_host->cmd_per_lun ++ = min(token, SRP_CMD_SQ_SIZE); + break; + + case SRP_OPT_IO_CLASS: +@@ -1891,7 +1892,7 @@ static ssize_t srp_create_target(struct device *dev, + + INIT_LIST_HEAD(&target->free_reqs); + INIT_LIST_HEAD(&target->req_queue); +- for (i = 0; i < SRP_SQ_SIZE; ++i) { ++ for (i = 0; i < SRP_CMD_SQ_SIZE; ++i) { + target->req_ring[i].index = i; + list_add_tail(&target->req_ring[i].list, &target->free_reqs); + } +@@ -2159,6 +2160,9 @@ static int __init srp_init_module(void) + { + int ret; + ++ BUILD_BUG_ON_NOT_POWER_OF_2(SRP_SQ_SIZE); ++ BUILD_BUG_ON_NOT_POWER_OF_2(SRP_RQ_SIZE); ++ + if (srp_sg_tablesize > 255) { + printk(KERN_WARNING PFX "Clamping srp_sg_tablesize to 255\n"); + srp_sg_tablesize = 255; +diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h +index 5a80eac..7a959d5 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.h ++++ b/drivers/infiniband/ulp/srp/ib_srp.h +@@ -59,7 +59,14 @@ enum { + + SRP_RQ_SHIFT = 6, + SRP_RQ_SIZE = 1 << SRP_RQ_SHIFT, +- SRP_SQ_SIZE = SRP_RQ_SIZE - 1, ++ SRP_RQ_MASK = SRP_RQ_SIZE - 1, ++ ++ SRP_SQ_SIZE = SRP_RQ_SIZE, ++ SRP_SQ_MASK = SRP_SQ_SIZE - 1, ++ SRP_RSP_SQ_SIZE = 1, ++ SRP_REQ_SQ_SIZE = SRP_SQ_SIZE - SRP_RSP_SQ_SIZE, ++ SRP_TSK_MGMT_SQ_SIZE = 1, ++ SRP_CMD_SQ_SIZE = SRP_REQ_SQ_SIZE - SRP_TSK_MGMT_SQ_SIZE, + + SRP_TAG_TSK_MGMT = 1 << (SRP_RQ_SHIFT + 1), + +@@ -144,11 +151,11 @@ struct srp_target_port { + + unsigned tx_head; + unsigned tx_tail; +- struct srp_iu *tx_ring[SRP_SQ_SIZE + 1]; ++ struct srp_iu *tx_ring[SRP_SQ_SIZE]; + + struct list_head free_reqs; + struct list_head req_queue; +- struct srp_request req_ring[SRP_SQ_SIZE]; ++ struct srp_request req_ring[SRP_CMD_SQ_SIZE]; + + struct work_struct work; + +EOF + ;; + 143391) + cat <scsi_host->host_lock, flags); + } + ++/* ++ * Must be called with target->scsi_host->host_lock locked to protect ++ * target->req_lim. ++ */ ++static void __srp_handle_cred_req(struct srp_target_port *target, ++ void *req_ptr, void *rsp_ptr) ++{ ++ struct srp_cred_req *req = req_ptr; ++ struct srp_cred_rsp *rsp = rsp_ptr; ++ ++ target->req_lim += be32_to_cpu(req->req_lim_delta); ++ ++ memset(rsp, 0, sizeof *rsp); ++ rsp->opcode = SRP_CRED_RSP; ++ rsp->tag = req->tag; ++} ++ ++/* ++ * Must be called with target->scsi_host->host_lock locked to protect ++ * target->req_lim. ++ */ ++static void __srp_handle_aer_req(struct srp_target_port *target, ++ void *req_ptr, void *rsp_ptr) ++{ ++ struct srp_aer_req *req = req_ptr; ++ struct srp_aer_rsp *rsp = rsp_ptr; ++ ++ target->req_lim += be32_to_cpu(req->req_lim_delta); ++ ++ shost_printk(KERN_ERR, target->scsi_host, ++ PFX "ignoring AER for LUN %llu\n", be64_to_cpu(req->lun)); ++ ++ memset(rsp, 0, sizeof *rsp); ++ rsp->opcode = SRP_AER_RSP; ++ rsp->tag = req->tag; ++} ++ ++static void srp_handle_req(struct srp_target_port *target, ++ struct srp_iu *req_iu, ++ void (*req_fn)(struct srp_target_port *, ++ void *, void *)) ++{ ++ struct ib_device *dev; ++ u8 *req_buf; ++ unsigned long flags; ++ struct srp_iu *rsp_iu; ++ u8 *rsp_buf; ++ int res; ++ ++ dev = target->srp_host->srp_dev->dev; ++ req_buf = req_iu->buf; ++ ++ spin_lock_irqsave(target->scsi_host->host_lock, flags); ++ ++ rsp_iu = __srp_get_tx_iu(target, SRP_IU_RSP); ++ if (!rsp_iu) ++ goto out_unlock; ++ ++ rsp_buf = rsp_iu->buf; ++ ++ (*req_fn)(target, req_buf, rsp_buf); ++ ++ ib_dma_sync_single_for_device(dev, rsp_iu->dma, srp_max_iu_len, ++ DMA_TO_DEVICE); ++ ++ res = __srp_post_send(target, rsp_iu, sizeof *rsp_iu, SRP_SEND_RSP); ++ if (res) ++ shost_printk(KERN_ERR, target->scsi_host, ++ PFX "Sending response failed -- res = %d\n", res); ++ ++out_unlock: ++ spin_unlock_irqrestore(target->scsi_host->host_lock, flags); ++} ++ + static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) + { + struct ib_device *dev; +@@ -929,6 +1008,14 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) + PFX "Got target logout request\n"); + break; + ++ case SRP_CRED_REQ: ++ srp_handle_req(target, iu, __srp_handle_cred_req); ++ break; ++ ++ case SRP_AER_REQ: ++ srp_handle_req(target, iu, __srp_handle_aer_req); ++ break; ++ + default: + shost_printk(KERN_WARNING, target->scsi_host, + PFX "Unhandled SRP opcode 0x%02x\n", opcode); +@@ -985,18 +1072,27 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr) + * Must be called with target->scsi_host->host_lock held to protect + * req_lim and tx_head. Lock cannot be dropped between call here and + * call to __srp_post_send(). ++ * ++ * Note: ++ * An upper limit for the number of allocated information units for each ++ * request type is: ++ * - SRP_IU_CMD: SRP_CMD_SQ_SIZE, since the SCSI mid-layer never queues ++ * more than Scsi_Host.can_queue requests. ++ * - SRP_IU_TSK_MGMT: SRP_TSK_MGMT_SQ_SIZE. ++ * - SRP_IU_RSP: 1, since a conforming SRP target never sends more than ++ * one unanswered SRP request to an initiator. + */ + static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target, +- enum srp_request_type req_type) ++ enum srp_tx_iu_type iu_type) + { +- s32 rsv = (req_type == SRP_REQ_TASK_MGMT) ? 0 : SRP_TSK_MGMT_SQ_SIZE; ++ s32 rsv = (iu_type == SRP_IU_TSK_MGMT) ? 0 : SRP_TSK_MGMT_SQ_SIZE; + + srp_send_completion(target->send_cq, target); + + if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE) + return NULL; + +- if (target->req_lim <= rsv) { ++ if (iu_type != SRP_IU_RSP && target->req_lim <= rsv) { + ++target->zero_req_lim; + return NULL; + } +@@ -1009,7 +1105,8 @@ static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target, + * req_lim and tx_head. + */ + static int __srp_post_send(struct srp_target_port *target, +- struct srp_iu *iu, int len) ++ struct srp_iu *iu, int len, ++ enum srp_send_iu_type iu_type) + { + struct ib_sge list; + struct ib_send_wr wr, *bad_wr; +@@ -1030,7 +1127,8 @@ static int __srp_post_send(struct srp_target_port *target, + + if (!ret) { + ++target->tx_head; +- --target->req_lim; ++ if (iu_type == SRP_SEND_REQ) ++ --target->req_lim; + } + + return ret; +@@ -1056,7 +1154,7 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, + return 0; + } + +- iu = __srp_get_tx_iu(target, SRP_REQ_NORMAL); ++ iu = __srp_get_tx_iu(target, SRP_IU_CMD); + if (!iu) + goto err; + +@@ -1093,7 +1191,7 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd, + ib_dma_sync_single_for_device(dev, iu->dma, srp_max_iu_len, + DMA_TO_DEVICE); + +- if (__srp_post_send(target, iu, len)) { ++ if (__srp_post_send(target, iu, len, SRP_SEND_REQ)) { + shost_printk(KERN_ERR, target->scsi_host, PFX "Send failed\n"); + goto err_unmap; + } +@@ -1363,7 +1461,7 @@ static int srp_send_tsk_mgmt(struct srp_target_port *target, + + init_completion(&req->done); + +- iu = __srp_get_tx_iu(target, SRP_REQ_TASK_MGMT); ++ iu = __srp_get_tx_iu(target, SRP_IU_TSK_MGMT); + if (!iu) + goto out; + +@@ -1376,7 +1474,7 @@ static int srp_send_tsk_mgmt(struct srp_target_port *target, + tsk_mgmt->tsk_mgmt_func = func; + tsk_mgmt->task_tag = req->index; + +- if (__srp_post_send(target, iu, sizeof *tsk_mgmt)) ++ if (__srp_post_send(target, iu, sizeof *tsk_mgmt, SRP_SEND_REQ)) + goto out; + + req->tsk_mgmt = iu; +diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h +index 7a959d5..854ec81 100644 +--- a/drivers/infiniband/ulp/srp/ib_srp.h ++++ b/drivers/infiniband/ulp/srp/ib_srp.h +@@ -82,9 +82,15 @@ enum srp_target_state { + SRP_TARGET_REMOVED + }; + +-enum srp_request_type { +- SRP_REQ_NORMAL, +- SRP_REQ_TASK_MGMT, ++enum srp_tx_iu_type { ++ SRP_IU_CMD, ++ SRP_IU_TSK_MGMT, ++ SRP_IU_RSP, ++}; ++ ++enum srp_send_iu_type { ++ SRP_SEND_REQ, ++ SRP_SEND_RSP, + }; + + struct srp_device { +diff --git a/include/scsi/srp.h b/include/scsi/srp.h +index ad178fa..1ae84db 100644 +--- a/include/scsi/srp.h ++++ b/include/scsi/srp.h +@@ -239,4 +239,42 @@ struct srp_rsp { + u8 data[0]; + } __attribute__((packed)); + ++struct srp_cred_req { ++ u8 opcode; ++ u8 sol_not; ++ u8 reserved[2]; ++ __be32 req_lim_delta; ++ u64 tag; ++}; ++ ++struct srp_cred_rsp { ++ u8 opcode; ++ u8 reserved[7]; ++ u64 tag; ++}; ++ ++/* ++ * The SRP spec defines the fixed portion of the AER_REQ structure to be ++ * 36 bytes, so it needs to be packed to avoid having it padded to 40 bytes ++ * on 64-bit architectures. ++ */ ++struct srp_aer_req { ++ u8 opcode; ++ u8 sol_not; ++ u8 reserved[2]; ++ __be32 req_lim_delta; ++ u64 tag; ++ u32 reserved2; ++ __be64 lun; ++ __be32 sense_data_len; ++ u32 reserved3; ++ u8 sense_data[0]; ++} __attribute__((packed)); ++ ++struct srp_aer_rsp { ++ u8 opcode; ++ u8 reserved[7]; ++ u64 tag; ++}; ++ + #endif /* SCSI_SRP_H */ +EOF + ;; + 143401) + cat <scsi_host->host_lock held to protect ++ * req_lim and tx_head. Lock cannot be dropped between call here and ++ * call to __srp_post_send(). ++ * ++ * Note: ++ * An upper limit for the number of allocated information units for each ++ * request type is: ++ * - SRP_IU_CMD: SRP_CMD_SQ_SIZE, since the SCSI mid-layer never queues ++ * more than Scsi_Host.can_queue requests. ++ * - SRP_IU_TSK_MGMT: SRP_TSK_MGMT_SQ_SIZE. ++ * - SRP_IU_RSP: 1, since a conforming SRP target never sends more than ++ * one unanswered SRP request to an initiator. ++ */ ++static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target, ++ enum srp_tx_iu_type iu_type) ++{ ++ s32 rsv = (iu_type == SRP_IU_TSK_MGMT) ? 0 : SRP_TSK_MGMT_SQ_SIZE; ++ ++ srp_send_completion(target->send_cq, target); ++ ++ if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE) ++ return NULL; ++ ++ if (iu_type != SRP_IU_RSP && target->req_lim <= rsv) { ++ ++target->zero_req_lim; ++ return NULL; ++ } ++ ++ return target->tx_ring[target->tx_head & SRP_SQ_MASK]; ++} ++ ++/* ++ * Must be called with target->scsi_host->host_lock held to protect ++ * req_lim and tx_head. ++ */ ++static int __srp_post_send(struct srp_target_port *target, ++ struct srp_iu *iu, int len, ++ enum srp_send_iu_type iu_type) ++{ ++ struct ib_sge list; ++ struct ib_send_wr wr, *bad_wr; ++ int ret = 0; ++ ++ list.addr = iu->dma; ++ list.length = len; ++ list.lkey = target->srp_host->srp_dev->mr->lkey; ++ ++ wr.next = NULL; ++ wr.wr_id = target->tx_head & SRP_SQ_MASK; ++ wr.sg_list = &list; ++ wr.num_sge = 1; ++ wr.opcode = IB_WR_SEND; ++ wr.send_flags = IB_SEND_SIGNALED; ++ ++ ret = ib_post_send(target->qp, &wr, &bad_wr); ++ ++ if (!ret) { ++ ++target->tx_head; ++ if (iu_type == SRP_SEND_REQ) ++ --target->req_lim; ++ } ++ ++ return ret; ++} ++ ++/* + * Must be called with target->scsi_host->host_lock locked to protect + * target->req_lim. + */ +@@ -1068,72 +1129,6 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr) + } + } + +-/* +- * Must be called with target->scsi_host->host_lock held to protect +- * req_lim and tx_head. Lock cannot be dropped between call here and +- * call to __srp_post_send(). +- * +- * Note: +- * An upper limit for the number of allocated information units for each +- * request type is: +- * - SRP_IU_CMD: SRP_CMD_SQ_SIZE, since the SCSI mid-layer never queues +- * more than Scsi_Host.can_queue requests. +- * - SRP_IU_TSK_MGMT: SRP_TSK_MGMT_SQ_SIZE. +- * - SRP_IU_RSP: 1, since a conforming SRP target never sends more than +- * one unanswered SRP request to an initiator. +- */ +-static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target, +- enum srp_tx_iu_type iu_type) +-{ +- s32 rsv = (iu_type == SRP_IU_TSK_MGMT) ? 0 : SRP_TSK_MGMT_SQ_SIZE; +- +- srp_send_completion(target->send_cq, target); +- +- if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE) +- return NULL; +- +- if (iu_type != SRP_IU_RSP && target->req_lim <= rsv) { +- ++target->zero_req_lim; +- return NULL; +- } +- +- return target->tx_ring[target->tx_head & SRP_SQ_MASK]; +-} +- +-/* +- * Must be called with target->scsi_host->host_lock held to protect +- * req_lim and tx_head. +- */ +-static int __srp_post_send(struct srp_target_port *target, +- struct srp_iu *iu, int len, +- enum srp_send_iu_type iu_type) +-{ +- struct ib_sge list; +- struct ib_send_wr wr, *bad_wr; +- int ret = 0; +- +- list.addr = iu->dma; +- list.length = len; +- list.lkey = target->srp_host->srp_dev->mr->lkey; +- +- wr.next = NULL; +- wr.wr_id = target->tx_head & SRP_SQ_MASK; +- wr.sg_list = &list; +- wr.num_sge = 1; +- wr.opcode = IB_WR_SEND; +- wr.send_flags = IB_SEND_SIGNALED; +- +- ret = ib_post_send(target->qp, &wr, &bad_wr); +- +- if (!ret) { +- ++target->tx_head; +- if (iu_type == SRP_SEND_REQ) +- --target->req_lim; +- } +- +- return ret; +-} +- + static int srp_queuecommand(struct scsi_cmnd *scmnd, + void (*done)(struct scsi_cmnd *)) + { +EOF + ;; + 143411) + cat <max_ti_iu_len = be32_to_cpu(rsp->max_ti_iu_len); + target->req_lim = be32_to_cpu(rsp->req_lim_delta); + +- target->scsi_host->can_queue = min(target->req_lim, +- target->scsi_host->can_queue); ++ /* ++ * Set can_queue such that we don't needlessly ++ * bounce requests back to the SCSI mid-layer. ++ */ ++ target->scsi_host->can_queue ++ = min(target->req_lim - SRP_TSK_MGMT_SQ_SIZE, ++ target->scsi_host->can_queue); + } else { + shost_printk(KERN_WARNING, target->scsi_host, + PFX "Unhandled RSP opcode %#x\n", opcode); +EOF + ;; + 143421) + cat <dma, srp_max_iu_len, + DMA_TO_DEVICE); + +- req = list_entry(target->free_reqs.next, struct srp_request, list); ++ req = list_first_entry(&target->free_reqs, struct srp_request, list); + + scmnd->scsi_done = done; + scmnd->result = 0; +EOF + ;; + *) + echo ERROR + ;; + esac +} + apply_locking_per_lun_patch() { patch -p1 <nr_batch_requests == q->nr_batching || +- (ioc->nr_batch_requests > 0 +- && time_before(jiffies, ioc->last_waited + BLK_BATCH_TIME)); +-} +- +-/* +- * ioc_set_batching sets ioc to be a new "batcher" if it is not one. This +- * will cause the process to be a "batcher" on all queues in the system. This +- * is the behaviour we want though - once it gets a wakeup it should be given +- * a nice run. +- */ +-static void ioc_set_batching(struct request_queue *q, struct io_context *ioc) +-{ +- if (!ioc || ioc_batching(q, ioc)) +- return; +- +- ioc->nr_batch_requests = q->nr_batching; +- ioc->last_waited = jiffies; +-} +- + static void __freed_request(struct request_queue *q, int sync) + { + struct request_list *rl = &q->rq; +@@ -749,7 +715,6 @@ static struct request *get_request(struct request_queue *q, int rw_flags, + { + struct request *rq = NULL; + struct request_list *rl = &q->rq; +- struct io_context *ioc = NULL; + const bool is_sync = rw_is_sync(rw_flags) != 0; + int may_queue, priv; + +@@ -757,41 +722,6 @@ static struct request *get_request(struct request_queue *q, int rw_flags, + if (may_queue == ELV_MQUEUE_NO) + goto rq_starved; + +- if (rl->count[is_sync]+1 >= queue_congestion_on_threshold(q)) { +- if (rl->count[is_sync]+1 >= q->nr_requests) { +- ioc = current_io_context(GFP_ATOMIC, q->node); +- /* +- * The queue will fill after this allocation, so set +- * it as full, and mark this process as "batching". +- * This process will be allowed to complete a batch of +- * requests, others will be blocked. +- */ +- if (!blk_queue_full(q, is_sync)) { +- ioc_set_batching(q, ioc); +- blk_set_queue_full(q, is_sync); +- } else { +- if (may_queue != ELV_MQUEUE_MUST +- && !ioc_batching(q, ioc)) { +- /* +- * The queue is full and the allocating +- * process is not a "batcher", and not +- * exempted by the IO scheduler +- */ +- goto out; +- } +- } +- } +- blk_set_queue_congested(q, is_sync); +- } +- +- /* +- * Only allow batching queuers to allocate up to 50% over the defined +- * limit of requests, otherwise we could have thousands of requests +- * allocated with any setting of ->nr_requests +- */ +- if (rl->count[is_sync] >= (3 * q->nr_requests / 2)) +- goto out; +- + rl->count[is_sync]++; + rl->starved[is_sync] = 0; + +@@ -829,15 +759,6 @@ rq_starved: + goto out; + } + +- /* +- * ioc may be NULL here, and ioc_batching will be false. That's +- * OK, if the queue is under the request limit then requests need +- * not count toward the nr_batch_requests limit. There will always +- * be some limit enforced by BLK_BATCH_TIME. +- */ +- if (ioc_batching(q, ioc)) +- ioc->nr_batch_requests--; +- + trace_block_getrq(q, bio, rw_flags & 1); + out: + return rq; +@@ -858,7 +779,6 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags, + rq = get_request(q, rw_flags, bio, GFP_NOIO); + while (!rq) { + DEFINE_WAIT(wait); +- struct io_context *ioc; + struct request_list *rl = &q->rq; + + prepare_to_wait_exclusive(&rl->wait[is_sync], &wait, +@@ -870,15 +790,6 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags, + spin_unlock_irq(q->queue_lock); + io_schedule(); + +- /* +- * After sleeping, we become a "batching" process and +- * will be able to allocate at least one request, and +- * up to a big batch of them for a small period time. +- * See ioc_batching, ioc_set_batching +- */ +- ioc = current_io_context(GFP_NOIO, q->node); +- ioc_set_batching(q, ioc); +- + spin_lock_irq(q->queue_lock); + finish_wait(&rl->wait[is_sync], &wait); + +diff --git a/block/blk-ioc.c b/block/blk-ioc.c +index d22c4c5..49beb97 100644 +--- a/block/blk-ioc.c ++++ b/block/blk-ioc.c +@@ -92,8 +92,6 @@ struct io_context *alloc_io_context(gfp_t gfp_flags, int node) + spin_lock_init(&ret->lock); + ret->ioprio_changed = 0; + ret->ioprio = 0; +- ret->last_waited = 0; /* doesn't matter... */ +- ret->nr_batch_requests = 0; /* because this is 0 */ + INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH); + INIT_HLIST_HEAD(&ret->cic_list); + ret->ioc_data = NULL; +diff --git a/block/blk-settings.c b/block/blk-settings.c +index a234f4b..4ce5d80 100644 +--- a/block/blk-settings.c ++++ b/block/blk-settings.c +@@ -161,7 +161,6 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn) + q->make_request_fn = mfn; + blk_queue_dma_alignment(q, 511); + blk_queue_congestion_threshold(q); +- q->nr_batching = BLK_BATCH_REQ; + + q->unplug_thresh = 4; /* hmm */ + q->unplug_delay = msecs_to_jiffies(3); /* 3 milliseconds */ +diff --git a/block/blk.h b/block/blk.h +index d6b911a..709e351 100644 +--- a/block/blk.h ++++ b/block/blk.h +@@ -1,12 +1,6 @@ + #ifndef BLK_INTERNAL_H + #define BLK_INTERNAL_H + +-/* Amount of time in which a process may batch requests */ +-#define BLK_BATCH_TIME (HZ/50UL) +- +-/* Number of requests a "batching" process may submit */ +-#define BLK_BATCH_REQ 32 +- + extern struct kmem_cache *blk_requestq_cachep; + extern struct kobj_type blk_queue_ktype; + +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index dd318ff..2ad9087 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -164,7 +164,6 @@ static noinline int run_scheduled_bios(struct btrfs_device *device) + unsigned long num_sync_run; + unsigned long batch_run = 0; + unsigned long limit; +- unsigned long last_waited = 0; + int force_reg = 0; + + bdi = blk_get_backing_dev_info(device->bdev); +@@ -279,39 +278,6 @@ loop_lock: + */ + if (pending && bdi_write_congested(bdi) && batch_run > 8 && + fs_info->fs_devices->open_devices > 1) { +- struct io_context *ioc; +- +- ioc = current->io_context; +- +- /* +- * the main goal here is that we don't want to +- * block if we're going to be able to submit +- * more requests without blocking. +- * +- * This code does two great things, it pokes into +- * the elevator code from a filesystem _and_ +- * it makes assumptions about how batching works. +- */ +- if (ioc && ioc->nr_batch_requests > 0 && +- time_before(jiffies, ioc->last_waited + HZ/50UL) && +- (last_waited == 0 || +- ioc->last_waited == last_waited)) { +- /* +- * we want to go through our batch of +- * requests and stop. So, we copy out +- * the ioc->last_waited time and test +- * against it before looping +- */ +- last_waited = ioc->last_waited; +- if (need_resched()) { +- if (num_sync_run) { +- blk_run_backing_dev(bdi, NULL); +- num_sync_run = 0; +- } +- cond_resched(); +- } +- continue; +- } + spin_lock(&device->io_lock); + requeue_list(pending_bios, pending, tail); + device->running_pending = 1; +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index 2c54906..2fc7917 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -326,7 +326,6 @@ struct request_queue + unsigned long nr_requests; /* Max # of requests */ + unsigned int nr_congestion_on; + unsigned int nr_congestion_off; +- unsigned int nr_batching; + + void *dma_drain_buffer; + unsigned int dma_drain_size; +diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h +index 64d5291..e8c9165 100644 +--- a/include/linux/iocontext.h ++++ b/include/linux/iocontext.h +@@ -45,12 +45,6 @@ struct io_context { + unsigned short cgroup_changed; + #endif + +- /* +- * For request batching +- */ +- int nr_batch_requests; /* Number of requests left in the batch */ +- unsigned long last_waited; /* Time last woken after wait for request */ +- + struct radix_tree_root radix_root; + struct hlist_head cic_list; + void *ioc_data; +-- +1.7.1.426.gb436 + +EOF + ;; + 76241c12f6a730241b9fa6a795dff55f826ce391) + cat <rq; + +- if (unlikely(rl->rq_pool)) ++ if (unlikely(rl->rq_pool[0])) + return 0; + + rl->count[BLK_RW_SYNC] = rl->count[BLK_RW_ASYNC] = 0; +@@ -476,11 +476,17 @@ static int blk_init_free_list(struct request_queue *q) + init_waitqueue_head(&rl->wait[BLK_RW_SYNC]); + init_waitqueue_head(&rl->wait[BLK_RW_ASYNC]); + +- rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, ++ rl->rq_pool[0] = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, + mempool_free_slab, request_cachep, q->node); ++ if (!rl->rq_pool[0]) ++ return -ENOMEM; + +- if (!rl->rq_pool) ++ rl->rq_pool[1] = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, ++ mempool_free_slab, request_cachep, q->node); ++ if (!rl->rq_pool[1]) { ++ mempool_destroy(rl->rq_pool[0]); + return -ENOMEM; ++ } + + return 0; + } +@@ -644,16 +650,21 @@ int blk_get_queue(struct request_queue *q) + + static inline void blk_free_request(struct request_queue *q, struct request *rq) + { ++ const bool is_sync = rq_is_sync(rq) != 0; ++ + if (rq->cmd_flags & REQ_ELVPRIV) + elv_put_request(q, rq); +- mempool_free(rq, q->rq.rq_pool); ++ ++ mempool_free(rq, q->rq.rq_pool[is_sync]); + } + + static struct request * + blk_alloc_request(struct request_queue *q, int flags, int priv, gfp_t gfp_mask) + { +- struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask); ++ const bool is_sync = rw_is_sync(flags) != 0; ++ struct request *rq; + ++ rq = mempool_alloc(q->rq.rq_pool[is_sync], gfp_mask); + if (!rq) + return NULL; + +@@ -663,7 +674,7 @@ blk_alloc_request(struct request_queue *q, int flags, int priv, gfp_t gfp_mask) + + if (priv) { + if (unlikely(elv_set_request(q, rq, gfp_mask))) { +- mempool_free(rq, q->rq.rq_pool); ++ mempool_free(rq, q->rq.rq_pool[is_sync]); + return NULL; + } + rq->cmd_flags |= REQ_ELVPRIV; +diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c +index 0749b89..ee44ce5 100644 +--- a/block/blk-sysfs.c ++++ b/block/blk-sysfs.c +@@ -460,8 +460,10 @@ static void blk_release_queue(struct kobject *kobj) + + blk_sync_queue(q); + +- if (rl->rq_pool) +- mempool_destroy(rl->rq_pool); ++ if (rl->rq_pool[0]) ++ mempool_destroy(rl->rq_pool[0]); ++ if (rl->rq_pool[1]) ++ mempool_destroy(rl->rq_pool[1]); + + if (q->queue_tags) + __blk_queue_free_tags(q); +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index 2fc7917..858235d 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -45,7 +45,7 @@ struct request_list { + int count[2]; + int starved[2]; + int elvpriv; +- mempool_t *rq_pool; ++ mempool_t *rq_pool[2]; + wait_queue_head_t wait[2]; + }; + +-- +1.7.1.426.gb436 + +EOF + ;; + 35f2046ac858ca165a8aba477c9236e53a8dbffa) + cat <count[BLK_RW_SYNC] = rl->count[BLK_RW_ASYNC] = 0; +- rl->starved[BLK_RW_SYNC] = rl->starved[BLK_RW_ASYNC] = 0; + rl->elvpriv = 0; + init_waitqueue_head(&rl->wait[BLK_RW_SYNC]); + init_waitqueue_head(&rl->wait[BLK_RW_ASYNC]); +@@ -711,9 +710,6 @@ static void freed_request(struct request_queue *q, int sync, int priv) + rl->elvpriv--; + + __freed_request(q, sync); +- +- if (unlikely(rl->starved[sync ^ 1])) +- __freed_request(q, sync ^ 1); + } + + /* +@@ -731,10 +727,9 @@ static struct request *get_request(struct request_queue *q, int rw_flags, + + may_queue = elv_may_queue(q, rw_flags); + if (may_queue == ELV_MQUEUE_NO) +- goto rq_starved; ++ goto out; + + rl->count[is_sync]++; +- rl->starved[is_sync] = 0; + + priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags); + if (priv) +@@ -755,18 +750,6 @@ static struct request *get_request(struct request_queue *q, int rw_flags, + */ + spin_lock_irq(q->queue_lock); + freed_request(q, is_sync, priv); +- +- /* +- * in the very unlikely event that allocation failed and no +- * requests for this direction was pending, mark us starved +- * so that freeing of a request in the other direction will +- * notice us. another possible fix would be to split the +- * rq mempool into READ and WRITE +- */ +-rq_starved: +- if (unlikely(rl->count[is_sync] == 0)) +- rl->starved[is_sync] = 1; +- + goto out; + } + +diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h +index 858235d..089b8a2 100644 +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -39,11 +39,10 @@ typedef void (rq_end_io_fn)(struct request *, int); + + struct request_list { + /* +- * count[], starved[], and wait[] are indexed by ++ * count[], and wait[] are indexed by + * BLK_RW_SYNC/BLK_RW_ASYNC + */ + int count[2]; +- int starved[2]; + int elvpriv; + mempool_t *rq_pool[2]; + wait_queue_head_t wait[2]; +-- +1.7.1.426.gb436 + +EOF + ;; + 38bb177765247024dad4b70a2abe0044d0574998) + cat <rq; + const bool is_sync = rw_is_sync(rw_flags) != 0; ++ const bool drop_lock = (gfp_mask & __GFP_WAIT) != 0; + int may_queue, priv; + + may_queue = elv_may_queue(q, rw_flags); +@@ -737,7 +736,9 @@ static struct request *get_request(struct request_queue *q, int rw_flags, + + if (blk_queue_io_stat(q)) + rw_flags |= REQ_IO_STAT; +- spin_unlock_irq(q->queue_lock); ++ ++ if (drop_lock) ++ spin_unlock_irq(q->queue_lock); + + rq = blk_alloc_request(q, rw_flags, priv, gfp_mask); + if (unlikely(!rq)) { +@@ -748,12 +749,17 @@ static struct request *get_request(struct request_queue *q, int rw_flags, + * Allocating task should really be put onto the front of the + * wait queue, but this is pretty rare. + */ +- spin_lock_irq(q->queue_lock); ++ if (drop_lock) ++ spin_lock_irq(q->queue_lock); ++ + freed_request(q, is_sync, priv); + goto out; + } + + trace_block_getrq(q, bio, rw_flags & 1); ++ ++ if (drop_lock) ++ spin_lock_irq(q->queue_lock); + out: + return rq; + } +@@ -762,7 +768,7 @@ out: + * No available requests for this queue, unplug the device and wait for some + * requests to become available. + * +- * Called with q->queue_lock held, and returns with it unlocked. ++ * Called with q->queue_lock held. + */ + static struct request *get_request_wait(struct request_queue *q, int rw_flags, + struct bio *bio) +@@ -770,7 +776,7 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags, + const bool is_sync = rw_is_sync(rw_flags) != 0; + struct request *rq; + +- rq = get_request(q, rw_flags, bio, GFP_NOIO); ++ rq = get_request(q, rw_flags, bio, GFP_ATOMIC); + while (!rq) { + DEFINE_WAIT(wait); + struct request_list *rl = &q->rq; +@@ -800,15 +806,13 @@ struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask) + BUG_ON(rw != READ && rw != WRITE); + + spin_lock_irq(q->queue_lock); +- if (gfp_mask & __GFP_WAIT) { ++ ++ if (gfp_mask & __GFP_WAIT) + rq = get_request_wait(q, rw, NULL); +- } else { ++ else + rq = get_request(q, rw, NULL, gfp_mask); +- if (!rq) +- spin_unlock_irq(q->queue_lock); +- } +- /* q->queue_lock is unlocked at this point */ + ++ spin_unlock_irq(q->queue_lock); + return rq; + } + EXPORT_SYMBOL(blk_get_request); +@@ -1200,8 +1204,7 @@ get_rq: + rw_flags |= REQ_SYNC; + + /* +- * Grab a free request. This is might sleep but can not fail. +- * Returns with the queue unlocked. ++ * Grab a free request. + */ + req = get_request_wait(q, rw_flags, bio); + +@@ -1213,7 +1216,6 @@ get_rq: + */ + init_request_from_bio(req, bio); + +- spin_lock_irq(q->queue_lock); + if (test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags) || + bio_flagged(bio, BIO_CPU_AFFINE)) + req->cpu = blk_cpu_to_group(smp_processor_id()); +diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c +index f65c6f0..3d8635d 100644 +--- a/block/cfq-iosched.c ++++ b/block/cfq-iosched.c +@@ -2543,12 +2543,12 @@ static void cfq_put_queue(struct cfq_queue *cfqq) + cfq_put_cfqg(orig_cfqg); + } + ++typedef void (cic_call_fn)(struct io_context *, struct cfq_io_context *); ++ + /* + * Must always be called with the rcu_read_lock() held + */ +-static void +-__call_for_each_cic(struct io_context *ioc, +- void (*func)(struct io_context *, struct cfq_io_context *)) ++static void __call_for_each_cic(struct io_context *ioc, cic_call_fn *func) + { + struct cfq_io_context *cic; + struct hlist_node *n; +@@ -2560,9 +2560,7 @@ __call_for_each_cic(struct io_context *ioc, + /* + * Call func for each cic attached to this ioc. + */ +-static void +-call_for_each_cic(struct io_context *ioc, +- void (*func)(struct io_context *, struct cfq_io_context *)) ++static void call_for_each_cic(struct io_context *ioc, cic_call_fn *func) + { + rcu_read_lock(); + __call_for_each_cic(ioc, func); +@@ -2787,13 +2785,10 @@ static void changed_ioprio(struct io_context *ioc, struct cfq_io_context *cic) + { + struct cfq_data *cfqd = cic_to_cfqd(cic); + struct cfq_queue *cfqq; +- unsigned long flags; + + if (unlikely(!cfqd)) + return; + +- spin_lock_irqsave(cfqd->queue->queue_lock, flags); +- + cfqq = cic->cfqq[BLK_RW_ASYNC]; + if (cfqq) { + struct cfq_queue *new_cfqq; +@@ -2808,8 +2803,6 @@ static void changed_ioprio(struct io_context *ioc, struct cfq_io_context *cic) + cfqq = cic->cfqq[BLK_RW_SYNC]; + if (cfqq) + cfq_mark_cfqq_prio_changed(cfqq); +- +- spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); + } + + static void cfq_ioc_set_ioprio(struct io_context *ioc) +@@ -3057,11 +3050,8 @@ static int cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, + + radix_tree_preload_end(); + +- if (!ret) { +- spin_lock_irqsave(cfqd->queue->queue_lock, flags); ++ if (!ret) + list_add(&cic->queue_list, &cfqd->cic_list); +- spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); +- } + } + + if (ret) +@@ -3081,8 +3071,6 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) + struct io_context *ioc = NULL; + struct cfq_io_context *cic; + +- might_sleep_if(gfp_mask & __GFP_WAIT); +- + ioc = get_io_context(gfp_mask, cfqd->queue->node); + if (!ioc) + return NULL; +@@ -3633,14 +3621,10 @@ cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask) + const int rw = rq_data_dir(rq); + const bool is_sync = rq_is_sync(rq); + struct cfq_queue *cfqq; +- unsigned long flags; + + might_sleep_if(gfp_mask & __GFP_WAIT); + + cic = cfq_get_io_context(cfqd, gfp_mask); +- +- spin_lock_irqsave(q->queue_lock, flags); +- + if (!cic) + goto queue_fail; + +@@ -3673,8 +3657,6 @@ new_queue: + cfqq->allocated[rw]++; + atomic_inc(&cfqq->ref); + +- spin_unlock_irqrestore(q->queue_lock, flags); +- + rq->elevator_private = cic; + rq->elevator_private2 = cfqq; + rq->elevator_private3 = cfq_ref_get_cfqg(cfqq->cfqg); +@@ -3685,7 +3667,6 @@ queue_fail: + put_io_context(cic->ioc); + + cfq_schedule_dispatch(cfqd); +- spin_unlock_irqrestore(q->queue_lock, flags); + cfq_log(cfqd, "set_request fail"); + return 1; + } +-- +1.7.1.426.gb436 + +EOF + ;; + *) + echo ERROR + ;; + esac +} + + # Argument processing if [ $# != 1 ]; then @@ -761,10 +2310,7 @@ if [ "${kernel_version}" "<" "2.6.36" ]; then 89de74866b846cc48780fda3de7fd223296aaca9 do echo "Applying patch $commit ..." - url="http://git.kernel.org/?p=linux/kernel/git/roland/infiniband.git;a=patch;h=$commit" - wget -O- -q "$url" | \ - awk 'BEGIN{h=1}h==0{print}/^diff /{h=0}' | \ - patch -p1 -s + get_2_6_36_patch $commit | patch -p1 -s done fi # IB/srp: Preparation for transmit ring response allocation @@ -780,8 +2326,7 @@ for p in \ 143421 do echo "Applying patch $p ..." - url="https://patchwork.kernel.org/patch/$p/raw/" - wget -O- -q "$url" | patch -p1 -s + get_2_6_37_patch $p | patch -p1 -s done echo "Applying locking-per-lun patch ..." @@ -800,9 +2345,6 @@ if [ "${kernel_version}" "<" "2.6.38" ]; then 38bb177765247024dad4b70a2abe0044d0574998 do echo "Applying patch $commit ..." - url="http://git.kernel.dk/?p=linux-2.6-block.git;a=patch;h=$commit" - wget -O- -q "$url" | \ - awk 'BEGIN{h=1}h==0{print}/^diff /{h=0}' | \ - patch -p1 -s + get_block_layer_patch $commit | patch -p1 -s done fi