Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1231421 > unrolled thread

[PATCH v2] storvsc: get rid of bounce buffer

Started byVitaly Kuznetsov <vkuznets@redhat.com>
First post2015-09-23 15:00 +0200
Last post2015-09-23 16:40 +0200
Articles 2 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2] storvsc: get rid of bounce buffer Vitaly Kuznetsov <vkuznets@redhat.com> - 2015-09-23 15:00 +0200
    RE: [PATCH v2] storvsc: get rid of bounce buffer KY Srinivasan <kys@microsoft.com> - 2015-09-23 16:40 +0200

#1231421 — [PATCH v2] storvsc: get rid of bounce buffer

FromVitaly Kuznetsov <vkuznets@redhat.com>
Date2015-09-23 15:00 +0200
Subject[PATCH v2] storvsc: get rid of bounce buffer
Message-ID<qbROq-4Bm-1@gated-at.bofh.it>
Storvsc driver needs to ensure there are no 'holes' in the presented
sg list (all segments in the middle of the list need to be of PAGE_SIZE).
When a hole is detected storvsc driver creates a 'bounce sgl' without
holes and copies data over with copy_{to,from}_bounce_buffer() functions.
Setting virt_boundary_mask to PAGE_SIZE - 1 guarantees we'll never see
such holes so we can significantly simplify the driver. This is also
supposed to bring us some performance improvement for certain workloads
as we eliminate copying.

Reported-by: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
Changes since v1:
- This patch is a successor of 'storvsc: get rid of homegrown
 copy_{to,from}_bounce_buffer()'. Use virt_boundary instead to
 eliminate the need for bounce buffer completely [Christoph Hellwig].
---
 drivers/scsi/storvsc_drv.c | 286 +--------------------------------------------
 1 file changed, 5 insertions(+), 281 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 40c43ae..eeade40 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -393,9 +393,6 @@ static void storvsc_on_channel_callback(void *context);
 struct storvsc_cmd_request {
 	struct scsi_cmnd *cmd;
 
-	unsigned int bounce_sgl_count;
-	struct scatterlist *bounce_sgl;
-
 	struct hv_device *device;
 
 	/* Synchronize the request/response if needed */
@@ -586,241 +583,6 @@ get_in_err:
 
 }
 
-static void destroy_bounce_buffer(struct scatterlist *sgl,
-				  unsigned int sg_count)
-{
-	int i;
-	struct page *page_buf;
-
-	for (i = 0; i < sg_count; i++) {
-		page_buf = sg_page((&sgl[i]));
-		if (page_buf != NULL)
-			__free_page(page_buf);
-	}
-
-	kfree(sgl);
-}
-
-static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count)
-{
-	int i;
-
-	/* No need to check */
-	if (sg_count < 2)
-		return -1;
-
-	/* We have at least 2 sg entries */
-	for (i = 0; i < sg_count; i++) {
-		if (i == 0) {
-			/* make sure 1st one does not have hole */
-			if (sgl[i].offset + sgl[i].length != PAGE_SIZE)
-				return i;
-		} else if (i == sg_count - 1) {
-			/* make sure last one does not have hole */
-			if (sgl[i].offset != 0)
-				return i;
-		} else {
-			/* make sure no hole in the middle */
-			if (sgl[i].length != PAGE_SIZE || sgl[i].offset != 0)
-				return i;
-		}
-	}
-	return -1;
-}
-
-static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
-						unsigned int sg_count,
-						unsigned int len,
-						int write)
-{
-	int i;
-	int num_pages;
-	struct scatterlist *bounce_sgl;
-	struct page *page_buf;
-	unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE);
-
-	num_pages = ALIGN(len, PAGE_SIZE) >> PAGE_SHIFT;
-
-	bounce_sgl = kcalloc(num_pages, sizeof(struct scatterlist), GFP_ATOMIC);
-	if (!bounce_sgl)
-		return NULL;
-
-	sg_init_table(bounce_sgl, num_pages);
-	for (i = 0; i < num_pages; i++) {
-		page_buf = alloc_page(GFP_ATOMIC);
-		if (!page_buf)
-			goto cleanup;
-		sg_set_page(&bounce_sgl[i], page_buf, buf_len, 0);
-	}
-
-	return bounce_sgl;
-
-cleanup:
-	destroy_bounce_buffer(bounce_sgl, num_pages);
-	return NULL;
-}
-
-/* Assume the original sgl has enough room */
-static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
-					    struct scatterlist *bounce_sgl,
-					    unsigned int orig_sgl_count,
-					    unsigned int bounce_sgl_count)
-{
-	int i;
-	int j = 0;
-	unsigned long src, dest;
-	unsigned int srclen, destlen, copylen;
-	unsigned int total_copied = 0;
-	unsigned long bounce_addr = 0;
-	unsigned long dest_addr = 0;
-	unsigned long flags;
-	struct scatterlist *cur_dest_sgl;
-	struct scatterlist *cur_src_sgl;
-
-	local_irq_save(flags);
-	cur_dest_sgl = orig_sgl;
-	cur_src_sgl = bounce_sgl;
-	for (i = 0; i < orig_sgl_count; i++) {
-		dest_addr = (unsigned long)
-				kmap_atomic(sg_page(cur_dest_sgl)) +
-				cur_dest_sgl->offset;
-		dest = dest_addr;
-		destlen = cur_dest_sgl->length;
-
-		if (bounce_addr == 0)
-			bounce_addr = (unsigned long)kmap_atomic(
-							sg_page(cur_src_sgl));
-
-		while (destlen) {
-			src = bounce_addr + cur_src_sgl->offset;
-			srclen = cur_src_sgl->length - cur_src_sgl->offset;
-
-			copylen = min(srclen, destlen);
-			memcpy((void *)dest, (void *)src, copylen);
-
-			total_copied += copylen;
-			cur_src_sgl->offset += copylen;
-			destlen -= copylen;
-			dest += copylen;
-
-			if (cur_src_sgl->offset == cur_src_sgl->length) {
-				/* full */
-				kunmap_atomic((void *)bounce_addr);
-				j++;
-
-				/*
-				 * It is possible that the number of elements
-				 * in the bounce buffer may not be equal to
-				 * the number of elements in the original
-				 * scatter list. Handle this correctly.
-				 */
-
-				if (j == bounce_sgl_count) {
-					/*
-					 * We are done; cleanup and return.
-					 */
-					kunmap_atomic((void *)(dest_addr -
-						cur_dest_sgl->offset));
-					local_irq_restore(flags);
-					return total_copied;
-				}
-
-				/* if we need to use another bounce buffer */
-				if (destlen || i != orig_sgl_count - 1) {
-					cur_src_sgl = sg_next(cur_src_sgl);
-					bounce_addr = (unsigned long)
-							kmap_atomic(
-							sg_page(cur_src_sgl));
-				}
-			} else if (destlen == 0 && i == orig_sgl_count - 1) {
-				/* unmap the last bounce that is < PAGE_SIZE */
-				kunmap_atomic((void *)bounce_addr);
-			}
-		}
-
-		kunmap_atomic((void *)(dest_addr - cur_dest_sgl->offset));
-		cur_dest_sgl = sg_next(cur_dest_sgl);
-	}
-
-	local_irq_restore(flags);
-
-	return total_copied;
-}
-
-/* Assume the bounce_sgl has enough room ie using the create_bounce_buffer() */
-static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
-					  struct scatterlist *bounce_sgl,
-					  unsigned int orig_sgl_count)
-{
-	int i;
-	int j = 0;
-	unsigned long src, dest;
-	unsigned int srclen, destlen, copylen;
-	unsigned int total_copied = 0;
-	unsigned long bounce_addr = 0;
-	unsigned long src_addr = 0;
-	unsigned long flags;
-	struct scatterlist *cur_src_sgl;
-	struct scatterlist *cur_dest_sgl;
-
-	local_irq_save(flags);
-
-	cur_src_sgl = orig_sgl;
-	cur_dest_sgl = bounce_sgl;
-
-	for (i = 0; i < orig_sgl_count; i++) {
-		src_addr = (unsigned long)
-				kmap_atomic(sg_page(cur_src_sgl)) +
-				cur_src_sgl->offset;
-		src = src_addr;
-		srclen = cur_src_sgl->length;
-
-		if (bounce_addr == 0)
-			bounce_addr = (unsigned long)
-					kmap_atomic(sg_page(cur_dest_sgl));
-
-		while (srclen) {
-			/* assume bounce offset always == 0 */
-			dest = bounce_addr + cur_dest_sgl->length;
-			destlen = PAGE_SIZE - cur_dest_sgl->length;
-
-			copylen = min(srclen, destlen);
-			memcpy((void *)dest, (void *)src, copylen);
-
-			total_copied += copylen;
-			cur_dest_sgl->length += copylen;
-			srclen -= copylen;
-			src += copylen;
-
-			if (cur_dest_sgl->length == PAGE_SIZE) {
-				/* full..move to next entry */
-				kunmap_atomic((void *)bounce_addr);
-				bounce_addr = 0;
-				j++;
-			}
-
-			/* if we need to use another bounce buffer */
-			if (srclen && bounce_addr == 0) {
-				cur_dest_sgl = sg_next(cur_dest_sgl);
-				bounce_addr = (unsigned long)
-						kmap_atomic(
-						sg_page(cur_dest_sgl));
-			}
-
-		}
-
-		kunmap_atomic((void *)(src_addr - cur_src_sgl->offset));
-		cur_src_sgl = sg_next(cur_src_sgl);
-	}
-
-	if (bounce_addr)
-		kunmap_atomic((void *)bounce_addr);
-
-	local_irq_restore(flags);
-
-	return total_copied;
-}
-
 static void handle_sc_creation(struct vmbus_channel *new_sc)
 {
 	struct hv_device *device = new_sc->primary_channel->device_obj;
@@ -1171,15 +933,6 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
 	host = stor_dev->host;
 
 	vm_srb = &cmd_request->vstor_packet.vm_srb;
-	if (cmd_request->bounce_sgl_count) {
-		if (vm_srb->data_in == READ_TYPE)
-			copy_from_bounce_buffer(scsi_sglist(scmnd),
-					cmd_request->bounce_sgl,
-					scsi_sg_count(scmnd),
-					cmd_request->bounce_sgl_count);
-		destroy_bounce_buffer(cmd_request->bounce_sgl,
-					cmd_request->bounce_sgl_count);
-	}
 
 	scmnd->result = vm_srb->scsi_status;
 
@@ -1474,6 +1227,9 @@ static int storvsc_device_configure(struct scsi_device *sdevice)
 
 	blk_queue_rq_timeout(sdevice->request_queue, (storvsc_timeout * HZ));
 
+	/* Ensure there are no gaps in presented sgls */
+	blk_queue_virt_boundary(sdevice->request_queue, PAGE_SIZE - 1);
+
 	sdevice->no_write_same = 1;
 
 	/*
@@ -1692,40 +1448,13 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
 	payload_sz = sizeof(cmd_request->mpb);
 
 	if (sg_count) {
-		/* check if we need to bounce the sgl */
-		if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
-			cmd_request->bounce_sgl =
-				create_bounce_buffer(sgl, sg_count,
-						     length,
-						     vm_srb->data_in);
-			if (!cmd_request->bounce_sgl)
-				return SCSI_MLQUEUE_HOST_BUSY;
-
-			cmd_request->bounce_sgl_count =
-				ALIGN(length, PAGE_SIZE) >> PAGE_SHIFT;
-
-			if (vm_srb->data_in == WRITE_TYPE)
-				copy_to_bounce_buffer(sgl,
-					cmd_request->bounce_sgl, sg_count);
-
-			sgl = cmd_request->bounce_sgl;
-			sg_count = cmd_request->bounce_sgl_count;
-		}
-
-
 		if (sg_count > MAX_PAGE_BUFFER_COUNT) {
 
 			payload_sz = (sg_count * sizeof(void *) +
 				      sizeof(struct vmbus_packet_mpb_array));
 			payload = kmalloc(payload_sz, GFP_ATOMIC);
-			if (!payload) {
-				if (cmd_request->bounce_sgl_count)
-					destroy_bounce_buffer(
-					cmd_request->bounce_sgl,
-					cmd_request->bounce_sgl_count);
-
-					return SCSI_MLQUEUE_DEVICE_BUSY;
-			}
+			if (!payload)
+				return SCSI_MLQUEUE_DEVICE_BUSY;
 		}
 
 		payload->range.len = length;
@@ -1754,11 +1483,6 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
 
 	if (ret == -EAGAIN) {
 		/* no more space */
-
-		if (cmd_request->bounce_sgl_count)
-			destroy_bounce_buffer(cmd_request->bounce_sgl,
-					cmd_request->bounce_sgl_count);
-
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1231476

FromKY Srinivasan <kys@microsoft.com>
Date2015-09-23 16:40 +0200
Message-ID<qbTnc-6Xk-13@gated-at.bofh.it>
In reply to#1231421
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogVml0YWx5IEt1em5ldHNv
diBbbWFpbHRvOnZrdXpuZXRzQHJlZGhhdC5jb21dDQo+IFNlbnQ6IFdlZG5lc2RheSwgU2VwdGVt
YmVyIDIzLCAyMDE1IDU6NTkgQU0NCj4gVG86IGxpbnV4LXNjc2lAdmdlci5rZXJuZWwub3JnDQo+
IENjOiBsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnOyBkZXZlbEBsaW51eGRyaXZlcnByb2pl
Y3Qub3JnOyBLWQ0KPiBTcmluaXZhc2FuIDxreXNAbWljcm9zb2Z0LmNvbT47IEhhaXlhbmcgWmhh
bmcNCj4gPGhhaXlhbmd6QG1pY3Jvc29mdC5jb20+OyBKYW1lcyBFLkouIEJvdHRvbWxleSA8SkJv
dHRvbWxleUBvZGluLmNvbT47DQo+IFJhZGltIEtyxI1tw6HFmSA8cmtyY21hckByZWRoYXQuY29t
PjsgQ2hyaXN0b3BoIEhlbGx3aWcNCj4gPGhjaEBpbmZyYWRlYWQub3JnPg0KPiBTdWJqZWN0OiBb
UEFUQ0ggdjJdIHN0b3J2c2M6IGdldCByaWQgb2YgYm91bmNlIGJ1ZmZlcg0KPiANCj4gU3RvcnZz
YyBkcml2ZXIgbmVlZHMgdG8gZW5zdXJlIHRoZXJlIGFyZSBubyAnaG9sZXMnIGluIHRoZSBwcmVz
ZW50ZWQNCj4gc2cgbGlzdCAoYWxsIHNlZ21lbnRzIGluIHRoZSBtaWRkbGUgb2YgdGhlIGxpc3Qg
bmVlZCB0byBiZSBvZiBQQUdFX1NJWkUpLg0KPiBXaGVuIGEgaG9sZSBpcyBkZXRlY3RlZCBzdG9y
dnNjIGRyaXZlciBjcmVhdGVzIGEgJ2JvdW5jZSBzZ2wnIHdpdGhvdXQNCj4gaG9sZXMgYW5kIGNv
cGllcyBkYXRhIG92ZXIgd2l0aCBjb3B5X3t0byxmcm9tfV9ib3VuY2VfYnVmZmVyKCkgZnVuY3Rp
b25zLg0KPiBTZXR0aW5nIHZpcnRfYm91bmRhcnlfbWFzayB0byBQQUdFX1NJWkUgLSAxIGd1YXJh
bnRlZXMgd2UnbGwgbmV2ZXIgc2VlDQo+IHN1Y2ggaG9sZXMgc28gd2UgY2FuIHNpZ25pZmljYW50
bHkgc2ltcGxpZnkgdGhlIGRyaXZlci4gVGhpcyBpcyBhbHNvDQo+IHN1cHBvc2VkIHRvIGJyaW5n
IHVzIHNvbWUgcGVyZm9ybWFuY2UgaW1wcm92ZW1lbnQgZm9yIGNlcnRhaW4gd29ya2xvYWRzDQo+
IGFzIHdlIGVsaW1pbmF0ZSBjb3B5aW5nLg0KPiANCj4gUmVwb3J0ZWQtYnk6IFJhZGltIEtyxI1t
w6HFmSA8cmtyY21hckByZWRoYXQuY29tPg0KPiBTaWduZWQtb2ZmLWJ5OiBWaXRhbHkgS3V6bmV0
c292IDx2a3V6bmV0c0ByZWRoYXQuY29tPg0KPiAtLS0NCj4gQ2hhbmdlcyBzaW5jZSB2MToNCj4g
LSBUaGlzIHBhdGNoIGlzIGEgc3VjY2Vzc29yIG9mICdzdG9ydnNjOiBnZXQgcmlkIG9mIGhvbWVn
cm93bg0KPiAgY29weV97dG8sZnJvbX1fYm91bmNlX2J1ZmZlcigpJy4gVXNlIHZpcnRfYm91bmRh
cnkgaW5zdGVhZCB0bw0KPiAgZWxpbWluYXRlIHRoZSBuZWVkIGZvciBib3VuY2UgYnVmZmVyIGNv
bXBsZXRlbHkgW0NocmlzdG9waCBIZWxsd2lnXS4NCj4gLS0tDQo+ICBkcml2ZXJzL3Njc2kvc3Rv
cnZzY19kcnYuYyB8IDI4NiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0NCj4gIDEgZmlsZSBjaGFuZ2VkLCA1IGluc2VydGlvbnMoKyksIDI4MSBkZWxldGlvbnMo
LSkNCj4gDQo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3Njc2kvc3RvcnZzY19kcnYuYyBiL2RyaXZl
cnMvc2NzaS9zdG9ydnNjX2Rydi5jDQo+IGluZGV4IDQwYzQzYWUuLmVlYWRlNDAgMTAwNjQ0DQo+
IC0tLSBhL2RyaXZlcnMvc2NzaS9zdG9ydnNjX2Rydi5jDQo+ICsrKyBiL2RyaXZlcnMvc2NzaS9z
dG9ydnNjX2Rydi5jDQo+IEBAIC0zOTMsOSArMzkzLDYgQEAgc3RhdGljIHZvaWQgc3RvcnZzY19v
bl9jaGFubmVsX2NhbGxiYWNrKHZvaWQNCj4gKmNvbnRleHQpOw0KPiAgc3RydWN0IHN0b3J2c2Nf
Y21kX3JlcXVlc3Qgew0KPiAgCXN0cnVjdCBzY3NpX2NtbmQgKmNtZDsNCj4gDQo+IC0JdW5zaWdu
ZWQgaW50IGJvdW5jZV9zZ2xfY291bnQ7DQo+IC0Jc3RydWN0IHNjYXR0ZXJsaXN0ICpib3VuY2Vf
c2dsOw0KPiAtDQo+ICAJc3RydWN0IGh2X2RldmljZSAqZGV2aWNlOw0KPiANCj4gIAkvKiBTeW5j
aHJvbml6ZSB0aGUgcmVxdWVzdC9yZXNwb25zZSBpZiBuZWVkZWQgKi8NCj4gQEAgLTU4NiwyNDEg
KzU4Myw2IEBAIGdldF9pbl9lcnI6DQo+IA0KPiAgfQ0KPiANCj4gLXN0YXRpYyB2b2lkIGRlc3Ry
b3lfYm91bmNlX2J1ZmZlcihzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnNnbCwNCj4gLQkJCQkgIHVuc2ln
bmVkIGludCBzZ19jb3VudCkNCj4gLXsNCj4gLQlpbnQgaTsNCj4gLQlzdHJ1Y3QgcGFnZSAqcGFn
ZV9idWY7DQo+IC0NCj4gLQlmb3IgKGkgPSAwOyBpIDwgc2dfY291bnQ7IGkrKykgew0KPiAtCQlw
YWdlX2J1ZiA9IHNnX3BhZ2UoKCZzZ2xbaV0pKTsNCj4gLQkJaWYgKHBhZ2VfYnVmICE9IE5VTEwp
DQo+IC0JCQlfX2ZyZWVfcGFnZShwYWdlX2J1Zik7DQo+IC0JfQ0KPiAtDQo+IC0Ja2ZyZWUoc2ds
KTsNCj4gLX0NCj4gLQ0KPiAtc3RhdGljIGludCBkb19ib3VuY2VfYnVmZmVyKHN0cnVjdCBzY2F0
dGVybGlzdCAqc2dsLCB1bnNpZ25lZCBpbnQgc2dfY291bnQpDQo+IC17DQo+IC0JaW50IGk7DQo+
IC0NCj4gLQkvKiBObyBuZWVkIHRvIGNoZWNrICovDQo+IC0JaWYgKHNnX2NvdW50IDwgMikNCj4g
LQkJcmV0dXJuIC0xOw0KPiAtDQo+IC0JLyogV2UgaGF2ZSBhdCBsZWFzdCAyIHNnIGVudHJpZXMg
Ki8NCj4gLQlmb3IgKGkgPSAwOyBpIDwgc2dfY291bnQ7IGkrKykgew0KPiAtCQlpZiAoaSA9PSAw
KSB7DQo+IC0JCQkvKiBtYWtlIHN1cmUgMXN0IG9uZSBkb2VzIG5vdCBoYXZlIGhvbGUgKi8NCj4g
LQkJCWlmIChzZ2xbaV0ub2Zmc2V0ICsgc2dsW2ldLmxlbmd0aCAhPSBQQUdFX1NJWkUpDQo+IC0J
CQkJcmV0dXJuIGk7DQo+IC0JCX0gZWxzZSBpZiAoaSA9PSBzZ19jb3VudCAtIDEpIHsNCj4gLQkJ
CS8qIG1ha2Ugc3VyZSBsYXN0IG9uZSBkb2VzIG5vdCBoYXZlIGhvbGUgKi8NCj4gLQkJCWlmIChz
Z2xbaV0ub2Zmc2V0ICE9IDApDQo+IC0JCQkJcmV0dXJuIGk7DQo+IC0JCX0gZWxzZSB7DQo+IC0J
CQkvKiBtYWtlIHN1cmUgbm8gaG9sZSBpbiB0aGUgbWlkZGxlICovDQo+IC0JCQlpZiAoc2dsW2ld
Lmxlbmd0aCAhPSBQQUdFX1NJWkUgfHwgc2dsW2ldLm9mZnNldCAhPSAwKQ0KPiAtCQkJCXJldHVy
biBpOw0KPiAtCQl9DQo+IC0JfQ0KPiAtCXJldHVybiAtMTsNCj4gLX0NCj4gLQ0KPiAtc3RhdGlj
IHN0cnVjdCBzY2F0dGVybGlzdCAqY3JlYXRlX2JvdW5jZV9idWZmZXIoc3RydWN0IHNjYXR0ZXJs
aXN0ICpzZ2wsDQo+IC0JCQkJCQl1bnNpZ25lZCBpbnQgc2dfY291bnQsDQo+IC0JCQkJCQl1bnNp
Z25lZCBpbnQgbGVuLA0KPiAtCQkJCQkJaW50IHdyaXRlKQ0KPiAtew0KPiAtCWludCBpOw0KPiAt
CWludCBudW1fcGFnZXM7DQo+IC0Jc3RydWN0IHNjYXR0ZXJsaXN0ICpib3VuY2Vfc2dsOw0KPiAt
CXN0cnVjdCBwYWdlICpwYWdlX2J1ZjsNCj4gLQl1bnNpZ25lZCBpbnQgYnVmX2xlbiA9ICgod3Jp
dGUgPT0gV1JJVEVfVFlQRSkgPyAwIDogUEFHRV9TSVpFKTsNCj4gLQ0KPiAtCW51bV9wYWdlcyA9
IEFMSUdOKGxlbiwgUEFHRV9TSVpFKSA+PiBQQUdFX1NISUZUOw0KPiAtDQo+IC0JYm91bmNlX3Nn
bCA9IGtjYWxsb2MobnVtX3BhZ2VzLCBzaXplb2Yoc3RydWN0IHNjYXR0ZXJsaXN0KSwNCj4gR0ZQ
X0FUT01JQyk7DQo+IC0JaWYgKCFib3VuY2Vfc2dsKQ0KPiAtCQlyZXR1cm4gTlVMTDsNCj4gLQ0K
PiAtCXNnX2luaXRfdGFibGUoYm91bmNlX3NnbCwgbnVtX3BhZ2VzKTsNCj4gLQlmb3IgKGkgPSAw
OyBpIDwgbnVtX3BhZ2VzOyBpKyspIHsNCj4gLQkJcGFnZV9idWYgPSBhbGxvY19wYWdlKEdGUF9B
VE9NSUMpOw0KPiAtCQlpZiAoIXBhZ2VfYnVmKQ0KPiAtCQkJZ290byBjbGVhbnVwOw0KPiAtCQlz
Z19zZXRfcGFnZSgmYm91bmNlX3NnbFtpXSwgcGFnZV9idWYsIGJ1Zl9sZW4sIDApOw0KPiAtCX0N
Cj4gLQ0KPiAtCXJldHVybiBib3VuY2Vfc2dsOw0KPiAtDQo+IC1jbGVhbnVwOg0KPiAtCWRlc3Ry
b3lfYm91bmNlX2J1ZmZlcihib3VuY2Vfc2dsLCBudW1fcGFnZXMpOw0KPiAtCXJldHVybiBOVUxM
Ow0KPiAtfQ0KPiAtDQo+IC0vKiBBc3N1bWUgdGhlIG9yaWdpbmFsIHNnbCBoYXMgZW5vdWdoIHJv
b20gKi8NCj4gLXN0YXRpYyB1bnNpZ25lZCBpbnQgY29weV9mcm9tX2JvdW5jZV9idWZmZXIoc3Ry
dWN0IHNjYXR0ZXJsaXN0ICpvcmlnX3NnbCwNCj4gLQkJCQkJICAgIHN0cnVjdCBzY2F0dGVybGlz
dCAqYm91bmNlX3NnbCwNCj4gLQkJCQkJICAgIHVuc2lnbmVkIGludCBvcmlnX3NnbF9jb3VudCwN
Cj4gLQkJCQkJICAgIHVuc2lnbmVkIGludCBib3VuY2Vfc2dsX2NvdW50KQ0KPiAtew0KPiAtCWlu
dCBpOw0KPiAtCWludCBqID0gMDsNCj4gLQl1bnNpZ25lZCBsb25nIHNyYywgZGVzdDsNCj4gLQl1
bnNpZ25lZCBpbnQgc3JjbGVuLCBkZXN0bGVuLCBjb3B5bGVuOw0KPiAtCXVuc2lnbmVkIGludCB0
b3RhbF9jb3BpZWQgPSAwOw0KPiAtCXVuc2lnbmVkIGxvbmcgYm91bmNlX2FkZHIgPSAwOw0KPiAt
CXVuc2lnbmVkIGxvbmcgZGVzdF9hZGRyID0gMDsNCj4gLQl1bnNpZ25lZCBsb25nIGZsYWdzOw0K
PiAtCXN0cnVjdCBzY2F0dGVybGlzdCAqY3VyX2Rlc3Rfc2dsOw0KPiAtCXN0cnVjdCBzY2F0dGVy
bGlzdCAqY3VyX3NyY19zZ2w7DQo+IC0NCj4gLQlsb2NhbF9pcnFfc2F2ZShmbGFncyk7DQo+IC0J
Y3VyX2Rlc3Rfc2dsID0gb3JpZ19zZ2w7DQo+IC0JY3VyX3NyY19zZ2wgPSBib3VuY2Vfc2dsOw0K
PiAtCWZvciAoaSA9IDA7IGkgPCBvcmlnX3NnbF9jb3VudDsgaSsrKSB7DQo+IC0JCWRlc3RfYWRk
ciA9ICh1bnNpZ25lZCBsb25nKQ0KPiAtCQkJCWttYXBfYXRvbWljKHNnX3BhZ2UoY3VyX2Rlc3Rf
c2dsKSkgKw0KPiAtCQkJCWN1cl9kZXN0X3NnbC0+b2Zmc2V0Ow0KPiAtCQlkZXN0ID0gZGVzdF9h
ZGRyOw0KPiAtCQlkZXN0bGVuID0gY3VyX2Rlc3Rfc2dsLT5sZW5ndGg7DQo+IC0NCj4gLQkJaWYg
KGJvdW5jZV9hZGRyID09IDApDQo+IC0JCQlib3VuY2VfYWRkciA9ICh1bnNpZ25lZCBsb25nKWtt
YXBfYXRvbWljKA0KPiAtDQo+IAlzZ19wYWdlKGN1cl9zcmNfc2dsKSk7DQo+IC0NCj4gLQkJd2hp
bGUgKGRlc3RsZW4pIHsNCj4gLQkJCXNyYyA9IGJvdW5jZV9hZGRyICsgY3VyX3NyY19zZ2wtPm9m
ZnNldDsNCj4gLQkJCXNyY2xlbiA9IGN1cl9zcmNfc2dsLT5sZW5ndGggLSBjdXJfc3JjX3NnbC0+
b2Zmc2V0Ow0KPiAtDQo+IC0JCQljb3B5bGVuID0gbWluKHNyY2xlbiwgZGVzdGxlbik7DQo+IC0J
CQltZW1jcHkoKHZvaWQgKilkZXN0LCAodm9pZCAqKXNyYywgY29weWxlbik7DQo+IC0NCj4gLQkJ
CXRvdGFsX2NvcGllZCArPSBjb3B5bGVuOw0KPiAtCQkJY3VyX3NyY19zZ2wtPm9mZnNldCArPSBj
b3B5bGVuOw0KPiAtCQkJZGVzdGxlbiAtPSBjb3B5bGVuOw0KPiAtCQkJZGVzdCArPSBjb3B5bGVu
Ow0KPiAtDQo+IC0JCQlpZiAoY3VyX3NyY19zZ2wtPm9mZnNldCA9PSBjdXJfc3JjX3NnbC0+bGVu
Z3RoKSB7DQo+IC0JCQkJLyogZnVsbCAqLw0KPiAtCQkJCWt1bm1hcF9hdG9taWMoKHZvaWQgKili
b3VuY2VfYWRkcik7DQo+IC0JCQkJaisrOw0KPiAtDQo+IC0JCQkJLyoNCj4gLQkJCQkgKiBJdCBp
cyBwb3NzaWJsZSB0aGF0IHRoZSBudW1iZXIgb2YgZWxlbWVudHMNCj4gLQkJCQkgKiBpbiB0aGUg
Ym91bmNlIGJ1ZmZlciBtYXkgbm90IGJlIGVxdWFsIHRvDQo+IC0JCQkJICogdGhlIG51bWJlciBv
ZiBlbGVtZW50cyBpbiB0aGUgb3JpZ2luYWwNCj4gLQkJCQkgKiBzY2F0dGVyIGxpc3QuIEhhbmRs
ZSB0aGlzIGNvcnJlY3RseS4NCj4gLQkJCQkgKi8NCj4gLQ0KPiAtCQkJCWlmIChqID09IGJvdW5j
ZV9zZ2xfY291bnQpIHsNCj4gLQkJCQkJLyoNCj4gLQkJCQkJICogV2UgYXJlIGRvbmU7IGNsZWFu
dXAgYW5kIHJldHVybi4NCj4gLQkJCQkJICovDQo+IC0JCQkJCWt1bm1hcF9hdG9taWMoKHZvaWQg
KikoZGVzdF9hZGRyIC0NCj4gLQkJCQkJCWN1cl9kZXN0X3NnbC0+b2Zmc2V0KSk7DQo+IC0JCQkJ
CWxvY2FsX2lycV9yZXN0b3JlKGZsYWdzKTsNCj4gLQkJCQkJcmV0dXJuIHRvdGFsX2NvcGllZDsN
Cj4gLQkJCQl9DQo+IC0NCj4gLQkJCQkvKiBpZiB3ZSBuZWVkIHRvIHVzZSBhbm90aGVyIGJvdW5j
ZSBidWZmZXINCj4gKi8NCj4gLQkJCQlpZiAoZGVzdGxlbiB8fCBpICE9IG9yaWdfc2dsX2NvdW50
IC0gMSkgew0KPiAtCQkJCQljdXJfc3JjX3NnbCA9IHNnX25leHQoY3VyX3NyY19zZ2wpOw0KPiAt
CQkJCQlib3VuY2VfYWRkciA9ICh1bnNpZ25lZCBsb25nKQ0KPiAtCQkJCQkJCWttYXBfYXRvbWlj
KA0KPiAtDQo+IAlzZ19wYWdlKGN1cl9zcmNfc2dsKSk7DQo+IC0JCQkJfQ0KPiAtCQkJfSBlbHNl
IGlmIChkZXN0bGVuID09IDAgJiYgaSA9PSBvcmlnX3NnbF9jb3VudCAtIDEpIHsNCj4gLQkJCQkv
KiB1bm1hcCB0aGUgbGFzdCBib3VuY2UgdGhhdCBpcyA8IFBBR0VfU0laRQ0KPiAqLw0KPiAtCQkJ
CWt1bm1hcF9hdG9taWMoKHZvaWQgKilib3VuY2VfYWRkcik7DQo+IC0JCQl9DQo+IC0JCX0NCj4g
LQ0KPiAtCQlrdW5tYXBfYXRvbWljKCh2b2lkICopKGRlc3RfYWRkciAtIGN1cl9kZXN0X3NnbC0+
b2Zmc2V0KSk7DQo+IC0JCWN1cl9kZXN0X3NnbCA9IHNnX25leHQoY3VyX2Rlc3Rfc2dsKTsNCj4g
LQl9DQo+IC0NCj4gLQlsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7DQo+IC0NCj4gLQlyZXR1cm4g
dG90YWxfY29waWVkOw0KPiAtfQ0KPiAtDQo+IC0vKiBBc3N1bWUgdGhlIGJvdW5jZV9zZ2wgaGFz
IGVub3VnaCByb29tIGllIHVzaW5nIHRoZQ0KPiBjcmVhdGVfYm91bmNlX2J1ZmZlcigpICovDQo+
IC1zdGF0aWMgdW5zaWduZWQgaW50IGNvcHlfdG9fYm91bmNlX2J1ZmZlcihzdHJ1Y3Qgc2NhdHRl
cmxpc3QgKm9yaWdfc2dsLA0KPiAtCQkJCQkgIHN0cnVjdCBzY2F0dGVybGlzdCAqYm91bmNlX3Nn
bCwNCj4gLQkJCQkJICB1bnNpZ25lZCBpbnQgb3JpZ19zZ2xfY291bnQpDQo+IC17DQo+IC0JaW50
IGk7DQo+IC0JaW50IGogPSAwOw0KPiAtCXVuc2lnbmVkIGxvbmcgc3JjLCBkZXN0Ow0KPiAtCXVu
c2lnbmVkIGludCBzcmNsZW4sIGRlc3RsZW4sIGNvcHlsZW47DQo+IC0JdW5zaWduZWQgaW50IHRv
dGFsX2NvcGllZCA9IDA7DQo+IC0JdW5zaWduZWQgbG9uZyBib3VuY2VfYWRkciA9IDA7DQo+IC0J
dW5zaWduZWQgbG9uZyBzcmNfYWRkciA9IDA7DQo+IC0JdW5zaWduZWQgbG9uZyBmbGFnczsNCj4g
LQlzdHJ1Y3Qgc2NhdHRlcmxpc3QgKmN1cl9zcmNfc2dsOw0KPiAtCXN0cnVjdCBzY2F0dGVybGlz
dCAqY3VyX2Rlc3Rfc2dsOw0KPiAtDQo+IC0JbG9jYWxfaXJxX3NhdmUoZmxhZ3MpOw0KPiAtDQo+
IC0JY3VyX3NyY19zZ2wgPSBvcmlnX3NnbDsNCj4gLQljdXJfZGVzdF9zZ2wgPSBib3VuY2Vfc2ds
Ow0KPiAtDQo+IC0JZm9yIChpID0gMDsgaSA8IG9yaWdfc2dsX2NvdW50OyBpKyspIHsNCj4gLQkJ
c3JjX2FkZHIgPSAodW5zaWduZWQgbG9uZykNCj4gLQkJCQlrbWFwX2F0b21pYyhzZ19wYWdlKGN1
cl9zcmNfc2dsKSkgKw0KPiAtCQkJCWN1cl9zcmNfc2dsLT5vZmZzZXQ7DQo+IC0JCXNyYyA9IHNy
Y19hZGRyOw0KPiAtCQlzcmNsZW4gPSBjdXJfc3JjX3NnbC0+bGVuZ3RoOw0KPiAtDQo+IC0JCWlm
IChib3VuY2VfYWRkciA9PSAwKQ0KPiAtCQkJYm91bmNlX2FkZHIgPSAodW5zaWduZWQgbG9uZykN
Cj4gLQ0KPiAJa21hcF9hdG9taWMoc2dfcGFnZShjdXJfZGVzdF9zZ2wpKTsNCj4gLQ0KPiAtCQl3
aGlsZSAoc3JjbGVuKSB7DQo+IC0JCQkvKiBhc3N1bWUgYm91bmNlIG9mZnNldCBhbHdheXMgPT0g
MCAqLw0KPiAtCQkJZGVzdCA9IGJvdW5jZV9hZGRyICsgY3VyX2Rlc3Rfc2dsLT5sZW5ndGg7DQo+
IC0JCQlkZXN0bGVuID0gUEFHRV9TSVpFIC0gY3VyX2Rlc3Rfc2dsLT5sZW5ndGg7DQo+IC0NCj4g
LQkJCWNvcHlsZW4gPSBtaW4oc3JjbGVuLCBkZXN0bGVuKTsNCj4gLQkJCW1lbWNweSgodm9pZCAq
KWRlc3QsICh2b2lkICopc3JjLCBjb3B5bGVuKTsNCj4gLQ0KPiAtCQkJdG90YWxfY29waWVkICs9
IGNvcHlsZW47DQo+IC0JCQljdXJfZGVzdF9zZ2wtPmxlbmd0aCArPSBjb3B5bGVuOw0KPiAtCQkJ
c3JjbGVuIC09IGNvcHlsZW47DQo+IC0JCQlzcmMgKz0gY29weWxlbjsNCj4gLQ0KPiAtCQkJaWYg
KGN1cl9kZXN0X3NnbC0+bGVuZ3RoID09IFBBR0VfU0laRSkgew0KPiAtCQkJCS8qIGZ1bGwuLm1v
dmUgdG8gbmV4dCBlbnRyeSAqLw0KPiAtCQkJCWt1bm1hcF9hdG9taWMoKHZvaWQgKilib3VuY2Vf
YWRkcik7DQo+IC0JCQkJYm91bmNlX2FkZHIgPSAwOw0KPiAtCQkJCWorKzsNCj4gLQkJCX0NCj4g
LQ0KPiAtCQkJLyogaWYgd2UgbmVlZCB0byB1c2UgYW5vdGhlciBib3VuY2UgYnVmZmVyICovDQo+
IC0JCQlpZiAoc3JjbGVuICYmIGJvdW5jZV9hZGRyID09IDApIHsNCj4gLQkJCQljdXJfZGVzdF9z
Z2wgPSBzZ19uZXh0KGN1cl9kZXN0X3NnbCk7DQo+IC0JCQkJYm91bmNlX2FkZHIgPSAodW5zaWdu
ZWQgbG9uZykNCj4gLQkJCQkJCWttYXBfYXRvbWljKA0KPiAtCQkJCQkJc2dfcGFnZShjdXJfZGVz
dF9zZ2wpKTsNCj4gLQkJCX0NCj4gLQ0KPiAtCQl9DQo+IC0NCj4gLQkJa3VubWFwX2F0b21pYygo
dm9pZCAqKShzcmNfYWRkciAtIGN1cl9zcmNfc2dsLT5vZmZzZXQpKTsNCj4gLQkJY3VyX3NyY19z
Z2wgPSBzZ19uZXh0KGN1cl9zcmNfc2dsKTsNCj4gLQl9DQo+IC0NCj4gLQlpZiAoYm91bmNlX2Fk
ZHIpDQo+IC0JCWt1bm1hcF9hdG9taWMoKHZvaWQgKilib3VuY2VfYWRkcik7DQo+IC0NCj4gLQls
b2NhbF9pcnFfcmVzdG9yZShmbGFncyk7DQo+IC0NCj4gLQlyZXR1cm4gdG90YWxfY29waWVkOw0K
PiAtfQ0KPiAtDQo+ICBzdGF0aWMgdm9pZCBoYW5kbGVfc2NfY3JlYXRpb24oc3RydWN0IHZtYnVz
X2NoYW5uZWwgKm5ld19zYykNCj4gIHsNCj4gIAlzdHJ1Y3QgaHZfZGV2aWNlICpkZXZpY2UgPSBu
ZXdfc2MtPnByaW1hcnlfY2hhbm5lbC0+ZGV2aWNlX29iajsNCj4gQEAgLTExNzEsMTUgKzkzMyw2
IEBAIHN0YXRpYyB2b2lkIHN0b3J2c2NfY29tbWFuZF9jb21wbGV0aW9uKHN0cnVjdA0KPiBzdG9y
dnNjX2NtZF9yZXF1ZXN0ICpjbWRfcmVxdWVzdCkNCj4gIAlob3N0ID0gc3Rvcl9kZXYtPmhvc3Q7
DQo+IA0KPiAgCXZtX3NyYiA9ICZjbWRfcmVxdWVzdC0+dnN0b3JfcGFja2V0LnZtX3NyYjsNCj4g
LQlpZiAoY21kX3JlcXVlc3QtPmJvdW5jZV9zZ2xfY291bnQpIHsNCj4gLQkJaWYgKHZtX3NyYi0+
ZGF0YV9pbiA9PSBSRUFEX1RZUEUpDQo+IC0JCQljb3B5X2Zyb21fYm91bmNlX2J1ZmZlcihzY3Np
X3NnbGlzdChzY21uZCksDQo+IC0JCQkJCWNtZF9yZXF1ZXN0LT5ib3VuY2Vfc2dsLA0KPiAtCQkJ
CQlzY3NpX3NnX2NvdW50KHNjbW5kKSwNCj4gLQkJCQkJY21kX3JlcXVlc3QtPmJvdW5jZV9zZ2xf
Y291bnQpOw0KPiAtCQlkZXN0cm95X2JvdW5jZV9idWZmZXIoY21kX3JlcXVlc3QtPmJvdW5jZV9z
Z2wsDQo+IC0JCQkJCWNtZF9yZXF1ZXN0LT5ib3VuY2Vfc2dsX2NvdW50KTsNCj4gLQl9DQo+IA0K
PiAgCXNjbW5kLT5yZXN1bHQgPSB2bV9zcmItPnNjc2lfc3RhdHVzOw0KPiANCj4gQEAgLTE0NzQs
NiArMTIyNyw5IEBAIHN0YXRpYyBpbnQgc3RvcnZzY19kZXZpY2VfY29uZmlndXJlKHN0cnVjdA0K
PiBzY3NpX2RldmljZSAqc2RldmljZSkNCj4gDQo+ICAJYmxrX3F1ZXVlX3JxX3RpbWVvdXQoc2Rl
dmljZS0+cmVxdWVzdF9xdWV1ZSwgKHN0b3J2c2NfdGltZW91dA0KPiAqIEhaKSk7DQo+IA0KPiAr
CS8qIEVuc3VyZSB0aGVyZSBhcmUgbm8gZ2FwcyBpbiBwcmVzZW50ZWQgc2dscyAqLw0KPiArCWJs
a19xdWV1ZV92aXJ0X2JvdW5kYXJ5KHNkZXZpY2UtPnJlcXVlc3RfcXVldWUsIFBBR0VfU0laRSAt
IDEpOw0KPiArDQo+ICAJc2RldmljZS0+bm9fd3JpdGVfc2FtZSA9IDE7DQo+IA0KPiAgCS8qDQo+
IEBAIC0xNjkyLDQwICsxNDQ4LDEzIEBAIHN0YXRpYyBpbnQgc3RvcnZzY19xdWV1ZWNvbW1hbmQo
c3RydWN0DQo+IFNjc2lfSG9zdCAqaG9zdCwgc3RydWN0IHNjc2lfY21uZCAqc2NtbmQpDQo+ICAJ
cGF5bG9hZF9zeiA9IHNpemVvZihjbWRfcmVxdWVzdC0+bXBiKTsNCj4gDQo+ICAJaWYgKHNnX2Nv
dW50KSB7DQo+IC0JCS8qIGNoZWNrIGlmIHdlIG5lZWQgdG8gYm91bmNlIHRoZSBzZ2wgKi8NCj4g
LQkJaWYgKGRvX2JvdW5jZV9idWZmZXIoc2dsLCBzY3NpX3NnX2NvdW50KHNjbW5kKSkgIT0gLTEp
IHsNCj4gLQkJCWNtZF9yZXF1ZXN0LT5ib3VuY2Vfc2dsID0NCj4gLQkJCQljcmVhdGVfYm91bmNl
X2J1ZmZlcihzZ2wsIHNnX2NvdW50LA0KPiAtCQkJCQkJICAgICBsZW5ndGgsDQo+IC0JCQkJCQkg
ICAgIHZtX3NyYi0+ZGF0YV9pbik7DQo+IC0JCQlpZiAoIWNtZF9yZXF1ZXN0LT5ib3VuY2Vfc2ds
KQ0KPiAtCQkJCXJldHVybiBTQ1NJX01MUVVFVUVfSE9TVF9CVVNZOw0KPiAtDQo+IC0JCQljbWRf
cmVxdWVzdC0+Ym91bmNlX3NnbF9jb3VudCA9DQo+IC0JCQkJQUxJR04obGVuZ3RoLCBQQUdFX1NJ
WkUpID4+IFBBR0VfU0hJRlQ7DQo+IC0NCj4gLQkJCWlmICh2bV9zcmItPmRhdGFfaW4gPT0gV1JJ
VEVfVFlQRSkNCj4gLQkJCQljb3B5X3RvX2JvdW5jZV9idWZmZXIoc2dsLA0KPiAtCQkJCQljbWRf
cmVxdWVzdC0+Ym91bmNlX3NnbCwNCj4gc2dfY291bnQpOw0KPiAtDQo+IC0JCQlzZ2wgPSBjbWRf
cmVxdWVzdC0+Ym91bmNlX3NnbDsNCj4gLQkJCXNnX2NvdW50ID0gY21kX3JlcXVlc3QtPmJvdW5j
ZV9zZ2xfY291bnQ7DQo+IC0JCX0NCj4gLQ0KPiAtDQo+ICAJCWlmIChzZ19jb3VudCA+IE1BWF9Q
QUdFX0JVRkZFUl9DT1VOVCkgew0KPiANCj4gIAkJCXBheWxvYWRfc3ogPSAoc2dfY291bnQgKiBz
aXplb2Yodm9pZCAqKSArDQo+ICAJCQkJICAgICAgc2l6ZW9mKHN0cnVjdCB2bWJ1c19wYWNrZXRf
bXBiX2FycmF5KSk7DQo+ICAJCQlwYXlsb2FkID0ga21hbGxvYyhwYXlsb2FkX3N6LCBHRlBfQVRP
TUlDKTsNCj4gLQkJCWlmICghcGF5bG9hZCkgew0KPiAtCQkJCWlmIChjbWRfcmVxdWVzdC0+Ym91
bmNlX3NnbF9jb3VudCkNCj4gLQkJCQkJZGVzdHJveV9ib3VuY2VfYnVmZmVyKA0KPiAtCQkJCQlj
bWRfcmVxdWVzdC0+Ym91bmNlX3NnbCwNCj4gLQkJCQkJY21kX3JlcXVlc3QtPmJvdW5jZV9zZ2xf
Y291bnQpOw0KPiAtDQo+IC0JCQkJCXJldHVybg0KPiBTQ1NJX01MUVVFVUVfREVWSUNFX0JVU1k7
DQo+IC0JCQl9DQo+ICsJCQlpZiAoIXBheWxvYWQpDQo+ICsJCQkJcmV0dXJuIFNDU0lfTUxRVUVV
RV9ERVZJQ0VfQlVTWTsNCj4gIAkJfQ0KPiANCj4gIAkJcGF5bG9hZC0+cmFuZ2UubGVuID0gbGVu
Z3RoOw0KPiBAQCAtMTc1NCwxMSArMTQ4Myw2IEBAIHN0YXRpYyBpbnQgc3RvcnZzY19xdWV1ZWNv
bW1hbmQoc3RydWN0IFNjc2lfSG9zdA0KPiAqaG9zdCwgc3RydWN0IHNjc2lfY21uZCAqc2NtbmQp
DQo+IA0KPiAgCWlmIChyZXQgPT0gLUVBR0FJTikgew0KPiAgCQkvKiBubyBtb3JlIHNwYWNlICov
DQo+IC0NCj4gLQkJaWYgKGNtZF9yZXF1ZXN0LT5ib3VuY2Vfc2dsX2NvdW50KQ0KPiAtCQkJZGVz
dHJveV9ib3VuY2VfYnVmZmVyKGNtZF9yZXF1ZXN0LT5ib3VuY2Vfc2dsLA0KPiAtCQkJCQljbWRf
cmVxdWVzdC0+Ym91bmNlX3NnbF9jb3VudCk7DQo+IC0NCj4gIAkJcmV0dXJuIFNDU0lfTUxRVUVV
RV9ERVZJQ0VfQlVTWTsNCj4gIAl9DQo+IA0KPiAtLQ0KPiAyLjQuMw0KVGhhbmtzIFZpdGFseSBh
bmQgQ2hyaXN0b3BoLiBXZSB3aWxsIHJ1biB0aGlzIHBhdGNoIHRocm91Z2ggb3VyIHRlc3Rpbmcu
DQoNClJlZ2FyZHMsDQoNCksuIFkNCg==
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web