From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Cyrus-Session-Id: sloti22d1t05-2820460-1526400135-2-14876721249558503473 X-Sieve: CMU Sieve 3.0 X-Spam-known-sender: no X-Spam-score: 0.0 X-Spam-hits: BAYES_00 -1.9, HEADER_FROM_DIFFERENT_DOMAINS 0.249, MAILING_LIST_MULTI -1, RCVD_IN_DNSWL_HI -5, LANGUAGES unknown, BAYES_USED global, SA_VERSION 3.4.0 X-Spam-source: IP='209.132.180.67', Host='vger.kernel.org', Country='US', FromHeader='org', MailFrom='org' X-Spam-charsets: X-Resolved-to: greg@kroah.com X-Delivered-to: greg@kroah.com X-Mail-from: linux-usb-owner@vger.kernel.org ARC-Seal: i=1; a=rsa-sha256; cv=none; d=messagingengine.com; s=fm2; t= 1526400134; b=XcAMjp1QJkNJ3WrKXxGzxrfyhfWGAFWB44g6lklesl9gENXyzB 79l7xY9WCJEZaNkL9fc3wpjwlWQwtwvqEXmNzn1NPYX4F+bruBUlu9dS9MkKinA4 C6I52LEf6zcieveJwEkYoAKGSfnPdvWJinQZ4tEvICHgANsJmYh/fcl2AxS9X8go 7grc7ocfS7koTRUsfln5Nr0AUOlctm41Q2FNfew+znMYcMC8ihM47PePTOmO3Fmm CF8ypOQWfVh+5RkWCZ3JBOOPtbGwtDBsjzuD6nMkBfy1EaBcNGzk0YTzs2pmUWyN Xg5wGqD4WqAgqpiywNMS+bZi08HfO7iaa6GQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=from:to:cc:subject:date:message-id :in-reply-to:references:sender:list-id; s=fm2; t=1526400134; bh= gWTbk4CSBCthT2KVu6BQp1svlXksOdjrQAm6rZ480lY=; b=de4tg2OR8/96c5SC BwXfq/ONZb8Ngb4WW/nUFT7qpMw1JXvIoPoDebnVUERtqhZd1Og5OVhuFmsrM8TK EZT4ngzSMz4p+2YiEV9/pxA/e+MID223WmWO2oXRCV2JO+RUPSeGIBR70S8dGwVH gnxQDtPZ7PKKkelTGiAwyTbyvJ7Y2CZ4ZhUFjQlY1yEpjH3u2f4Gu9ojjHpgMcsE htkLmUeNgmuDYx6Cx9hSVB4mXMuqC/XatHdwscchM3cDS56vlkTN6qc1L3U0pf+4 qXFvr7A0qB5eDBOSppvnZrfjKcwtjMhRuo9yd0YSDyxb7LaR6P0w3xMo/R3/COgv qzvwwA== ARC-Authentication-Results: i=1; mx2.messagingengine.com; arc=none (no signatures found); dkim=fail (message has been altered, 2048-bit rsa key sha256) header.d=infradead.org header.i=@infradead.org header.b=rE5Li5P2 x-bits=2048 x-keytype=rsa x-algorithm=sha256 x-selector=bombadil.20170209; dmarc=none (p=none,has-list-id=yes,d=none) header.from=infradead.org; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=linux-usb-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-cm=none score=0; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=infradead.org header.result=pass header_is_org_domain=yes; x-vs=clean score=-100 state=0 Authentication-Results: mx2.messagingengine.com; arc=none (no signatures found); dkim=fail (message has been altered, 2048-bit rsa key sha256) header.d=infradead.org header.i=@infradead.org header.b=rE5Li5P2 x-bits=2048 x-keytype=rsa x-algorithm=sha256 x-selector=bombadil.20170209; dmarc=none (p=none,has-list-id=yes,d=none) header.from=infradead.org; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=linux-usb-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-cm=none score=0; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=infradead.org header.result=pass header_is_org_domain=yes; x-vs=clean score=-100 state=0 X-ME-VSCategory: clean X-CM-Envelope: MS4wfAijrgtzKOaYadlR/3HAZVYm78anh7wxxR9Jv/0K3Ids1aeYZrlOy8j0NXLAWCyheKrYbOUGLekPZR4QursiLX58T2rm9l4jX4Jk4uPILY9ij1557yE9 hxE+aEy87JlW7KsTMXwg7igOtrFlXgKyaznPRr4MWE/6qmXMwmQlXC2Ex8BkC5D16WhNCAYxVwO7Z+Ax9WOqPWTxB0R4J+sn28yZiomAuEvtgBoVNiQfW2Eh X-CM-Analysis: v=2.3 cv=E8HjW5Vl c=1 sm=1 tr=0 a=UK1r566ZdBxH71SXbqIOeA==:117 a=UK1r566ZdBxH71SXbqIOeA==:17 a=VUJBJC2UJ8kA:10 a=yMhMjlubAAAA:8 a=VwQbUJbxAAAA:8 a=9lzwh7rvio9E-izmRKQA:9 a=UK6S5VkUStsS62D2:21 a=7SI9RTbED5ouPe54:21 a=x8gzFH9gYPwA:10 a=AjGcO6oz07-iQ99wixmX:22 X-ME-CMScore: 0 X-ME-CMCategory: none Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752972AbeEOQAw (ORCPT ); Tue, 15 May 2018 12:00:52 -0400 Received: from bombadil.infradead.org ([198.137.202.133]:55476 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752539AbeEOQAt (ORCPT ); Tue, 15 May 2018 12:00:49 -0400 From: Matthew Wilcox To: linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org, target-devel@vger.kernel.org, linux1394-devel@lists.sourceforge.net, linux-usb@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, Juergen Gross , qla2xxx-upstream@qlogic.com, Kent Overstreet , Jens Axboe Cc: Matthew Wilcox Subject: [PATCH 2/2] Remove percpu_ida Date: Tue, 15 May 2018 09:00:43 -0700 Message-Id: <20180515160043.27044-3-willy@infradead.org> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180515160043.27044-1-willy@infradead.org> References: <20180515160043.27044-1-willy@infradead.org> Sender: linux-usb-owner@vger.kernel.org X-Mailing-List: linux-usb@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-Mailing-List: linux-kernel@vger.kernel.org List-ID: From: Matthew Wilcox With its one user gone, remove the library code. Signed-off-by: Matthew Wilcox --- include/linux/percpu_ida.h | 83 -------- lib/Makefile | 2 +- lib/percpu_ida.c | 391 ------------------------------------- 3 files changed, 1 insertion(+), 475 deletions(-) delete mode 100644 include/linux/percpu_ida.h delete mode 100644 lib/percpu_ida.c diff --git a/include/linux/percpu_ida.h b/include/linux/percpu_ida.h deleted file mode 100644 index 07d78e4653bc..000000000000 --- a/include/linux/percpu_ida.h +++ /dev/null @@ -1,83 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __PERCPU_IDA_H__ -#define __PERCPU_IDA_H__ - -#include -#include -#include -#include -#include -#include -#include - -struct percpu_ida_cpu; - -struct percpu_ida { - /* - * number of tags available to be allocated, as passed to - * percpu_ida_init() - */ - unsigned nr_tags; - unsigned percpu_max_size; - unsigned percpu_batch_size; - - struct percpu_ida_cpu __percpu *tag_cpu; - - /* - * Bitmap of cpus that (may) have tags on their percpu freelists: - * steal_tags() uses this to decide when to steal tags, and which cpus - * to try stealing from. - * - * It's ok for a freelist to be empty when its bit is set - steal_tags() - * will just keep looking - but the bitmap _must_ be set whenever a - * percpu freelist does have tags. - */ - cpumask_t cpus_have_tags; - - struct { - spinlock_t lock; - /* - * When we go to steal tags from another cpu (see steal_tags()), - * we want to pick a cpu at random. Cycling through them every - * time we steal is a bit easier and more or less equivalent: - */ - unsigned cpu_last_stolen; - - /* For sleeping on allocation failure */ - wait_queue_head_t wait; - - /* - * Global freelist - it's a stack where nr_free points to the - * top - */ - unsigned nr_free; - unsigned *freelist; - } ____cacheline_aligned_in_smp; -}; - -/* - * Number of tags we move between the percpu freelist and the global freelist at - * a time - */ -#define IDA_DEFAULT_PCPU_BATCH_MOVE 32U -/* Max size of percpu freelist, */ -#define IDA_DEFAULT_PCPU_SIZE ((IDA_DEFAULT_PCPU_BATCH_MOVE * 3) / 2) - -int percpu_ida_alloc(struct percpu_ida *pool, int state); -void percpu_ida_free(struct percpu_ida *pool, unsigned tag); - -void percpu_ida_destroy(struct percpu_ida *pool); -int __percpu_ida_init(struct percpu_ida *pool, unsigned long nr_tags, - unsigned long max_size, unsigned long batch_size); -static inline int percpu_ida_init(struct percpu_ida *pool, unsigned long nr_tags) -{ - return __percpu_ida_init(pool, nr_tags, IDA_DEFAULT_PCPU_SIZE, - IDA_DEFAULT_PCPU_BATCH_MOVE); -} - -typedef int (*percpu_ida_cb)(unsigned, void *); -int percpu_ida_for_each_free(struct percpu_ida *pool, percpu_ida_cb fn, - void *data); - -unsigned percpu_ida_free_tags(struct percpu_ida *pool, int cpu); -#endif /* __PERCPU_IDA_H__ */ diff --git a/lib/Makefile b/lib/Makefile index ce20696d5a92..7626dece1d27 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -39,7 +39,7 @@ obj-y += bcd.o div64.o sort.o parser.o debug_locks.o random32.o \ bust_spinlocks.o kasprintf.o bitmap.o scatterlist.o \ gcd.o lcm.o list_sort.o uuid.o flex_array.o iov_iter.o clz_ctz.o \ bsearch.o find_bit.o llist.o memweight.o kfifo.o \ - percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o \ + percpu-refcount.o rhashtable.o reciprocal_div.o \ once.o refcount.o usercopy.o errseq.o bucket_locks.o obj-$(CONFIG_STRING_SELFTEST) += test_string.o obj-y += string_helpers.o diff --git a/lib/percpu_ida.c b/lib/percpu_ida.c deleted file mode 100644 index 6016f1deb1f5..000000000000 --- a/lib/percpu_ida.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Percpu IDA library - * - * Copyright (C) 2013 Datera, Inc. Kent Overstreet - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct percpu_ida_cpu { - /* - * Even though this is percpu, we need a lock for tag stealing by remote - * CPUs: - */ - spinlock_t lock; - - /* nr_free/freelist form a stack of free IDs */ - unsigned nr_free; - unsigned freelist[]; -}; - -static inline void move_tags(unsigned *dst, unsigned *dst_nr, - unsigned *src, unsigned *src_nr, - unsigned nr) -{ - *src_nr -= nr; - memcpy(dst + *dst_nr, src + *src_nr, sizeof(unsigned) * nr); - *dst_nr += nr; -} - -/* - * Try to steal tags from a remote cpu's percpu freelist. - * - * We first check how many percpu freelists have tags - * - * Then we iterate through the cpus until we find some tags - we don't attempt - * to find the "best" cpu to steal from, to keep cacheline bouncing to a - * minimum. - */ -static inline void steal_tags(struct percpu_ida *pool, - struct percpu_ida_cpu *tags) -{ - unsigned cpus_have_tags, cpu = pool->cpu_last_stolen; - struct percpu_ida_cpu *remote; - - for (cpus_have_tags = cpumask_weight(&pool->cpus_have_tags); - cpus_have_tags; cpus_have_tags--) { - cpu = cpumask_next(cpu, &pool->cpus_have_tags); - - if (cpu >= nr_cpu_ids) { - cpu = cpumask_first(&pool->cpus_have_tags); - if (cpu >= nr_cpu_ids) - BUG(); - } - - pool->cpu_last_stolen = cpu; - remote = per_cpu_ptr(pool->tag_cpu, cpu); - - cpumask_clear_cpu(cpu, &pool->cpus_have_tags); - - if (remote == tags) - continue; - - spin_lock(&remote->lock); - - if (remote->nr_free) { - memcpy(tags->freelist, - remote->freelist, - sizeof(unsigned) * remote->nr_free); - - tags->nr_free = remote->nr_free; - remote->nr_free = 0; - } - - spin_unlock(&remote->lock); - - if (tags->nr_free) - break; - } -} - -/* - * Pop up to IDA_PCPU_BATCH_MOVE IDs off the global freelist, and push them onto - * our percpu freelist: - */ -static inline void alloc_global_tags(struct percpu_ida *pool, - struct percpu_ida_cpu *tags) -{ - move_tags(tags->freelist, &tags->nr_free, - pool->freelist, &pool->nr_free, - min(pool->nr_free, pool->percpu_batch_size)); -} - -static inline unsigned alloc_local_tag(struct percpu_ida_cpu *tags) -{ - int tag = -ENOSPC; - - spin_lock(&tags->lock); - if (tags->nr_free) - tag = tags->freelist[--tags->nr_free]; - spin_unlock(&tags->lock); - - return tag; -} - -/** - * percpu_ida_alloc - allocate a tag - * @pool: pool to allocate from - * @state: task state for prepare_to_wait - * - * Returns a tag - an integer in the range [0..nr_tags) (passed to - * tag_pool_init()), or otherwise -ENOSPC on allocation failure. - * - * Safe to be called from interrupt context (assuming it isn't passed - * TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, of course). - * - * @gfp indicates whether or not to wait until a free id is available (it's not - * used for internal memory allocations); thus if passed __GFP_RECLAIM we may sleep - * however long it takes until another thread frees an id (same semantics as a - * mempool). - * - * Will not fail if passed TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE. - */ -int percpu_ida_alloc(struct percpu_ida *pool, int state) -{ - DEFINE_WAIT(wait); - struct percpu_ida_cpu *tags; - unsigned long flags; - int tag; - - local_irq_save(flags); - tags = this_cpu_ptr(pool->tag_cpu); - - /* Fastpath */ - tag = alloc_local_tag(tags); - if (likely(tag >= 0)) { - local_irq_restore(flags); - return tag; - } - - while (1) { - spin_lock(&pool->lock); - - /* - * prepare_to_wait() must come before steal_tags(), in case - * percpu_ida_free() on another cpu flips a bit in - * cpus_have_tags - * - * global lock held and irqs disabled, don't need percpu lock - */ - if (state != TASK_RUNNING) - prepare_to_wait(&pool->wait, &wait, state); - - if (!tags->nr_free) - alloc_global_tags(pool, tags); - if (!tags->nr_free) - steal_tags(pool, tags); - - if (tags->nr_free) { - tag = tags->freelist[--tags->nr_free]; - if (tags->nr_free) - cpumask_set_cpu(smp_processor_id(), - &pool->cpus_have_tags); - } - - spin_unlock(&pool->lock); - local_irq_restore(flags); - - if (tag >= 0 || state == TASK_RUNNING) - break; - - if (signal_pending_state(state, current)) { - tag = -ERESTARTSYS; - break; - } - - schedule(); - - local_irq_save(flags); - tags = this_cpu_ptr(pool->tag_cpu); - } - if (state != TASK_RUNNING) - finish_wait(&pool->wait, &wait); - - return tag; -} -EXPORT_SYMBOL_GPL(percpu_ida_alloc); - -/** - * percpu_ida_free - free a tag - * @pool: pool @tag was allocated from - * @tag: a tag previously allocated with percpu_ida_alloc() - * - * Safe to be called from interrupt context. - */ -void percpu_ida_free(struct percpu_ida *pool, unsigned tag) -{ - struct percpu_ida_cpu *tags; - unsigned long flags; - unsigned nr_free; - - BUG_ON(tag >= pool->nr_tags); - - local_irq_save(flags); - tags = this_cpu_ptr(pool->tag_cpu); - - spin_lock(&tags->lock); - tags->freelist[tags->nr_free++] = tag; - - nr_free = tags->nr_free; - spin_unlock(&tags->lock); - - if (nr_free == 1) { - cpumask_set_cpu(smp_processor_id(), - &pool->cpus_have_tags); - wake_up(&pool->wait); - } - - if (nr_free == pool->percpu_max_size) { - spin_lock(&pool->lock); - - /* - * Global lock held and irqs disabled, don't need percpu - * lock - */ - if (tags->nr_free == pool->percpu_max_size) { - move_tags(pool->freelist, &pool->nr_free, - tags->freelist, &tags->nr_free, - pool->percpu_batch_size); - - wake_up(&pool->wait); - } - spin_unlock(&pool->lock); - } - - local_irq_restore(flags); -} -EXPORT_SYMBOL_GPL(percpu_ida_free); - -/** - * percpu_ida_destroy - release a tag pool's resources - * @pool: pool to free - * - * Frees the resources allocated by percpu_ida_init(). - */ -void percpu_ida_destroy(struct percpu_ida *pool) -{ - free_percpu(pool->tag_cpu); - free_pages((unsigned long) pool->freelist, - get_order(pool->nr_tags * sizeof(unsigned))); -} -EXPORT_SYMBOL_GPL(percpu_ida_destroy); - -/** - * percpu_ida_init - initialize a percpu tag pool - * @pool: pool to initialize - * @nr_tags: number of tags that will be available for allocation - * - * Initializes @pool so that it can be used to allocate tags - integers in the - * range [0, nr_tags). Typically, they'll be used by driver code to refer to a - * preallocated array of tag structures. - * - * Allocation is percpu, but sharding is limited by nr_tags - for best - * performance, the workload should not span more cpus than nr_tags / 128. - */ -int __percpu_ida_init(struct percpu_ida *pool, unsigned long nr_tags, - unsigned long max_size, unsigned long batch_size) -{ - unsigned i, cpu, order; - - memset(pool, 0, sizeof(*pool)); - - init_waitqueue_head(&pool->wait); - spin_lock_init(&pool->lock); - pool->nr_tags = nr_tags; - pool->percpu_max_size = max_size; - pool->percpu_batch_size = batch_size; - - /* Guard against overflow */ - if (nr_tags > (unsigned) INT_MAX + 1) { - pr_err("percpu_ida_init(): nr_tags too large\n"); - return -EINVAL; - } - - order = get_order(nr_tags * sizeof(unsigned)); - pool->freelist = (void *) __get_free_pages(GFP_KERNEL, order); - if (!pool->freelist) - return -ENOMEM; - - for (i = 0; i < nr_tags; i++) - pool->freelist[i] = i; - - pool->nr_free = nr_tags; - - pool->tag_cpu = __alloc_percpu(sizeof(struct percpu_ida_cpu) + - pool->percpu_max_size * sizeof(unsigned), - sizeof(unsigned)); - if (!pool->tag_cpu) - goto err; - - for_each_possible_cpu(cpu) - spin_lock_init(&per_cpu_ptr(pool->tag_cpu, cpu)->lock); - - return 0; -err: - percpu_ida_destroy(pool); - return -ENOMEM; -} -EXPORT_SYMBOL_GPL(__percpu_ida_init); - -/** - * percpu_ida_for_each_free - iterate free ids of a pool - * @pool: pool to iterate - * @fn: interate callback function - * @data: parameter for @fn - * - * Note, this doesn't guarantee to iterate all free ids restrictly. Some free - * ids might be missed, some might be iterated duplicated, and some might - * be iterated and not free soon. - */ -int percpu_ida_for_each_free(struct percpu_ida *pool, percpu_ida_cb fn, - void *data) -{ - unsigned long flags; - struct percpu_ida_cpu *remote; - unsigned cpu, i, err = 0; - - local_irq_save(flags); - for_each_possible_cpu(cpu) { - remote = per_cpu_ptr(pool->tag_cpu, cpu); - spin_lock(&remote->lock); - for (i = 0; i < remote->nr_free; i++) { - err = fn(remote->freelist[i], data); - if (err) - break; - } - spin_unlock(&remote->lock); - if (err) - goto out; - } - - spin_lock(&pool->lock); - for (i = 0; i < pool->nr_free; i++) { - err = fn(pool->freelist[i], data); - if (err) - break; - } - spin_unlock(&pool->lock); -out: - local_irq_restore(flags); - return err; -} -EXPORT_SYMBOL_GPL(percpu_ida_for_each_free); - -/** - * percpu_ida_free_tags - return free tags number of a specific cpu or global pool - * @pool: pool related - * @cpu: specific cpu or global pool if @cpu == nr_cpu_ids - * - * Note: this just returns a snapshot of free tags number. - */ -unsigned percpu_ida_free_tags(struct percpu_ida *pool, int cpu) -{ - struct percpu_ida_cpu *remote; - if (cpu == nr_cpu_ids) - return pool->nr_free; - remote = per_cpu_ptr(pool->tag_cpu, cpu); - return remote->nr_free; -} -EXPORT_SYMBOL_GPL(percpu_ida_free_tags); -- 2.17.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Matthew Wilcox Date: Tue, 15 May 2018 16:00:43 +0000 Subject: [PATCH 2/2] Remove percpu_ida Message-Id: <20180515160043.27044-3-willy@infradead.org> List-Id: References: <20180515160043.27044-1-willy@infradead.org> In-Reply-To: <20180515160043.27044-1-willy@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org, target-devel@vger.kernel.org, linux1394-devel@lists.sourceforge.net, linux-usb@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, Juergen Gross , qla2xxx-upstream@qlogic.com, Kent Overstreet , Jens Axboe Cc: Matthew Wilcox From: Matthew Wilcox With its one user gone, remove the library code. Signed-off-by: Matthew Wilcox --- include/linux/percpu_ida.h | 83 -------- lib/Makefile | 2 +- lib/percpu_ida.c | 391 ------------------------------------- 3 files changed, 1 insertion(+), 475 deletions(-) delete mode 100644 include/linux/percpu_ida.h delete mode 100644 lib/percpu_ida.c diff --git a/include/linux/percpu_ida.h b/include/linux/percpu_ida.h deleted file mode 100644 index 07d78e4653bc..000000000000 --- a/include/linux/percpu_ida.h +++ /dev/null @@ -1,83 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __PERCPU_IDA_H__ -#define __PERCPU_IDA_H__ - -#include -#include -#include -#include -#include -#include -#include - -struct percpu_ida_cpu; - -struct percpu_ida { - /* - * number of tags available to be allocated, as passed to - * percpu_ida_init() - */ - unsigned nr_tags; - unsigned percpu_max_size; - unsigned percpu_batch_size; - - struct percpu_ida_cpu __percpu *tag_cpu; - - /* - * Bitmap of cpus that (may) have tags on their percpu freelists: - * steal_tags() uses this to decide when to steal tags, and which cpus - * to try stealing from. - * - * It's ok for a freelist to be empty when its bit is set - steal_tags() - * will just keep looking - but the bitmap _must_ be set whenever a - * percpu freelist does have tags. - */ - cpumask_t cpus_have_tags; - - struct { - spinlock_t lock; - /* - * When we go to steal tags from another cpu (see steal_tags()), - * we want to pick a cpu at random. Cycling through them every - * time we steal is a bit easier and more or less equivalent: - */ - unsigned cpu_last_stolen; - - /* For sleeping on allocation failure */ - wait_queue_head_t wait; - - /* - * Global freelist - it's a stack where nr_free points to the - * top - */ - unsigned nr_free; - unsigned *freelist; - } ____cacheline_aligned_in_smp; -}; - -/* - * Number of tags we move between the percpu freelist and the global freelist at - * a time - */ -#define IDA_DEFAULT_PCPU_BATCH_MOVE 32U -/* Max size of percpu freelist, */ -#define IDA_DEFAULT_PCPU_SIZE ((IDA_DEFAULT_PCPU_BATCH_MOVE * 3) / 2) - -int percpu_ida_alloc(struct percpu_ida *pool, int state); -void percpu_ida_free(struct percpu_ida *pool, unsigned tag); - -void percpu_ida_destroy(struct percpu_ida *pool); -int __percpu_ida_init(struct percpu_ida *pool, unsigned long nr_tags, - unsigned long max_size, unsigned long batch_size); -static inline int percpu_ida_init(struct percpu_ida *pool, unsigned long nr_tags) -{ - return __percpu_ida_init(pool, nr_tags, IDA_DEFAULT_PCPU_SIZE, - IDA_DEFAULT_PCPU_BATCH_MOVE); -} - -typedef int (*percpu_ida_cb)(unsigned, void *); -int percpu_ida_for_each_free(struct percpu_ida *pool, percpu_ida_cb fn, - void *data); - -unsigned percpu_ida_free_tags(struct percpu_ida *pool, int cpu); -#endif /* __PERCPU_IDA_H__ */ diff --git a/lib/Makefile b/lib/Makefile index ce20696d5a92..7626dece1d27 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -39,7 +39,7 @@ obj-y += bcd.o div64.o sort.o parser.o debug_locks.o random32.o \ bust_spinlocks.o kasprintf.o bitmap.o scatterlist.o \ gcd.o lcm.o list_sort.o uuid.o flex_array.o iov_iter.o clz_ctz.o \ bsearch.o find_bit.o llist.o memweight.o kfifo.o \ - percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o \ + percpu-refcount.o rhashtable.o reciprocal_div.o \ once.o refcount.o usercopy.o errseq.o bucket_locks.o obj-$(CONFIG_STRING_SELFTEST) += test_string.o obj-y += string_helpers.o diff --git a/lib/percpu_ida.c b/lib/percpu_ida.c deleted file mode 100644 index 6016f1deb1f5..000000000000 --- a/lib/percpu_ida.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Percpu IDA library - * - * Copyright (C) 2013 Datera, Inc. Kent Overstreet - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct percpu_ida_cpu { - /* - * Even though this is percpu, we need a lock for tag stealing by remote - * CPUs: - */ - spinlock_t lock; - - /* nr_free/freelist form a stack of free IDs */ - unsigned nr_free; - unsigned freelist[]; -}; - -static inline void move_tags(unsigned *dst, unsigned *dst_nr, - unsigned *src, unsigned *src_nr, - unsigned nr) -{ - *src_nr -= nr; - memcpy(dst + *dst_nr, src + *src_nr, sizeof(unsigned) * nr); - *dst_nr += nr; -} - -/* - * Try to steal tags from a remote cpu's percpu freelist. - * - * We first check how many percpu freelists have tags - * - * Then we iterate through the cpus until we find some tags - we don't attempt - * to find the "best" cpu to steal from, to keep cacheline bouncing to a - * minimum. - */ -static inline void steal_tags(struct percpu_ida *pool, - struct percpu_ida_cpu *tags) -{ - unsigned cpus_have_tags, cpu = pool->cpu_last_stolen; - struct percpu_ida_cpu *remote; - - for (cpus_have_tags = cpumask_weight(&pool->cpus_have_tags); - cpus_have_tags; cpus_have_tags--) { - cpu = cpumask_next(cpu, &pool->cpus_have_tags); - - if (cpu >= nr_cpu_ids) { - cpu = cpumask_first(&pool->cpus_have_tags); - if (cpu >= nr_cpu_ids) - BUG(); - } - - pool->cpu_last_stolen = cpu; - remote = per_cpu_ptr(pool->tag_cpu, cpu); - - cpumask_clear_cpu(cpu, &pool->cpus_have_tags); - - if (remote = tags) - continue; - - spin_lock(&remote->lock); - - if (remote->nr_free) { - memcpy(tags->freelist, - remote->freelist, - sizeof(unsigned) * remote->nr_free); - - tags->nr_free = remote->nr_free; - remote->nr_free = 0; - } - - spin_unlock(&remote->lock); - - if (tags->nr_free) - break; - } -} - -/* - * Pop up to IDA_PCPU_BATCH_MOVE IDs off the global freelist, and push them onto - * our percpu freelist: - */ -static inline void alloc_global_tags(struct percpu_ida *pool, - struct percpu_ida_cpu *tags) -{ - move_tags(tags->freelist, &tags->nr_free, - pool->freelist, &pool->nr_free, - min(pool->nr_free, pool->percpu_batch_size)); -} - -static inline unsigned alloc_local_tag(struct percpu_ida_cpu *tags) -{ - int tag = -ENOSPC; - - spin_lock(&tags->lock); - if (tags->nr_free) - tag = tags->freelist[--tags->nr_free]; - spin_unlock(&tags->lock); - - return tag; -} - -/** - * percpu_ida_alloc - allocate a tag - * @pool: pool to allocate from - * @state: task state for prepare_to_wait - * - * Returns a tag - an integer in the range [0..nr_tags) (passed to - * tag_pool_init()), or otherwise -ENOSPC on allocation failure. - * - * Safe to be called from interrupt context (assuming it isn't passed - * TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, of course). - * - * @gfp indicates whether or not to wait until a free id is available (it's not - * used for internal memory allocations); thus if passed __GFP_RECLAIM we may sleep - * however long it takes until another thread frees an id (same semantics as a - * mempool). - * - * Will not fail if passed TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE. - */ -int percpu_ida_alloc(struct percpu_ida *pool, int state) -{ - DEFINE_WAIT(wait); - struct percpu_ida_cpu *tags; - unsigned long flags; - int tag; - - local_irq_save(flags); - tags = this_cpu_ptr(pool->tag_cpu); - - /* Fastpath */ - tag = alloc_local_tag(tags); - if (likely(tag >= 0)) { - local_irq_restore(flags); - return tag; - } - - while (1) { - spin_lock(&pool->lock); - - /* - * prepare_to_wait() must come before steal_tags(), in case - * percpu_ida_free() on another cpu flips a bit in - * cpus_have_tags - * - * global lock held and irqs disabled, don't need percpu lock - */ - if (state != TASK_RUNNING) - prepare_to_wait(&pool->wait, &wait, state); - - if (!tags->nr_free) - alloc_global_tags(pool, tags); - if (!tags->nr_free) - steal_tags(pool, tags); - - if (tags->nr_free) { - tag = tags->freelist[--tags->nr_free]; - if (tags->nr_free) - cpumask_set_cpu(smp_processor_id(), - &pool->cpus_have_tags); - } - - spin_unlock(&pool->lock); - local_irq_restore(flags); - - if (tag >= 0 || state = TASK_RUNNING) - break; - - if (signal_pending_state(state, current)) { - tag = -ERESTARTSYS; - break; - } - - schedule(); - - local_irq_save(flags); - tags = this_cpu_ptr(pool->tag_cpu); - } - if (state != TASK_RUNNING) - finish_wait(&pool->wait, &wait); - - return tag; -} -EXPORT_SYMBOL_GPL(percpu_ida_alloc); - -/** - * percpu_ida_free - free a tag - * @pool: pool @tag was allocated from - * @tag: a tag previously allocated with percpu_ida_alloc() - * - * Safe to be called from interrupt context. - */ -void percpu_ida_free(struct percpu_ida *pool, unsigned tag) -{ - struct percpu_ida_cpu *tags; - unsigned long flags; - unsigned nr_free; - - BUG_ON(tag >= pool->nr_tags); - - local_irq_save(flags); - tags = this_cpu_ptr(pool->tag_cpu); - - spin_lock(&tags->lock); - tags->freelist[tags->nr_free++] = tag; - - nr_free = tags->nr_free; - spin_unlock(&tags->lock); - - if (nr_free = 1) { - cpumask_set_cpu(smp_processor_id(), - &pool->cpus_have_tags); - wake_up(&pool->wait); - } - - if (nr_free = pool->percpu_max_size) { - spin_lock(&pool->lock); - - /* - * Global lock held and irqs disabled, don't need percpu - * lock - */ - if (tags->nr_free = pool->percpu_max_size) { - move_tags(pool->freelist, &pool->nr_free, - tags->freelist, &tags->nr_free, - pool->percpu_batch_size); - - wake_up(&pool->wait); - } - spin_unlock(&pool->lock); - } - - local_irq_restore(flags); -} -EXPORT_SYMBOL_GPL(percpu_ida_free); - -/** - * percpu_ida_destroy - release a tag pool's resources - * @pool: pool to free - * - * Frees the resources allocated by percpu_ida_init(). - */ -void percpu_ida_destroy(struct percpu_ida *pool) -{ - free_percpu(pool->tag_cpu); - free_pages((unsigned long) pool->freelist, - get_order(pool->nr_tags * sizeof(unsigned))); -} -EXPORT_SYMBOL_GPL(percpu_ida_destroy); - -/** - * percpu_ida_init - initialize a percpu tag pool - * @pool: pool to initialize - * @nr_tags: number of tags that will be available for allocation - * - * Initializes @pool so that it can be used to allocate tags - integers in the - * range [0, nr_tags). Typically, they'll be used by driver code to refer to a - * preallocated array of tag structures. - * - * Allocation is percpu, but sharding is limited by nr_tags - for best - * performance, the workload should not span more cpus than nr_tags / 128. - */ -int __percpu_ida_init(struct percpu_ida *pool, unsigned long nr_tags, - unsigned long max_size, unsigned long batch_size) -{ - unsigned i, cpu, order; - - memset(pool, 0, sizeof(*pool)); - - init_waitqueue_head(&pool->wait); - spin_lock_init(&pool->lock); - pool->nr_tags = nr_tags; - pool->percpu_max_size = max_size; - pool->percpu_batch_size = batch_size; - - /* Guard against overflow */ - if (nr_tags > (unsigned) INT_MAX + 1) { - pr_err("percpu_ida_init(): nr_tags too large\n"); - return -EINVAL; - } - - order = get_order(nr_tags * sizeof(unsigned)); - pool->freelist = (void *) __get_free_pages(GFP_KERNEL, order); - if (!pool->freelist) - return -ENOMEM; - - for (i = 0; i < nr_tags; i++) - pool->freelist[i] = i; - - pool->nr_free = nr_tags; - - pool->tag_cpu = __alloc_percpu(sizeof(struct percpu_ida_cpu) + - pool->percpu_max_size * sizeof(unsigned), - sizeof(unsigned)); - if (!pool->tag_cpu) - goto err; - - for_each_possible_cpu(cpu) - spin_lock_init(&per_cpu_ptr(pool->tag_cpu, cpu)->lock); - - return 0; -err: - percpu_ida_destroy(pool); - return -ENOMEM; -} -EXPORT_SYMBOL_GPL(__percpu_ida_init); - -/** - * percpu_ida_for_each_free - iterate free ids of a pool - * @pool: pool to iterate - * @fn: interate callback function - * @data: parameter for @fn - * - * Note, this doesn't guarantee to iterate all free ids restrictly. Some free - * ids might be missed, some might be iterated duplicated, and some might - * be iterated and not free soon. - */ -int percpu_ida_for_each_free(struct percpu_ida *pool, percpu_ida_cb fn, - void *data) -{ - unsigned long flags; - struct percpu_ida_cpu *remote; - unsigned cpu, i, err = 0; - - local_irq_save(flags); - for_each_possible_cpu(cpu) { - remote = per_cpu_ptr(pool->tag_cpu, cpu); - spin_lock(&remote->lock); - for (i = 0; i < remote->nr_free; i++) { - err = fn(remote->freelist[i], data); - if (err) - break; - } - spin_unlock(&remote->lock); - if (err) - goto out; - } - - spin_lock(&pool->lock); - for (i = 0; i < pool->nr_free; i++) { - err = fn(pool->freelist[i], data); - if (err) - break; - } - spin_unlock(&pool->lock); -out: - local_irq_restore(flags); - return err; -} -EXPORT_SYMBOL_GPL(percpu_ida_for_each_free); - -/** - * percpu_ida_free_tags - return free tags number of a specific cpu or global pool - * @pool: pool related - * @cpu: specific cpu or global pool if @cpu = nr_cpu_ids - * - * Note: this just returns a snapshot of free tags number. - */ -unsigned percpu_ida_free_tags(struct percpu_ida *pool, int cpu) -{ - struct percpu_ida_cpu *remote; - if (cpu = nr_cpu_ids) - return pool->nr_free; - remote = per_cpu_ptr(pool->tag_cpu, cpu); - return remote->nr_free; -} -EXPORT_SYMBOL_GPL(percpu_ida_free_tags); -- 2.17.0 From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [2/2] Remove percpu_ida From: Matthew Wilcox Message-Id: <20180515160043.27044-3-willy@infradead.org> Date: Tue, 15 May 2018 09:00:43 -0700 To: linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org, target-devel@vger.kernel.org, linux1394-devel@lists.sourceforge.net, linux-usb@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, Juergen Gross , qla2xxx-upstream@qlogic.com, Kent Overstreet , Jens Axboe Cc: Matthew Wilcox List-ID: RnJvbTogTWF0dGhldyBXaWxjb3ggPG1hd2lsY294QG1pY3Jvc29mdC5jb20+CgpXaXRoIGl0cyBv bmUgdXNlciBnb25lLCByZW1vdmUgdGhlIGxpYnJhcnkgY29kZS4KClNpZ25lZC1vZmYtYnk6IE1h dHRoZXcgV2lsY294IDxtYXdpbGNveEBtaWNyb3NvZnQuY29tPgotLS0KIGluY2x1ZGUvbGludXgv cGVyY3B1X2lkYS5oIHwgIDgzIC0tLS0tLS0tCiBsaWIvTWFrZWZpbGUgICAgICAgICAgICAgICB8 ICAgMiArLQogbGliL3BlcmNwdV9pZGEuYyAgICAgICAgICAgfCAzOTEgLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogMyBmaWxlcyBjaGFuZ2VkLCAxIGluc2VydGlvbigrKSwg NDc1IGRlbGV0aW9ucygtKQogZGVsZXRlIG1vZGUgMTAwNjQ0IGluY2x1ZGUvbGludXgvcGVyY3B1 X2lkYS5oCiBkZWxldGUgbW9kZSAxMDA2NDQgbGliL3BlcmNwdV9pZGEuYwoKZGlmZiAtLWdpdCBh L2luY2x1ZGUvbGludXgvcGVyY3B1X2lkYS5oIGIvaW5jbHVkZS9saW51eC9wZXJjcHVfaWRhLmgK ZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA3ZDc4ZTQ2NTNiYy4uMDAwMDAwMDAwMDAw Ci0tLSBhL2luY2x1ZGUvbGludXgvcGVyY3B1X2lkYS5oCisrKyAvZGV2L251bGwKQEAgLTEsODMg KzAsMCBAQAotLyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAgKi8KLSNpZm5kZWYg X19QRVJDUFVfSURBX0hfXwotI2RlZmluZSBfX1BFUkNQVV9JREFfSF9fCi0KLSNpbmNsdWRlIDxs aW51eC90eXBlcy5oPgotI2luY2x1ZGUgPGxpbnV4L2JpdG9wcy5oPgotI2luY2x1ZGUgPGxpbnV4 L2luaXQuaD4KLSNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgotI2luY2x1ZGUgPGxpbnV4L3NwaW5s b2NrX3R5cGVzLmg+Ci0jaW5jbHVkZSA8bGludXgvd2FpdC5oPgotI2luY2x1ZGUgPGxpbnV4L2Nw dW1hc2suaD4KLQotc3RydWN0IHBlcmNwdV9pZGFfY3B1OwotCi1zdHJ1Y3QgcGVyY3B1X2lkYSB7 Ci0JLyoKLQkgKiBudW1iZXIgb2YgdGFncyBhdmFpbGFibGUgdG8gYmUgYWxsb2NhdGVkLCBhcyBw YXNzZWQgdG8KLQkgKiBwZXJjcHVfaWRhX2luaXQoKQotCSAqLwotCXVuc2lnbmVkCQkJbnJfdGFn czsKLQl1bnNpZ25lZAkJCXBlcmNwdV9tYXhfc2l6ZTsKLQl1bnNpZ25lZAkJCXBlcmNwdV9iYXRj aF9zaXplOwotCi0Jc3RydWN0IHBlcmNwdV9pZGFfY3B1IF9fcGVyY3B1CSp0YWdfY3B1OwotCi0J LyoKLQkgKiBCaXRtYXAgb2YgY3B1cyB0aGF0IChtYXkpIGhhdmUgdGFncyBvbiB0aGVpciBwZXJj cHUgZnJlZWxpc3RzOgotCSAqIHN0ZWFsX3RhZ3MoKSB1c2VzIHRoaXMgdG8gZGVjaWRlIHdoZW4g dG8gc3RlYWwgdGFncywgYW5kIHdoaWNoIGNwdXMKLQkgKiB0byB0cnkgc3RlYWxpbmcgZnJvbS4K LQkgKgotCSAqIEl0J3Mgb2sgZm9yIGEgZnJlZWxpc3QgdG8gYmUgZW1wdHkgd2hlbiBpdHMgYml0 IGlzIHNldCAtIHN0ZWFsX3RhZ3MoKQotCSAqIHdpbGwganVzdCBrZWVwIGxvb2tpbmcgLSBidXQg dGhlIGJpdG1hcCBfbXVzdF8gYmUgc2V0IHdoZW5ldmVyIGEKLQkgKiBwZXJjcHUgZnJlZWxpc3Qg ZG9lcyBoYXZlIHRhZ3MuCi0JICovCi0JY3B1bWFza190CQkJY3B1c19oYXZlX3RhZ3M7Ci0KLQlz dHJ1Y3QgewotCQlzcGlubG9ja190CQlsb2NrOwotCQkvKgotCQkgKiBXaGVuIHdlIGdvIHRvIHN0 ZWFsIHRhZ3MgZnJvbSBhbm90aGVyIGNwdSAoc2VlIHN0ZWFsX3RhZ3MoKSksCi0JCSAqIHdlIHdh bnQgdG8gcGljayBhIGNwdSBhdCByYW5kb20uIEN5Y2xpbmcgdGhyb3VnaCB0aGVtIGV2ZXJ5Ci0J CSAqIHRpbWUgd2Ugc3RlYWwgaXMgYSBiaXQgZWFzaWVyIGFuZCBtb3JlIG9yIGxlc3MgZXF1aXZh bGVudDoKLQkJICovCi0JCXVuc2lnbmVkCQljcHVfbGFzdF9zdG9sZW47Ci0KLQkJLyogRm9yIHNs ZWVwaW5nIG9uIGFsbG9jYXRpb24gZmFpbHVyZSAqLwotCQl3YWl0X3F1ZXVlX2hlYWRfdAl3YWl0 OwotCi0JCS8qCi0JCSAqIEdsb2JhbCBmcmVlbGlzdCAtIGl0J3MgYSBzdGFjayB3aGVyZSBucl9m cmVlIHBvaW50cyB0byB0aGUKLQkJICogdG9wCi0JCSAqLwotCQl1bnNpZ25lZAkJbnJfZnJlZTsK LQkJdW5zaWduZWQJCSpmcmVlbGlzdDsKLQl9IF9fX19jYWNoZWxpbmVfYWxpZ25lZF9pbl9zbXA7 Ci19OwotCi0vKgotICogTnVtYmVyIG9mIHRhZ3Mgd2UgbW92ZSBiZXR3ZWVuIHRoZSBwZXJjcHUg ZnJlZWxpc3QgYW5kIHRoZSBnbG9iYWwgZnJlZWxpc3QgYXQKLSAqIGEgdGltZQotICovCi0jZGVm aW5lIElEQV9ERUZBVUxUX1BDUFVfQkFUQ0hfTU9WRQkzMlUKLS8qIE1heCBzaXplIG9mIHBlcmNw dSBmcmVlbGlzdCwgKi8KLSNkZWZpbmUgSURBX0RFRkFVTFRfUENQVV9TSVpFCSgoSURBX0RFRkFV TFRfUENQVV9CQVRDSF9NT1ZFICogMykgLyAyKQotCi1pbnQgcGVyY3B1X2lkYV9hbGxvYyhzdHJ1 Y3QgcGVyY3B1X2lkYSAqcG9vbCwgaW50IHN0YXRlKTsKLXZvaWQgcGVyY3B1X2lkYV9mcmVlKHN0 cnVjdCBwZXJjcHVfaWRhICpwb29sLCB1bnNpZ25lZCB0YWcpOwotCi12b2lkIHBlcmNwdV9pZGFf ZGVzdHJveShzdHJ1Y3QgcGVyY3B1X2lkYSAqcG9vbCk7Ci1pbnQgX19wZXJjcHVfaWRhX2luaXQo c3RydWN0IHBlcmNwdV9pZGEgKnBvb2wsIHVuc2lnbmVkIGxvbmcgbnJfdGFncywKLQl1bnNpZ25l ZCBsb25nIG1heF9zaXplLCB1bnNpZ25lZCBsb25nIGJhdGNoX3NpemUpOwotc3RhdGljIGlubGlu ZSBpbnQgcGVyY3B1X2lkYV9pbml0KHN0cnVjdCBwZXJjcHVfaWRhICpwb29sLCB1bnNpZ25lZCBs b25nIG5yX3RhZ3MpCi17Ci0JcmV0dXJuIF9fcGVyY3B1X2lkYV9pbml0KHBvb2wsIG5yX3RhZ3Ms IElEQV9ERUZBVUxUX1BDUFVfU0laRSwKLQkJSURBX0RFRkFVTFRfUENQVV9CQVRDSF9NT1ZFKTsK LX0KLQotdHlwZWRlZiBpbnQgKCpwZXJjcHVfaWRhX2NiKSh1bnNpZ25lZCwgdm9pZCAqKTsKLWlu dCBwZXJjcHVfaWRhX2Zvcl9lYWNoX2ZyZWUoc3RydWN0IHBlcmNwdV9pZGEgKnBvb2wsIHBlcmNw dV9pZGFfY2IgZm4sCi0Jdm9pZCAqZGF0YSk7Ci0KLXVuc2lnbmVkIHBlcmNwdV9pZGFfZnJlZV90 YWdzKHN0cnVjdCBwZXJjcHVfaWRhICpwb29sLCBpbnQgY3B1KTsKLSNlbmRpZiAvKiBfX1BFUkNQ VV9JREFfSF9fICovCmRpZmYgLS1naXQgYS9saWIvTWFrZWZpbGUgYi9saWIvTWFrZWZpbGUKaW5k ZXggY2UyMDY5NmQ1YTkyLi43NjI2ZGVjZTFkMjcgMTAwNjQ0Ci0tLSBhL2xpYi9NYWtlZmlsZQor KysgYi9saWIvTWFrZWZpbGUKQEAgLTM5LDcgKzM5LDcgQEAgb2JqLXkgKz0gYmNkLm8gZGl2NjQu byBzb3J0Lm8gcGFyc2VyLm8gZGVidWdfbG9ja3MubyByYW5kb20zMi5vIFwKIAkgYnVzdF9zcGlu bG9ja3MubyBrYXNwcmludGYubyBiaXRtYXAubyBzY2F0dGVybGlzdC5vIFwKIAkgZ2NkLm8gbGNt Lm8gbGlzdF9zb3J0Lm8gdXVpZC5vIGZsZXhfYXJyYXkubyBpb3ZfaXRlci5vIGNsel9jdHoubyBc CiAJIGJzZWFyY2gubyBmaW5kX2JpdC5vIGxsaXN0Lm8gbWVtd2VpZ2h0Lm8ga2ZpZm8ubyBcCi0J IHBlcmNwdS1yZWZjb3VudC5vIHBlcmNwdV9pZGEubyByaGFzaHRhYmxlLm8gcmVjaXByb2NhbF9k aXYubyBcCisJIHBlcmNwdS1yZWZjb3VudC5vIHJoYXNodGFibGUubyByZWNpcHJvY2FsX2Rpdi5v IFwKIAkgb25jZS5vIHJlZmNvdW50Lm8gdXNlcmNvcHkubyBlcnJzZXEubyBidWNrZXRfbG9ja3Mu bwogb2JqLSQoQ09ORklHX1NUUklOR19TRUxGVEVTVCkgKz0gdGVzdF9zdHJpbmcubwogb2JqLXkg Kz0gc3RyaW5nX2hlbHBlcnMubwpkaWZmIC0tZ2l0IGEvbGliL3BlcmNwdV9pZGEuYyBiL2xpYi9w ZXJjcHVfaWRhLmMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDYwMTZmMWRlYjFmNS4u MDAwMDAwMDAwMDAwCi0tLSBhL2xpYi9wZXJjcHVfaWRhLmMKKysrIC9kZXYvbnVsbApAQCAtMSwz OTEgKzAsMCBAQAotLyoKLSAqIFBlcmNwdSBJREEgbGlicmFyeQotICoKLSAqIENvcHlyaWdodCAo QykgMjAxMyBEYXRlcmEsIEluYy4gS2VudCBPdmVyc3RyZWV0Ci0gKgotICogVGhpcyBwcm9ncmFt IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgotICogbW9k aWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2Ug YXMKLSAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIg dmVyc2lvbiAyLCBvciAoYXQKLSAqIHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KLSAq Ci0gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxs IGJlIHVzZWZ1bCwgYnV0Ci0gKiBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRo ZSBpbXBsaWVkIHdhcnJhbnR5IG9mCi0gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1Ig QSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQotICogR2VuZXJhbCBQdWJsaWMgTGlj ZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgotICovCi0KLSNpbmNsdWRlIDxsaW51eC9tbS5oPgotI2lu Y2x1ZGUgPGxpbnV4L2JpdG1hcC5oPgotI2luY2x1ZGUgPGxpbnV4L2JpdG9wcy5oPgotI2luY2x1 ZGUgPGxpbnV4L2J1Zy5oPgotI2luY2x1ZGUgPGxpbnV4L2Vyci5oPgotI2luY2x1ZGUgPGxpbnV4 L2V4cG9ydC5oPgotI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KLSNpbmNsdWRlIDxsaW51eC9rZXJu ZWwuaD4KLSNpbmNsdWRlIDxsaW51eC9wZXJjcHUuaD4KLSNpbmNsdWRlIDxsaW51eC9zY2hlZC9z aWduYWwuaD4KLSNpbmNsdWRlIDxsaW51eC9zdHJpbmcuaD4KLSNpbmNsdWRlIDxsaW51eC9zcGlu bG9jay5oPgotI2luY2x1ZGUgPGxpbnV4L3BlcmNwdV9pZGEuaD4KLQotc3RydWN0IHBlcmNwdV9p ZGFfY3B1IHsKLQkvKgotCSAqIEV2ZW4gdGhvdWdoIHRoaXMgaXMgcGVyY3B1LCB3ZSBuZWVkIGEg bG9jayBmb3IgdGFnIHN0ZWFsaW5nIGJ5IHJlbW90ZQotCSAqIENQVXM6Ci0JICovCi0Jc3Bpbmxv Y2tfdAkJCWxvY2s7Ci0KLQkvKiBucl9mcmVlL2ZyZWVsaXN0IGZvcm0gYSBzdGFjayBvZiBmcmVl IElEcyAqLwotCXVuc2lnbmVkCQkJbnJfZnJlZTsKLQl1bnNpZ25lZAkJCWZyZWVsaXN0W107Ci19 OwotCi1zdGF0aWMgaW5saW5lIHZvaWQgbW92ZV90YWdzKHVuc2lnbmVkICpkc3QsIHVuc2lnbmVk ICpkc3RfbnIsCi0JCQkgICAgIHVuc2lnbmVkICpzcmMsIHVuc2lnbmVkICpzcmNfbnIsCi0JCQkg ICAgIHVuc2lnbmVkIG5yKQotewotCSpzcmNfbnIgLT0gbnI7Ci0JbWVtY3B5KGRzdCArICpkc3Rf bnIsIHNyYyArICpzcmNfbnIsIHNpemVvZih1bnNpZ25lZCkgKiBucik7Ci0JKmRzdF9uciArPSBu cjsKLX0KLQotLyoKLSAqIFRyeSB0byBzdGVhbCB0YWdzIGZyb20gYSByZW1vdGUgY3B1J3MgcGVy Y3B1IGZyZWVsaXN0LgotICoKLSAqIFdlIGZpcnN0IGNoZWNrIGhvdyBtYW55IHBlcmNwdSBmcmVl bGlzdHMgaGF2ZSB0YWdzCi0gKgotICogVGhlbiB3ZSBpdGVyYXRlIHRocm91Z2ggdGhlIGNwdXMg dW50aWwgd2UgZmluZCBzb21lIHRhZ3MgLSB3ZSBkb24ndCBhdHRlbXB0Ci0gKiB0byBmaW5kIHRo ZSAiYmVzdCIgY3B1IHRvIHN0ZWFsIGZyb20sIHRvIGtlZXAgY2FjaGVsaW5lIGJvdW5jaW5nIHRv IGEKLSAqIG1pbmltdW0uCi0gKi8KLXN0YXRpYyBpbmxpbmUgdm9pZCBzdGVhbF90YWdzKHN0cnVj dCBwZXJjcHVfaWRhICpwb29sLAotCQkJICAgICAgc3RydWN0IHBlcmNwdV9pZGFfY3B1ICp0YWdz KQotewotCXVuc2lnbmVkIGNwdXNfaGF2ZV90YWdzLCBjcHUgPSBwb29sLT5jcHVfbGFzdF9zdG9s ZW47Ci0Jc3RydWN0IHBlcmNwdV9pZGFfY3B1ICpyZW1vdGU7Ci0KLQlmb3IgKGNwdXNfaGF2ZV90 YWdzID0gY3B1bWFza193ZWlnaHQoJnBvb2wtPmNwdXNfaGF2ZV90YWdzKTsKLQkgICAgIGNwdXNf aGF2ZV90YWdzOyBjcHVzX2hhdmVfdGFncy0tKSB7Ci0JCWNwdSA9IGNwdW1hc2tfbmV4dChjcHUs ICZwb29sLT5jcHVzX2hhdmVfdGFncyk7Ci0KLQkJaWYgKGNwdSA+PSBucl9jcHVfaWRzKSB7Ci0J CQljcHUgPSBjcHVtYXNrX2ZpcnN0KCZwb29sLT5jcHVzX2hhdmVfdGFncyk7Ci0JCQlpZiAoY3B1 ID49IG5yX2NwdV9pZHMpCi0JCQkJQlVHKCk7Ci0JCX0KLQotCQlwb29sLT5jcHVfbGFzdF9zdG9s ZW4gPSBjcHU7Ci0JCXJlbW90ZSA9IHBlcl9jcHVfcHRyKHBvb2wtPnRhZ19jcHUsIGNwdSk7Ci0K LQkJY3B1bWFza19jbGVhcl9jcHUoY3B1LCAmcG9vbC0+Y3B1c19oYXZlX3RhZ3MpOwotCi0JCWlm IChyZW1vdGUgPT0gdGFncykKLQkJCWNvbnRpbnVlOwotCi0JCXNwaW5fbG9jaygmcmVtb3RlLT5s b2NrKTsKLQotCQlpZiAocmVtb3RlLT5ucl9mcmVlKSB7Ci0JCQltZW1jcHkodGFncy0+ZnJlZWxp c3QsCi0JCQkgICAgICAgcmVtb3RlLT5mcmVlbGlzdCwKLQkJCSAgICAgICBzaXplb2YodW5zaWdu ZWQpICogcmVtb3RlLT5ucl9mcmVlKTsKLQotCQkJdGFncy0+bnJfZnJlZSA9IHJlbW90ZS0+bnJf ZnJlZTsKLQkJCXJlbW90ZS0+bnJfZnJlZSA9IDA7Ci0JCX0KLQotCQlzcGluX3VubG9jaygmcmVt b3RlLT5sb2NrKTsKLQotCQlpZiAodGFncy0+bnJfZnJlZSkKLQkJCWJyZWFrOwotCX0KLX0KLQot LyoKLSAqIFBvcCB1cCB0byBJREFfUENQVV9CQVRDSF9NT1ZFIElEcyBvZmYgdGhlIGdsb2JhbCBm cmVlbGlzdCwgYW5kIHB1c2ggdGhlbSBvbnRvCi0gKiBvdXIgcGVyY3B1IGZyZWVsaXN0OgotICov Ci1zdGF0aWMgaW5saW5lIHZvaWQgYWxsb2NfZ2xvYmFsX3RhZ3Moc3RydWN0IHBlcmNwdV9pZGEg KnBvb2wsCi0JCQkJICAgICBzdHJ1Y3QgcGVyY3B1X2lkYV9jcHUgKnRhZ3MpCi17Ci0JbW92ZV90 YWdzKHRhZ3MtPmZyZWVsaXN0LCAmdGFncy0+bnJfZnJlZSwKLQkJICBwb29sLT5mcmVlbGlzdCwg JnBvb2wtPm5yX2ZyZWUsCi0JCSAgbWluKHBvb2wtPm5yX2ZyZWUsIHBvb2wtPnBlcmNwdV9iYXRj aF9zaXplKSk7Ci19Ci0KLXN0YXRpYyBpbmxpbmUgdW5zaWduZWQgYWxsb2NfbG9jYWxfdGFnKHN0 cnVjdCBwZXJjcHVfaWRhX2NwdSAqdGFncykKLXsKLQlpbnQgdGFnID0gLUVOT1NQQzsKLQotCXNw aW5fbG9jaygmdGFncy0+bG9jayk7Ci0JaWYgKHRhZ3MtPm5yX2ZyZWUpCi0JCXRhZyA9IHRhZ3Mt PmZyZWVsaXN0Wy0tdGFncy0+bnJfZnJlZV07Ci0Jc3Bpbl91bmxvY2soJnRhZ3MtPmxvY2spOwot Ci0JcmV0dXJuIHRhZzsKLX0KLQotLyoqCi0gKiBwZXJjcHVfaWRhX2FsbG9jIC0gYWxsb2NhdGUg YSB0YWcKLSAqIEBwb29sOiBwb29sIHRvIGFsbG9jYXRlIGZyb20KLSAqIEBzdGF0ZTogdGFzayBz dGF0ZSBmb3IgcHJlcGFyZV90b193YWl0Ci0gKgotICogUmV0dXJucyBhIHRhZyAtIGFuIGludGVn ZXIgaW4gdGhlIHJhbmdlIFswLi5ucl90YWdzKSAocGFzc2VkIHRvCi0gKiB0YWdfcG9vbF9pbml0 KCkpLCBvciBvdGhlcndpc2UgLUVOT1NQQyBvbiBhbGxvY2F0aW9uIGZhaWx1cmUuCi0gKgotICog U2FmZSB0byBiZSBjYWxsZWQgZnJvbSBpbnRlcnJ1cHQgY29udGV4dCAoYXNzdW1pbmcgaXQgaXNu J3QgcGFzc2VkCi0gKiBUQVNLX1VOSU5URVJSVVBUSUJMRSB8IFRBU0tfSU5URVJSVVBUSUJMRSwg b2YgY291cnNlKS4KLSAqCi0gKiBAZ2ZwIGluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0byB3YWl0 IHVudGlsIGEgZnJlZSBpZCBpcyBhdmFpbGFibGUgKGl0J3Mgbm90Ci0gKiB1c2VkIGZvciBpbnRl cm5hbCBtZW1vcnkgYWxsb2NhdGlvbnMpOyB0aHVzIGlmIHBhc3NlZCBfX0dGUF9SRUNMQUlNIHdl IG1heSBzbGVlcAotICogaG93ZXZlciBsb25nIGl0IHRha2VzIHVudGlsIGFub3RoZXIgdGhyZWFk IGZyZWVzIGFuIGlkIChzYW1lIHNlbWFudGljcyBhcyBhCi0gKiBtZW1wb29sKS4KLSAqCi0gKiBX aWxsIG5vdCBmYWlsIGlmIHBhc3NlZCBUQVNLX1VOSU5URVJSVVBUSUJMRSB8IFRBU0tfSU5URVJS VVBUSUJMRS4KLSAqLwotaW50IHBlcmNwdV9pZGFfYWxsb2Moc3RydWN0IHBlcmNwdV9pZGEgKnBv b2wsIGludCBzdGF0ZSkKLXsKLQlERUZJTkVfV0FJVCh3YWl0KTsKLQlzdHJ1Y3QgcGVyY3B1X2lk YV9jcHUgKnRhZ3M7Ci0JdW5zaWduZWQgbG9uZyBmbGFnczsKLQlpbnQgdGFnOwotCi0JbG9jYWxf aXJxX3NhdmUoZmxhZ3MpOwotCXRhZ3MgPSB0aGlzX2NwdV9wdHIocG9vbC0+dGFnX2NwdSk7Ci0K LQkvKiBGYXN0cGF0aCAqLwotCXRhZyA9IGFsbG9jX2xvY2FsX3RhZyh0YWdzKTsKLQlpZiAobGlr ZWx5KHRhZyA+PSAwKSkgewotCQlsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7Ci0JCXJldHVybiB0 YWc7Ci0JfQotCi0Jd2hpbGUgKDEpIHsKLQkJc3Bpbl9sb2NrKCZwb29sLT5sb2NrKTsKLQotCQkv KgotCQkgKiBwcmVwYXJlX3RvX3dhaXQoKSBtdXN0IGNvbWUgYmVmb3JlIHN0ZWFsX3RhZ3MoKSwg aW4gY2FzZQotCQkgKiBwZXJjcHVfaWRhX2ZyZWUoKSBvbiBhbm90aGVyIGNwdSBmbGlwcyBhIGJp dCBpbgotCQkgKiBjcHVzX2hhdmVfdGFncwotCQkgKgotCQkgKiBnbG9iYWwgbG9jayBoZWxkIGFu ZCBpcnFzIGRpc2FibGVkLCBkb24ndCBuZWVkIHBlcmNwdSBsb2NrCi0JCSAqLwotCQlpZiAoc3Rh dGUgIT0gVEFTS19SVU5OSU5HKQotCQkJcHJlcGFyZV90b193YWl0KCZwb29sLT53YWl0LCAmd2Fp dCwgc3RhdGUpOwotCi0JCWlmICghdGFncy0+bnJfZnJlZSkKLQkJCWFsbG9jX2dsb2JhbF90YWdz KHBvb2wsIHRhZ3MpOwotCQlpZiAoIXRhZ3MtPm5yX2ZyZWUpCi0JCQlzdGVhbF90YWdzKHBvb2ws IHRhZ3MpOwotCi0JCWlmICh0YWdzLT5ucl9mcmVlKSB7Ci0JCQl0YWcgPSB0YWdzLT5mcmVlbGlz dFstLXRhZ3MtPm5yX2ZyZWVdOwotCQkJaWYgKHRhZ3MtPm5yX2ZyZWUpCi0JCQkJY3B1bWFza19z ZXRfY3B1KHNtcF9wcm9jZXNzb3JfaWQoKSwKLQkJCQkJCSZwb29sLT5jcHVzX2hhdmVfdGFncyk7 Ci0JCX0KLQotCQlzcGluX3VubG9jaygmcG9vbC0+bG9jayk7Ci0JCWxvY2FsX2lycV9yZXN0b3Jl KGZsYWdzKTsKLQotCQlpZiAodGFnID49IDAgfHwgc3RhdGUgPT0gVEFTS19SVU5OSU5HKQotCQkJ YnJlYWs7Ci0KLQkJaWYgKHNpZ25hbF9wZW5kaW5nX3N0YXRlKHN0YXRlLCBjdXJyZW50KSkgewot CQkJdGFnID0gLUVSRVNUQVJUU1lTOwotCQkJYnJlYWs7Ci0JCX0KLQotCQlzY2hlZHVsZSgpOwot Ci0JCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKLQkJdGFncyA9IHRoaXNfY3B1X3B0cihwb29sLT50 YWdfY3B1KTsKLQl9Ci0JaWYgKHN0YXRlICE9IFRBU0tfUlVOTklORykKLQkJZmluaXNoX3dhaXQo JnBvb2wtPndhaXQsICZ3YWl0KTsKLQotCXJldHVybiB0YWc7Ci19Ci1FWFBPUlRfU1lNQk9MX0dQ TChwZXJjcHVfaWRhX2FsbG9jKTsKLQotLyoqCi0gKiBwZXJjcHVfaWRhX2ZyZWUgLSBmcmVlIGEg dGFnCi0gKiBAcG9vbDogcG9vbCBAdGFnIHdhcyBhbGxvY2F0ZWQgZnJvbQotICogQHRhZzogYSB0 YWcgcHJldmlvdXNseSBhbGxvY2F0ZWQgd2l0aCBwZXJjcHVfaWRhX2FsbG9jKCkKLSAqCi0gKiBT YWZlIHRvIGJlIGNhbGxlZCBmcm9tIGludGVycnVwdCBjb250ZXh0LgotICovCi12b2lkIHBlcmNw dV9pZGFfZnJlZShzdHJ1Y3QgcGVyY3B1X2lkYSAqcG9vbCwgdW5zaWduZWQgdGFnKQotewotCXN0 cnVjdCBwZXJjcHVfaWRhX2NwdSAqdGFnczsKLQl1bnNpZ25lZCBsb25nIGZsYWdzOwotCXVuc2ln bmVkIG5yX2ZyZWU7Ci0KLQlCVUdfT04odGFnID49IHBvb2wtPm5yX3RhZ3MpOwotCi0JbG9jYWxf aXJxX3NhdmUoZmxhZ3MpOwotCXRhZ3MgPSB0aGlzX2NwdV9wdHIocG9vbC0+dGFnX2NwdSk7Ci0K LQlzcGluX2xvY2soJnRhZ3MtPmxvY2spOwotCXRhZ3MtPmZyZWVsaXN0W3RhZ3MtPm5yX2ZyZWUr K10gPSB0YWc7Ci0KLQlucl9mcmVlID0gdGFncy0+bnJfZnJlZTsKLQlzcGluX3VubG9jaygmdGFn cy0+bG9jayk7Ci0KLQlpZiAobnJfZnJlZSA9PSAxKSB7Ci0JCWNwdW1hc2tfc2V0X2NwdShzbXBf cHJvY2Vzc29yX2lkKCksCi0JCQkJJnBvb2wtPmNwdXNfaGF2ZV90YWdzKTsKLQkJd2FrZV91cCgm cG9vbC0+d2FpdCk7Ci0JfQotCi0JaWYgKG5yX2ZyZWUgPT0gcG9vbC0+cGVyY3B1X21heF9zaXpl KSB7Ci0JCXNwaW5fbG9jaygmcG9vbC0+bG9jayk7Ci0KLQkJLyoKLQkJICogR2xvYmFsIGxvY2sg aGVsZCBhbmQgaXJxcyBkaXNhYmxlZCwgZG9uJ3QgbmVlZCBwZXJjcHUKLQkJICogbG9jawotCQkg Ki8KLQkJaWYgKHRhZ3MtPm5yX2ZyZWUgPT0gcG9vbC0+cGVyY3B1X21heF9zaXplKSB7Ci0JCQlt b3ZlX3RhZ3MocG9vbC0+ZnJlZWxpc3QsICZwb29sLT5ucl9mcmVlLAotCQkJCSAgdGFncy0+ZnJl ZWxpc3QsICZ0YWdzLT5ucl9mcmVlLAotCQkJCSAgcG9vbC0+cGVyY3B1X2JhdGNoX3NpemUpOwot Ci0JCQl3YWtlX3VwKCZwb29sLT53YWl0KTsKLQkJfQotCQlzcGluX3VubG9jaygmcG9vbC0+bG9j ayk7Ci0JfQotCi0JbG9jYWxfaXJxX3Jlc3RvcmUoZmxhZ3MpOwotfQotRVhQT1JUX1NZTUJPTF9H UEwocGVyY3B1X2lkYV9mcmVlKTsKLQotLyoqCi0gKiBwZXJjcHVfaWRhX2Rlc3Ryb3kgLSByZWxl YXNlIGEgdGFnIHBvb2wncyByZXNvdXJjZXMKLSAqIEBwb29sOiBwb29sIHRvIGZyZWUKLSAqCi0g KiBGcmVlcyB0aGUgcmVzb3VyY2VzIGFsbG9jYXRlZCBieSBwZXJjcHVfaWRhX2luaXQoKS4KLSAq Lwotdm9pZCBwZXJjcHVfaWRhX2Rlc3Ryb3koc3RydWN0IHBlcmNwdV9pZGEgKnBvb2wpCi17Ci0J ZnJlZV9wZXJjcHUocG9vbC0+dGFnX2NwdSk7Ci0JZnJlZV9wYWdlcygodW5zaWduZWQgbG9uZykg cG9vbC0+ZnJlZWxpc3QsCi0JCSAgIGdldF9vcmRlcihwb29sLT5ucl90YWdzICogc2l6ZW9mKHVu c2lnbmVkKSkpOwotfQotRVhQT1JUX1NZTUJPTF9HUEwocGVyY3B1X2lkYV9kZXN0cm95KTsKLQot LyoqCi0gKiBwZXJjcHVfaWRhX2luaXQgLSBpbml0aWFsaXplIGEgcGVyY3B1IHRhZyBwb29sCi0g KiBAcG9vbDogcG9vbCB0byBpbml0aWFsaXplCi0gKiBAbnJfdGFnczogbnVtYmVyIG9mIHRhZ3Mg dGhhdCB3aWxsIGJlIGF2YWlsYWJsZSBmb3IgYWxsb2NhdGlvbgotICoKLSAqIEluaXRpYWxpemVz IEBwb29sIHNvIHRoYXQgaXQgY2FuIGJlIHVzZWQgdG8gYWxsb2NhdGUgdGFncyAtIGludGVnZXJz IGluIHRoZQotICogcmFuZ2UgWzAsIG5yX3RhZ3MpLiBUeXBpY2FsbHksIHRoZXknbGwgYmUgdXNl ZCBieSBkcml2ZXIgY29kZSB0byByZWZlciB0byBhCi0gKiBwcmVhbGxvY2F0ZWQgYXJyYXkgb2Yg dGFnIHN0cnVjdHVyZXMuCi0gKgotICogQWxsb2NhdGlvbiBpcyBwZXJjcHUsIGJ1dCBzaGFyZGlu ZyBpcyBsaW1pdGVkIGJ5IG5yX3RhZ3MgLSBmb3IgYmVzdAotICogcGVyZm9ybWFuY2UsIHRoZSB3 b3JrbG9hZCBzaG91bGQgbm90IHNwYW4gbW9yZSBjcHVzIHRoYW4gbnJfdGFncyAvIDEyOC4KLSAq LwotaW50IF9fcGVyY3B1X2lkYV9pbml0KHN0cnVjdCBwZXJjcHVfaWRhICpwb29sLCB1bnNpZ25l ZCBsb25nIG5yX3RhZ3MsCi0JdW5zaWduZWQgbG9uZyBtYXhfc2l6ZSwgdW5zaWduZWQgbG9uZyBi YXRjaF9zaXplKQotewotCXVuc2lnbmVkIGksIGNwdSwgb3JkZXI7Ci0KLQltZW1zZXQocG9vbCwg MCwgc2l6ZW9mKCpwb29sKSk7Ci0KLQlpbml0X3dhaXRxdWV1ZV9oZWFkKCZwb29sLT53YWl0KTsK LQlzcGluX2xvY2tfaW5pdCgmcG9vbC0+bG9jayk7Ci0JcG9vbC0+bnJfdGFncyA9IG5yX3RhZ3M7 Ci0JcG9vbC0+cGVyY3B1X21heF9zaXplID0gbWF4X3NpemU7Ci0JcG9vbC0+cGVyY3B1X2JhdGNo X3NpemUgPSBiYXRjaF9zaXplOwotCi0JLyogR3VhcmQgYWdhaW5zdCBvdmVyZmxvdyAqLwotCWlm IChucl90YWdzID4gKHVuc2lnbmVkKSBJTlRfTUFYICsgMSkgewotCQlwcl9lcnIoInBlcmNwdV9p ZGFfaW5pdCgpOiBucl90YWdzIHRvbyBsYXJnZVxuIik7Ci0JCXJldHVybiAtRUlOVkFMOwotCX0K LQotCW9yZGVyID0gZ2V0X29yZGVyKG5yX3RhZ3MgKiBzaXplb2YodW5zaWduZWQpKTsKLQlwb29s LT5mcmVlbGlzdCA9ICh2b2lkICopIF9fZ2V0X2ZyZWVfcGFnZXMoR0ZQX0tFUk5FTCwgb3JkZXIp OwotCWlmICghcG9vbC0+ZnJlZWxpc3QpCi0JCXJldHVybiAtRU5PTUVNOwotCi0JZm9yIChpID0g MDsgaSA8IG5yX3RhZ3M7IGkrKykKLQkJcG9vbC0+ZnJlZWxpc3RbaV0gPSBpOwotCi0JcG9vbC0+ bnJfZnJlZSA9IG5yX3RhZ3M7Ci0KLQlwb29sLT50YWdfY3B1ID0gX19hbGxvY19wZXJjcHUoc2l6 ZW9mKHN0cnVjdCBwZXJjcHVfaWRhX2NwdSkgKwotCQkJCSAgICAgICBwb29sLT5wZXJjcHVfbWF4 X3NpemUgKiBzaXplb2YodW5zaWduZWQpLAotCQkJCSAgICAgICBzaXplb2YodW5zaWduZWQpKTsK LQlpZiAoIXBvb2wtPnRhZ19jcHUpCi0JCWdvdG8gZXJyOwotCi0JZm9yX2VhY2hfcG9zc2libGVf Y3B1KGNwdSkKLQkJc3Bpbl9sb2NrX2luaXQoJnBlcl9jcHVfcHRyKHBvb2wtPnRhZ19jcHUsIGNw dSktPmxvY2spOwotCi0JcmV0dXJuIDA7Ci1lcnI6Ci0JcGVyY3B1X2lkYV9kZXN0cm95KHBvb2wp OwotCXJldHVybiAtRU5PTUVNOwotfQotRVhQT1JUX1NZTUJPTF9HUEwoX19wZXJjcHVfaWRhX2lu aXQpOwotCi0vKioKLSAqIHBlcmNwdV9pZGFfZm9yX2VhY2hfZnJlZSAtIGl0ZXJhdGUgZnJlZSBp ZHMgb2YgYSBwb29sCi0gKiBAcG9vbDogcG9vbCB0byBpdGVyYXRlCi0gKiBAZm46IGludGVyYXRl IGNhbGxiYWNrIGZ1bmN0aW9uCi0gKiBAZGF0YTogcGFyYW1ldGVyIGZvciBAZm4KLSAqCi0gKiBO b3RlLCB0aGlzIGRvZXNuJ3QgZ3VhcmFudGVlIHRvIGl0ZXJhdGUgYWxsIGZyZWUgaWRzIHJlc3Ry aWN0bHkuIFNvbWUgZnJlZQotICogaWRzIG1pZ2h0IGJlIG1pc3NlZCwgc29tZSBtaWdodCBiZSBp dGVyYXRlZCBkdXBsaWNhdGVkLCBhbmQgc29tZSBtaWdodAotICogYmUgaXRlcmF0ZWQgYW5kIG5v dCBmcmVlIHNvb24uCi0gKi8KLWludCBwZXJjcHVfaWRhX2Zvcl9lYWNoX2ZyZWUoc3RydWN0IHBl cmNwdV9pZGEgKnBvb2wsIHBlcmNwdV9pZGFfY2IgZm4sCi0Jdm9pZCAqZGF0YSkKLXsKLQl1bnNp Z25lZCBsb25nIGZsYWdzOwotCXN0cnVjdCBwZXJjcHVfaWRhX2NwdSAqcmVtb3RlOwotCXVuc2ln bmVkIGNwdSwgaSwgZXJyID0gMDsKLQotCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKLQlmb3JfZWFj aF9wb3NzaWJsZV9jcHUoY3B1KSB7Ci0JCXJlbW90ZSA9IHBlcl9jcHVfcHRyKHBvb2wtPnRhZ19j cHUsIGNwdSk7Ci0JCXNwaW5fbG9jaygmcmVtb3RlLT5sb2NrKTsKLQkJZm9yIChpID0gMDsgaSA8 IHJlbW90ZS0+bnJfZnJlZTsgaSsrKSB7Ci0JCQllcnIgPSBmbihyZW1vdGUtPmZyZWVsaXN0W2ld LCBkYXRhKTsKLQkJCWlmIChlcnIpCi0JCQkJYnJlYWs7Ci0JCX0KLQkJc3Bpbl91bmxvY2soJnJl bW90ZS0+bG9jayk7Ci0JCWlmIChlcnIpCi0JCQlnb3RvIG91dDsKLQl9Ci0KLQlzcGluX2xvY2so JnBvb2wtPmxvY2spOwotCWZvciAoaSA9IDA7IGkgPCBwb29sLT5ucl9mcmVlOyBpKyspIHsKLQkJ ZXJyID0gZm4ocG9vbC0+ZnJlZWxpc3RbaV0sIGRhdGEpOwotCQlpZiAoZXJyKQotCQkJYnJlYWs7 Ci0JfQotCXNwaW5fdW5sb2NrKCZwb29sLT5sb2NrKTsKLW91dDoKLQlsb2NhbF9pcnFfcmVzdG9y ZShmbGFncyk7Ci0JcmV0dXJuIGVycjsKLX0KLUVYUE9SVF9TWU1CT0xfR1BMKHBlcmNwdV9pZGFf Zm9yX2VhY2hfZnJlZSk7Ci0KLS8qKgotICogcGVyY3B1X2lkYV9mcmVlX3RhZ3MgLSByZXR1cm4g ZnJlZSB0YWdzIG51bWJlciBvZiBhIHNwZWNpZmljIGNwdSBvciBnbG9iYWwgcG9vbAotICogQHBv b2w6IHBvb2wgcmVsYXRlZAotICogQGNwdTogc3BlY2lmaWMgY3B1IG9yIGdsb2JhbCBwb29sIGlm IEBjcHUgPT0gbnJfY3B1X2lkcwotICoKLSAqIE5vdGU6IHRoaXMganVzdCByZXR1cm5zIGEgc25h cHNob3Qgb2YgZnJlZSB0YWdzIG51bWJlci4KLSAqLwotdW5zaWduZWQgcGVyY3B1X2lkYV9mcmVl X3RhZ3Moc3RydWN0IHBlcmNwdV9pZGEgKnBvb2wsIGludCBjcHUpCi17Ci0Jc3RydWN0IHBlcmNw dV9pZGFfY3B1ICpyZW1vdGU7Ci0JaWYgKGNwdSA9PSBucl9jcHVfaWRzKQotCQlyZXR1cm4gcG9v bC0+bnJfZnJlZTsKLQlyZW1vdGUgPSBwZXJfY3B1X3B0cihwb29sLT50YWdfY3B1LCBjcHUpOwot CXJldHVybiByZW1vdGUtPm5yX2ZyZWU7Ci19Ci1FWFBPUlRfU1lNQk9MX0dQTChwZXJjcHVfaWRh X2ZyZWVfdGFncyk7Cg==