if (!test_and_clear_bit(CollisionCheck, &rdev->flags))
return;
- kfree(rdev->serial);
+ kvfree(rdev->serial);
rdev->serial = NULL;
}
static int rdev_init_serial(struct md_rdev *rdev)
{
+ /* serial_nums equals with BARRIER_BUCKETS_NR */
+ int i, serial_nums = 1 << ((PAGE_SHIFT - ilog2(sizeof(atomic_t))));
struct serial_in_rdev *serial = NULL;
if (test_bit(CollisionCheck, &rdev->flags))
return 0;
- serial = kmalloc(sizeof(struct serial_in_rdev), GFP_KERNEL);
+ serial = kvmalloc(sizeof(struct serial_in_rdev) * serial_nums,
+ GFP_KERNEL);
if (!serial)
return -ENOMEM;
- spin_lock_init(&serial->serial_lock);
- serial->serial_rb = RB_ROOT_CACHED;
- init_waitqueue_head(&serial->serial_io_wait);
+ for (i = 0; i < serial_nums; i++) {
+ struct serial_in_rdev *serial_tmp = &serial[i];
+
+ spin_lock_init(&serial_tmp->serial_lock);
+ serial_tmp->serial_rb = RB_ROOT_CACHED;
+ init_waitqueue_head(&serial_tmp->serial_io_wait);
+ }
+
rdev->serial = serial;
set_bit(CollisionCheck, &rdev->flags);
unsigned long flags;
int ret = 0;
struct mddev *mddev = rdev->mddev;
- struct serial_in_rdev *serial = rdev->serial;
+ int idx = sector_to_idx(lo);
+ struct serial_in_rdev *serial = &rdev->serial[idx];
si = mempool_alloc(mddev->serial_info_pool, GFP_NOIO);
unsigned long flags;
int found = 0;
struct mddev *mddev = rdev->mddev;
- struct serial_in_rdev *serial = rdev->serial;
+ int idx = sector_to_idx(lo);
+ struct serial_in_rdev *serial = &rdev->serial[idx];
spin_lock_irqsave(&serial->serial_lock, flags);
for (si = raid1_rb_iter_first(&serial->serial_rb, lo, hi);
for (i = 0; i < disks; i++) {
struct bio *mbio = NULL;
struct md_rdev *rdev = conf->mirrors[i].rdev;
- struct serial_in_rdev *serial = rdev->serial;
+ int idx = sector_to_idx(lo);
+ struct serial_in_rdev *serial = &rdev->serial[idx];
if (!r1_bio->bios[i])
continue;