linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: akpm@linux-foundation.org, Denis Kirjanov <kda@linux-powerpc.org>,
	"Christoph Hellwig" <hch@lst.de>,
	"Martin K. Petersen" <martin.petersen@oracle.com>,
	"Johannes Thumshirn" <jthumshirn@suse.de>,
	"Hannes Reinecke" <hare@suse.com>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Hannes Reinecke" <hare@suse.de>
Subject: [PATCH 3.16 31/61] scsi: sg: use standard lists for sg_requests
Date: Tue, 09 Jun 2020 19:04:22 +0100	[thread overview]
Message-ID: <lsq.1591725832.998347312@decadent.org.uk> (raw)
In-Reply-To: <lsq.1591725831.850867383@decadent.org.uk>

3.16.85-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Hannes Reinecke <hare@suse.de>

commit 109bade9c625c89bb5ea753aaa1a0a97e6fbb548 upstream.

'Sg_request' is using a private list implementation; convert it to
standard lists.

Signed-off-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Tested-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 drivers/scsi/sg.c | 147 +++++++++++++++++++---------------------------
 1 file changed, 61 insertions(+), 86 deletions(-)

--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -130,7 +130,7 @@ struct sg_device;		/* forward declaratio
 struct sg_fd;
 
 typedef struct sg_request {	/* SG_MAX_QUEUE requests outstanding per file */
-	struct sg_request *nextrp;	/* NULL -> tail request (slist) */
+	struct list_head entry;	/* list entry */
 	struct sg_fd *parentfp;	/* NULL -> not in use */
 	Sg_scatter_hold data;	/* hold buffer, perhaps scatter list */
 	sg_io_hdr_t header;	/* scsi command+info, see <scsi/sg.h> */
@@ -154,7 +154,7 @@ typedef struct sg_fd {		/* holds the sta
 	int timeout;		/* defaults to SG_DEFAULT_TIMEOUT      */
 	int timeout_user;	/* defaults to SG_DEFAULT_TIMEOUT_USER */
 	Sg_scatter_hold reserve;	/* buffer held for this file descriptor */
-	Sg_request *headrp;	/* head of request slist, NULL->empty */
+	struct list_head rq_list; /* head of request list */
 	struct fasync_struct *async_qp;	/* used by asynchronous notification */
 	Sg_request req_arr[SG_MAX_QUEUE];	/* used as singly-linked list */
 	char low_dma;		/* as in parent but possibly overridden to 1 */
@@ -981,7 +981,7 @@ sg_ioctl(struct file *filp, unsigned int
 		if (!access_ok(VERIFY_WRITE, ip, sizeof (int)))
 			return -EFAULT;
 		read_lock_irqsave(&sfp->rq_list_lock, iflags);
-		for (srp = sfp->headrp; srp; srp = srp->nextrp) {
+		list_for_each_entry(srp, &sfp->rq_list, entry) {
 			if ((1 == srp->done) && (!srp->sg_io_owned)) {
 				read_unlock_irqrestore(&sfp->rq_list_lock,
 						       iflags);
@@ -994,7 +994,8 @@ sg_ioctl(struct file *filp, unsigned int
 		return 0;
 	case SG_GET_NUM_WAITING:
 		read_lock_irqsave(&sfp->rq_list_lock, iflags);
-		for (val = 0, srp = sfp->headrp; srp; srp = srp->nextrp) {
+		val = 0;
+		list_for_each_entry(srp, &sfp->rq_list, entry) {
 			if ((1 == srp->done) && (!srp->sg_io_owned))
 				++val;
 		}
@@ -1069,35 +1070,33 @@ sg_ioctl(struct file *filp, unsigned int
 			if (!rinfo)
 				return -ENOMEM;
 			read_lock_irqsave(&sfp->rq_list_lock, iflags);
-			for (srp = sfp->headrp, val = 0; val < SG_MAX_QUEUE;
-			     ++val, srp = srp ? srp->nextrp : srp) {
+			val = 0;
+			list_for_each_entry(srp, &sfp->rq_list, entry) {
+				if (val > SG_MAX_QUEUE)
+					break;
 				memset(&rinfo[val], 0, SZ_SG_REQ_INFO);
-				if (srp) {
-					rinfo[val].req_state = srp->done + 1;
-					rinfo[val].problem =
-					    srp->header.masked_status & 
-					    srp->header.host_status & 
-					    srp->header.driver_status;
-					if (srp->done)
-						rinfo[val].duration =
-							srp->header.duration;
-					else {
-						ms = jiffies_to_msecs(jiffies);
-						rinfo[val].duration =
-						    (ms > srp->header.duration) ?
-						    (ms - srp->header.duration) : 0;
-					}
-					rinfo[val].orphan = srp->orphan;
-					rinfo[val].sg_io_owned =
-							srp->sg_io_owned;
-					rinfo[val].pack_id =
-							srp->header.pack_id;
-					rinfo[val].usr_ptr =
-							srp->header.usr_ptr;
+				rinfo[val].req_state = srp->done + 1;
+				rinfo[val].problem =
+					srp->header.masked_status &
+					srp->header.host_status &
+					srp->header.driver_status;
+				if (srp->done)
+					rinfo[val].duration =
+						srp->header.duration;
+				else {
+					ms = jiffies_to_msecs(jiffies);
+					rinfo[val].duration =
+						(ms > srp->header.duration) ?
+						(ms - srp->header.duration) : 0;
 				}
+				rinfo[val].orphan = srp->orphan;
+				rinfo[val].sg_io_owned = srp->sg_io_owned;
+				rinfo[val].pack_id = srp->header.pack_id;
+				rinfo[val].usr_ptr = srp->header.usr_ptr;
+				val++;
 			}
 			read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
-			result = __copy_to_user(p, rinfo, 
+			result = __copy_to_user(p, rinfo,
 						SZ_SG_REQ_INFO * SG_MAX_QUEUE);
 			result = result ? -EFAULT : 0;
 			kfree(rinfo);
@@ -1229,7 +1228,7 @@ sg_poll(struct file *filp, poll_table *
 		return POLLERR;
 	poll_wait(filp, &sfp->read_wait, wait);
 	read_lock_irqsave(&sfp->rq_list_lock, iflags);
-	for (srp = sfp->headrp; srp; srp = srp->nextrp) {
+	list_for_each_entry(srp, &sfp->rq_list, entry) {
 		/* if any read waiting, flag it */
 		if ((0 == res) && (1 == srp->done) && (!srp->sg_io_owned))
 			res = POLLIN | POLLRDNORM;
@@ -2080,7 +2079,7 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id)
 	unsigned long iflags;
 
 	write_lock_irqsave(&sfp->rq_list_lock, iflags);
-	for (resp = sfp->headrp; resp; resp = resp->nextrp) {
+	list_for_each_entry(resp, &sfp->rq_list, entry) {
 		/* look for requests that are ready + not SG_IO owned */
 		if ((1 == resp->done) && (!resp->sg_io_owned) &&
 		    ((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
@@ -2098,70 +2097,45 @@ sg_add_request(Sg_fd * sfp)
 {
 	int k;
 	unsigned long iflags;
-	Sg_request *resp;
 	Sg_request *rp = sfp->req_arr;
 
 	write_lock_irqsave(&sfp->rq_list_lock, iflags);
-	resp = sfp->headrp;
-	if (!resp) {
-		memset(rp, 0, sizeof (Sg_request));
-		rp->parentfp = sfp;
-		resp = rp;
-		sfp->headrp = resp;
-	} else {
-		if (0 == sfp->cmd_q)
-			resp = NULL;	/* command queuing disallowed */
-		else {
-			for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) {
-				if (!rp->parentfp)
-					break;
-			}
-			if (k < SG_MAX_QUEUE) {
-				memset(rp, 0, sizeof (Sg_request));
-				rp->parentfp = sfp;
-				while (resp->nextrp)
-					resp = resp->nextrp;
-				resp->nextrp = rp;
-				resp = rp;
-			} else
-				resp = NULL;
+	if (!list_empty(&sfp->rq_list)) {
+		if (!sfp->cmd_q)
+			goto out_unlock;
+
+		for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) {
+			if (!rp->parentfp)
+				break;
 		}
+		if (k >= SG_MAX_QUEUE)
+			goto out_unlock;
 	}
-	if (resp) {
-		resp->nextrp = NULL;
-		resp->header.duration = jiffies_to_msecs(jiffies);
-	}
+	memset(rp, 0, sizeof (Sg_request));
+	rp->parentfp = sfp;
+	rp->header.duration = jiffies_to_msecs(jiffies);
+	list_add_tail(&rp->entry, &sfp->rq_list);
 	write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
-	return resp;
+	return rp;
+out_unlock:
+	write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+	return NULL;
 }
 
 /* Return of 1 for found; 0 for not found */
 static int
 sg_remove_request(Sg_fd * sfp, Sg_request * srp)
 {
-	Sg_request *prev_rp;
-	Sg_request *rp;
 	unsigned long iflags;
 	int res = 0;
 
-	if ((!sfp) || (!srp) || (!sfp->headrp))
+	if (!sfp || !srp || list_empty(&sfp->rq_list))
 		return res;
 	write_lock_irqsave(&sfp->rq_list_lock, iflags);
-	prev_rp = sfp->headrp;
-	if (srp == prev_rp) {
-		sfp->headrp = prev_rp->nextrp;
-		prev_rp->parentfp = NULL;
+	if (!list_empty(&srp->entry)) {
+		list_del(&srp->entry);
+		srp->parentfp = NULL;
 		res = 1;
-	} else {
-		while ((rp = prev_rp->nextrp)) {
-			if (srp == rp) {
-				prev_rp->nextrp = rp->nextrp;
-				rp->parentfp = NULL;
-				res = 1;
-				break;
-			}
-			prev_rp = rp;
-		}
 	}
 	write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
 	return res;
@@ -2180,7 +2154,7 @@ sg_add_sfp(Sg_device * sdp, int dev)
 
 	init_waitqueue_head(&sfp->read_wait);
 	rwlock_init(&sfp->rq_list_lock);
-
+	INIT_LIST_HEAD(&sfp->rq_list);
 	kref_init(&sfp->f_ref);
 	mutex_init(&sfp->f_mutex);
 	sfp->timeout = SG_DEFAULT_TIMEOUT;
@@ -2218,10 +2192,13 @@ sg_remove_sfp_usercontext(struct work_st
 {
 	struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work);
 	struct sg_device *sdp = sfp->parentdp;
+	Sg_request *srp;
 
 	/* Cleanup any responses which were never read(). */
-	while (sfp->headrp)
-		sg_finish_rem_req(sfp->headrp);
+	while (!list_empty(&sfp->rq_list)) {
+		srp = list_first_entry(&sfp->rq_list, Sg_request, entry);
+		sg_finish_rem_req(srp);
+	}
 
 	if (sfp->reserve.bufflen > 0) {
 		SCSI_LOG_TIMEOUT(6,
@@ -2626,7 +2603,7 @@ static int sg_proc_seq_show_devstrs(stru
 /* must be called while holding sg_index_lock */
 static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp)
 {
-	int k, m, new_interface, blen, usg;
+	int k, new_interface, blen, usg;
 	Sg_request *srp;
 	Sg_fd *fp;
 	const sg_io_hdr_t *hp;
@@ -2646,13 +2623,11 @@ static void sg_proc_debug_helper(struct
 		seq_printf(s, "   cmd_q=%d f_packid=%d k_orphan=%d closed=0\n",
 			   (int) fp->cmd_q, (int) fp->force_packid,
 			   (int) fp->keep_orphan);
-		for (m = 0, srp = fp->headrp;
-				srp != NULL;
-				++m, srp = srp->nextrp) {
+		list_for_each_entry(srp, &fp->rq_list, entry) {
 			hp = &srp->header;
 			new_interface = (hp->interface_id == '\0') ? 0 : 1;
 			if (srp->res_used) {
-				if (new_interface && 
+				if (new_interface &&
 				    (SG_FLAG_MMAP_IO & hp->flags))
 					cp = "     mmap>> ";
 				else
@@ -2683,7 +2658,7 @@ static void sg_proc_debug_helper(struct
 			seq_printf(s, "ms sgat=%d op=0x%02x\n", usg,
 				   (int) srp->data.cmd_opcode);
 		}
-		if (0 == m)
+		if (list_empty(&fp->rq_list))
 			seq_puts(s, "     No requests active\n");
 		read_unlock(&fp->rq_list_lock);
 	}


  parent reply	other threads:[~2020-06-09 18:07 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-09 18:03 [PATCH 3.16 00/61] 3.16.85-rc1 review Ben Hutchings
2020-06-09 18:03 ` [PATCH 3.16 01/61] slcan: Fix memory leak in error path Ben Hutchings
2020-06-09 18:03 ` [PATCH 3.16 02/61] can: slcan: Fix use-after-free Read in slcan_open Ben Hutchings
2020-06-09 18:03 ` [PATCH 3.16 03/61] slcan: not call free_netdev before rtnl_unlock " Ben Hutchings
2020-06-09 18:03 ` [PATCH 3.16 04/61] slip: Fix memory leak in slip_open error path Ben Hutchings
2020-06-09 18:03 ` [PATCH 3.16 05/61] slip: Fix use-after-free Read in slip_open Ben Hutchings
2020-06-09 18:03 ` [PATCH 3.16 06/61] slip: not call free_netdev before rtnl_unlock " Ben Hutchings
2020-06-09 18:03 ` [PATCH 3.16 07/61] net-sysfs: Fix reference count leak in rx|netdev_queue_add_kobject Ben Hutchings
2020-06-09 18:03 ` [PATCH 3.16 08/61] net-sysfs: fix netdev_queue_add_kobject() breakage Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 09/61] net-sysfs: Call dev_hold always in netdev_queue_add_kobject Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 10/61] net-sysfs: Call dev_hold always in rx_queue_add_kobject Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 11/61] selinux: cleanup error reporting in selinux_nlmsg_perm() Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 12/61] selinux: convert WARN_ONCE() to printk() " Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 13/61] selinux: Print 'sclass' as string when unrecognized netlink message occurs Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 14/61] selinux: rate-limit netlink message warnings in selinux_nlmsg_perm() Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 15/61] selinux: properly handle multiple messages in selinux_netlink_send() Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 16/61] drivers: usb: core: Don't disable irqs in usb_sg_wait() during URB submit Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 17/61] drivers: usb: core: Minimize irq disabling in usb_sg_cancel() Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 18/61] USB: core: Fix free-while-in-use bug in the USB S-Glibrary Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 19/61] scsi: mptfusion: Add bounds check in mptctl_hp_targetinfo() Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 20/61] scsi: mptfusion: Fix double fetch bug in ioctl Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 21/61] mwifiex: Fix possible buffer overflows in mwifiex_cmd_append_vsie_tlv() Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 22/61] mwifiex: Fix possible buffer overflows in mwifiex_ret_wmm_get_status() Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 23/61] sg: O_EXCL and other lock handling Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 24/61] sg: prevent integer overflow when converting from sectors to bytes Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 25/61] scsi: sg: Change next_cmd_len handling to mirror upstream Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 26/61] scsi: sg: protect accesses to 'reserved' page array Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 27/61] scsi: sg: reset 'res_in_use' after unlinking reserved array Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 28/61] scsi: sg: protect against races between mmap() and SG_SET_RESERVED_SIZE Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 29/61] scsi: sg: recheck MMAP_IO request length with lock held Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 30/61] scsi: sg: remove 'save_scat_len' Ben Hutchings
2020-06-09 18:04 ` Ben Hutchings [this message]
2020-06-09 18:04 ` [PATCH 3.16 32/61] scsi: sg: off by one in sg_ioctl() Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 33/61] scsi: sg: factor out sg_fill_request_table() Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 34/61] scsi: sg: fixup infoleak when using SG_GET_REQUEST_TABLE Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 35/61] scsi: sg: Re-fix off by one in sg_fill_request_table() Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 36/61] scsi: sg: disable SET_FORCE_LOW_DMA Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 37/61] scsi: sg: check for valid direction before starting the request Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 38/61] scsi: sg: close race condition in sg_remove_sfp_usercontext() Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 39/61] scsi: sg: fix SG_DXFER_FROM_DEV transfers Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 40/61] scsi: sg: fix static checker warning in sg_is_valid_dxfer Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 41/61] scsi: sg: only check for dxfer_len greater than 256M Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 42/61] scsi: sg: don't return bogus Sg_requests Ben Hutchings
2020-06-09 18:28   ` Tony Battersby
2020-06-09 19:03     ` Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 43/61] scsi: sg: fix minor memory leak in error path Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 44/61] scsi: sg: add sg_remove_request in sg_common_write Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 45/61] scsi: sg: add sg_remove_request in sg_write Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 46/61] signal: Extend exec_id to 64bits Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 47/61] USB: gadget: fix illegal array access in binding with UDC Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 48/61] ext4: Make checks for metadata_csum feature safer Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 49/61] ext4: protect journal inode's blocks using block_validity Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 50/61] ext4: unsigned int compared against zero Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 51/61] ext4: fix block validity checks for journal inodes using indirect blocks Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 52/61] ext4: don't perform block validity checks on the journal inode Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 53/61] ext4: add cond_resched() to ext4_protect_reserved_inode Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 54/61] x86/cpu: Rename cpu_data.x86_mask to cpu_data.x86_stepping Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 55/61] x86/cpu: Add a steppings field to struct x86_cpu_id Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 56/61] x86/cpu: Add 'table' argument to cpu_matches() Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 57/61] x86/speculation: Add Special Register Buffer Data Sampling (SRBDS) mitigation Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 58/61] x86/speculation: Add SRBDS vulnerability and mitigation documentation Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 59/61] x86/speculation: Add Ivy Bridge to affected list Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 60/61] random: always use batched entropy for get_random_u{32,64} Ben Hutchings
2020-06-09 18:04 ` [PATCH 3.16 61/61] fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info() Ben Hutchings
2020-06-10 19:08 ` [PATCH 3.16 00/61] 3.16.85-rc1 review Guenter Roeck
2020-06-10 21:25   ` Ben Hutchings

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=lsq.1591725832.998347312@decadent.org.uk \
    --to=ben@decadent.org.uk \
    --cc=akpm@linux-foundation.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=hare@suse.com \
    --cc=hare@suse.de \
    --cc=hch@lst.de \
    --cc=jthumshirn@suse.de \
    --cc=kda@linux-powerpc.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).