Re: [PATCH V3 10/24] aacraid: Reworked aac_command_thread

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jan 27, 2017 at 11:28:39AM -0800, Raghava Aditya Renukunta wrote:
> Reworked aac_command_thread into aac_process_events
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@xxxxxxxxxxxxx>
> Signed-off-by: Dave Carroll <David.Carroll@xxxxxxxxxxxxx>
> 
> ---

Wow, thanks for factoring this out.

> +static void aac_process_events(struct aac_dev *dev)
> +{
> +	struct hw_fib *hw_fib, *hw_newfib;
> +	struct fib *fib, *newfib;
> +	struct aac_fib_context *fibctx;
> +	unsigned long flags;
> +	spinlock_t *t_lock;
> +

	t_lock = dev->queues->queue[HostNormCmdQueue].lock;
	spin_lock_irqsave(t_lock, flags);

> +	spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);
> +	while (!list_empty(&(dev->queues->queue[HostNormCmdQueue].cmdq))) {
> +		struct list_head *entry;
> +		struct aac_aifcmd *aifcmd;
> +		u32 time_now, time_last;
> +		unsigned long flagv;
> +		unsigned int  num;
> +		struct hw_fib **hw_fib_pool, **hw_fib_p;
> +		struct fib **fib_pool, **fib_p;
> +
> +		set_current_state(TASK_RUNNING);
> +
> +		entry = dev->queues->queue[HostNormCmdQueue].cmdq.next;
> +		list_del(entry);
> +
> +
> +		t_lock = dev->queues->queue[HostNormCmdQueue].lock;
> +		spin_unlock_irqrestore(t_lock, flags);
> +
> +		fib = list_entry(entry, struct fib, fiblink);
> +		hw_fib = fib->hw_fib_va;
> +		/*
> +		 *	We will process the FIB here or pass it to a
> +		 *	worker thread that is TBD. We Really can't
> +		 *	do anything at this point since we don't have
> +		 *	anything defined for this thread to do.
> +		 */
> +		memset(fib, 0, sizeof(struct fib));
> +		fib->type = FSAFS_NTC_FIB_CONTEXT;
> +		fib->size = sizeof(struct fib);
> +		fib->hw_fib_va = hw_fib;
> +		fib->data = hw_fib->data;
> +		fib->dev = dev;
> +		/*
> +		 *	We only handle AifRequest fibs from the adapter.
> +		 */
> +
> +		aifcmd = (struct aac_aifcmd *) hw_fib->data;
> +		if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {
> +			/* Handle Driver Notify Events */
> +			aac_handle_aif(dev, fib);
> +			*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
> +			aac_fib_adapter_complete(fib, (u16)sizeof(u32));
> +			continue;
> +		}
> +		/*
> +		 * The u32 here is important and intended. We are using
> +		 * 32bit wrapping time to fit the adapter field
> +		 */
> +
> +
> +		/* Sniff events */
> +		if ((aifcmd->command ==	cpu_to_le32(AifCmdEventNotify)) ||
> +				(aifcmd->command ==
> +				cpu_to_le32(AifCmdJobProgress))) {

Parenthesis and indentation.

> +			aac_handle_aif(dev, fib);
> +		}
> +
> +		time_now = jiffies/HZ;
> +
> +		/*
> +		 * Warning: no sleep allowed while
> +		 * holding spinlock. We take the estimate
> +		 * and pre-allocate a set of fibs outside the
> +		 * lock.
> +		 */
> +		num = le32_to_cpu(dev->init->r7.adapter_fibs_size)
> +				/ sizeof(struct hw_fib); /* some extra */
> +		spin_lock_irqsave(&dev->fib_lock, flagv);
> +		entry = dev->fib_list.next;
> +		while (entry != &dev->fib_list) {
> +			entry = entry->next;
> +			++num;
> +		}
> +		spin_unlock_irqrestore(&dev->fib_lock, flagv);

Bonus points for getting the estimation of the fibs into an own function. From
the start of the comment till the spin_unlock().

> +		hw_fib_pool = kmalloc_array(num, sizeof(struct hw_fib *),
> +						GFP_KERNEL);
> +		fib_pool = kmalloc_array(num, sizeof(struct fib *),
> +						GFP_KERNEL);
> +		if (num	&& fib_pool && hw_fib_pool) {

Ditto for the following block (this would have the benefit of describing what
the block does).

> +			hw_fib_p = hw_fib_pool;
> +			fib_p = fib_pool;
> +			while (hw_fib_p < &hw_fib_pool[num]) {
> +				*(hw_fib_p) = kmalloc(sizeof(struct hw_fib),
> +						GFP_KERNEL);
> +				if (!(*(hw_fib_p++))) {
> +					--hw_fib_p;
> +					break;
> +				}
> +				*(fib_p) = kmalloc(sizeof(struct fib),
> +						GFP_KERNEL);
> +				if (!(*(fib_p++))) {
> +					kfree(*(--hw_fib_p));
> +					break;
> +				}
> +			}
> +			num = hw_fib_p - hw_fib_pool;
> +			if (!num) {
> +				kfree(fib_pool);
> +				fib_pool = NULL;
> +				kfree(hw_fib_pool);
> +				hw_fib_pool = NULL;
> +				continue;
> +			}
> +		} else {
> +			kfree(hw_fib_pool);
> +			hw_fib_pool = NULL;
> +			kfree(fib_pool);
> +			fib_pool = NULL;
> +		}

And for either everything under the fib_lock or the while loop. 

> +		spin_lock_irqsave(&dev->fib_lock, flagv);
> +		entry = dev->fib_list.next;
> +		/*
> +		 * For each Context that is on the
> +		 * fibctxList, make a copy of the
> +		 * fib, and then set the event to wake up the
> +		 * thread that is waiting for it.
> +		 */
> +		hw_fib_p = hw_fib_pool;
> +		fib_p = fib_pool;
> +		while (entry != &dev->fib_list) {
> +			/*
> +			 * Extract the fibctx
> +			 */
> +			fibctx = list_entry(entry, struct aac_fib_context,
> +					next);
> +			/*
> +			 * Check if the queue is getting
> +			 * backlogged
> +			 */
> +			if (fibctx->count > 20) {
> +				/*
> +				 * It's *not* jiffies folks,
> +				 * but jiffies / HZ so do not
> +				 * panic ...
> +				 */
> +				time_last = fibctx->jiffies;
> +				/*
> +				 * Has it been > 2 minutes
> +				 * since the last read off
> +				 * the queue?
> +				 */
> +				if ((time_now - time_last) > aif_timeout) {
> +					entry = entry->next;
> +					aac_close_fib_context(dev, fibctx);
> +					continue;
> +				}
> +			}
> +			/*
> +			 * Warning: no sleep allowed while
> +			 * holding spinlock
> +			 */
> +			if (hw_fib_p < &hw_fib_pool[num]) {
> +				hw_newfib = *hw_fib_p;
> +				*(hw_fib_p++) = NULL;
> +				newfib = *fib_p;
> +				*(fib_p++) = NULL;
> +				/*
> +				 * Make the copy of the FIB
> +				 */
> +				memcpy(hw_newfib, hw_fib,
> +					sizeof(struct hw_fib));
> +				memcpy(newfib, fib, sizeof(struct fib));
> +				newfib->hw_fib_va = hw_newfib;
> +				/*
> +				 * Put the FIB onto the
> +				 * fibctx's fibs
> +				 */
> +				list_add_tail(&newfib->fiblink,
> +					&fibctx->fib_list);
> +				fibctx->count++;
> +				/*
> +				 * Set the event to wake up the
> +				 * thread that is waiting.
> +				 */
> +				up(&fibctx->wait_sem);
> +			} else {
> +				pr_warn("aifd: didn't allocate NewFib.\n");
> +			}
> +			entry = entry->next;
> +		}
> +		/*
> +		 *	Set the status of this FIB
> +		 */
> +		*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
> +		aac_fib_adapter_complete(fib, sizeof(u32));
> +		spin_unlock_irqrestore(&dev->fib_lock, flagv);
> +		/* Free up the remaining resources */
> +		hw_fib_p = hw_fib_pool;
> +		fib_p = fib_pool;
> +		while (hw_fib_p < &hw_fib_pool[num]) {
> +			kfree(*hw_fib_p);
> +			kfree(*fib_p);
> +			++fib_p;
> +			++hw_fib_p;
> +		}
> +		kfree(hw_fib_pool);
> +		kfree(fib_pool);
> +		kfree(fib);
> +		spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock,
> +				flags);
> +	}
> +	/*
> +	 *	There are no more AIF's
> +	 */
> +	spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock,
> +			flags);
> +}

[...]

Thanks, 
this change is highly appreciated by me

	Johannes

-- 
Johannes Thumshirn                                          Storage
jthumshirn@xxxxxxx                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux