1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2018 Mellanox Technologies. All rights reserved */
4 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
6 #include <linux/kernel.h>
7 #include <linux/module.h>
8 #include <linux/slab.h>
9 #include <linux/random.h>
10 #include <linux/objagg.h>
18 static int key_id_index(unsigned int key_id
)
20 if (key_id
>= NUM_KEYS
) {
30 unsigned int root_count
;
31 unsigned int delta_count
;
32 char next_root_buf
[BUF_LEN
];
33 struct objagg_obj
*objagg_objs
[NUM_KEYS
];
34 unsigned int key_refs
[NUM_KEYS
];
43 unsigned int key_id_diff
;
46 static struct objagg_obj
*world_obj_get(struct world
*world
,
47 struct objagg
*objagg
,
50 struct objagg_obj
*objagg_obj
;
55 objagg_obj
= objagg_obj_get(objagg
, &key
);
56 if (IS_ERR(objagg_obj
)) {
57 pr_err("Key %u: Failed to get object.\n", key_id
);
60 if (!world
->key_refs
[key_id_index(key_id
)]) {
61 world
->objagg_objs
[key_id_index(key_id
)] = objagg_obj
;
62 } else if (world
->objagg_objs
[key_id_index(key_id
)] != objagg_obj
) {
63 pr_err("Key %u: God another object for the same key.\n",
66 goto err_key_id_check
;
68 world
->key_refs
[key_id_index(key_id
)]++;
72 objagg_obj_put(objagg
, objagg_obj
);
76 static void world_obj_put(struct world
*world
, struct objagg
*objagg
,
79 struct objagg_obj
*objagg_obj
;
81 if (!world
->key_refs
[key_id_index(key_id
)])
83 objagg_obj
= world
->objagg_objs
[key_id_index(key_id
)];
84 objagg_obj_put(objagg
, objagg_obj
);
85 world
->key_refs
[key_id_index(key_id
)]--;
88 #define MAX_KEY_ID_DIFF 5
90 static void *delta_create(void *priv
, void *parent_obj
, void *obj
)
92 struct tokey
*parent_key
= parent_obj
;
93 struct world
*world
= priv
;
94 struct tokey
*key
= obj
;
95 int diff
= key
->id
- parent_key
->id
;
98 if (diff
< 0 || diff
> MAX_KEY_ID_DIFF
)
99 return ERR_PTR(-EINVAL
);
101 delta
= kzalloc(sizeof(*delta
), GFP_KERNEL
);
103 return ERR_PTR(-ENOMEM
);
104 delta
->key_id_diff
= diff
;
105 world
->delta_count
++;
109 static void delta_destroy(void *priv
, void *delta_priv
)
111 struct delta
*delta
= delta_priv
;
112 struct world
*world
= priv
;
114 world
->delta_count
--;
118 static void *root_create(void *priv
, void *obj
)
120 struct world
*world
= priv
;
121 struct tokey
*key
= obj
;
124 root
= kzalloc(sizeof(*root
), GFP_KERNEL
);
126 return ERR_PTR(-ENOMEM
);
127 memcpy(&root
->key
, key
, sizeof(root
->key
));
128 memcpy(root
->buf
, world
->next_root_buf
, sizeof(root
->buf
));
133 static void root_destroy(void *priv
, void *root_priv
)
135 struct root
*root
= root_priv
;
136 struct world
*world
= priv
;
142 static int test_nodelta_obj_get(struct world
*world
, struct objagg
*objagg
,
143 unsigned int key_id
, bool should_create_root
)
145 unsigned int orig_root_count
= world
->root_count
;
146 struct objagg_obj
*objagg_obj
;
147 const struct root
*root
;
150 if (should_create_root
)
151 prandom_bytes(world
->next_root_buf
,
152 sizeof(world
->next_root_buf
));
154 objagg_obj
= world_obj_get(world
, objagg
, key_id
);
155 if (IS_ERR(objagg_obj
)) {
156 pr_err("Key %u: Failed to get object.\n", key_id
);
157 return PTR_ERR(objagg_obj
);
159 if (should_create_root
) {
160 if (world
->root_count
!= orig_root_count
+ 1) {
161 pr_err("Key %u: Root was not created\n", key_id
);
163 goto err_check_root_count
;
166 if (world
->root_count
!= orig_root_count
) {
167 pr_err("Key %u: Root was incorrectly created\n",
170 goto err_check_root_count
;
173 root
= objagg_obj_root_priv(objagg_obj
);
174 if (root
->key
.id
!= key_id
) {
175 pr_err("Key %u: Root has unexpected key id\n", key_id
);
177 goto err_check_key_id
;
179 if (should_create_root
&&
180 memcmp(world
->next_root_buf
, root
->buf
, sizeof(root
->buf
))) {
181 pr_err("Key %u: Buffer does not match the expected content\n",
190 err_check_root_count
:
191 objagg_obj_put(objagg
, objagg_obj
);
195 static int test_nodelta_obj_put(struct world
*world
, struct objagg
*objagg
,
196 unsigned int key_id
, bool should_destroy_root
)
198 unsigned int orig_root_count
= world
->root_count
;
200 world_obj_put(world
, objagg
, key_id
);
202 if (should_destroy_root
) {
203 if (world
->root_count
!= orig_root_count
- 1) {
204 pr_err("Key %u: Root was not destroyed\n", key_id
);
208 if (world
->root_count
!= orig_root_count
) {
209 pr_err("Key %u: Root was incorrectly destroyed\n",
217 static int check_stats_zero(struct objagg
*objagg
)
219 const struct objagg_stats
*stats
;
222 stats
= objagg_stats_get(objagg
);
224 return PTR_ERR(stats
);
226 if (stats
->stats_info_count
!= 0) {
227 pr_err("Stats: Object count is not zero while it should be\n");
231 objagg_stats_put(stats
);
235 static int check_stats_nodelta(struct objagg
*objagg
)
237 const struct objagg_stats
*stats
;
241 stats
= objagg_stats_get(objagg
);
243 return PTR_ERR(stats
);
245 if (stats
->stats_info_count
!= NUM_KEYS
) {
246 pr_err("Stats: Unexpected object count (%u expected, %u returned)\n",
247 NUM_KEYS
, stats
->stats_info_count
);
252 for (i
= 0; i
< stats
->stats_info_count
; i
++) {
253 if (stats
->stats_info
[i
].stats
.user_count
!= 2) {
254 pr_err("Stats: incorrect user count\n");
258 if (stats
->stats_info
[i
].stats
.delta_user_count
!= 2) {
259 pr_err("Stats: incorrect delta user count\n");
267 objagg_stats_put(stats
);
271 static void *delta_create_dummy(void *priv
, void *parent_obj
, void *obj
)
273 return ERR_PTR(-EOPNOTSUPP
);
276 static void delta_destroy_dummy(void *priv
, void *delta_priv
)
280 static const struct objagg_ops nodelta_ops
= {
281 .obj_size
= sizeof(struct tokey
),
282 .delta_create
= delta_create_dummy
,
283 .delta_destroy
= delta_destroy_dummy
,
284 .root_create
= root_create
,
285 .root_destroy
= root_destroy
,
288 static int test_nodelta(void)
290 struct world world
= {};
291 struct objagg
*objagg
;
295 objagg
= objagg_create(&nodelta_ops
, &world
);
297 return PTR_ERR(objagg
);
299 err
= check_stats_zero(objagg
);
301 goto err_stats_first_zero
;
303 /* First round of gets, the root objects should be created */
304 for (i
= 0; i
< NUM_KEYS
; i
++) {
305 err
= test_nodelta_obj_get(&world
, objagg
, i
, true);
307 goto err_obj_first_get
;
310 /* Do the second round of gets, all roots are already created,
311 * make sure that no new root is created
313 for (i
= 0; i
< NUM_KEYS
; i
++) {
314 err
= test_nodelta_obj_get(&world
, objagg
, i
, false);
316 goto err_obj_second_get
;
319 err
= check_stats_nodelta(objagg
);
321 goto err_stats_nodelta
;
323 for (i
= NUM_KEYS
- 1; i
>= 0; i
--) {
324 err
= test_nodelta_obj_put(&world
, objagg
, i
, false);
326 goto err_obj_first_put
;
328 for (i
= NUM_KEYS
- 1; i
>= 0; i
--) {
329 err
= test_nodelta_obj_put(&world
, objagg
, i
, true);
331 goto err_obj_second_put
;
334 err
= check_stats_zero(objagg
);
336 goto err_stats_second_zero
;
338 objagg_destroy(objagg
);
344 for (i
--; i
>= 0; i
--)
345 world_obj_put(&world
, objagg
, i
);
350 for (i
--; i
>= 0; i
--)
351 world_obj_put(&world
, objagg
, i
);
352 err_stats_first_zero
:
353 err_stats_second_zero
:
354 objagg_destroy(objagg
);
358 static const struct objagg_ops delta_ops
= {
359 .obj_size
= sizeof(struct tokey
),
360 .delta_create
= delta_create
,
361 .delta_destroy
= delta_destroy
,
362 .root_create
= root_create
,
363 .root_destroy
= root_destroy
,
383 struct expect_stats_info
{
384 struct objagg_obj_stats stats
;
389 struct expect_stats
{
390 unsigned int info_count
;
391 struct expect_stats_info info
[NUM_KEYS
];
397 enum expect_delta expect_delta
;
398 enum expect_root expect_root
;
399 struct expect_stats expect_stats
;
402 #define EXPECT_STATS(count, ...) \
404 .info_count = count, \
405 .info = { __VA_ARGS__ } \
408 #define ROOT(key_id, user_count, delta_user_count) \
409 {{user_count, delta_user_count}, true, key_id}
411 #define DELTA(key_id, user_count) \
412 {{user_count, user_count}, false, key_id}
414 static const struct action_item action_items
[] = {
416 1, ACTION_GET
, EXPECT_DELTA_SAME
, EXPECT_ROOT_INC
,
417 EXPECT_STATS(1, ROOT(1, 1, 1)),
420 7, ACTION_GET
, EXPECT_DELTA_SAME
, EXPECT_ROOT_INC
,
421 EXPECT_STATS(2, ROOT(1, 1, 1), ROOT(7, 1, 1)),
424 3, ACTION_GET
, EXPECT_DELTA_INC
, EXPECT_ROOT_SAME
,
425 EXPECT_STATS(3, ROOT(1, 1, 2), ROOT(7, 1, 1),
427 }, /* r: 1, 7 d: 3^1 */
429 5, ACTION_GET
, EXPECT_DELTA_INC
, EXPECT_ROOT_SAME
,
430 EXPECT_STATS(4, ROOT(1, 1, 3), ROOT(7, 1, 1),
431 DELTA(3, 1), DELTA(5, 1)),
432 }, /* r: 1, 7 d: 3^1, 5^1 */
434 3, ACTION_GET
, EXPECT_DELTA_SAME
, EXPECT_ROOT_SAME
,
435 EXPECT_STATS(4, ROOT(1, 1, 4), ROOT(7, 1, 1),
436 DELTA(3, 2), DELTA(5, 1)),
437 }, /* r: 1, 7 d: 3^1, 3^1, 5^1 */
439 1, ACTION_GET
, EXPECT_DELTA_SAME
, EXPECT_ROOT_SAME
,
440 EXPECT_STATS(4, ROOT(1, 2, 5), ROOT(7, 1, 1),
441 DELTA(3, 2), DELTA(5, 1)),
442 }, /* r: 1, 1, 7 d: 3^1, 3^1, 5^1 */
444 30, ACTION_GET
, EXPECT_DELTA_SAME
, EXPECT_ROOT_INC
,
445 EXPECT_STATS(5, ROOT(1, 2, 5), ROOT(7, 1, 1), ROOT(30, 1, 1),
446 DELTA(3, 2), DELTA(5, 1)),
447 }, /* r: 1, 1, 7, 30 d: 3^1, 3^1, 5^1 */
449 8, ACTION_GET
, EXPECT_DELTA_INC
, EXPECT_ROOT_SAME
,
450 EXPECT_STATS(6, ROOT(1, 2, 5), ROOT(7, 1, 2), ROOT(30, 1, 1),
451 DELTA(3, 2), DELTA(5, 1), DELTA(8, 1)),
452 }, /* r: 1, 1, 7, 30 d: 3^1, 3^1, 5^1, 8^7 */
454 8, ACTION_GET
, EXPECT_DELTA_SAME
, EXPECT_ROOT_SAME
,
455 EXPECT_STATS(6, ROOT(1, 2, 5), ROOT(7, 1, 3), ROOT(30, 1, 1),
456 DELTA(3, 2), DELTA(8, 2), DELTA(5, 1)),
457 }, /* r: 1, 1, 7, 30 d: 3^1, 3^1, 5^1, 8^7, 8^7 */
459 3, ACTION_PUT
, EXPECT_DELTA_SAME
, EXPECT_ROOT_SAME
,
460 EXPECT_STATS(6, ROOT(1, 2, 4), ROOT(7, 1, 3), ROOT(30, 1, 1),
461 DELTA(8, 2), DELTA(3, 1), DELTA(5, 1)),
462 }, /* r: 1, 1, 7, 30 d: 3^1, 5^1, 8^7, 8^7 */
464 3, ACTION_PUT
, EXPECT_DELTA_DEC
, EXPECT_ROOT_SAME
,
465 EXPECT_STATS(5, ROOT(1, 2, 3), ROOT(7, 1, 3), ROOT(30, 1, 1),
466 DELTA(8, 2), DELTA(5, 1)),
467 }, /* r: 1, 1, 7, 30 d: 5^1, 8^7, 8^7 */
469 1, ACTION_PUT
, EXPECT_DELTA_SAME
, EXPECT_ROOT_SAME
,
470 EXPECT_STATS(5, ROOT(7, 1, 3), ROOT(1, 1, 2), ROOT(30, 1, 1),
471 DELTA(8, 2), DELTA(5, 1)),
472 }, /* r: 1, 7, 30 d: 5^1, 8^7, 8^7 */
474 1, ACTION_PUT
, EXPECT_DELTA_SAME
, EXPECT_ROOT_SAME
,
475 EXPECT_STATS(5, ROOT(7, 1, 3), ROOT(30, 1, 1), ROOT(1, 0, 1),
476 DELTA(8, 2), DELTA(5, 1)),
477 }, /* r: 7, 30 d: 5^1, 8^7, 8^7 */
479 5, ACTION_PUT
, EXPECT_DELTA_DEC
, EXPECT_ROOT_DEC
,
480 EXPECT_STATS(3, ROOT(7, 1, 3), ROOT(30, 1, 1),
482 }, /* r: 7, 30 d: 8^7, 8^7 */
484 5, ACTION_GET
, EXPECT_DELTA_SAME
, EXPECT_ROOT_INC
,
485 EXPECT_STATS(4, ROOT(7, 1, 3), ROOT(30, 1, 1), ROOT(5, 1, 1),
487 }, /* r: 7, 30, 5 d: 8^7, 8^7 */
489 6, ACTION_GET
, EXPECT_DELTA_INC
, EXPECT_ROOT_SAME
,
490 EXPECT_STATS(5, ROOT(7, 1, 3), ROOT(5, 1, 2), ROOT(30, 1, 1),
491 DELTA(8, 2), DELTA(6, 1)),
492 }, /* r: 7, 30, 5 d: 8^7, 8^7, 6^5 */
494 8, ACTION_GET
, EXPECT_DELTA_SAME
, EXPECT_ROOT_SAME
,
495 EXPECT_STATS(5, ROOT(7, 1, 4), ROOT(5, 1, 2), ROOT(30, 1, 1),
496 DELTA(8, 3), DELTA(6, 1)),
497 }, /* r: 7, 30, 5 d: 8^7, 8^7, 8^7, 6^5 */
499 8, ACTION_PUT
, EXPECT_DELTA_SAME
, EXPECT_ROOT_SAME
,
500 EXPECT_STATS(5, ROOT(7, 1, 3), ROOT(5, 1, 2), ROOT(30, 1, 1),
501 DELTA(8, 2), DELTA(6, 1)),
502 }, /* r: 7, 30, 5 d: 8^7, 8^7, 6^5 */
504 8, ACTION_PUT
, EXPECT_DELTA_SAME
, EXPECT_ROOT_SAME
,
505 EXPECT_STATS(5, ROOT(7, 1, 2), ROOT(5, 1, 2), ROOT(30, 1, 1),
506 DELTA(8, 1), DELTA(6, 1)),
507 }, /* r: 7, 30, 5 d: 8^7, 6^5 */
509 8, ACTION_PUT
, EXPECT_DELTA_DEC
, EXPECT_ROOT_SAME
,
510 EXPECT_STATS(4, ROOT(5, 1, 2), ROOT(7, 1, 1), ROOT(30, 1, 1),
512 }, /* r: 7, 30, 5 d: 6^5 */
514 8, ACTION_GET
, EXPECT_DELTA_INC
, EXPECT_ROOT_SAME
,
515 EXPECT_STATS(5, ROOT(5, 1, 3), ROOT(7, 1, 1), ROOT(30, 1, 1),
516 DELTA(6, 1), DELTA(8, 1)),
517 }, /* r: 7, 30, 5 d: 6^5, 8^5 */
519 7, ACTION_PUT
, EXPECT_DELTA_SAME
, EXPECT_ROOT_DEC
,
520 EXPECT_STATS(4, ROOT(5, 1, 3), ROOT(30, 1, 1),
521 DELTA(6, 1), DELTA(8, 1)),
522 }, /* r: 30, 5 d: 6^5, 8^5 */
524 30, ACTION_PUT
, EXPECT_DELTA_SAME
, EXPECT_ROOT_DEC
,
525 EXPECT_STATS(3, ROOT(5, 1, 3),
526 DELTA(6, 1), DELTA(8, 1)),
527 }, /* r: 5 d: 6^5, 8^5 */
529 5, ACTION_PUT
, EXPECT_DELTA_SAME
, EXPECT_ROOT_SAME
,
530 EXPECT_STATS(3, ROOT(5, 0, 2),
531 DELTA(6, 1), DELTA(8, 1)),
532 }, /* r: d: 6^5, 8^5 */
534 6, ACTION_PUT
, EXPECT_DELTA_DEC
, EXPECT_ROOT_SAME
,
535 EXPECT_STATS(2, ROOT(5, 0, 1),
539 8, ACTION_PUT
, EXPECT_DELTA_DEC
, EXPECT_ROOT_DEC
,
544 static int check_expect(struct world
*world
,
545 const struct action_item
*action_item
,
546 unsigned int orig_delta_count
,
547 unsigned int orig_root_count
)
549 unsigned int key_id
= action_item
->key_id
;
551 switch (action_item
->expect_delta
) {
552 case EXPECT_DELTA_SAME
:
553 if (orig_delta_count
!= world
->delta_count
) {
554 pr_err("Key %u: Delta count changed while expected to remain the same.\n",
559 case EXPECT_DELTA_INC
:
560 if (WARN_ON(action_item
->action
== ACTION_PUT
))
562 if (orig_delta_count
+ 1 != world
->delta_count
) {
563 pr_err("Key %u: Delta count was not incremented.\n",
568 case EXPECT_DELTA_DEC
:
569 if (WARN_ON(action_item
->action
== ACTION_GET
))
571 if (orig_delta_count
- 1 != world
->delta_count
) {
572 pr_err("Key %u: Delta count was not decremented.\n",
579 switch (action_item
->expect_root
) {
580 case EXPECT_ROOT_SAME
:
581 if (orig_root_count
!= world
->root_count
) {
582 pr_err("Key %u: Root count changed while expected to remain the same.\n",
587 case EXPECT_ROOT_INC
:
588 if (WARN_ON(action_item
->action
== ACTION_PUT
))
590 if (orig_root_count
+ 1 != world
->root_count
) {
591 pr_err("Key %u: Root count was not incremented.\n",
596 case EXPECT_ROOT_DEC
:
597 if (WARN_ON(action_item
->action
== ACTION_GET
))
599 if (orig_root_count
- 1 != world
->root_count
) {
600 pr_err("Key %u: Root count was not decremented.\n",
609 static unsigned int obj_to_key_id(struct objagg_obj
*objagg_obj
)
611 const struct tokey
*root_key
;
612 const struct delta
*delta
;
615 root_key
= objagg_obj_root_priv(objagg_obj
);
616 key_id
= root_key
->id
;
617 delta
= objagg_obj_delta_priv(objagg_obj
);
619 key_id
+= delta
->key_id_diff
;
624 check_expect_stats_nums(const struct objagg_obj_stats_info
*stats_info
,
625 const struct expect_stats_info
*expect_stats_info
,
628 if (stats_info
->is_root
!= expect_stats_info
->is_root
) {
630 *errmsg
= "Incorrect root/delta indication";
633 if (stats_info
->stats
.user_count
!=
634 expect_stats_info
->stats
.user_count
) {
636 *errmsg
= "Incorrect user count";
639 if (stats_info
->stats
.delta_user_count
!=
640 expect_stats_info
->stats
.delta_user_count
) {
642 *errmsg
= "Incorrect delta user count";
649 check_expect_stats_key_id(const struct objagg_obj_stats_info
*stats_info
,
650 const struct expect_stats_info
*expect_stats_info
,
653 if (obj_to_key_id(stats_info
->objagg_obj
) !=
654 expect_stats_info
->key_id
) {
656 *errmsg
= "incorrect key id";
662 static int check_expect_stats_neigh(const struct objagg_stats
*stats
,
663 const struct expect_stats
*expect_stats
,
669 for (i
= pos
- 1; i
>= 0; i
--) {
670 err
= check_expect_stats_nums(&stats
->stats_info
[i
],
671 &expect_stats
->info
[pos
], NULL
);
674 err
= check_expect_stats_key_id(&stats
->stats_info
[i
],
675 &expect_stats
->info
[pos
], NULL
);
679 for (i
= pos
+ 1; i
< stats
->stats_info_count
; i
++) {
680 err
= check_expect_stats_nums(&stats
->stats_info
[i
],
681 &expect_stats
->info
[pos
], NULL
);
684 err
= check_expect_stats_key_id(&stats
->stats_info
[i
],
685 &expect_stats
->info
[pos
], NULL
);
692 static int __check_expect_stats(const struct objagg_stats
*stats
,
693 const struct expect_stats
*expect_stats
,
699 if (stats
->stats_info_count
!= expect_stats
->info_count
) {
700 *errmsg
= "Unexpected object count";
704 for (i
= 0; i
< stats
->stats_info_count
; i
++) {
705 err
= check_expect_stats_nums(&stats
->stats_info
[i
],
706 &expect_stats
->info
[i
], errmsg
);
709 err
= check_expect_stats_key_id(&stats
->stats_info
[i
],
710 &expect_stats
->info
[i
], errmsg
);
712 /* It is possible that one of the neighbor stats with
713 * same numbers have the correct key id, so check it
715 err
= check_expect_stats_neigh(stats
, expect_stats
, i
);
723 static int check_expect_stats(struct objagg
*objagg
,
724 const struct expect_stats
*expect_stats
,
727 const struct objagg_stats
*stats
;
730 stats
= objagg_stats_get(objagg
);
732 return PTR_ERR(stats
);
733 err
= __check_expect_stats(stats
, expect_stats
, errmsg
);
734 objagg_stats_put(stats
);
738 static int test_delta_action_item(struct world
*world
,
739 struct objagg
*objagg
,
740 const struct action_item
*action_item
,
743 unsigned int orig_delta_count
= world
->delta_count
;
744 unsigned int orig_root_count
= world
->root_count
;
745 unsigned int key_id
= action_item
->key_id
;
746 enum action action
= action_item
->action
;
747 struct objagg_obj
*objagg_obj
;
752 action
= action
== ACTION_GET
? ACTION_PUT
: ACTION_GET
;
756 objagg_obj
= world_obj_get(world
, objagg
, key_id
);
757 if (IS_ERR(objagg_obj
))
758 return PTR_ERR(objagg_obj
);
761 world_obj_put(world
, objagg
, key_id
);
767 err
= check_expect(world
, action_item
,
768 orig_delta_count
, orig_root_count
);
773 err
= check_expect_stats(objagg
, &action_item
->expect_stats
, &errmsg
);
775 pr_err("Key %u: Stats: %s\n", action_item
->key_id
, errmsg
);
782 /* This can only happen when action is not inversed.
783 * So in case of an error, cleanup by doing inverse action.
785 test_delta_action_item(world
, objagg
, action_item
, true);
789 static int test_delta(void)
791 struct world world
= {};
792 struct objagg
*objagg
;
796 objagg
= objagg_create(&delta_ops
, &world
);
798 return PTR_ERR(objagg
);
800 for (i
= 0; i
< ARRAY_SIZE(action_items
); i
++) {
801 err
= test_delta_action_item(&world
, objagg
,
802 &action_items
[i
], false);
804 goto err_do_action_item
;
807 objagg_destroy(objagg
);
811 for (i
--; i
>= 0; i
--)
812 test_delta_action_item(&world
, objagg
, &action_items
[i
], true);
814 objagg_destroy(objagg
);
818 static int __init
test_objagg_init(void)
822 err
= test_nodelta();
828 static void __exit
test_objagg_exit(void)
832 module_init(test_objagg_init
);
833 module_exit(test_objagg_exit
);
834 MODULE_LICENSE("Dual BSD/GPL");
835 MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
836 MODULE_DESCRIPTION("Test module for objagg");