[dpdk-dev] [PATCH v4 09/20] eal/dev: implement device iteration initialization

Wiles, Keith keith.wiles at intel.com
Fri Mar 30 18:22:15 CEST 2018



> On Mar 30, 2018, at 10:53 AM, Gaëtan Rivet <gaetan.rivet at 6wind.com> wrote:
> 
> Hello Keith,

Hello Gaëtan,

>>> +		layers[i].kvlist = rte_kvargs_parse(copy, NULL);
>>> +		free(copy);
>> 
>> I am sorry this method of not adding blank lines is a bit silly and we need to rethink at least adding a few blank lines to help with grouping the code. This style will cause problems for new readers (old readers) to understand the code. This to me is a maintenance problem for the future and we need to fix this now.
>> 
>> Blank lines after if statements (with possible more comments) can help along with adding blank lines to group code is really the minimum amount of lines required. I have never seen someone state you have to many blanks lines in the code except two or more blank lines in a row. This is akin to having a single paragraph in a novel or letter and it makes it very hard to read. It is not hard to add some blank lines to the code for readability.
>> 
> 
> I understand. What I dislike is having inconsistencies in the layout of
> the code.
> 
> "Paragraphs", for lack of a better word, are high subjective and a
> matter of taste.

I bet your teacher(s) would disagree with that statement with one single paragraph in your book reports :-)
> 
> Given that subjectivity is not helpful in review and taste is hard to
> debate, I prefer to have a single terse rule, that is to avoid any
> additional bytes beside the bare minimum to respect checkpatch.

Taste is hard to debate, but you have gone the extreme route with only the bare minimum blank lines and that is not good as well. A silly script does not read code or understand code we the humans have to make the code readable.
> 
> When I feel the need to have a new "conceptual group", then I am forced
> to add a comment to explain what is happening. By not allowing blank
> lines, I thus feel the pressure for space and explanation more acutely.

A blank can give somewhat convey the same information without a comment, but not in all cases. Even a blank before a group of lines can convey this is a new logic section. I do not buy the point for needing the same terse rule here as most of the coding style is free form and allows for reading between the lines a bit.

We can make a rule here, but no blank lines in a function this size and the patch of this size is making DPDK not as professional looking as it could be.

I am not asking for a blank line after every statement, but when I see functions of this size without a blank lines it means we are not addressing readability for future developers to read this code. If you have to put a comment before a section of code then normally a blank line before the comment is reasonable.

Look at the rest of DPDK code and tell me that we do not use blank lines wisely or no blank lines other then what the silly checkpatch script flags.


Below I added a few blank lines not many, but just few to help the reader detect sections and breaks in the code. Even if you added a few lines or removed a few lines I would think this is much more readable in the long run.

(Wish I could remove the ‘+’ it would help to make my point clearer, but afraid email will left justify the code). 

+int __rte_experimental
+rte_dev_iterator_init(struct rte_dev_iterator *it,
+		      const char *devstr)
+{
+	struct {
+		const char *key;
+		const char *str;
+		struct rte_kvargs *kvlist;
+	} layers[] = {
+		{ "bus=",    NULL, NULL, },
+		{ "class=",  NULL, NULL, },
+		{ "driver=", NULL, NULL, },
+	};
+	struct rte_kvargs_pair *kv = NULL;
+	struct rte_class *cls = NULL;
+	struct rte_bus *bus = NULL;
+	const char *s = devstr;
+	size_t nblayer;
+	size_t i = 0;
+
+	/* Having both busstr and clsstr NULL is illegal,
+	 * marking this iterator as invalid unless
+	 * everything goes well.
+	 */
+	it->busstr = NULL;
+	it->clsstr = NULL;
+
+	/* Split each sub-lists. */
+	nblayer = dev_layer_count(devstr);
+	if (nblayer > RTE_DIM(layers)) {
+		RTE_LOG(ERR, EAL, "Invalid query: too many layers (%zu)\n",
+			nblayer);
+		rte_errno = EINVAL;
+		goto get_out;
+	}
+
+	while (s != NULL) {
+		char *copy;
+		char *end;
+
+		if (strncmp(layers[i].key, s,
+			    strlen(layers[i].key)))
+			goto next_layer;
+
+		layers[i].str = s;
+		copy = strdup(s);
+		if (copy == NULL) {
+			RTE_LOG(ERR, EAL, "OOM\n");
+			rte_errno = ENOMEM;
+			goto get_out;
+		}
+
+		end = strchr(copy, '/');
+		end = end ? end : strchr(copy, '\0');
+		end[0] = '\0';
+		layers[i].kvlist = rte_kvargs_parse(copy, NULL);
+		free(copy);
+
+		if (layers[i].kvlist == NULL) {
+			RTE_LOG(ERR, EAL, "Could not parse %s\n", s);
+			rte_errno = EINVAL;
+			goto get_out;
+		}
+
+		s = strchr(s, '/');
+		if (s != NULL)
+			s++;
+
+next_layer:
+		if (i >= RTE_DIM(layers)) {
+			RTE_LOG(ERR, EAL, "Unrecognized layer %s\n", s);
+			rte_errno = EINVAL;
+			goto get_out;
+		}
+		i++;
+	}
+
+	/* Parse each sub-list. */
+	for (i = 0; i < RTE_DIM(layers); i++) {
+		if (layers[i].kvlist == NULL)
+			continue;
+
+		kv = &layers[i].kvlist->pairs[0];
+		if (strcmp(kv->key, "bus") == 0) {
+			bus = rte_bus_find_by_name(kv->value);
+			if (bus == NULL) {
+				RTE_LOG(ERR, EAL, "Could not find bus \"%s\"\n",
+					kv->value);
+				rte_errno = EFAULT;
+				goto get_out;
+			}
+		} else if (strcmp(kv->key, "class") == 0) {
+			cls = rte_class_find_by_name(kv->value);
+			if (cls == NULL) {
+				RTE_LOG(ERR, EAL, "Could not find class \"%s\"\n",
+					kv->value);
+				rte_errno = EFAULT;
+				goto get_out;
+			}
+		} else if (strcmp(kv->key, "driver") == 0) {
+			/* Ignore */
+			continue;
+		}
+	}
+
+	/* The string should have at least
+	 * one layer specified.
+	 */
+	if (bus == NULL && cls == NULL) {
+		RTE_LOG(ERR, EAL,
+			"Either bus or class must be specified.\n");
+		rte_errno = EINVAL;
+		goto get_out;
+	}
+
+	if (bus != NULL && bus->dev_iterate == NULL) {
+		RTE_LOG(ERR, EAL, "Bus %s not supported\n", bus->name);
+		rte_errno = ENOTSUP;
+		goto get_out;
+	}
+
+	if (cls != NULL && cls->dev_iterate == NULL) {
+		RTE_LOG(ERR, EAL, "Class %s not supported\n", cls->name);
+		rte_errno = ENOTSUP;
+		goto get_out;
+	}
+
+	/* Fill iterator fields. */
+	if (bus != NULL)
+		it->busstr = layers[0].str;
+	if (cls != NULL)
+		it->clsstr = layers[1].str;
+
+	it->devstr = devstr;
+	it->bus = bus;
+	it->cls = cls;
+	it->device = NULL;
+	it->class_device = NULL;
+
+get_out:
+	for (i = 0; i < RTE_DIM(layers); i++) {
+		if (layers[i].kvlist)
+			rte_kvargs_free(layers[i].kvlist);
+	}
+
+	return -rte_errno;
+}

> 
> Also, this makes a patch context as information-rich as possible.
> 
>> I stopped reviewing the code as it became difficult to read IMO and just causing me a headache.
>> 
>> This problem needs to be addressed by the TSC IMO.
> 
> Sorry that it made it more difficult than necessary.
> It would be interesting if an addendum to the kernel coding style was
> made regarding blank lines.
> 
> Regards,
> -- 
> Gaëtan Rivet
> 6WIND

Regards,
Keith



More information about the dev mailing list